diff --git a/.github/workflows/lock-threads.yml b/.github/workflows/lock-threads.yml index a39cefc4..5dfb3fcc 100644 --- a/.github/workflows/lock-threads.yml +++ b/.github/workflows/lock-threads.yml @@ -17,8 +17,9 @@ jobs: if: github.repository == 'vuejs/vitepress' runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@v4 + - uses: dessant/lock-threads@v5 with: issue-inactive-days: 7 pr-inactive-days: 7 exclude-any-issue-labels: 'keep-open' + exclude-any-pr-labels: 'keep-open' diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml index 1aa123ab..84a03487 100644 --- a/.github/workflows/release-tag.yml +++ b/.github/workflows/release-tag.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Create Release for Tag id: release_tag diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index ac4dc17e..3c646aa3 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -6,7 +6,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v8 + - uses: actions/stale@v9 with: days-before-stale: 30 days-before-close: -1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e36c5ee2..4fdb4296 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,13 +27,13 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v3 - name: Set node version to ${{ matrix.node_version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node_version }} cache: pnpm diff --git a/.gitignore b/.gitignore index 81c00934..64331052 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ examples-temp node_modules pnpm-global TODOs.md +*.timestamp-*.mjs diff --git a/CHANGELOG.md b/CHANGELOG.md index 24718ec2..27c4163e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,207 @@ +## [1.1.3](https://github.com/vuejs/vitepress/compare/v1.1.1...v1.1.3) (2024-04-18) + +### Bug Fixes + +- **build/regression:** markdown backslash escapes not working ([d02d1e9](https://github.com/vuejs/vitepress/commit/d02d1e923aacdb1e8061a3f76af30e8a13518277)), closes [#3808](https://github.com/vuejs/vitepress/issues/3808) + +## [1.1.1](https://github.com/vuejs/vitepress/compare/v1.1.0...v1.1.1) (2024-04-18) + +### Bug Fixes + +- **client:** don't reload page on hash change ([#3777](https://github.com/vuejs/vitepress/issues/3777)) ([74b725a](https://github.com/vuejs/vitepress/commit/74b725a224438ef776fed25ee82274429d94ac83)) +- let vue compiler handle entity decoding ([f86ac56](https://github.com/vuejs/vitepress/commit/f86ac56b78da76f3061e6537b897bb13c1ed802d)) +- hot updating config file suppresses error logs ([#3592](https://github.com/vuejs/vitepress/issues/3592)) ([cd5adf3](https://github.com/vuejs/vitepress/commit/cd5adf3011d677263c93ce6f8066aaa7870b1dfc)) + +# [1.1.0](https://github.com/vuejs/vitepress/compare/v1.0.2...v1.1.0) (2024-04-09) + +### Bug Fixes + +- **client:** hashchange should only be triggered for same page navigations ([#3768](https://github.com/vuejs/vitepress/issues/3768)) ([2a9fc2a](https://github.com/vuejs/vitepress/commit/2a9fc2a26b829bb3f28067ac6f4a41bc1e8b7a1e)) +- **client:** emit correct `Event` instance in hashchange event +- **theme:** remove small layout shift on `On this page` button ([#3767](https://github.com/vuejs/vitepress/issues/3767)) ([5f28e74](https://github.com/vuejs/vitepress/commit/5f28e74abfc984cdc7e0d9d9f7b7e15cb2b46923)) + +### Features + +- **client:** add `hash` property to `useData()` +- **theme:** update Inter to version 4 ([#3693](https://github.com/vuejs/vitepress/issues/3693)) ([#3694](https://github.com/vuejs/vitepress/issues/3694)) ([ffafa31](https://github.com/vuejs/vitepress/commit/ffafa31b9204f996f4b819684214fa631c224575)) + +## [1.0.2](https://github.com/vuejs/vitepress/compare/v1.0.1...v1.0.2) (2024-04-01) + +### Bug Fixes + +- **theme:** text containing html not showing properly in mobile nav menu ([3c8b4c7](https://github.com/vuejs/vitepress/commit/3c8b4c706051592dd2cca0ae57e293254cbb51ce)) + +## [1.0.1](https://github.com/vuejs/vitepress/compare/v1.0.0...v1.0.1) (2024-03-22) + +### Bug Fixes + +- **build:** vendor vue-demi to avoid resolution issues with yarn berry ([#3680](https://github.com/vuejs/vitepress/issues/3680)) ([5d3cb96](https://github.com/vuejs/vitepress/commit/5d3cb96ac364413aa9eb494bc91744bd8f4a2c79)) + +# [1.0.0](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.45...v1.0.0) (2024-03-21) + +### Bug Fixes + +- **build:** resolve pattern relative to srcDir instead of root in createContentLoader ([#3638](https://github.com/vuejs/vitepress/issues/3638)) ([59183e9](https://github.com/vuejs/vitepress/commit/59183e9cef112a004c8a8e2b365478af657858b0)) +- **localSearch:** remove empty titles that may appear in search results ([#3665](https://github.com/vuejs/vitepress/issues/3665)) ([f7aef3c](https://github.com/vuejs/vitepress/commit/f7aef3ca23dae39e226c85d7bb2579dbf7c758f3)) +- **theme:** fixed sidebar expand caret showing when no children are present ([#3657](https://github.com/vuejs/vitepress/issues/3657)) ([e13f932](https://github.com/vuejs/vitepress/commit/e13f93292ce1a2b1d5ba161fddfe947a1824a2b0)) +- **theme:** ignore inner-page items in next/prev link ([#3663](https://github.com/vuejs/vitepress/issues/3663)) ([b50a8a1](https://github.com/vuejs/vitepress/commit/b50a8a132577693817a15ab43fc4cc22670a8a65)) +- **theme:** local nav separator not visible on pages having no outline ([1909041](https://github.com/vuejs/vitepress/commit/190904171500ad22998c8666080fd58c867a59b5)) + +### Features + +- **theme:** allow selectively disabling external link icon on navbar items ([#3607](https://github.com/vuejs/vitepress/issues/3607)) ([5f6297c](https://github.com/vuejs/vitepress/commit/5f6297cb3df98926154235f31570e75820d4ea16)) + +# [1.0.0-rc.45](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.44...v1.0.0-rc.45) (2024-03-06) + +### Bug Fixes + +- **router:** hashchange not emitted in certain cases ([#3637](https://github.com/vuejs/vitepress/issues/3637)) ([f6bd99e...6c0125b](https://github.com/vuejs/vitepress/compare/f6bd99eb1311238e1114301a767634b139327916...6c0125b65513531870f00ebef1ae11096027875a)) + +### Features + +- set `__VITEPRESS__` for easy detection by plugins and other tools ([#3634](https://github.com/vuejs/vitepress/issues/3634)) ([f6bd99e](https://github.com/vuejs/vitepress/commit/f6bd99eb1311238e1114301a767634b139327916)) + +# [1.0.0-rc.44](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.43...v1.0.0-rc.44) (2024-2-19) + +### Reverts + +- types for internal components ([e703429](https://github.com/vuejs/vitepress/commit/e7034294731493a198cdd4789198f1c94f21b181)) + +# [1.0.0-rc.43](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.42...v1.0.0-rc.43) (2024-2-17) + +### Bug Fixes + +- handle process.env being undefined while process is not ([b63e0a0](https://github.com/vuejs/vitepress/commit/b63e0a0c57f886f49aa7e073ff623c918164bd0b)), closes [#3579](https://github.com/vuejs/vitepress/issues/3579) +- make local search work in combination with vue-i18n ([#3559](https://github.com/vuejs/vitepress/issues/3559)) ([6624bb7](https://github.com/vuejs/vitepress/commit/6624bb748610079b88e2dcef7ea1810833a54a85)) +- **theme:** adjust mathjax svg styles ([#3567](https://github.com/vuejs/vitepress/issues/3567)) ([2051100](https://github.com/vuejs/vitepress/commit/20511006dba516ca8c06ed1dd3516547af668a0e)) + +### Features + +- **theme:** auto style markdown content in home page ([#3561](https://github.com/vuejs/vitepress/issues/3561)) ([0903027](https://github.com/vuejs/vitepress/commit/09030272b4a5c8f723b7e11303265f24b7481575)) + +### Performance Improvements + +- **theme:** move svg icons to css ([#3537](https://github.com/vuejs/vitepress/issues/3537)) ([636cca0](https://github.com/vuejs/vitepress/commit/636cca042dfbca006af2d702ddec0a2ff601cb46)) + +### BREAKING CHANGES + +- The default theme now styles the markdown content in the home page. If you have custom styles that rely on the markdown content not being styled, you may need to adjust your styles, or add `markdownStyles: false` to the frontmatter of your home page. + +# [1.0.0-rc.42](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.41...v1.0.0-rc.42) (2024-2-6) + +### Bug Fixes + +- **md:** dont break on nesting blockquotes inside gfm alerts ([8f8a6fe](https://github.com/vuejs/vitepress/commit/8f8a6feb053b3f521a2c90e343dffa7f98bb63b3)), closes [#3512](https://github.com/vuejs/vitepress/issues/3512) +- **theme:** correctly normalize paths ending with "index" ([#3544](https://github.com/vuejs/vitepress/issues/3544)) ([c582a8d](https://github.com/vuejs/vitepress/commit/c582a8d5fd82b84d412c7e6c84e74faeb23beac6)) + +# [1.0.0-rc.41](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.40...v1.0.0-rc.41) (2024-2-1) + +### Bug Fixes + +- handle CRLF in snippet plugin ([5811b62](https://github.com/vuejs/vitepress/commit/5811b626576ec4569fa0079d921b8e328d87ca91)), closes [#3499](https://github.com/vuejs/vitepress/issues/3499) +- lazy evaluate known extensions to allow env set in config ([04f794b](https://github.com/vuejs/vitepress/commit/04f794bf55f8191ea9eed62f545b812f346017d8)) + +### Features + +- **home:** add target and rel attribute to home actions ([#3528](https://github.com/vuejs/vitepress/issues/3528)) ([ab39fd8](https://github.com/vuejs/vitepress/commit/ab39fd8592c994fbc6feba5ee369ca1205c50f04)) +- rename shiki packages ([#3506](https://github.com/vuejs/vitepress/issues/3506)) ([b8487d3](https://github.com/vuejs/vitepress/commit/b8487d3a97679f5b2eb225ee1eb85754b66fee30)) +- wrap site title in span ([#3522](https://github.com/vuejs/vitepress/issues/3522)) ([6b1f951](https://github.com/vuejs/vitepress/commit/6b1f951928a3b9e53dcc9697327b5aba4a5905e2)) +- **theme:** add hero slots that are inside container ([#3524](https://github.com/vuejs/vitepres/issues/3524)) ([28870e6](https://github.com/vuejs/vitepress/commit/28870e68faf0ddaa418ffe0d4371316f6b0bcd02)) + +### BREAKING CHANGES + +- vitepress now uses shiki instead of shikiji. If you’re on the latest version and using shikiji specific features, you just need to change imports. The shikijiSetup hook is renamed to shikiSetup. + +# [1.0.0-rc.40](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.39...v1.0.0-rc.40) (2024-1-22) + +### Bug Fixes + +- **client:** handle head orphans added in initial load ([#3474](https://github.com/vuejs/vitepress/issues/3474)) ([5e2d853](https://github.com/vuejs/vitepress/commit/5e2d853e1a315216dce5fc98ee2efd15c724a25d)) +- **theme:** avoid selecting summary on toggling details ([77a318c](https://github.com/vuejs/vitepress/commit/77a318c2a348d341dd3ea1e1650fcf8ad3abfcd7)) +- **theme:** hover color for code links inside custom containers ([#3467](https://github.com/vuejs/vitepress/issues/3467)) ([d529ed4](https://github.com/vuejs/vitepress/commit/d529ed49756841f055024c559d09875501bc6d76)) +- **type:** fix missed `VPBadge` type in `theme.d.ts` ([#3470](https://github.com/vuejs/vitepress/issues/3470)) ([fcf828c](https://github.com/vuejs/vitepress/commit/fcf828c2a71892dad5af8d21e405f4d1e2cc280c)) + +### Features + +- support GitHub-flavored alerts ([#3482](https://github.com/vuejs/vitepress/issues/3482)) ([ac87d19](https://github.com/vuejs/vitepress/commit/ac87d19ca1bbc966e5fe1cca5f433f5ea4b11be3)) +- support specifying custom extensions to escape routing ([#3466](https://github.com/vuejs/vitepress/issues/3466)) ([c22f5d9](https://github.com/vuejs/vitepress/commit/c22f5d983f3e5d5c4f0ed0683a93ece564487c13)) +- **theme:** add npm icon ([#3483](https://github.com/vuejs/vitepress/issues/3483)) ([c882fa1](https://github.com/vuejs/vitepress/commit/c882fa1469a7bd0d6e28196e7a841adf48e803f1)) + +# [1.0.0-rc.39](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.38...v1.0.0-rc.39) (2024-01-16) + +### Bug Fixes + +- **theme:** misaligned outline indicator ([#3458](https://github.com/vuejs/vitepress/issues/3458)) ([0ce5ece](https://github.com/vuejs/vitepress/commit/0ce5ece35687bdad7a65d61432419cfe3961a329)) +- **theme:** enter key behavior conflict with IME in search box ([#3454](https://github.com/vuejs/vitepress/issues/3454)) ([cd8ee6f](https://github.com/vuejs/vitepress/commit/cd8ee6fb32d8135e78c5827a36b79efad509042c)) +- **theme:** use`--vp-c-tip-` CSS variable for badge/block colors with type`tip` ([#3434](https://github.com/vuejs/vitepress/issues/3434)) ([78abf47](https://github.com/vuejs/vitepress/commit/78abf47b8b563d66db9d481a98bbdefac95cc84c)) + +### Features + +- **theme:** export VPBadge ([#3431](https://github.com/vuejs/vitepress/issues/3431)) ([18981c1](https://github.com/vuejs/vitepress/commit/18981c1d1c74a4f4ca379a88b00c02ba5eace6db)) + +# [1.0.0-rc.36](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.35...v1.0.0-rc.36) (2024-1-8) + +### Bug Fixes + +- avoid pushing to history when clicking on the current link ([#3405](https://github.com/vuejs/vitepress/issues/3405)) ([d279e63](https://github.com/vuejs/vitepress/commit/d279e63cb4d417420cdc3fb3e6e03c96b777289f)) +- **theme/regression:** external link icon not working ([c236570](https://github.com/vuejs/vitepress/commit/c236570f2806fe76bbc6a69568cf64ed5a3fc2ce)), closes [#3424](https://github.com/vuejs/vitepress/issues/3424) +- **theme/regression:** inter getting bundled even importing without-fonts entry ([#3412](https://github.com/vuejs/vitepress/issues/3412)) ([b03fb83](https://github.com/vuejs/vitepress/commit/b03fb83a4e67d92a865d90908ccbde3dd0f97373)) + +# [1.0.0-rc.35](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.34...v1.0.0-rc.35) (2024-1-3) + +### Bug Fixes + +- **client:** add computed dir and lang to html root ([c2b4c66](https://github.com/vuejs/vitepress/commit/c2b4c66e79fde7479f5f43841e1921a5c220c9a5)), closes [#3353](https://github.com//github.com/vuejs/vitepress/pull/3353/issues/issuecomment-1874753809) +- fill all empty code lines ([563020b](https://github.com/vuejs/vitepress/commit/563020ba61abda254af9a124ddafd12de644cd4e)), closes [#3305](https://github.com/vuejs/vitepress/issues/3305) +- fix theme chunking logic causing out-of-order styles ([#3403](https://github.com/vuejs/vitepress/issues/3403)) ([a6cd891](https://github.com/vuejs/vitepress/commit/a6cd891d95454b3130aaf08f499659d2585acc63)) +- invalidate module cache for subsequent builds ([#3398](https://github.com/vuejs/vitepress/issues/3398)) ([27f60e0](https://github.com/vuejs/vitepress/commit/27f60e0b7784603c6fb300bd8dce64515eb98962)) + +### Features + +- allow passing options to emoji plugin ([09e48db](https://github.com/vuejs/vitepress/commit/09e48db355f530c7a138437004659b61239f4b75)), closes [#3174](https://github.com/vuejs/vitepress/issues/3174) +- **theme:** allow specifying rel and target in logoLink ([6c89943](https://github.com/vuejs/vitepress/commit/6c899437c15b126b488e73c99cdaad77fc7e5611)), closes [#3264](https://github.com/vuejs/vitepress/issues/3264) [#3271](https://github.com/vuejs/vitepress/issues/3271) + +### Performance Improvements + +- **localSearch:** add concurrency pooling, cleanup logic, improve performance ([#3374](https://github.com/vuejs/vitepress/issues/3374)) ([ac5881e](https://github.com/vuejs/vitepress/commit/ac5881eeac3f042a8fbf034edb99e5f2b45eaa2a)) + +# [1.0.0-rc.34](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.33...v1.0.0-rc.34) (2023-12-30) + +### Bug Fixes + +- **build:** clear cache after build ([9568fea](https://github.com/vuejs/vitepress/commit/9568fea8fc50e625c8ef27c588eca3dbe5a44e81)), closes [#3363](https://github.com/vuejs/vitepress/issues/3363) +- **default-theme:** remove use of reactify for search i18n ([8687b86](https://github.com/vuejs/vitepress/commit/8687b86e1e00ae39ff9c8173aef04eb8a9cda0a8)) +- print errors when importing an invalid dynamic route ([#3201](https://github.com/vuejs/vitepress/issues/3201)) ([6d89a08](https://github.com/vuejs/vitepress/commit/6d89a08cb76674f4d92f54218f8af5624bcf4c47)) +- remove double title from home pages ([9f1f04e](https://github.com/vuejs/vitepress/commit/9f1f04e00a9722ec7369941c40d3d8ad86f61d35)), closes [#3375](https://github.com/vuejs/vitepress/issues/3375) +- **theme/i18n:** support customizing dark mode switch titles ([#3311](https://github.com/vuejs/vitepress/issues/3311)) ([50c9758](https://github.com/vuejs/vitepress/commit/50c9758d3fa1b60aad5399a0db890644ac44a522)) + +### Features + +- support custom image lazy loading ([#3346](https://github.com/vuejs/vitepress/issues/3346)) ([55be3f1](https://github.com/vuejs/vitepress/commit/55be3f14d79eb578c9aa2e3bc7a90205c910005d)) +- support dir in frontmatter ([#3353](https://github.com/vuejs/vitepress/issues/3353)) ([203446d](https://github.com/vuejs/vitepress/commit/203446d69193483a46e1082bba5fbad0e35966fb)) +- **theme/i18n:** allow customizing sponsor link's text ([#3276](https://github.com/vuejs/vitepress/issues/3276)) ([9c20e3b](https://github.com/vuejs/vitepress/commit/9c20e3b5f80e4197c14c20fa751ec3c8c8219e8e)) +- **theme:** allow using VPBadge classes in sidebar ([#3391](https://github.com/vuejs/vitepress/issues/3391)) ([50a774e](https://github.com/vuejs/vitepress/commit/50a774ea7c70bb200e12c176d6691ab7144a73f9)) +- **theme:** new design for local nav and global header ([#3359](https://github.com/vuejs/vitepress/issues/3359)) ([d10bf42](https://github.com/vuejs/vitepress/commit/d10bf42c2632f1aacb905bc01b36274e9004cbd9)) + +# [1.0.0-rc.33](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.32...v1.0.0-rc.33) (2023-12-26) + +### Features + +- allow explicitly mark code element as `.vp-copy-ignore` ([#3360](https://github.com/vuejs/vitepress/issues/3360)) ([93122ee](https://github.com/vuejs/vitepress/commit/93122eee20cb6586026c1ffac04d9787861cc2f3)) +- **build:** enable VUE_PROD_HYDRATION_MISMATCH_DETAILS when DEBUG is truthy ([f4d4280](https://github.com/vuejs/vitepress/commit/f4d4280d7d1728a966bb04968a9bac10470c3d06)), closes [#422](https://github.com/vuejs/vitepress/issues/422) + +### Performance Improvements + +- implement concurrent promise pooling for render task ([#3366](https://github.com/vuejs/vitepress/issues/3366)) + +# [1.0.0-rc.32](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.31...v1.0.0-rc.32) (2023-12-16) + +### Features + +- allow ignoring node in header ([#3331](https://github.com/vuejs/vitepress/issues/3331)) ([e4bf1e4](https://github.com/vuejs/vitepress/commit/e4bf1e48e6a1592d583b218425c1fa7497955dc5)) +- expose `shikijiSetup` hook ([#3344](https://github.com/vuejs/vitepress/issues/3344)) ([d12e23d](https://github.com/vuejs/vitepress/commit/d12e23ddf69480418078ff39846c99ecf2e1eb1b)) +- update shikiji, support twoslash ([#3339](https://github.com/vuejs/vitepress/issues/3339)) ([8800195](https://github.com/vuejs/vitepress/commit/880019545795fd075be89d94794bfbd05af461b5)) + # [1.0.0-rc.31](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.30...v1.0.0-rc.31) (2023-11-25) ### Bug Fixes diff --git a/README.md b/README.md index a8ccec37..2e70a766 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,12 @@ -# VitePress (RC: release candidate) 📝💨 +# VitePress 📝💨 -[![Test](https://github.com/vuejs/vitepress/workflows/Test/badge.svg)](https://github.com/vuejs/vitepress/actions) +[![test](https://github.com/vuejs/vitepress/workflows/Test/badge.svg)](https://github.com/vuejs/vitepress/actions) [![npm](https://img.shields.io/npm/v/vitepress)](https://www.npmjs.com/package/vitepress) [![chat](https://img.shields.io/badge/chat-discord-blue?logo=discord)](https://chat.vuejs.org) --- -VitePress is [VuePress](https://vuepress.vuejs.org)' spiritual successor, built on top of [vite](https://github.com/vitejs/vite). - -Currently, it is in the `release candidate` stage. It is already suitable for out-of-the-box documentation use. We do not plan to introduce any breaking changes from here on until the stable release. +VitePress is a Vue-powered static site generator and a spiritual successor to [VuePress](https://vuepress.vuejs.org), built on top of [Vite](https://github.com/vitejs/vite). ## Documentation diff --git a/__tests__/e2e/.vitepress/config.ts b/__tests__/e2e/.vitepress/config.ts index 84fc64f2..e4e503a6 100644 --- a/__tests__/e2e/.vitepress/config.ts +++ b/__tests__/e2e/.vitepress/config.ts @@ -86,6 +86,11 @@ const sidebar: DefaultTheme.Config['sidebar'] = { export default defineConfig({ title: 'Example', description: 'An example app using VitePress.', + markdown: { + image: { + lazyLoading: true + } + }, themeConfig: { sidebar, search: { diff --git a/__tests__/e2e/markdown-extensions/index.md b/__tests__/e2e/markdown-extensions/index.md index 36d6c028..47246c18 100644 --- a/__tests__/e2e/markdown-extensions/index.md +++ b/__tests__/e2e/markdown-extensions/index.md @@ -196,3 +196,7 @@ export default config ## Markdown File Inclusion with Range without End + +## Image Lazy Loading + +![vitepress logo](/vitepress.png) \ No newline at end of file diff --git a/__tests__/e2e/markdown-extensions/markdown-extensions.test.ts b/__tests__/e2e/markdown-extensions/markdown-extensions.test.ts index 42a89891..23b8b1a0 100644 --- a/__tests__/e2e/markdown-extensions/markdown-extensions.test.ts +++ b/__tests__/e2e/markdown-extensions/markdown-extensions.test.ts @@ -65,7 +65,7 @@ describe('Table of Contents', () => { test('render toc', async () => { const items = page.locator('#table-of-contents + nav ul li') const count = await items.count() - expect(count).toBe(35) + expect(count).toBe(36) }) }) @@ -280,3 +280,10 @@ describe('Markdown File Inclusion', () => { expect(await p.textContent()).not.toContain('title') }) }) + +describe('Image Lazy Loading', () => { + test('render loading="lazy" in the tag', async () => { + const img = page.locator('#image-lazy-loading + p img') + expect(await img.getAttribute('loading')).toBe('lazy') + }) +}) diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config/en.ts similarity index 69% rename from docs/.vitepress/config.ts rename to docs/.vitepress/config/en.ts index 500c583e..1f619347 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config/en.ts @@ -4,48 +4,11 @@ import { defineConfig, type DefaultTheme } from 'vitepress' const require = createRequire(import.meta.url) const pkg = require('vitepress/package.json') -export default defineConfig({ +export const en = defineConfig({ lang: 'en-US', - title: 'VitePress', description: 'Vite & Vue powered static site generator.', - lastUpdated: true, - cleanUrls: true, - - markdown: { - math: true, - codeTransformers: [ - // We use `[!!code` in demo to prevent transformation, here we revert it back. - { - postprocess(code) { - return code.replace(/\[\!\!code/g, '[!code') - } - } - ] - }, - - sitemap: { - hostname: 'https://vitepress.dev', - transformItems(items) { - return items.filter((item) => !item.url.includes('migration')) - } - }, - - /* prettier-ignore */ - head: [ - ['link', { rel: 'icon', type: 'image/svg+xml', href: '/vitepress-logo-mini.svg' }], - ['link', { rel: 'icon', type: 'image/png', href: '/vitepress-logo-mini.png' }], - ['meta', { name: 'theme-color', content: '#5f67ee' }], - ['meta', { name: 'og:type', content: 'website' }], - ['meta', { name: 'og:locale', content: 'en' }], - ['meta', { name: 'og:site_name', content: 'VitePress' }], - ['meta', { name: 'og:image', content: 'https://vitepress.dev/vitepress-og.jpg' }], - ['script', { src: 'https://cdn.usefathom.com/script.js', 'data-site': 'AZBRSFGG', 'data-spa': 'auto', defer: '' }] - ], - themeConfig: { - logo: { src: '/vitepress-logo-mini.svg', width: 24, height: 24 }, - nav: nav(), sidebar: { @@ -58,27 +21,9 @@ export default defineConfig({ text: 'Edit this page on GitHub' }, - socialLinks: [ - { icon: 'github', link: 'https://github.com/vuejs/vitepress' } - ], - footer: { message: 'Released under the MIT License.', copyright: 'Copyright © 2019-present Evan You' - }, - - search: { - provider: 'algolia', - options: { - appId: '8J64VVRP8K', - apiKey: 'a18e2f4cc5665f6602c5631fd868adfd', - indexName: 'vitepress' - } - }, - - carbonAds: { - code: 'CEBDT27Y', - placement: 'vuejsorg' } } }) @@ -111,7 +56,6 @@ function nav(): DefaultTheme.NavItem[] { ] } -/* prettier-ignore */ function sidebarGuide(): DefaultTheme.SidebarItem[] { return [ { @@ -140,7 +84,10 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] { collapsed: false, items: [ { text: 'Using a Custom Theme', link: 'custom-theme' }, - { text: 'Extending the Default Theme', link: 'extending-default-theme' }, + { + text: 'Extending the Default Theme', + link: 'extending-default-theme' + }, { text: 'Build-Time Data Loading', link: 'data-loading' }, { text: 'SSR Compatibility', link: 'ssr-compat' }, { text: 'Connecting to a CMS', link: 'cms' } diff --git a/docs/.vitepress/config/index.ts b/docs/.vitepress/config/index.ts new file mode 100644 index 00000000..df198ad4 --- /dev/null +++ b/docs/.vitepress/config/index.ts @@ -0,0 +1,17 @@ +import { defineConfig } from 'vitepress' +import { shared } from './shared' +import { en } from './en' +import { zh } from './zh' +import { pt } from './pt' +import { ru } from './ru' + +export default defineConfig({ + ...shared, + locales: { + root: { label: 'English', ...en }, + zh: { label: '简体中文', ...zh }, + pt: { label: 'Português', ...pt }, + ru: { label: 'Русский', ...ru }, + ko: { label: '한국어', lang: 'ko-KR', link: 'https://vitepress.vuejs.kr/' } + } +}) diff --git a/docs/.vitepress/config/pt.ts b/docs/.vitepress/config/pt.ts new file mode 100644 index 00000000..f8ce02a1 --- /dev/null +++ b/docs/.vitepress/config/pt.ts @@ -0,0 +1,212 @@ +import { createRequire } from 'module' +import { defineConfig, type DefaultTheme } from 'vitepress' + +const require = createRequire(import.meta.url) +const pkg = require('vitepress/package.json') + +export const pt = defineConfig({ + lang: 'pt-BR', + description: 'Gerador de Site Estático desenvolvido com Vite e Vue.', + + themeConfig: { + nav: nav(), + + sidebar: { + '/pt/guide/': { base: '/pt/guide/', items: sidebarGuide() }, + '/pt/reference/': { base: '/pt/reference/', items: sidebarReference() } + }, + + editLink: { + pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path', + text: 'Edite esta página no GitHub' + }, + + footer: { + message: 'Lançado sob licença MIT', + copyright: `Direitos reservados © 2019-${new Date().getFullYear()} Evan You` + }, + + docFooter: { + prev: 'Anterior', + next: 'Próximo' + }, + + outline: { + label: 'Nesta página' + }, + + lastUpdated: { + text: 'Atualizado em', + formatOptions: { + dateStyle: 'short', + timeStyle: 'medium' + } + }, + + langMenuLabel: 'Alterar Idioma', + returnToTopLabel: 'Voltar ao Topo', + sidebarMenuLabel: 'Menu Lateral', + darkModeSwitchLabel: 'Tema Escuro', + lightModeSwitchTitle: 'Mudar para Modo Claro', + darkModeSwitchTitle: 'Mudar para Modo Escuro' + } +}) + +function nav(): DefaultTheme.NavItem[] { + return [ + { + text: 'Guia', + link: '/pt/guide/what-is-vitepress', + activeMatch: '/pt/guide/' + }, + { + text: 'Referência', + link: '/pt/reference/site-config', + activeMatch: '/pt/reference/' + }, + { + text: pkg.version, + items: [ + { + text: 'Registro de Mudanças', + link: 'https://github.com/vuejs/vitepress/blob/main/CHANGELOG.md' + }, + { + text: 'Contribuindo', + link: 'https://github.com/vuejs/vitepress/blob/main/.github/contributing.md' + } + ] + } + ] +} + +function sidebarGuide(): DefaultTheme.SidebarItem[] { + return [ + { + text: 'Introdução', + collapsed: false, + items: [ + { text: 'O que é VitePress?', link: 'what-is-vitepress' }, + { text: 'Iniciando', link: 'getting-started' }, + { text: 'Roteamento', link: 'routing' }, + { text: 'Implantação', link: 'deploy' } + ] + }, + { + text: 'Escrevendo', + collapsed: false, + items: [ + { text: 'Extensões Markdown', link: 'markdown' }, + { text: 'Manipulando Ativos', link: 'asset-handling' }, + { text: 'Frontmatter', link: 'frontmatter' }, + { text: 'Usando Vue em Markdown', link: 'using-vue' }, + { text: 'Internacionalização', link: 'i18n' } + ] + }, + { + text: 'Personalização', + collapsed: false, + items: [ + { text: 'Usando um tema personalizado', link: 'custom-theme' }, + { text: 'Estendendo o tema padrão', link: 'extending-default-theme' }, + { + text: 'Carregamento de dados no momento da compilação', + link: 'data-loading' + }, + { text: 'Compatibilidade SSR', link: 'ssr-compat' }, + { text: 'Conectando a um CMS', link: 'cms' } + ] + }, + { + text: 'Experimental', + collapsed: false, + items: [ + { text: 'Modo MPA', link: 'mpa-mode' }, + { text: 'Geração de Sitemap', link: 'sitemap-generation' } + ] + }, + { + text: 'Configuração e Referência da API', + base: '/pt/reference/', + link: 'site-config' + } + ] +} + +function sidebarReference(): DefaultTheme.SidebarItem[] { + return [ + { + text: 'Referência', + items: [ + { text: 'Configuração do Site', link: 'site-config' }, + { text: 'Configuração Frontmatter', link: 'frontmatter-config' }, + { text: 'API do tempo de execução', link: 'runtime-api' }, + { text: 'CLI', link: 'cli' }, + { + text: 'Tema padrão', + base: '/pt/reference/default-theme-', + items: [ + { text: 'Visão Geral', link: 'config' }, + { text: 'Navegação', link: 'nav' }, + { text: 'Barra Lateral', link: 'sidebar' }, + { text: 'Página Inicial', link: 'home-page' }, + { text: 'Rodapé', link: 'footer' }, + { text: 'Layout', link: 'layout' }, + { text: 'Distintivo', link: 'badge' }, + { text: 'Página da Equipe', link: 'team-page' }, + { text: 'Links Anterior / Próximo', link: 'prev-next-links' }, + { text: 'Editar Link', link: 'edit-link' }, + { text: 'Selo Temporal de Atualização', link: 'last-updated' }, + { text: 'Busca', link: 'search' }, + { text: 'Carbon Ads', link: 'carbon-ads' } + ] + } + ] + } + ] +} + +export const search: DefaultTheme.AlgoliaSearchOptions['locales'] = { + pt: { + placeholder: 'Pesquisar documentos', + translations: { + button: { + buttonText: 'Pesquisar', + buttonAriaLabel: 'Pesquisar' + }, + modal: { + searchBox: { + resetButtonTitle: 'Limpar pesquisa', + resetButtonAriaLabel: 'Limpar pesquisa', + cancelButtonText: 'Cancelar', + cancelButtonAriaLabel: 'Cancelar' + }, + startScreen: { + recentSearchesTitle: 'Histórico de Pesquisa', + noRecentSearchesText: 'Nenhuma pesquisa recente', + saveRecentSearchButtonTitle: 'Salvar no histórico de pesquisas', + removeRecentSearchButtonTitle: 'Remover do histórico de pesquisas', + favoriteSearchesTitle: 'Favoritos', + removeFavoriteSearchButtonTitle: 'Remover dos favoritos' + }, + errorScreen: { + titleText: 'Não foi possível obter resultados', + helpText: 'Verifique a sua conexão de rede' + }, + footer: { + selectText: 'Selecionar', + navigateText: 'Navegar', + closeText: 'Fechar', + searchByText: 'Pesquisa por' + }, + noResultsScreen: { + noResultsText: 'Não foi possível encontrar resultados', + suggestedQueryText: 'Você pode tentar uma nova consulta', + reportMissingResultsText: + 'Deveriam haver resultados para essa consulta?', + reportMissingResultsLinkText: 'Clique para enviar feedback' + } + } + } + } +} diff --git a/docs/.vitepress/config/ru.ts b/docs/.vitepress/config/ru.ts new file mode 100644 index 00000000..6e536347 --- /dev/null +++ b/docs/.vitepress/config/ru.ts @@ -0,0 +1,208 @@ +import { createRequire } from 'module' +import { defineConfig, type DefaultTheme } from 'vitepress' + +const require = createRequire(import.meta.url) +const pkg = require('vitepress/package.json') + +export const ru = defineConfig({ + lang: 'ru-RU', + description: 'Генератор статических сайтов на основе Vite и Vue.', + + themeConfig: { + nav: nav(), + + sidebar: { + '/ru/guide/': { base: '/ru/guide/', items: sidebarGuide() }, + '/ru/reference/': { base: '/ru/reference/', items: sidebarReference() } + }, + + editLink: { + pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path', + text: 'Редактировать страницу' + }, + + footer: { + message: 'Опубликовано под лицензией MIT.', + copyright: '© 2019 – настоящее время, Эван Ю' + }, + + outline: { label: 'Содержание страницы' }, + + docFooter: { + prev: 'Предыдущая страница', + next: 'Следующая страница' + }, + + lastUpdated: { + text: 'Обновлено' + }, + + darkModeSwitchLabel: 'Оформление', + lightModeSwitchTitle: 'Переключить на светлую тему', + darkModeSwitchTitle: 'Переключить на тёмную тему', + sidebarMenuLabel: 'Меню', + returnToTopLabel: 'Вернуться к началу', + langMenuLabel: 'Изменить язык' + } +}) + +function nav(): DefaultTheme.NavItem[] { + return [ + { + text: 'Руководство', + link: '/ru/guide/what-is-vitepress', + activeMatch: '/ru/guide/' + }, + { + text: 'Справочник', + link: '/ru/reference/site-config', + activeMatch: '/ru/reference/' + }, + { + text: pkg.version, + items: [ + { + text: 'Изменения', + link: 'https://github.com/vuejs/vitepress/blob/main/CHANGELOG.md' + }, + { + text: 'Вклад', + link: 'https://github.com/vuejs/vitepress/blob/main/.github/contributing.md' + } + ] + } + ] +} + +function sidebarGuide(): DefaultTheme.SidebarItem[] { + return [ + { + text: 'Введение', + collapsed: false, + items: [ + { text: 'Что такое VitePress?', link: 'what-is-vitepress' }, + { text: 'Первые шаги', link: 'getting-started' }, + { text: 'Маршрутизация', link: 'routing' }, + { text: 'Развёртывание', link: 'deploy' } + ] + }, + { + text: 'Написание', + collapsed: false, + items: [ + { text: 'Расширения Markdown', link: 'markdown' }, + { text: 'Обработка ресурсов', link: 'asset-handling' }, + { text: 'Метаданные', link: 'frontmatter' }, + { text: 'Использование Vue в Markdown', link: 'using-vue' }, + { text: 'Интернационализация', link: 'i18n' } + ] + }, + { + text: 'Настройка', + collapsed: false, + items: [ + { text: 'Пользовательская тема', link: 'custom-theme' }, + { + text: 'Расширение темы по умолчанию', + link: 'extending-default-theme' + }, + { + text: 'Загрузка данных в режиме реального времени', + link: 'data-loading' + }, + { text: 'Совместимость с SSR', link: 'ssr-compat' }, + { text: 'Подключение к CMS', link: 'cms' } + ] + }, + { + text: 'Экспериментально', + collapsed: false, + items: [ + { text: 'Режим MPA', link: 'mpa-mode' }, + { text: 'Генерация карты сайта', link: 'sitemap-generation' } + ] + }, + { text: 'Конфигурация и API', base: '/ru/reference/', link: 'site-config' } + ] +} + +function sidebarReference(): DefaultTheme.SidebarItem[] { + return [ + { + text: 'Справочник', + items: [ + { text: 'Конфигурация сайта', link: 'site-config' }, + { text: 'Конфигурация метаданных', link: 'frontmatter-config' }, + { text: 'Runtime API', link: 'runtime-api' }, + { text: 'Командная строка', link: 'cli' }, + { + text: 'Тема по умолчанию', + base: '/ru/reference/default-theme-', + items: [ + { text: 'Обзор', link: 'config' }, + { text: 'Навигация', link: 'nav' }, + { text: 'Сайдбар', link: 'sidebar' }, + { text: 'Главная страница', link: 'home-page' }, + { text: 'Подвал', link: 'footer' }, + { text: 'Макет', link: 'layout' }, + { text: 'Значки', link: 'badge' }, + { text: 'Страница команды', link: 'team-page' }, + { + text: 'Предыдущая и следующая страницы', + link: 'prev-next-links' + }, + { text: 'Ссылка для редактирования', link: 'edit-link' }, + { text: 'Последнее обновление', link: 'last-updated' }, + { text: 'Поиск', link: 'search' }, + { text: 'Carbon Ads (реклама)', link: 'carbon-ads' } + ] + } + ] + } + ] +} + +export const search: DefaultTheme.AlgoliaSearchOptions['locales'] = { + ru: { + placeholder: 'Поиск в документации', + translations: { + button: { + buttonText: 'Поиск', + buttonAriaLabel: 'Поиск' + }, + modal: { + searchBox: { + resetButtonTitle: 'Сбросить поиск', + resetButtonAriaLabel: 'Сбросить поиск', + cancelButtonText: 'Отменить поиск', + cancelButtonAriaLabel: 'Отменить поиск' + }, + startScreen: { + recentSearchesTitle: 'История поиска', + noRecentSearchesText: 'Нет истории поиска', + saveRecentSearchButtonTitle: 'Сохранить в истории поиска', + removeRecentSearchButtonTitle: 'Удалить из истории поиска', + favoriteSearchesTitle: 'Избранное', + removeFavoriteSearchButtonTitle: 'Удалить из избранного' + }, + errorScreen: { + titleText: 'Невозможно получить результаты', + helpText: 'Вам может потребоваться проверить подключение к Интернету' + }, + footer: { + selectText: 'выбрать', + navigateText: 'перейти', + closeText: 'закрыть', + searchByText: 'поставщик поиска' + }, + noResultsScreen: { + noResultsText: 'Нет результатов для', + suggestedQueryText: 'Вы можете попытаться узнать', + reportMissingResultsText: + 'Считаете, что поиск даёт ложные результаты?', + reportMissingResultsLinkText: 'Нажмите на кнопку «Обратная связь»' + } + } + } + } +} diff --git a/docs/.vitepress/config/shared.ts b/docs/.vitepress/config/shared.ts new file mode 100644 index 00000000..77386002 --- /dev/null +++ b/docs/.vitepress/config/shared.ts @@ -0,0 +1,65 @@ +import { defineConfig } from 'vitepress' +import { search as zhSearch } from './zh' +import { search as ptSearch } from './pt' +import { search as ruSearch } from './ru' + +export const shared = defineConfig({ + title: 'VitePress', + + lastUpdated: true, + cleanUrls: true, + metaChunk: true, + + markdown: { + math: true, + codeTransformers: [ + // We use `[!!code` in demo to prevent transformation, here we revert it back. + { + postprocess(code) { + return code.replace(/\[\!\!code/g, '[!code') + } + } + ] + }, + + sitemap: { + hostname: 'https://vitepress.dev', + transformItems(items) { + return items.filter((item) => !item.url.includes('migration')) + } + }, + + /* prettier-ignore */ + head: [ + ['link', { rel: 'icon', type: 'image/svg+xml', href: '/vitepress-logo-mini.svg' }], + ['link', { rel: 'icon', type: 'image/png', href: '/vitepress-logo-mini.png' }], + ['meta', { name: 'theme-color', content: '#5f67ee' }], + ['meta', { property: 'og:type', content: 'website' }], + ['meta', { property: 'og:locale', content: 'en' }], + ['meta', { property: 'og:title', content: 'VitePress | Vite & Vue Powered Static Site Generator' }], + ['meta', { property: 'og:site_name', content: 'VitePress' }], + ['meta', { property: 'og:image', content: 'https://vitepress.dev/vitepress-og.jpg' }], + ['meta', { property: 'og:url', content: 'https://vitepress.dev/' }], + ['script', { src: 'https://cdn.usefathom.com/script.js', 'data-site': 'AZBRSFGG', 'data-spa': 'auto', defer: '' }] + ], + + themeConfig: { + logo: { src: '/vitepress-logo-mini.svg', width: 24, height: 24 }, + + socialLinks: [ + { icon: 'github', link: 'https://github.com/vuejs/vitepress' } + ], + + search: { + provider: 'algolia', + options: { + appId: '8J64VVRP8K', + apiKey: 'a18e2f4cc5665f6602c5631fd868adfd', + indexName: 'vitepress', + locales: { ...zhSearch, ...ptSearch, ...ruSearch } + } + }, + + carbonAds: { code: 'CEBDT27Y', placement: 'vuejsorg' } + } +}) diff --git a/docs/.vitepress/config/zh.ts b/docs/.vitepress/config/zh.ts new file mode 100644 index 00000000..b7463980 --- /dev/null +++ b/docs/.vitepress/config/zh.ts @@ -0,0 +1,204 @@ +import { createRequire } from 'module' +import { defineConfig, type DefaultTheme } from 'vitepress' + +const require = createRequire(import.meta.url) +const pkg = require('vitepress/package.json') + +export const zh = defineConfig({ + lang: 'zh-Hans', + description: '由 Vite 和 Vue 驱动的静态站点生成器', + + themeConfig: { + nav: nav(), + + sidebar: { + '/zh/guide/': { base: '/zh/guide/', items: sidebarGuide() }, + '/zh/reference/': { base: '/zh/reference/', items: sidebarReference() } + }, + + editLink: { + pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path', + text: '在 GitHub 上编辑此页面' + }, + + footer: { + message: '基于 MIT 许可发布', + copyright: `版权所有 © 2019-${new Date().getFullYear()} 尤雨溪` + }, + + docFooter: { + prev: '上一页', + next: '下一页' + }, + + outline: { + label: '页面导航' + }, + + lastUpdated: { + text: '最后更新于', + formatOptions: { + dateStyle: 'short', + timeStyle: 'medium' + } + }, + + langMenuLabel: '多语言', + returnToTopLabel: '回到顶部', + sidebarMenuLabel: '菜单', + darkModeSwitchLabel: '主题', + lightModeSwitchTitle: '切换到浅色模式', + darkModeSwitchTitle: '切换到深色模式' + } +}) + +function nav(): DefaultTheme.NavItem[] { + return [ + { + text: '指南', + link: '/zh/guide/what-is-vitepress', + activeMatch: '/zh/guide/' + }, + { + text: '参考', + link: '/zh/reference/site-config', + activeMatch: '/zh/reference/' + }, + { + text: pkg.version, + items: [ + { + text: '更新日志', + link: 'https://github.com/vuejs/vitepress/blob/main/CHANGELOG.md' + }, + { + text: '参与贡献', + link: 'https://github.com/vuejs/vitepress/blob/main/.github/contributing.md' + } + ] + } + ] +} + +function sidebarGuide(): DefaultTheme.SidebarItem[] { + return [ + { + text: '简介', + collapsed: false, + items: [ + { text: '什么是 VitePress?', link: 'what-is-vitepress' }, + { text: '快速开始', link: 'getting-started' }, + { text: '路由', link: 'routing' }, + { text: '部署', link: 'deploy' } + ] + }, + { + text: '写作', + collapsed: false, + items: [ + { text: 'Markdown 扩展', link: 'markdown' }, + { text: '资源处理', link: 'asset-handling' }, + { text: 'frontmatter', link: 'frontmatter' }, + { text: '在 Markdown 使用 Vue', link: 'using-vue' }, + { text: '国际化', link: 'i18n' } + ] + }, + { + text: '自定义', + collapsed: false, + items: [ + { text: '自定义主题', link: 'custom-theme' }, + { text: '扩展默认主题', link: 'extending-default-theme' }, + { text: '构建时数据加载', link: 'data-loading' }, + { text: 'SSR 兼容性', link: 'ssr-compat' }, + { text: '连接 CMS', link: 'cms' } + ] + }, + { + text: '实验性功能', + collapsed: false, + items: [ + { text: 'MPA 模式', link: 'mpa-mode' }, + { text: 'sitemap 生成', link: 'sitemap-generation' } + ] + }, + { text: '配置和 API 参考', base: '/zh/reference/', link: 'site-config' } + ] +} + +function sidebarReference(): DefaultTheme.SidebarItem[] { + return [ + { + text: '参考', + items: [ + { text: '站点配置', link: 'site-config' }, + { text: 'frontmatter 配置', link: 'frontmatter-config' }, + { text: '运行时 API', link: 'runtime-api' }, + { text: 'CLI', link: 'cli' }, + { + text: '默认主题', + base: '/zh/reference/default-theme-', + items: [ + { text: '概览', link: 'config' }, + { text: '导航栏', link: 'nav' }, + { text: '侧边栏', link: 'sidebar' }, + { text: '主页', link: 'home-page' }, + { text: '页脚', link: 'footer' }, + { text: '布局', link: 'layout' }, + { text: '徽章', link: 'badge' }, + { text: '团队页', link: 'team-page' }, + { text: '上下页链接', link: 'prev-next-links' }, + { text: '编辑链接', link: 'edit-link' }, + { text: '最后更新时间戳', link: 'last-updated' }, + { text: '搜索', link: 'search' }, + { text: 'Carbon Ads', link: 'carbon-ads' } + ] + } + ] + } + ] +} + +export const search: DefaultTheme.AlgoliaSearchOptions['locales'] = { + zh: { + placeholder: '搜索文档', + translations: { + button: { + buttonText: '搜索文档', + buttonAriaLabel: '搜索文档' + }, + modal: { + searchBox: { + resetButtonTitle: '清除查询条件', + resetButtonAriaLabel: '清除查询条件', + cancelButtonText: '取消', + cancelButtonAriaLabel: '取消' + }, + startScreen: { + recentSearchesTitle: '搜索历史', + noRecentSearchesText: '没有搜索历史', + saveRecentSearchButtonTitle: '保存至搜索历史', + removeRecentSearchButtonTitle: '从搜索历史中移除', + favoriteSearchesTitle: '收藏', + removeFavoriteSearchButtonTitle: '从收藏中移除' + }, + errorScreen: { + titleText: '无法获取结果', + helpText: '你可能需要检查你的网络连接' + }, + footer: { + selectText: '选择', + navigateText: '切换', + closeText: '关闭', + searchByText: '搜索提供者' + }, + noResultsScreen: { + noResultsText: '无法找到相关结果', + suggestedQueryText: '你可以尝试查询', + reportMissingResultsText: '你认为该查询应该有结果?', + reportMissingResultsLinkText: '点击反馈' + } + } + } + } +} diff --git a/docs/.vitepress/theme/AdComponent.vue b/docs/.vitepress/theme/AdComponent.vue deleted file mode 100644 index 15fc4d2e..00000000 --- a/docs/.vitepress/theme/AdComponent.vue +++ /dev/null @@ -1,43 +0,0 @@ - - - - - diff --git a/docs/.vitepress/theme/documate.vue b/docs/.vitepress/theme/documate.vue deleted file mode 100644 index d89e2f40..00000000 --- a/docs/.vitepress/theme/documate.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts deleted file mode 100644 index 8c9aecc6..00000000 --- a/docs/.vitepress/theme/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -// .vitepress/theme/index.js -import { h } from 'vue' -import DefaultTheme from 'vitepress/theme' -import AdComponent from './AdComponent.vue' - -export default { - ...DefaultTheme, - Layout() { - return h(DefaultTheme.Layout, null, { - 'doc-before': () => h(AdComponent) - }) - } -} diff --git a/docs/guide/asset-handling.md b/docs/guide/asset-handling.md index 7d2ce57a..eeedc8c0 100644 --- a/docs/guide/asset-handling.md +++ b/docs/guide/asset-handling.md @@ -12,6 +12,10 @@ You can reference static assets in your markdown files, your `*.vue` components Common image, media, and font filetypes are detected and included as assets automatically. +::: tip Linked files are not treated as assets +PDFs or other documents referenced by links within markdown files are not automatically treated as assets. To make linked files accessible, you must manually place them within the [`public`](#the-public-directory) directory of your project. +::: + All referenced assets, including those using absolute paths, will be copied to the output directory with a hashed file name in the production build. Never-referenced assets will not be copied. Image assets smaller than 4kb will be base64 inlined - this can be configured via the [`vite`](../reference/site-config#vite) config option. All **static** path references, including absolute paths, should be based on your working directory structure. diff --git a/docs/guide/custom-theme.md b/docs/guide/custom-theme.md index 83625a23..1d168ce9 100644 --- a/docs/guide/custom-theme.md +++ b/docs/guide/custom-theme.md @@ -196,7 +196,7 @@ export default { If the theme requires special VitePress config, you will need to also extend it in your own config: ```ts -// .vitepress/theme/config.ts +// .vitepress/config.ts import baseConfig from 'awesome-vitepress-theme/config' export default { @@ -208,7 +208,7 @@ export default { Finally, if the theme provides types for its theme config: ```ts -// .vitepress/theme/config.ts +// .vitepress/config.ts import baseConfig from 'awesome-vitepress-theme/config' import { defineConfigWithTheme } from 'vitepress' import type { ThemeConfig } from 'awesome-vitepress-theme' diff --git a/docs/guide/deploy.md b/docs/guide/deploy.md index f7c60322..01eeafd3 100644 --- a/docs/guide/deploy.md +++ b/docs/guide/deploy.md @@ -153,26 +153,24 @@ Don't enable options like _Auto Minify_ for HTML code. It will remove comments f runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 # Not needed if lastUpdated is not enabled - # - uses: pnpm/action-setup@v2 # Uncomment this if you're using pnpm + # - uses: pnpm/action-setup@v3 # Uncomment this if you're using pnpm # - uses: oven-sh/setup-bun@v1 # Uncomment this if you're using Bun - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 20 cache: npm # or pnpm / yarn - name: Setup Pages - uses: actions/configure-pages@v3 + uses: actions/configure-pages@v4 - name: Install dependencies run: npm ci # or pnpm install / yarn install / bun install - name: Build with VitePress - run: | - npm run docs:build # or pnpm docs:build / yarn docs:build / bun run docs:build - touch docs/.vitepress/dist/.nojekyll + run: npm run docs:build # or pnpm docs:build / yarn docs:build / bun run docs:build - name: Upload artifact - uses: actions/upload-pages-artifact@v2 + uses: actions/upload-pages-artifact@v3 with: path: docs/.vitepress/dist @@ -187,7 +185,7 @@ Don't enable options like _Auto Minify_ for HTML code. It will remove comments f steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v2 + uses: actions/deploy-pages@v4 ``` ::: warning @@ -289,3 +287,51 @@ Refer [Creating and Deploying a VitePress App To Edgio](https://docs.edg.io/guid ### Kinsta Static Site Hosting You can deploy your Vitepress website on [Kinsta](https://kinsta.com/static-site-hosting/) by following these [instructions](https://kinsta.com/docs/vitepress-static-site-example/). + +### Stormkit + +You can deploy your VitePress project to [Stormkit](https://www.stormkit.io) by following these [instructions](https://stormkit.io/blog/how-to-deploy-vitepress). + +### Nginx + +Here is a example of an Nginx server block configuration. This setup includes gzip compression for common text-based assets, rules for serving your VitePress site's static files with proper caching headers as well as handling `cleanUrls: true`. + +```nginx +server { + gzip on; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + listen 80; + server_name _; + index index.html; + + location / { + # content location + root /app; + + # exact matches -> reverse clean urls -> folders -> not found + try_files $uri $uri.html $uri/ =404; + + # non existent pages + error_page 404 /404.html; + + # a folder without index.html raises 403 in this setup + error_page 403 /404.html; + + # adjust caching headers + # files in the assets folder have hashes filenames + location ~* ^/assets/ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + } +} +``` + +This configuration assumes that your built VitePress site is located in the `/app` directory on your server. Adjust the `root` directive accordingly if your site's files are located elsewhere. + +::: warning Do not default to index.html +The try_files resolution must not default to index.html like in other Vue applications. This would result in an invalid page state. +::: + +Further information can be found in the [official nginx documentation](https://nginx.org/en/docs/), in these issues [#2837](https://github.com/vuejs/vitepress/discussions/2837), [#3235](https://github.com/vuejs/vitepress/issues/3235) as well as in this [blog post](https://blog.mehdi.cc/articles/vitepress-cleanurls-on-nginx-environment#readings) by Mehdi Merah. diff --git a/docs/guide/extending-default-theme.md b/docs/guide/extending-default-theme.md index b7b29bde..71f369f9 100644 --- a/docs/guide/extending-default-theme.md +++ b/docs/guide/extending-default-theme.md @@ -195,7 +195,10 @@ Full list of slots available in the default theme layout: - `aside-ads-after` - When `layout: 'home'` is enabled via frontmatter: - `home-hero-before` + - `home-hero-info-before` - `home-hero-info` + - `home-hero-info-after` + - `home-hero-actions-after` - `home-hero-image` - `home-hero-after` - `home-features-before` diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md index a2541bd4..7d7c577e 100644 --- a/docs/guide/getting-started.md +++ b/docs/guide/getting-started.md @@ -71,8 +71,12 @@ $ npx vitepress init $ pnpm vitepress init ``` +```sh [yarn] +$ yarn vitepress init +``` + ```sh [bun] -$ bunx vitepress init +$ bun vitepress init ``` ::: @@ -82,7 +86,7 @@ You will be greeted with a few simple questions: <<< @/snippets/init.ansi ::: tip Vue as Peer Dependency -If you intend to perform customization that uses Vue components or APIs, you should also explicitly install `vue` as a peer dependency. +If you intend to perform customization that uses Vue components or APIs, you should also explicitly install `vue` as a dependency. ::: ## File Structure @@ -182,11 +186,15 @@ $ npx vitepress dev docs ``` ```sh [pnpm] -$ pnpm exec vitepress dev docs +$ pnpm vitepress dev docs +``` + +```sh [yarn] +$ yarn vitepress dev docs ``` ```sh [bun] -$ bunx vitepress dev docs +$ bun vitepress dev docs ``` ::: @@ -199,7 +207,7 @@ The dev server should be running at `http://localhost:5173`. Visit the URL in yo - To better understand how markdown files are mapped to generated HTML, proceed to the [Routing Guide](./routing). -- To discover more about what you can do on the page, such as writing markdown content or using Vue Component, refer to the "Writing" section of the guide. A great place to start would be to learn about [Markdown Extensions](./markdown). +- To discover more about what you can do on the page, such as writing markdown content or using Vue Components, refer to the "Writing" section of the guide. A great place to start would be to learn about [Markdown Extensions](./markdown). - To explore the features provided by the default documentation theme, check out the [Default Theme Config Reference](../reference/default-theme-config). diff --git a/docs/guide/i18n.md b/docs/guide/i18n.md index 0d256c73..b055c160 100644 --- a/docs/guide/i18n.md +++ b/docs/guide/i18n.md @@ -75,25 +75,39 @@ However, VitePress won't redirect `/` to `/en/` by default. You'll need to confi /* /en/:splat 302 ``` -**Pro tip:** If using the above approach, you can use `nf_lang` cookie to persist user's language choice. A very basic way to do this is register a watcher inside the [setup](./custom-theme#using-a-custom-theme) function of custom theme: +**Pro tip:** If using the above approach, you can use `nf_lang` cookie to persist user's language choice: ```ts // docs/.vitepress/theme/index.ts import DefaultTheme from 'vitepress/theme' +import Layout from './Layout.vue' export default { extends: DefaultTheme, - setup() { - const { lang } = useData() - watchEffect(() => { - if (inBrowser) { - document.cookie = `nf_lang=${lang.value}; expires=Mon, 1 Jan 2024 00:00:00 UTC; path=/` - } - }) - } + Layout } ``` +```vue + + + + +``` + ## RTL Support (Experimental) For RTL support, specify `dir: 'rtl'` in config and use some RTLCSS PostCSS plugin like , or . You'll need to configure your PostCSS plugin to use `:where([dir="ltr"])` and `:where([dir="rtl"])` as prefixes to prevent CSS specificity issues. diff --git a/docs/guide/markdown.md b/docs/guide/markdown.md index c7fcbd47..d5b68de6 100644 --- a/docs/guide/markdown.md +++ b/docs/guide/markdown.md @@ -108,7 +108,7 @@ For more details, see [Frontmatter](../reference/frontmatter-config). :tada: :100: -A [list of all emojis](https://github.com/markdown-it/markdown-it-emoji/blob/master/lib/data/full.json) is available. +A [list of all emojis](https://github.com/markdown-it/markdown-it-emoji/blob/master/lib/data/full.mjs) is available. ## Table of Contents @@ -263,9 +263,45 @@ Wraps in a
}) ``` +## GitHub-flavored Alerts + +VitePress also supports [GitHub-flavored alerts](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts) to render as callouts. They will be rendered the same as the [custom containers](#custom-containers). + +```md +> [!NOTE] +> Highlights information that users should take into account, even when skimming. + +> [!TIP] +> Optional information to help a user be more successful. + +> [!IMPORTANT] +> Crucial information necessary for users to succeed. + +> [!WARNING] +> Critical content demanding immediate user attention due to potential risks. + +> [!CAUTION] +> Negative potential consequences of an action. +``` + +> [!NOTE] +> Highlights information that users should take into account, even when skimming. + +> [!TIP] +> Optional information to help a user be more successful. + +> [!IMPORTANT] +> Crucial information necessary for users to succeed. + +> [!WARNING] +> Critical content demanding immediate user attention due to potential risks. + +> [!CAUTION] +> Negative potential consequences of an action. + ## Syntax Highlighting in Code Blocks -VitePress uses [Shikiji](https://github.com/antfu/shikiji) (an improved version of [Shiki](https://shiki.matsu.io/)) to highlight language syntax in Markdown code blocks, using coloured text. Shiki supports a wide variety of programming languages. All you need to do is append a valid language alias to the beginning backticks for the code block: +VitePress uses [Shiki](https://github.com/shikijs/shiki) to highlight language syntax in Markdown code blocks, using coloured text. Shiki supports a wide variety of programming languages. All you need to do is append a valid language alias to the beginning backticks for the code block: **Input** @@ -305,7 +341,7 @@ export default { ``` -A [list of valid languages](https://github.com/antfu/shikiji/blob/main/docs/languages.md) is available on Shikiji's repository. +A [list of valid languages](https://shiki.style/languages) is available on Shiki's repository. You may also customize syntax highlight theme in app config. Please see [`markdown` options](../reference/site-config#markdown) for more details. @@ -377,7 +413,7 @@ export default { // Highlighted } ``` -Alternatively, it's possible to highlight directly in the line by using the `// [!code hightlight]` comment. +Alternatively, it's possible to highlight directly in the line by using the `// [!code highlight]` comment. **Input** @@ -587,7 +623,7 @@ It also supports [line highlighting](#line-highlighting-in-code-blocks): **Output** -<<< @/snippets/snippet.js +<<< @/snippets/snippet.js{2} ::: tip The value of `@` corresponds to the source root. By default it's the VitePress project root, unless `srcDir` is configured. Alternatively, you can also import from relative paths: @@ -847,6 +883,21 @@ $$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$ | $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$ | | $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _wha?_ | +## Image Lazy Loading + +You can enable lazy loading for each image added via markdown by setting `lazyLoading` to `true` in your config file: + +```js +export default { + markdown: { + image: { + // image lazy loading is disabled by default + lazyLoading: true + } + } +} +``` + ## Advanced Configuration VitePress uses [markdown-it](https://github.com/markdown-it/markdown-it) as the Markdown renderer. A lot of the extensions above are implemented via custom plugins. You can further customize the `markdown-it` instance using the `markdown` option in `.vitepress/config.js`: diff --git a/docs/guide/routing.md b/docs/guide/routing.md index 641807e4..945e63c0 100644 --- a/docs/guide/routing.md +++ b/docs/guide/routing.md @@ -129,9 +129,9 @@ To serve clean URLs with VitePress, server-side support is required. By default, VitePress resolves inbound links to URLs ending with `.html`. However, some users may prefer "Clean URLs" without the `.html` extension - for example, `example.com/path` instead of `example.com/path.html`. -Some servers or hosting platforms (for example Netlify or Vercel) provide the ability to map a URL like `/foo` to `/foo.html` if it exists, without a redirect: +Some servers or hosting platforms (for example Netlify, Vercel, GitHub Pages) provide the ability to map a URL like `/foo` to `/foo.html` if it exists, without a redirect: -- Netlify supports this by default. +- Netlify and GitHub Pages support this by default. - Vercel requires enabling the [`cleanUrls` option in `vercel.json`](https://vercel.com/docs/concepts/projects/project-configuration#cleanurls). If this feature is available to you, you can then also enable VitePress' own [`cleanUrls`](../reference/site-config#cleanurls) config option so that: @@ -139,7 +139,7 @@ If this feature is available to you, you can then also enable VitePress' own [`c - Inbound links between pages are generated without the `.html` extension. - If current path ends with `.html`, the router will perform a client-side redirect to the extension-less path. -If, however, you cannot configure your server with such support (e.g. GitHub pages), you will have to manually resort to the following directory structure: +If, however, you cannot configure your server with such support, you will have to manually resort to the following directory structure: ``` . diff --git a/docs/guide/what-is-vitepress.md b/docs/guide/what-is-vitepress.md index 22ca0316..a498d17e 100644 --- a/docs/guide/what-is-vitepress.md +++ b/docs/guide/what-is-vitepress.md @@ -34,11 +34,11 @@ VitePress aims to provide a great Developer Experience (DX) when working with Ma ## Performance -Unlike many traditional SSGs, a website generated by VitePress is in fact a [Single Page Application](https://en.wikipedia.org/wiki/Single-page_application) (SPA). +Unlike many traditional SSGs where each navigation results in a full page reload, a website generated by VitePress serves static HTML on the initial visit, but becomes a [Single Page Application](https://en.wikipedia.org/wiki/Single-page_application) (SPA) for subsequent navigation within the site. This model, in our opinion, provides an optimal balance for performance: - **Fast Initial Load** - The initial visit to any page will be served the static, pre-rendered HTML for blazing fast loading speed and optimal SEO. The page then loads a JavaScript bundle that turns the page into a Vue SPA ("hydration"). The hydration process is extremely fast: on [PageSpeed Insights](https://pagespeed.web.dev/report?url=https%3A%2F%2Fvitepress.dev%2F), typical VitePress sites achieve near-perfect performance scores even on low-end mobile devices with a slow network. + The initial visit to any page will be served the static, pre-rendered HTML for fast loading speed and optimal SEO. The page then loads a JavaScript bundle that turns the page into a Vue SPA ("hydration"). Contrary to common assumptions of SPA hydration being slow, this process is actually extremely fast thanks to Vue 3's raw performance and compiler optimizations. On [PageSpeed Insights](https://pagespeed.web.dev/report?url=https%3A%2F%2Fvitepress.dev%2F), typical VitePress sites achieve near-perfect performance scores even on low-end mobile devices with a slow network. - **Fast Post-load Navigation** diff --git a/docs/index.md b/docs/index.md index 9bdd428b..9be32c3e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -7,13 +7,16 @@ titleTemplate: Vite & Vue Powered Static Site Generator hero: name: VitePress text: Vite & Vue Powered Static Site Generator - tagline: Simple, powerful, and fast. Meet the modern SSG framework you've always wanted. + tagline: Markdown to Beautiful Docs in Minutes actions: - theme: brand - text: Get Started + text: What is VitePress? + link: /guide/what-is-vitepress + - theme: alt + text: Quickstart link: /guide/getting-started - theme: alt - text: View on GitHub + text: GitHub link: https://github.com/vuejs/vitepress image: src: /vitepress-logo-large.webp diff --git a/docs/lunaria.config.json b/docs/lunaria.config.json new file mode 100644 index 00000000..73b7a38a --- /dev/null +++ b/docs/lunaria.config.json @@ -0,0 +1,39 @@ +{ + "$schema": "./node_modules/@lunariajs/core/config.schema.json", + "repository": { + "name": "vuejs/vitepress", + "rootDir": "docs" + }, + "files": [ + { + "location": ".vitepress/config/{en,zh,pt,ru}.ts", + "pattern": ".vitepress/config/@lang.ts", + "type": "universal" + }, + { + "location": "**/*.md", + "pattern": "@lang/@path", + "type": "universal" + } + ], + "defaultLocale": { + "label": "English", + "lang": "en" + }, + "locales": [ + { + "label": "简体中文", + "lang": "zh" + }, + { + "label": "Português", + "lang": "pt" + }, + { + "label": "Русский", + "lang": "ru" + } + ], + "outDir": ".vitepress/dist/_translations", + "ignoreKeywords": ["lunaria-ignore"] +} diff --git a/docs/package.json b/docs/package.json index 817fb9f6..9ef5821a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -3,12 +3,16 @@ "private": true, "type": "module", "scripts": { - "dev": "vitepress dev", "build": "vitepress build", + "dev": "vitepress dev", + "lunaria:build": "lunaria build", + "lunaria:open": "open-cli .vitepress/dist/_translations/index.html", "preview": "vitepress preview" }, "devDependencies": { + "@lunariajs/core": "^0.0.32", "markdown-it-mathjax3": "^4.3.2", + "open-cli": "^8.0.0", "vitepress": "workspace:*" } } diff --git a/docs/pt/guide/asset-handling.md b/docs/pt/guide/asset-handling.md new file mode 100644 index 00000000..9bd66f24 --- /dev/null +++ b/docs/pt/guide/asset-handling.md @@ -0,0 +1,59 @@ +# Manipulação de Ativos {#asset-handling} + +## Referenciando Ativos Estáticos {#referencing-static-assets} + +Todos os arquivos Markdown são compilados em componentes Vue e processados por [Vite](https://vitejs.dev/guide/assets.html). Você pode **e deve** referenciar quaisquer ativos usando URLs relativas: + +```md +![Uma imagem](./imagem.png) +``` + +Você pode referenciar ativos estáticos em seus arquivos markdown, seus componentes `*.vue` no tema, estilos e simples arquivos `.css`, usando caminhos públicos absolutos (com base na raiz do projeto) ou caminhos relativos (com base em seu sistema de arquivos). Este último é semelhante ao comportamento que você está acostumado se já usou Vite, Vue CLI ou o `file-loader` do webpack. + +Tipos comuns de arquivos de imagem, mídia e fonte são detectados e incluídos automaticamente como ativos. + +Todos os ativos referenciados, incluindo aqueles usando caminhos absolutos, serão copiados para o diretório de saída com um nome de arquivo hash na compilação de produção. Ativos nunca referenciados não serão copiados. Ativos de imagem menores que 4KB serão incorporados em base64 - isso pode ser configurado pela opção [`vite`](../reference/site-config#vite) da configuração. + +Todas as referências de caminho **estáticas**, incluindo caminhos absolutos, devem ser baseadas na estrutura do seu diretório de trabalho. + +## O Diretório Público {#the-public-directory} + +Às vezes, pode ser necessário fornecer ativos estáticos que não são referenciados diretamente em nenhum de seus componentes do tema ou Markdown, ou você pode querer servir certos arquivos com o nome de arquivo original. Exemplos de tais arquivos incluem `robots.txt`, favicons e ícones PWA. + +Você pode colocar esses arquivos no diretório `public` sob o [diretório fonte](./routing#source-directory). Por exemplo, se a raiz do seu projeto for `./docs` e estiver usando a localização padrão do diretório fonte, então o diretório público será `./docs/public`. + +Os ativos colocados em `public` serão copiados para a raiz do diretório de saída como são. + +Observe que você deve referenciar arquivos colocados em `public` usando o caminho absoluto da raiz - por exemplo, `public/icon.png` deve sempre ser referenciado no código fonte como `/icon.png`. + +## URL Base {#base-url} + +Se seu site for implantado em uma URL que não seja a raiz, será necessário definir a opção `base` em `.vitepress/config.js`. Por exemplo, se você planeja implantar seu site em `https://foo.github.io/bar/`, então `base` deve ser definido como `'/bar/'` (sempre deve começar e terminar com uma barra). + +Todos os caminhos dos seus ativos estáticos são processados automaticamente para se ajustar aos diferentes valores de configuração `base`. Por exemplo, se você tiver uma referência absoluta a um ativo sob `public` no seu markdown: + +```md +![Uma imagem](/imagem-dentro-de-public.png) +``` + +Você **não** precisa atualizá-lo quando alterar o valor de configuração `base` nesse caso. + +No entanto, se você estiver criando um componente de tema que vincula ativos dinamicamente, por exemplo, uma imagem cujo `src` é baseado em um valor de configuração do tema: + +```vue + +``` + +Nesse caso, é recomendável envolver o caminho com o [`auxiliar withBase`](../reference/runtime-api#withbase) fornecido por VitePress: + +```vue + + + +``` diff --git a/docs/pt/guide/cms.md b/docs/pt/guide/cms.md new file mode 100644 index 00000000..c4593b6d --- /dev/null +++ b/docs/pt/guide/cms.md @@ -0,0 +1,56 @@ +--- +outline: deep +--- + +# Conectando a um CMS {#connecting-to-a-cms} + +## Fluxo de Trabalho Geral {#general-workflow} + +Conectar VitePress a um CMS orbitará majoritariamente sobre [Rotas Dinâmicas](./routing#dynamic-routes). Certifique-se de entender como funcionam antes de proceder. + +Como cada CMS funcionará de forma diferente, aqui podemos fornecer apenas um fluxo de trabalho genérico que precisará ser adaptado para cada cenário específico. + +1. Se seu CMS exige autenticação, crie um arquivo `.env` para armazenar os tokens da API e carregá-los como: + + ```js + // posts/[id].paths.js + import { loadEnv } from 'vitepress' + + const env = loadEnv('', process.cwd()) + ``` + +2. Obtenha os dados necessários do CMS e formate-os em caminhos de dados apropriados: + + ```js + export default { + async paths() { + // use a biblitoca do cliente CMS respectiva se preciso + const data = await (await fetch('https://my-cms-api', { + headers: { + // token se necessário + } + })).json() + + return data.map(entry => { + return { + params: { id: entry.id, /* título, autores, data, etc. */ }, + content: entry.content + } + }) + } + } + ``` + +3. Apresente o conteúdo na página: + + ```md + # {{ $params.title }} + + - por {{ $params.author }} em {{ $params.date }} + + + ``` + +## Guias de Integração {#integration-guides} + +Se você tiver escrito um guia sobre como integrar VitePress com um CMS específico, por favor use o link "Edite esta página" abaixo para enviá-lo para cá! diff --git a/docs/pt/guide/custom-theme.md b/docs/pt/guide/custom-theme.md new file mode 100644 index 00000000..caffd65b --- /dev/null +++ b/docs/pt/guide/custom-theme.md @@ -0,0 +1,222 @@ +# Usando um Tema Personalizado {#using-a-custom-theme} + +## Resolução de Tema {#theme-resolving} + +Você pode habilitar um tema personalizado criando um arquivo `.vitepress/theme/index.js` ou `.vitepress/theme/index.ts` (o "arquivo de entrada do tema"): + +``` +. +├─ docs # raiz do projeto +│ ├─ .vitepress +│ │ ├─ theme +│ │ │ └─ index.js # entrada do tema +│ │ └─ config.js # arquivo de configuração +│ └─ index.md +└─ package.json +``` + +VitePress sempre usará o tema personalizado em vez do tema padrão quando detectar a presença de um arquivo de entrada do tema. No entanto, você pode [estender o tema padrão](./extending-default-theme) para realizar personalizações avançadas sobre ele. + +## Interface do Tema {#theme-interface} + +Um tema personalizado do VitePress é definido como um objeto com a seguinte interface: + +```ts +interface Theme { + /** + * Componente raiz de layout para toda página + * @required + */ + Layout: Component + /** + * Aprimora a instância da aplicação Vue + * @optional + */ + enhanceApp?: (ctx: EnhanceAppContext) => Awaitable + /** + * Estende outro tema, chamando seu `enhanceApp` antes do nosso + * @optional + */ + extends?: Theme +} + +interface EnhanceAppContext { + app: App // instância da aplicação Vue + router: Router // instância do roteador VitePress + siteData: Ref // Metadados do nível do site +} +``` + +O arquivo de entrada do tema deve exportar o tema como sua exportação padrão: + +```js +// .vitepress/theme/index.js + +// Você pode importar arquivos Vue diretamente no arquivo de entrada do tema +// VitePress já está pré-configurado com @vitejs/plugin-vue. +import Layout from './Layout.vue' + +export default { + Layout, + enhanceApp({ app, router, siteData }) { + // ... + } +} +``` + +A exportação padrão é o único contrato para um tema personalizado, e apenas a propriedade `Layout` é exigida. Tecnicamente, um tema do VitePress pode ser tão simples quanto um único componente Vue. + +Dentro do seu componente de layout, ele funciona como uma aplicação Vite + Vue 3 normal. Note que o tema também precisa ser [compatível com SSR](./ssr-compat). + +## Construindo um Layout {#building-a-layout} + +O componente de layout mais básico precisa conter um componente [``](../reference/runtime-api#content): + +```vue + + +``` + +O layout acima simplesmente renderiza o markdown de toda página como HTML. A primeira melhoria que podemos adicionar é lidar com erros 404: + +```vue{1-4,9-12} + + + +``` + +O auxiliar [`useData()`](../reference/runtime-api#usedata) fornece todos os dados em tempo de execução que precisamos para mostrar layouts diferentes. Um dos outros dados que podemos acessar é o frontmatter da página atual. Podemos aproveitar isso para permitir que o usuário final controle o layout em cada página. Por exemplo, o usuário pode indicar que a página deve usar um layout especial de página inicial com: + +```md +--- +layout: home +--- +``` + +E podemos ajustar nosso tema para lidar com isso: + +```vue{3,12-14} + + + +``` + +Você pode, é claro, dividir o layout em mais componentes: + +```vue{3-5,12-15} + + + +``` + +Consulte a [Referência da API em Tempo de Execução](../reference/runtime-api) para tudo que está disponível em componentes de tema. Além disso, você pode aproveitar [Carregamento de Dados em Tempo de Compilação](./data-loading) para gerar layouts orientados por dados - por exemplo, uma página que lista todas as postagens do blog no projeto atual. + +## Distribuindo um Tema Personalizado {#distributing-a-custom-theme} + +A maneira mais fácil de distribuir um tema personalizado é fornecê-lo como um [repositório de modelo no GitHub](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository). + +Se você deseja distribuir seu tema como um pacote npm, siga estas etapas: + +1. Exporte o objeto do tema como a exportação padrão no seu arquivo de pacote. + +2. Se aplicável, exporte a definição de configuração de tipo do tema como `ThemeConfig`. + +3. Se seu tema exigir ajustes na configuração VitePress, exporte essa configuração em um subdiretório do pacote (por exemplo, `meu-tema/config`) para que o usuário possa estendê-la. + +4. Documente as opções de configuração do tema (tanto via arquivo de configuração quanto em frontmatter). + +5. Forneça instruções claras sobre como consumir seu tema (veja abaixo). + +## Consumindo um Tema Personalizado {#consuming-a-custom-theme} + +Para consumir um tema externo, importe-o e reexporte-o a partir do arquivo de entrada do tema personalizado: + +```js +// .vitepress/theme/index.js +import Theme from 'awesome-vitepress-theme' + +export default Theme +``` + +Se o tema precisar ser estendido: + +```js +// .vitepress/theme/index.js +import Theme from 'awesome-vitepress-theme' + +export default { + extends: Theme, + enhanceApp(ctx) { + // ... + } +} +``` + +Se o tema exigir uma configuração especial do VitePress, você também precisará estendê-lo em sua própria configuração: + +```ts +// .vitepress/theme/config.ts +import baseConfig from 'awesome-vitepress-theme/config' + +export default { + // estenda a configuração base do tema (se preciso) + extends: baseConfig +} +``` + +Finalmente, se o tema fornecer tipos para a configuração do tema: + +```ts +// .vitepress/theme/config.ts +import baseConfig from 'awesome-vitepress-theme/config' +import { defineConfigWithTheme } from 'vitepress' +import type { ThemeConfig } from 'awesome-vitepress-theme' + +export default defineConfigWithTheme({ + extends: baseConfig, + themeConfig: { + // O tipo é `ThemeConfig` + } +}) +``` diff --git a/docs/pt/guide/data-loading.md b/docs/pt/guide/data-loading.md new file mode 100644 index 00000000..6efb7ddf --- /dev/null +++ b/docs/pt/guide/data-loading.md @@ -0,0 +1,248 @@ +# Carregamento de Dados em Tempo de Compilação {#build-time-data-loading} + +VitePress fornece um recurso chamado **carregadores de dado** que permite carregar dados arbitrários e importá-los de páginas ou de componentes. O carregamento de dados é executado **apenas no tempo da construção**: os dados resultantes serão serializados como JSON no pacote JavaScript final. + +Os carregadores de dados podem ser usados para buscar dados remotos ou gerar metadados com base em arquivos locais. Por exemplo, você pode usar carregadores de dados para processar todas as suas páginas API locais e gerar automaticamente um índice de todas as entradas da API. + +## Uso Básico {#basic-usage} + +Um arquivo de carregador de dados deve terminar com `.data.js` ou `.data.ts`. O arquivo deve fornecer uma exportação padrão de um objeto com o método `load()`: + +```js +// example.data.js +export default { + load() { + return { + hello: 'world' + } + } +} +``` + +O módulo do carregador é avaliado apenas no Node.js, então você pode importar APIs Node e dependências npm conforme necessário. + +Você pode então importar dados deste arquivo em páginas `.md` e componentes `.vue` usando a exportação nomeada `data`: + +```vue + + +
{{ data }}
+``` + +Saída: + +```json +{ + "hello": "world" +} +``` + +Você notará que o próprio carregador de dados não exporta o `data`. É o VitePress chamando o método `load()` nos bastidores e expondo implicitamente o resultado por meio da exportação nomeada `data`. + +Isso funciona mesmo se o carregador for assíncrono: + +```js +export default { + async load() { + // buscar dados remotos + return (await fetch('...')).json() + } +} +``` + +## Dados de Arquivos Locais {#data-from-local-files} + +Quando você precisa gerar dados com base em arquivos locais, você deve usar a opção `watch` no carregador de dados para que as alterações feitas nesses arquivos possam acionar atualizações rápidas. + +A opção `watch` também é conveniente porque você pode usar [padrões glob](https://github.com/mrmlnc/fast-glob#pattern-syntax) para corresponder a vários arquivos. Os padrões podem ser relativos ao próprio arquivo do carregador, e a função `load()` receberá os arquivos correspondentes como caminhos absolutos. + +O exemplo a seguir mostra o carregamento de arquivos CSV e a transformação deles em JSON usando [csv-parse](https://github.com/adaltas/node-csv/tree/master/packages/csv-parse/). Como este arquivo só é executado no tempo da construção, você não enviará o procesador CSV para o cliente! + +```js +import fs from 'node:fs' +import { parse } from 'csv-parse/sync' + +export default { + watch: ['./data/*.csv'], + load(watchedFiles) { + // watchedFiles será um array de caminhos absolutos dos arquivos correspondidos. + // gerar um array de metadados de post que pode ser usada para mostrar + // uma lista no layout do tema + return watchedFiles.map((file) => { + return parse(fs.readFileSync(file, 'utf-8'), { + columns: true, + skip_empty_lines: true + }) + }) + } +} +``` + +## `createContentLoader` + +Ao construir um site focado em conteúdo, frequentemente precisamos criar uma página de "arquivo" ou "índice": uma página onde listamos todas as entradas disponíveis em nossa coleção de conteúdo, por exemplo, artigos de blog ou páginas de API. Nós **podemos** implementar isso diretamente com a API de carregador de dados, mas como este é um caso de uso tão comum, VitePress também fornece um auxiliar `createContentLoader` para simplificar isso: + +```js +// posts.data.js +import { createContentLoader } from 'vitepress' + +export default createContentLoader('posts/*.md', /* opções */) +``` + +O auxiliar aceita um padrão glob relativo ao [diretório fonte](./routing#source-directory) e retorna um objeto de carregador de dados `{ watch, load }` que pode ser usado como exportação padrão em um arquivo de carregador de dados. Ele também implementa cache com base nos selos de data do arquivo para melhorar o desempenho no desenvolvimento. + +Note que o carregador só funciona com arquivos Markdown - arquivos não-Markdown correspondidos serão ignorados. + +Os dados carregados serão um _array_ com o tipo `ContentData[]`: + +```ts +interface ContentData { + // URL mapeada para a página. Ex: /posts/hello.html (não inclui a base) + // itere manualmente ou use `transform` personalizado para normalizar os caminhos + url: string + // dados frontmatter da página + frontmatter: Record + + // os seguintes estão presentes apenas se as opções relevantes estiverem habilitadas + // discutiremos sobre eles abaixo + src: string | undefined + html: string | undefined + excerpt: string | undefined +} +``` + +Por padrão, apenas `url` e `frontmatter` são fornecidos. Isso ocorre porque os dados carregados serão incorporados como JSON no pacote do cliente, então precisamos ser cautelosos com seu tamanho. Aqui está um exemplo de como usar os dados para construir uma página de índice de blog mínima: + +```vue + + + +``` + +### Opções {#options} + +Os dados padrão podem não atender a todas as necessidades - você pode optar por transformar os dados usando opções: + +```js +// posts.data.js +import { createContentLoader } from 'vitepress' + +export default createContentLoader('posts/*.md', { + includeSrc: true, // incluir fonte markdown crua? + render: true, // incluir HTML completo da página apresentada? + excerpt: true, // incluir excerto? + transform(rawData) { + // mapeie, ordene ou filtre os dados crus conforme quiser. + // o resultado final é o que será enviado ao cliente. + return rawData.sort((a, b) => { + return +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date) + }).map((page) => { + page.src // fonte markdown crua + page.html // HTML completo da página apresentada + page.excerpt // HTML do excerto apresentado (conteúdo acima do primeiro `---`) + return {/* ... */} + }) + } +}) +``` + +Veja como é usado no [blog Vue.js](https://github.com/vuejs/blog/blob/main/.vitepress/theme/posts.data.ts). + +A API `createContentLoader` também pode ser usada dentro dos [ganchos de construção](../reference/site-config#build-hooks): + +```js +// .vitepress/config.js +export default { + async buildEnd() { + const posts = await createContentLoader('posts/*.md').load() + // gerar arquivos com base nos metadados dos posts, por exemplo, feed RSS + } +} +``` + +**Tipos** + +```ts +interface ContentOptions { + /** + * Incluir src? + * @default false + */ + includeSrc?: boolean + + /** + * Renderizar src para HTML e incluir nos dados? + * @default false + */ + render?: boolean + + /** + * Se `boolean`, deve-se processar e incluir o resumo? (apresentado como HTML) + * + * Se `function`, controla como o excerto é extraído do conteúdo. + * + * Se `string`, define um separador personalizado a ser usado para extrair o + * excerto. O separador padrão é `---` se `excerpt` for `true`. + * + * @see https://github.com/jonschlinkert/gray-matter#optionsexcerpt + * @see https://github.com/jonschlinkert/gray-matter#optionsexcerpt_separator + * + * @default false + */ + excerpt?: + | boolean + | ((file: { data: { [key: string]: any }; content: string; excerpt?: string }, options?: any) => void) + | string + + /** + * Transforma os dados. Observe que os dados serão incorporados como JSON no pacote do cliente + * se importados de componentes ou arquivos markdown. + */ + transform?: (data: ContentData[]) => T | Promise +} +``` + +## Carregadores de Dados com Tipos {#typed-data-loaders} + +Ao usar TypeScript, você pode tipar seu carregador e exportar `data` da seguinte forma: + +```ts +import { defineLoader } from 'vitepress' + +export interface Data { + // tipo de dado +} + +declare const data: Data +export { data } + +export default defineLoader({ + // opções do carregador verificadas pelo tipo + watch: ['...'], + async load(): Promise { + // ... + } +}) +``` + +## Configuração {#configuration} + +Para obter as informações de configuração dentro de um carregador, você pode usar um código como este: + +```ts +import type { SiteConfig } from 'vitepress' + +const config: SiteConfig = (globalThis as any).VITEPRESS_CONFIG +``` diff --git a/docs/pt/guide/deploy.md b/docs/pt/guide/deploy.md new file mode 100644 index 00000000..ba8b2fd8 --- /dev/null +++ b/docs/pt/guide/deploy.md @@ -0,0 +1,291 @@ +--- +outline: deep +--- + +# Implante seu Site VitePress {#deploy-your-vitepress-site} + +Os guias a seguir são baseados em alguns pressupostos: + +- O site VitePress está dentro do diretório `docs` do seu projeto. +- Você está usando o diretório de saída de compilação padrão (`.vitepress/dist`). +- VitePress está instalado como uma dependência local em seu projeto, e você configurou os seguintes scripts em seu `package.json`: + + ```json + { + "scripts": { + "docs:build": "vitepress build docs", + "docs:preview": "vitepress preview docs" + } + } + ``` + +## Compilar e Testar Localmente {#build-and-test-locally} + +1. Execute este comando para compilar a documentação: + + ```sh + $ npm run docs:build + ``` + +2. Após a compilação, veja a prévia local executando: + + ```sh + $ npm run docs:preview + ``` + + O comando `preview` inicializará um servidor web estático local que servirá o diretório de saída `.vitepress/dist` em `http://localhost:4173`. Você pode usar isso para garantir que tudo esteja correto antes de enviar para produção. + +3. Você pode configurar a porta do servidor passando `--port` como argumento. + + ```json + { + "scripts": { + "docs:preview": "vitepress preview docs --port 8080" + } + } + ``` + + Agora o método `docs:preview` implantará o servidor em `http://localhost:8080`. + +## Configurando um Caminho Base Público {#setting-a-public-base-path} + +Por padrão, assumimos que o site será implantado no caminho raiz de um domínio (`/`). Se seu site for servido em um subcaminho, por exemplo, `https://meusite.com/blog/`, você precisa então configurar a opção [`base`](../reference/site-config#base) para `'/blog/'` na configuração VitePress. + +**Exemplo:** Ao usar GitHub Pages (ou GitLab Pages) e implantar em `user.github.io/repo/`, defina seu `base` como `/repo/`. + +## Cabeçalhos de Cache HTTP {#http-cache-headers} + +Se você tiver controle sobre os cabeçalhos HTTP de seu servidor em produção, pode-se configurar cabeçalhos `cache-control` para obter melhor desempenho em visitas repetidas. + +A compilação de produção usa nomes de arquivos com hash para ativos estáticos (JavaScript, CSS e outros ativos importados que não estão em `public`). Se você inspecionar a prévia de produção usando as ferramentas de desenvolvedor do seu nevegador na aba rede, verá arquivos como `app.4f283b18.js`. + +Este hash `4f283b18` é gerado a partir do conteúdo deste arquivo. A mesma URL com hash é garantida para servir o mesmo conteúdo do arquivo - se o conteúdo mudar, as URLs também mudam. Isso significa que você pode usar com segurança os cabeçalhos de cache mais fortes para esses arquivos. Todos esses arquivos serão colocados em `assets/` no diretório de saída, então você pode configurar o seguinte cabeçalho para eles: + +``` +Cache-Control: max-age=31536000,immutable +``` + +::: details Exemplo de arquivo `_headers` do Netlify + +``` +/assets/* + cache-control: max-age=31536000 + cache-control: immutable +``` + +Nota: o arquivo `_headers` deve ser colocado no [diretório public](./asset-handling#the-public-directory) - em nosso caso, `docs/public/_headers` - para que ele seja copiado exatamente para o diretório de saída. + +[Documentação de cabeçalhos personalizados do Netlify](https://docs.netlify.com/routing/headers/) + +::: + +::: details Exemplo de configuração Vercel em `vercel.json` + +```json +{ + "headers": [ + { + "source": "/assets/(.*)", + "headers": [ + { + "key": "Cache-Control", + "value": "max-age=31536000, immutable" + } + ] + } + ] +} +``` + +Nota: o arquivo `vercel.json` deve ser colocado na raiz do seu **repositório**. + +[Documentação Vercel sobre configuração de cabeçalhos](https://vercel.com/docs/concepts/projects/project-configuration#headers) + +::: + +## Guias de Plataforma {#platform-guides} + +### Netlify / Vercel / Cloudflare Pages / AWS Amplify / Render + +Configure um novo projeto e altere estas configurações usando seu painel: + +- **Comando de Compilação:** `npm run docs:build` +- **Diretório de Saída:** `docs/.vitepress/dist` +- **Versão do Node:** `18` (ou superior) + +::: warning +Não ative opções como _Auto Minify_ para código HTML. Isso removerá comentários da saída que têm significado para Vue. Haverão erros de incompatibilidade de hidratação se forem removidos. +::: + +### GitHub Pages + +1. Crie um arquivo chamado `deploy.yml` dentro do diretório `.github/workflows` do seu projeto com algum conteúdo como este: + + ```yaml + # Exemplo de fluxo de trabalho para compilar e implantar um site VitePress no GitHub Pages + # + name: Implante o site VitePress no Pages + + on: + # Executa em pushes direcionados à branch `main`. + # Altere para `master` se estiver usando a branch `master` como padrão. + push: + branches: [main] + + # Permite executar manualmente este fluxo de trabalho na guia Actions + workflow_dispatch: + + # Define permissões GITHUB_TOKEN para a implantação no GitHub Pages + permissions: + contents: read + pages: write + id-token: write + + # Permite apenas uma implantação simultânea, pulando execuções em fila entre a execução em andamento e a última da fila. + # No entanto, NÃO cancela execuções em andamento, pois queremos permitir que essas implantações de produção sejam concluídas. + concurrency: + group: pages + cancel-in-progress: false + + jobs: + # Trabalho de compilação + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Não necessário se lastUpdated não estiver habilitado + # - uses: pnpm/action-setup@v3 # Descomente isso se estiver usando pnpm + # - uses: oven-sh/setup-bun@v1 # Descomente isso se estiver usando Bun + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm # ou pnpm / yarn + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Install dependencies + run: npm ci # ou pnpm install / yarn install / bun install + - name: Build with VitePress + run: | + npm run docs:build # ou pnpm docs:build / yarn docs:build / bun run docs:build + touch docs/.vitepress/dist/.nojekyll + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs/.vitepress/dist + + # Trabalho de implantação + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + name: Deploy + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 + ``` + + ::: warning + Certifique-se de que a opção `base` em seu VitePress esteja configurada corretamente. Veja [Configurando um Caminho Base Público](#setting-a-public-base-path) para mais detalhes. + ::: + +2. Nas configurações do seu repositório sob o item do menu "Pages", selecione "GitHub Actions" em "Build and deployment > Source". + +3. Envie suas alterações para a branch `main` e aguarde a conclusão do fluxo de trabalho do GitHub Actions. Você verá seu site implantado em `https://.github.io/[repository]/` ou `https:///` dependendo das suas configurações. Seu site será implantado automaticamente em cada push para a branch `main`. + +### GitLab Pages + +1. Defina `outDir` na configuração VitePress como `../public`. Configure a opção `base` para `'//'` se você deseja implantar em `https://.gitlab.io//`. + +2. Crie um arquivo chamado `.gitlab-ci.yml` na raiz do seu projeto com o conteúdo abaixo. Isso construirá e implantará seu site sempre que você fizer alterações no conteúdo: + + ```yaml + image: node:18 + pages: + cache: + paths: + - node_modules/ + script: + # - apk add git # Descomente isso se estiver usando imagens pequenas do Docker como o Alpine e tiver lastUpdated habilitado + - npm install + - npm run docs:build + artifacts: + paths: + - public + only: + - main + ``` + +### Azure Static Web Apps {#azure-static-web-apps} + +1. Siga a [documentação oficial](https://docs.microsoft.com/en-us/azure/static-web-apps/build-configuration). + +2. Configure esses valores em seu arquivo de configuração (e remova aqueles que você não precisa, como `api_location`): + + - **`app_location`**: `/` + - **`output_location`**: `docs/.vitepress/dist` + - **`app_build_command`**: `npm run docs:build` + +### Firebase {#firebase} + +1. Crie `firebase.json` e `.firebaserc` na raiz do seu projeto: + + `firebase.json`: + + ```json + { + "hosting": { + "public": "docs/.vitepress/dist", + "ignore": [] + } + } + ``` + + `.firebaserc`: + + ```json + { + "projects": { + "default": "" + } + } + ``` + +2. Após executar `npm run docs:build`, execute este comando para implantar: + + ```sh + firebase deploy + ``` + +### Surge + +1. Após executar `npm run docs:build`, execute este comando para implantar: + + ```sh + npx surge docs/.vitepress/dist + ``` + +### Heroku + +1. Siga a documentação e o guia fornecidos em [`heroku-buildpack-static`](https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-static). + +2. Crie um arquivo chamado `static.json` na raiz do seu projeto com o conteúdo abaixo: + + ```json + { + "root": "docs/.vitepress/dist" + } + ``` + +### Edgio + +Consulte [Criar e Implantar um Aplicativo VitePress no Edgio](https://docs.edg.io/guides/vitepress). + +### Kinsta Static Site Hosting {#kinsta-static-site-hosting} + +Você pode implantar seu site Vitepress em [Kinsta](https://kinsta.com/static-site-hosting/) seguindo estas [instruções](https://kinsta.com/docs/vitepress-static-site-example/). diff --git a/docs/pt/guide/extending-default-theme.md b/docs/pt/guide/extending-default-theme.md new file mode 100644 index 00000000..db68e954 --- /dev/null +++ b/docs/pt/guide/extending-default-theme.md @@ -0,0 +1,340 @@ +--- +outline: deep +--- + +# Estendendo o Tema Padrão {#extending-the-default-theme} + +O tema padrão do VitePress é otimizado para documentação e pode ser personalizado. Consulte a [Visão Geral de Configuração do Tema Padrão](../reference/default-theme-config) para uma lista abrangente de opções. + +No entanto, há casos em que apenas a configuração não será suficiente. Por exemplo: + +1. É necessário ajustar a estilização CSS; +2. É necessário modificar a instância da aplicação Vue, por exemplo para registrar componentes globais; +3. É necessário injetar conteúdo personalizado no tema por meio de _slots_ no layout. + +Essas personalizações avançadas exigirão o uso de um tema personalizado que "estende" o tema padrão. + +::: tip +Antes de prosseguir, certifique-se de ler primeiro [Usando um Tema Personalizado](./custom-theme) para entender como temas personalizados funcionam. +::: + +## Personalizando o CSS {#customizing-css} + +O CSS do tema padrão pode ser personalizado substituindo as variáveis CSS no nível raiz: + +```js +// .vitepress/theme/index.js +import DefaultTheme from 'vitepress/theme' +import './custom.css' + +export default DefaultTheme +``` + +```css +/* .vitepress/theme/custom.css */ +:root { + --vp-c-brand-1: #646cff; + --vp-c-brand-2: #747bff; +} +``` + +Veja as [variáveis CSS do tema padrão](https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css) que podem ser substituídas. + +## Usando Fontes Diferentes {#using-different-fonts} + +VitePress usa [Inter](https://rsms.me/inter/) como fonte padrão e incluirá as fontes na saída de compilação. A fonte também é pré-carregada automaticamente em produção. No entanto, isso pode não ser desejável se você quiser usar uma fonte principal diferente. + +Para evitar a inclusão de Inter na saída de compilação, importe o tema de `vitepress/theme-without-fonts`: + +```js +// .vitepress/theme/index.js +import DefaultTheme from 'vitepress/theme-without-fonts' +import './my-fonts.css' + +export default DefaultTheme +``` + +```css +/* .vitepress/theme/custom.css */ +:root { + --vp-font-family-base: /* fonte de texto normal */ + --vp-font-family-mono: /* fonte de código */ +} +``` + +::: warning +Se estiver usando componentes opcionais como os componentes da [Página da Equipe](../reference/default-theme-team-page), certifique-se de também importá-los de `vitepress/theme-without-fonts`! +::: + +Se a sua fonte é um arquivo local referenciado via `@font-face`, ela será processada como um ativo e incluída em `.vitepress/dist/assets` com um nome de arquivo hash. Para pré-carregar esse arquivo, use o gancho de construção [transformHead](../reference/site-config#transformhead): + +```js +// .vitepress/config.js +export default { + transformHead({ assets }) { + // ajuste o regex para corresponder à sua fonte + const myFontFile = assets.find(file => /font-name\.\w+\.woff2/) + if (myFontFile) { + return [ + [ + 'link', + { + rel: 'preload', + href: myFontFile, + as: 'font', + type: 'font/woff2', + crossorigin: '' + } + ] + ] + } + } +} +``` + +## Registrando Componentes Globais {#registering-global-components} + +```js +// .vitepress/theme/index.js +import DefaultTheme from 'vitepress/theme' + +/** @type {import('vitepress').Theme} */ +export default { + extends: DefaultTheme, + enhanceApp({ app }) { + // registre seus componentes globais personalizados + app.component('MyGlobalComponent' /* ... */) + } +} +``` + +Se estiver usando TypeScript: +```ts +// .vitepress/theme/index.ts +import type { Theme } from 'vitepress' +import DefaultTheme from 'vitepress/theme' + +export default { + extends: DefaultTheme, + enhanceApp({ app }) { + // registre seus componentes globais personalizados + app.component('MyGlobalComponent' /* ... */) + } +} satisfies Theme +``` + +Como estamos usando Vite, você também pode aproveitar a [funcionalidade de importação glob](https://vitejs.dev/guide/features.html#glob-import) do Vite para registrar automaticamente um diretório de componentes. + +## _Slots_ no Layout {#layout-slots} + +O componente `` do tema padrão possui alguns _slots_ que podem ser usados para injetar conteúdo em locais específicos da página. Aqui está um exemplo de como injetar um componente antes do esquema : + +```js +// .vitepress/theme/index.js +import DefaultTheme from 'vitepress/theme' +import MyLayout from './MyLayout.vue' + +export default { + extends: DefaultTheme, + // substitua o Layout por um componente envolvente que + // injeta os slots + Layout: MyLayout +} +``` + +```vue + + + + +``` + +Ou você também pode usar a função _render_. + +```js +// .vitepress/theme/index.js +import { h } from 'vue' +import DefaultTheme from 'vitepress/theme' +import MyComponent from './MyComponent.vue' + +export default { + extends: DefaultTheme, + Layout() { + return h(DefaultTheme.Layout, null, { + 'aside-outline-before': () => h(MyComponent) + }) + } +} +``` + +Lista completa de _slots_ disponíveis no layout do tema padrão: + +- Quando `layout: 'doc'` (padrão) está habilitado via frontmatter: + - `doc-top` + - `doc-bottom` + - `doc-footer-before` + - `doc-before` + - `doc-after` + - `sidebar-nav-before` + - `sidebar-nav-after` + - `aside-top` + - `aside-bottom` + - `aside-outline-before` + - `aside-outline-after` + - `aside-ads-before` + - `aside-ads-after` +- Quando `layout: 'home'` está habilitado via frontmatter: + - `home-hero-before` + - `home-hero-info-before` + - `home-hero-info` + - `home-hero-actions-after` + - `home-hero-image` + - `home-hero-after` + - `home-features-before` + - `home-features-after` +- Quando `layout: 'page'` está habilitado via frontmatter: + - `page-top` + - `page-bottom` +- Na página não encontrada (404): + - `not-found` +- Sempre: + - `layout-top` + - `layout-bottom` + - `nav-bar-title-before` + - `nav-bar-title-after` + - `nav-bar-content-before` + - `nav-bar-content-after` + - `nav-screen-content-before` + - `nav-screen-content-after` + +## Usando a API View Transitions + +### Na Alternância de Aparência {#on-appearance-toggle} + +Você pode estender o tema padrão para fornecer uma transição personalizada quando o modo de cor é alternado. Um exemplo: + +```vue + + + + + + + +``` + +Resultado (**atenção!**: cores piscantes, movimentos súbitos, luzes brilhantes): + +
+Demo + +![Demo de Transição de Alternância de Aparência](/appearance-toggle-transition.webp) + +
+ +Consulte [Chrome Docs](https://developer.chrome.com/docs/web-platform/view-transitions/) para mais detalhes sobre _view transitions_. + +### Na Mudança de Rota {#on-route-change} + +Em breve. + +## Substituindo Componentes Internos {#overriding-internal-components} + +Você pode usar os [aliases](https://vitejs.dev/config/shared-options.html#resolve-alias) Vite para substituir os componentes do tema padrão pelos seus personalizados: + +```ts +import { fileURLToPath, URL } from 'node:url' +import { defineConfig } from 'vitepress' + +export default defineConfig({ + vite: { + resolve: { + alias: [ + { + find: /^.*\/VPNavBar\.vue$/, + replacement: fileURLToPath( + new URL('./components/CustomNavBar.vue', import.meta.url) + ) + } + ] + } + } +}) +``` + +Para saber o nome exato do componente consulte [nosso código fonte](https://github.com/vuejs/vitepress/tree/main/src/client/theme-default/components). Como os componentes são internos, há uma pequena chance de que o nome deles seja atualizado entre lançamentos secundários. \ No newline at end of file diff --git a/docs/pt/guide/frontmatter.md b/docs/pt/guide/frontmatter.md new file mode 100644 index 00000000..0ab4ac51 --- /dev/null +++ b/docs/pt/guide/frontmatter.md @@ -0,0 +1,48 @@ +# Frontmatter + +## Utilização {#usage} + +VitePress suporta frontmatter YAML em todos os arquivos Markdown, processando-os com [gray-matter](https://github.com/jonschlinkert/gray-matter). O frontmatter deve estar no topo do arquivo Markdown (antes de qualquer elemento, incluindo tags ` + + +``` + +## Suporte a RTL (Experimental) {#rtl-support-experimental} + +Para suporte a RTL (Right to Left), especifique `dir: 'rtl'` na configuração e use algum plugin RTLCSS PostCSS como , ou . Você precisará configurar seu plugin PostCSS para usar `:where([dir="ltr"])` e `:where([dir="rtl"])` como prefixos para evitar problemas de especificidade CSS. \ No newline at end of file diff --git a/docs/pt/guide/markdown.md b/docs/pt/guide/markdown.md new file mode 100644 index 00000000..5fba7333 --- /dev/null +++ b/docs/pt/guide/markdown.md @@ -0,0 +1,929 @@ +# Extensões Markdown {#markdown-extensions} + +VitePress vem com Extensões Markdown embutidas. + +## Âncoras de Cabeçalho {#header-anchors} + +Cabeçalhos recebem a aplicação automaticamente de links âncora. A apresentação das âncoras pode ser configurada usando a opção `markdown.anchor`. + +### Âncoras personalizadas {#custom-anchors} + +Para especificar uma _tag_ âncora personalizada para um cabeçalho em vez de usar aquela gerada automaticamente, adicione um sufixo ao cabeçalho: + +``` +# Usando âncoras personalizadas {#minha-ancora} +``` + +Isso permite que você tenha um link do cabeçalho como `#minha-ancora` em vez do padrão `#usando-ancoras-personalizadas`. + +## Links {#links} + +Ambos os links internos e externos recebem tratamento especial. + +### Links Internos {#internal-links} + +Os links internos são convertidos em links de roteador para navegação SPA. Além disso, todo arquivo `index.md` contido em cada subdiretório será automaticamente convertido para `index.html`, com a URL correspondente `/`. + +Por exemplo, dada a seguinte estrutura de diretórios: + +``` +. +├─ index.md +├─ foo +│ ├─ index.md +│ ├─ one.md +│ └─ two.md +└─ bar + ├─ index.md + ├─ three.md + └─ four.md +``` + +E supondo que você esteja em `foo/one.md`: + +```md +[Página Inicial](/) +[foo](/foo/) +[foo heading](./#heading) +[bar - three](../bar/three) +[bar - three](../bar/three.md) +[bar - four](../bar/four.html) +``` + +### Sufixo de Página {#page-suffix} + +Páginas e links internos são gerados com o sufixo `.html` por padrão. + +### Links Externos {#external-links} + +Links externos recebem automaticamente `target="_blank" rel="noreferrer"`: + +- [vuejs.org](https://vuejs.org) +- [VitePress no GitHub](https://github.com/vuejs/vitepress) + +## Frontmatter {#frontmatter} + +[YAML frontmatter](https://jekyllrb.com/docs/front-matter/) é suportado por padrão: + +```yaml +--- +título: Escrevendo como um Hacker +idioma: pt-BR +--- +``` + +Esses dados estarão disponíveis para o restante da página, junto com todos os componentes personalizados e de temas. + +Para mais detalhes, veja [Frontmatter](../reference/frontmatter-config). + +## Tabelas ao Estilo GitHub {#github-style-tables} + +**Entrada** + +```md +| Tabelas | São | Legais | +| ------------- | :-----------: | ----: | +| col 3 está | à direita | $1600 | +| col 2 está | centralizada | $12 | +| listras | são legais | $1 | +``` + +**Saída** + +| Tabelas | São | Legais | +| ------------- | :-----------: | -----: | +| col 3 está | à direita | \$1600 | +| col 2 está | centralizada | \$12 | +| listras | são legais | \$1 | + +## Emoji :tada: + +**Entrada** + +``` +:tada: :100: +``` + +**Saída** + +:tada: :100: + +Uma [lista de todos os emojis](https://github.com/markdown-it/markdown-it-emoji/blob/master/lib/data/full.mjs) está disponível. + +## Tabela de Conteúdo (TOC) + +**Entrada** + +``` +[[toc]] +``` + +**Saída** + +[[toc]] + +A apresentação de TOC (Table of Contents) pode ser configurada usando a opção `markdown.toc`. + +## Recipientes Personalizados {#custom-containers} + +Recipientes personalizados podem ser definidos por seus tipos, títulos e conteúdos. + +### Título Padrão {#default-title} + +**Entrada** + +```md +::: info +Este é um bloco de informações. +::: + +::: tip +Este é um aviso. +::: + +::: warning +Este é um aviso. +::: + +::: danger +Este é um aviso de perigo. +::: + +::: details +Este é um bloco de detalhes. +::: +``` + +**Saída** + +::: info +Este é um bloco de informações. +::: + +::: tip +Este é um aviso. +::: + +::: warning +Este é um aviso. +::: + +::: danger +Este é um aviso de perigo. +::: + +::: details +Este é um bloco de detalhes. +::: + +### Título Personalizado {#custom-title} + +Você pode definir um título personalizado adicionando o texto imediatamente após o "tipo" do recipiente. + +**Entrada** + +```md +::: danger STOP +Zona de perigo, não prossiga +::: + +::: details Clique para ver o código +```js +console.log('Olá, VitePress!') +``` +::: +``` + +**Saída** + +::: danger STOP +Zona de perigo, não prossiga +::: + +::: details Clique para ver o código +```js +console.log('Olá, VitePress!') +``` +::: + +Além disso, você pode definir títulos personalizados globalmente adicionando o seguinte conteúdo no arquivo de configuração do site, útil se não estiver escrevendo em inglês: + +```ts +// config.ts +export default defineConfig({ + // ... + markdown: { + container: { + tipLabel: '提示', + warningLabel: '警告', + dangerLabel: '危险', + infoLabel: '信息', + detailsLabel: '详细信息' + } + } + // ... +}) +``` + +### `raw` + +Este é um recipiente especial que pode ser usado para evitar conflitos de estilo e roteador com VitePress. Isso é especialmente útil ao documentar bibliotecas de componentes. Você também pode verificar [whyframe](https://whyframe.dev/docs/integrations/vitepress) para melhor isolamento. + +**Sintaxe** + +```md +::: raw +Envolve em um
+::: +``` + +A classe `vp-raw` também pode ser usada diretamente em elementos. O isolamento de estilo é atualmente opcional: + +- Instale o `postcss` com seu gerenciador de pacotes preferido: + + ```sh + $ npm add -D postcss + ``` + +- Crie um arquivo chamado `docs/postcss.config.mjs` e adicione o seguinte: + + ```js + import { postcssIsolateStyles } from 'vitepress' + + export default { + plugins: [postcssIsolateStyles()] + } + ``` + + Ele utiliza [`postcss-prefix-selector`](https://github.com/postcss/postcss-load-config) internamente. Você pode passar opções assim: + + ```js + postcssIsolateStyles({ + includeFiles: [/vp-doc\.css/] // o padrão é /base\.css/ + }) + ``` + +## Alertas no estilo GitHub {#github-flavored-alerts} + +VitePress também suporta [alertas no estilo GitHub](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts) para apresentar como um bloco de chamada. Eles serão apresentados da mesma forma que [elementos personalizados](#custom-containers). + +```md +> [!NOTE] +> Destaca informações que os usuários devem levar em consideração, mesmo ao ler rapidamente. + +> [!TIP] +> Informações opcionais para ajudar o usuário a ter mais sucesso. + +> [!IMPORTANT] +> Informações cruciais necessárias para que os usuários tenham sucesso. + +> [!WARNING] +> Conteúdo crítico exigindo atenção imediata do usuário devido a riscos potenciais. + +> [!CAUTION] +> Potenciais consequências negativas de uma ação. +``` + +> [!NOTE] +> Destaca informações que os usuários devem levar em consideração, mesmo ao ler rapidamente. + +> [!TIP] +> Informações opcionais para ajudar o usuário a ter mais sucesso. + +> [!IMPORTANT] +> Informações cruciais necessárias para que os usuários tenham sucesso. + +> [!WARNING] +> Conteúdo crítico exigindo atenção imediata do usuário devido a riscos potenciais. + +> [!CAUTION] +> Potenciais consequências negativas de uma ação. + +## Destaque de Sintaxe em Blocos de Código {#syntax-highlighting-in-code-blocks} + +VitePress utiliza [Shiki](https://github.com/shikijs/shiki) para destacar a sintaxe da linguagem em blocos de código Markdown, usando texto colorido. Shiki suporta uma ampla variedade de linguagens de programação. Tudo o que você precisa fazer é adicionar um _alias_ de linguagem válido após os crases iniciais do bloco de código: + +**Entrada** + +```` +```js +export default { + name: 'MyComponent', + // ... +} +``` +```` + +```` +```html +
    +
  • + {{ todo.text }} +
  • +
+``` +```` + +**Saída** + +```js +export default { + name: 'MyComponent' + // ... +} +``` + +```html +
    +
  • + {{ todo.text }} +
  • +
+``` + +Uma [lista de linguagens válidas](https://shiki.style/languages) está disponível no repositório Shiki. + +Você também pode personalizar o tema de destaque de sintaxe na configuração do aplicativo. Consulte as [opções `markdown`](../reference/site-config#markdown) para mais detalhes. + +## Destaque de Linha em Blocos de Código {#line-highlighting-in-code-blocks} + +**Entrada** + +```` +```js{4} +export default { + data () { + return { + msg: 'Destacado!' + } + } +} +``` +```` + +**Saída** + +```js{4} +export default { + data () { + return { + msg: 'Destacado!' + } + } +} +``` + +Além de uma única linha, você também pode especificar múltiplas linhas únicas, intervalos, ou ambos: + +- Intervalos de linha: por exemplo, `{5-8}`, `{3-10}`, `{10-17}` +- Múltiplas linhas únicas: por exemplo, `{4,7,9}` +- Intervalos de linha e linhas únicas: por exemplo, `{4,7-13,16,23-27,40}` + +**Entrada** + +```` +```js{1,4,6-8} +export default { // Destacado + data () { + return { + msg: `Destacado! + Esta linha não está destacada, + mas esta e as próximas 2 estão.`, + motd: 'VitePress é incrível', + lorem: 'ipsum' + } + } +} +``` +```` + +**Saída** + +```js{1,4,6-8} +export default { // Destacado + data () { + return { + msg: `Destacado! + Esta linha não está destacada, + mas esta e as próximas 2 estão.`, + motd: 'VitePress é incrível', + lorem: 'ipsum', + } + } +} +``` + +Alternativamente, é possível destacar diretamente na linha usando o comentário `// [!code highlight]`. + +**Entrada** + +```` +```js +export default { + data () { + return { + msg: 'Destacado!' // [!!code highlight] + } + } +} +``` +```` + +**Saída** + +```js +export default { + data() { + return { + msg: 'Destacado!' // [!code destaque] + } + } +} +``` + +## Foco em Blocos de Código {#focus-in-code-blocks} + +Adicionando o comentário `// [!code focus]` em uma linha irá destacá-la e desfocar as outras partes do código. + +Além disso, você pode definir o número de linhas para focar usando `// [!code focus:]`. + +**Entrada** + +```` +```js +export default { + data () { + return { + msg: 'Focado!' // [!!code focus] + } + } +} +``` +```` + +**Saída** + +```js +export default { + data() { + return { + msg: 'Focado!' // [!code focus] + } + } +} +``` + +## Diferenças Coloridas em Blocos de Código {#colored-diffs-in-code-blocks} + +Adicionar os comentários `// [!code --]` ou `// [!code ++]` em uma linha criará uma diferença nessa linha, mantendo as cores do bloco de código. + +**Entrada** + +```` +```js +export default { + data () { + return { + msg: 'Removido' // [!!code --] + msg: 'Adicionado' // [!!code ++] + } + } +} +``` +```` + +**Saída** + +```js +export default { + data () { + return { + msg: 'Removido' // [!code --] + msg: 'Adicionado' // [!code ++] + } + } +} +``` + +## Erros e Avisos em Blocos de Código {#errors-and-warnings-in-code-blocks} + +Adicionar os comentários `// [!code warning]` ou `// [!code error]` em uma linha colorirá os blocos conforme apropriado. + +**Entrada** + +```` +```js +export default { + data () { + return { + msg: 'Erro', // [!!code error] + msg: 'Aviso' // [!!code warning] + } + } +} +``` +```` + +**Saída** + +```js +export default { + data() { + return { + msg: 'Erro', // [!code error] + msg: 'Aviso' // [!code warning] + } + } +} +``` + +## Números de Linha {#line-numbers} + +Você pode habilitar números de linha para cada bloco de código através do arquivo de configuração: + +```js +export default { + markdown: { + lineNumbers: true + } +} +``` + +Consulte as [opções markdown](../reference/site-config#markdown) para mais detalhes. + +Você pode adicionar a marca `:line-numbers` / `:no-line-numbers` em seus blocos de código para substituir o valor definido na configuração. + +Você também pode personalizar o número inicial da linha adicionando `=` após `:line-numbers`. Por exemplo, `:line-numbers=2` significa que os números das linhas nos blocos de código começarão a partir de `2`. + +**Entrada** + +````md +```ts {1} +// números de linha desativados por padrão +const line2 = 'Esta é a linha 2' +const line3 = 'Esta é a linha 3' +``` + +```ts:line-numbers {1} +// números de linha ativados +const line2 = 'Esta é a linha 2' +const line3 = 'Esta é a linha 3' +``` + +```ts:line-numbers=2 {1} +// números de linha ativados e começam do 2 +const line3 = 'Esta é a linha 3' +const line4 = 'Esta é a linha 4' +``` +```` + +**Saída** + +```ts {1} +// números de linha desativados por padrão +const line2 = 'Esta é a linha 2' +const line3 = 'Esta é a linha 3' +``` + +```ts:line-numbers {1} +// números de linha ativados +const line2 = 'Esta é a linha 2' +const line3 = 'Esta é a linha 3' +``` + +```ts:line-numbers=2 {1} +// números de linha ativados e começam do 2 +const line3 = 'Esta é a linha 3' +const line4 = 'Esta é a linha 4' +``` + +## Importar _Snippets_ de Código {#import-code-snippets} + +Você pode importar trechos de código de arquivos existentes usando a seguinte sintaxe: + +```md +<<< @/filepath +``` + +Também suporta [destaque de linha](#line-highlighting-in-code-blocks): + +```md +<<< @/filepath{highlightLines} +``` + +**Entrada** + +```md +<<< @/snippets/snippet.js{2} +``` + +**Arquivo de Código** + +<<< @/snippets/snippet.js + +**Saída** + +<<< @/snippets/snippet.js{2} + +::: dica +O valor de `@` corresponde à raiz do código fonte. Por padrão, é a raiz do projeto VitePress, a menos que `srcDir` seja configurado. Alternativamente, você também pode importar de caminhos relativos: + +```md +<<< ../snippets/snippet.js +``` + +::: + +Você também pode usar uma [região VS Code](https://code.visualstudio.com/docs/editor/codebasics#_folding) para incluir apenas a parte correspondente do arquivo de código. Você pode fornecer um nome de região personalizado após um `#` seguindo o caminho do arquivo: + +**Entrada** + +```md +<<< @/snippets/snippet-with-region.js#snippet{1} +``` + +**Arquivo de Código** + +<<< @/snippets/snippet-with-region.js + +**Saída** + +<<< @/snippets/snippet-with-region.js#snippet{1} + +Você também pode especificar o idioma dentro das chaves (`{}`), assim: + +```md +<<< @/snippets/snippet.cs{c#} + + + +<<< @/snippets/snippet.cs{1,2,4-6 c#} + + + +<<< @/snippets/snippet.cs{1,2,4-6 c#:line-numbers} +``` + +Isso é útil se a linguagem original não puder ser inferida pela extensão do arquivo. + +## Grupos de Código {#code-groups} + +Você pode agrupar vários blocos de código assim: + +**Entrada** + +````md +::: code-group + +```js [config.js] +/** + * @type {import('vitepress').UserConfig} + */ +const config = { + // ... +} + +export default config +``` + +```ts [config.ts] +import type { UserConfig } from 'vitepress' + +const config: UserConfig = { + // ... +} + +export default config +``` + +::: +```` + +**Saída** + +::: code-group + +```js [config.js] +/** + * @type {import('vitepress').UserConfig} + */ +const config = { + // ... +} + +export default config +``` + +```ts [config.ts] +import type { UserConfig } from 'vitepress' + +const config: UserConfig = { + // ... +} + +export default config +``` + +::: + +Você também pode [importar _snippets_ de código](#import-code-snippets) em grupos de código: + +**Entrada** + +```md +::: code-group + + + +<<< @/snippets/snippet.js + + + +<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region] + +::: +``` + +**Output** + +::: code-group + +<<< @/snippets/snippet.js + +<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region] + +::: + +## Inclusão de Arquivo Markdown {#markdown-file-inclusion} + +Você pode incluir um arquivo markdown em outro arquivo markdown, mesmo aninhado. + +::: dica +Você também pode prefixar o caminho do markdown com `@`, ele atuará como a raiz de origem. Por padrão, é a raiz do projeto VitePress, a menos que `srcDir` seja configurado. +::: + +Por exemplo, você pode incluir um arquivo markdown relativo usando isto: + +**Entrada** + +```md +# Documentação + +## Conceitos Básicos + + +``` + +**Arquivo da Parte** (`parts/basics.md`) + +```md +Algumas coisas básicas. + +### Configuração + +Pode ser criada usando `.foorc.json`. +``` + +**Código Equivalente** + +```md +# Documentação + +## Conceitos Básicos + +Algumas coisas básicas. + +### Configuração + +Pode ser criada usando `.foorc.json`. +``` + +Também suporta a seleção de um intervalo de linhas: + +**Entrada** + +```md +# Documentação + +## Conceitos Básicos + + +``` + +**Arquivo da Parte** (`parts/basics.md`) + +```md +Algumas coisas básicas. + +### Configuração + +Pode ser criada usando `.foorc.json`. +``` + +**Código Equivalente** + +```md +# Documentação + +## Conceitos Básicos + +### Configuração + +Pode ser criada usando `.foorc.json`. +``` + +O formato do intervalo de linhas selecionado pode ser: `{3,}`, `{,10}`, `{1,10}` + +::: aviso +Observe que isso não gera erros se o arquivo não estiver presente. Portanto, ao usar esse recurso, certifique-se de que o conteúdo está sendo mostrado como esperado. +::: + +## Equações Matemáticas {#math-equations} + +Isso é atualmente opcional. Para ativá-lo, você precisa instalar `markdown-it-mathjax3` e definir `markdown.math` como `true` no seu arquivo de configuração: + +```sh +npm add -D markdown-it-mathjax3 +``` + +```ts +// .vitepress/config.ts +export default { + markdown: { + math: true + } +} +``` + +**Entrada** + +```md +Quando $a \ne 0$, existem duas soluções para $(ax^2 + bx + c = 0)$ e elas são +$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$ + +**Equações de Maxwell:** + +| equação | descrição | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| $\nabla \cdot \vec{\mathbf{B}} = 0$ | a divergência de $\vec{\mathbf{B}}$ é zero | +| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | a rotacional de $\vec{\mathbf{E}}$ é proporcional à taxa de variação de $\vec{\mathbf{B}}$ | +| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _hã?_ | + +**Saída** + +Quando $a \ne 0$, existem duas soluções para $(ax^2 + bx + c = 0)$ e são +$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$ + +**Equações de Maxwell:** + +| equação | descrição | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| $\nabla \cdot \vec{\mathbf{B}} = 0$ | a divergência de $\vec{\mathbf{B}}$ é zero | +| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | a rotacional de $\vec{\mathbf{E}}$ é proporcional à taxa de variação de $\vec{\mathbf{B}}$ | +| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _hã?_ | + +## _Lazy Loading_ de Imagens {#image-lazy-loading} + +Você pode ativar o "carregamento folgado" para cada imagem adicionada via markdown definindo `lazyLoading` como `true` no seu arquivo de configuração: + +```js +export default { + markdown: { + image: { + // o carregamento folgado de imagens está desativado por padrão + lazyLoading: true + } + } +} +``` + +## Configuração Avançada {#advanced-configuration} + +VitePress usa [markdown-it](https://github.com/markdown-it/markdown-it) como interpretador Markdown. Muitas das extensões acima são implementadas por meio de _plugins_ personalizados. Você pode personalizar ainda mais a instância `markdown-it` usando a opção `markdown` em `.vitepress/config.js`: + +```js +import { defineConfig } from 'vitepress' +import markdownItAnchor from 'markdown-it-anchor' +import markdownItFoo from 'markdown-it-foo' + +export default defineConfig({ + markdown: { + // opções para markdown-it-anchor + // https://github.com/valeriangalliat/markdown-it-anchor#usage + anchor: { + permalink: markdownItAnchor.permalink.headerLink() + }, + + // opções para @mdit-vue/plugin-toc + // https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options + toc: { level: [1, 2] }, + + config: (md) => { + // use mais plugins markdown-it! + md.use(markdownItFoo) + } + } +}) +``` + +Consulte a lista completa de propriedades configuráveis em [Referência de Configuração: Configuração da Aplicação](../reference/site-config#markdown). \ No newline at end of file diff --git a/docs/pt/guide/mpa-mode.md b/docs/pt/guide/mpa-mode.md new file mode 100644 index 00000000..28aabae1 --- /dev/null +++ b/docs/pt/guide/mpa-mode.md @@ -0,0 +1,23 @@ +# Modo MPA {#mpa-mode} + +O modo MPA (Aplicação Multipáginas) pode ser habilitado pela linha de comando com `vitepress build --mpa`, ou através da configuração pela opção `mpa: true`. + +No modo MPA, todas as páginas são apresentadas por padrão sem qualquer JavaScript incluído. Como resultado, o site em produção provavelmente terá uma nota de desempenho de visita inicial superior com ferramentas de auditoria. + +Entretanto, devido a ausência de navegação SPA, links entre páginas acarretarão em recarregamentos de página completos. Navegações pós-carregamento no modo MPA não parecerão tão instantâneas quanto no modo SPA. + +Também note que não ter JavaScript por padrão significa que você está essencialmente utilizando Vue como modelo de linguagem no lado do servidor. Nenhum manipulador de evento será embutido no navegador, então não haverá interatividade. Para carregar JavaScript no lado do cliente, você precisará usar a tag especial ` + +# Olá +``` + +` +``` + +### Apresentando Conteúdo Cru {#rendering-raw-content} + +Parâmetros passados para a página serão serializados na carga JavaScript do cliente, portanto, evite passar dados pesados nos parâmetros, como Markdown cru ou conteúdo HTML obtido de um CMS remoto. + +Em vez disso, você pode passar tal conteúdo para cada página usando a propriedade `content` em cada objeto de caminho: + +```js +export default { + async paths() { + const posts = await (await fetch('https://my-cms.com/blog-posts')).json() + + return posts.map((post) => { + return { + params: { id: post.id }, + content: post.content // Markdown ou HTML cru + } + }) + } +} +``` + +Em seguida, use a seguinte sintaxe especial para apresentar o conteúdo como parte do próprio arquivo Markdown: + +```md + +``` diff --git a/docs/pt/guide/sitemap-generation.md b/docs/pt/guide/sitemap-generation.md new file mode 100644 index 00000000..c6f8d9b8 --- /dev/null +++ b/docs/pt/guide/sitemap-generation.md @@ -0,0 +1,53 @@ +# Geração de Sitemap {#sitemap-generation} + +VitePress vem com suporte embutido para gerar um arquivo `sitemap.xml` para seu site. Para habilitar, adicione o seguinte ao seu `.vitepress/config.js`: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + sitemap: { + hostname: 'https://example.com' + } +}) +``` + +Para ter tags `` em seu `sitemap.xml`, você pode habilitar a opção [`lastUpdated`](../reference/default-theme-last-updated). + +## Opções {#options} + +O suporte de Sietmap é alimentado pelo módulo [`sitemap`](https://www.npmjs.com/package/sitemap). Você pode passar qualquer uma das opções suportadas por ele na opção `sitemap` do seu arquivo de configuração. Esses serão passados diretamente ao construtor `SitemapStream`. Refira-se a [documentação `sitemap`](https://www.npmjs.com/package/sitemap#options-you-can-pass) para mais detalhes. Exemplo: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + sitemap: { + hostname: 'https://example.com', + lastmodDateOnly: false + } +}) +``` + +## Gancho `transformItems` + +Você pode usar o gancho `sitemap.transformItems` para modificar os itens do sitemap antes de eles serem escritos no arquivo `sitemap.xml`. Este gancho é chamado com um _array_ de itens sitemap e espera um _array_ de itens sitemap como retorno. Exemplo: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + sitemap: { + hostname: 'https://example.com', + transformItems: (items) => { + // adiciona novos itens ou modifica/filtra itens existentes + items.push({ + url: '/extra-page', + changefreq: 'monthly', + priority: 0.8 + }) + return items + } + } +}) +``` diff --git a/docs/pt/guide/ssr-compat.md b/docs/pt/guide/ssr-compat.md new file mode 100644 index 00000000..deec9a7b --- /dev/null +++ b/docs/pt/guide/ssr-compat.md @@ -0,0 +1,136 @@ +--- +outline: deep +--- + +# Compatibilidade SSR {#ssr-compatibility} + +VitePress pré-interpreta a aplicação no Node.js durante a compilação de produção, utilizando as capacidades de Interpretação do Lado do Servidor (SSR) do Vue. Isso significa que todo o código personalizado nos componentes do tema está sujeito à Compatibilidade SSR. + +A [seção SSR na documentação Vue oficial](https://vuejs.org/guide/scaling-up/ssr.html) fornece mais contexto sobre o que é SSR, a relação entre SSR / SSG e notas comuns sobre escrever código amigável a SSR. A regra geral é acessar apenas APIs do navegador / DOM nos gatilhos `beforeMount` ou `mounted` dos componentes Vue. + +## `` + +Se você estiver usando ou demonstrando componentes que não são compatíveis com SSR (por exemplo, contêm diretivas personalizadas), você pode envolvê-los no componente embutido ``: + +```md + + + +``` + +## Bibliotecas que Acessam a API do Navegador na Importação {#libraries-that-access-browser-api-on-import} + +Alguns componentes ou bibliotecas acessam APIs do navegador **na importação**. Para usar código que assume um ambiente de navegador na importação, você precisa importá-los dinamicamente. + +### Importando no Gatilho `mounted` {#importing-in-mounted-hook} + +```vue + +``` + +### Importação Condicional {#conditional-import} + +Você também pode importar condicionalmente uma dependência usando o sinalizador `import.meta.env.SSR` (parte das [variáveis de ambiente Vite](https://vitejs.dev/guide/env-and-mode.html#env-variables)): + +```js +if (!import.meta.env.SSR) { + import('./lib-que-acessa-window-na-importacao').then((module) => { + // usar código + }) +} +``` + +Como [`Theme.enhanceApp`](./custom-theme#theme-interface) pode ser assíncrono, você pode importar condicionalmente e registrar plugins Vue que acessam APIs do navegador na importação: + +```js +// .vitepress/theme/index.js +/** @type {import('vitepress').Theme} */ +export default { + // ... + async enhanceApp({ app }) { + if (!import.meta.env.SSR) { + const plugin = await import('plugin-que-acessa-window-na-importacao') + app.use(plugin.default) + } + } +} +``` + +Se estiver usando TypeScript: +```ts +// .vitepress/theme/index.ts +import type { Theme } from 'vitepress' + +export default { + // ... + async enhanceApp({ app }) { + if (!import.meta.env.SSR) { + const plugin = await import('plugin-que-acessa-window-na-importacao') + app.use(plugin.default) + } + } +} satisfies Theme +``` + +### `defineClientComponent` + +VitePress fornece um auxiliar de conveniência para importar componentes Vue que acessam APIs do navegador na importação. + +```vue + + + +``` + +Você também pode passar propriedades/filhos/_slots_ para o componente alvo: + +```vue + + + +``` + +O componente alvo só será importado no gatilho `mounted` do componente que o envolve. \ No newline at end of file diff --git a/docs/pt/guide/using-vue.md b/docs/pt/guide/using-vue.md new file mode 100644 index 00000000..6c2002ac --- /dev/null +++ b/docs/pt/guide/using-vue.md @@ -0,0 +1,255 @@ +# Usando Vue em Markdown {#using-vue-in-markdown} + +Em VitePress, cada arquivo Markdown é compilado para HTML e então processado como um [Componente de Arquivo Único Vue](https://vuejs.org/guide/scaling-up/sfc.html). Isso significa que você pode usar qualquer funcionalidade Vue dentro do Markdown, incluindo a interpolação dinâmica, usar componentes Vue ou lógica arbitrária de componentes Vue dentro da página adicionando uma tag ` + +## Conteúdo Markdown + +A contagem é: {{ count }} + + + + +``` + +::: warning Evite ` +``` + +## Usando _Teleports_ {#using-teleports} + +Vitepress atualmente oferece suporte a SSG para _teleports_ apenas para o corpo. Para outros alvos, você pode envolvê-los dentro do componente embutido `` ou injetar a marcação de _teleport_ na localização correta em sua página final HTML por meio do [gancho `postRender`](../reference/site-config#postrender). + + + +::: details +<<< @/components/ModalDemo.vue +::: + +```md + + +
+ // ... +
+
+
+``` + + + + diff --git a/docs/pt/guide/what-is-vitepress.md b/docs/pt/guide/what-is-vitepress.md new file mode 100644 index 00000000..835f5bd3 --- /dev/null +++ b/docs/pt/guide/what-is-vitepress.md @@ -0,0 +1,57 @@ +# O que é VitePress? {#what-is-vitepress} + +O VitePress é um [Gerador de Site Estático](https://en.wikipedia.org/wiki/Static_site_generator) (SSG) projetado para criar sites rápidos e centrados em conteúdo. Em suma, VitePress utiliza seu conteúdo-fonte escrito em [Markdown](https://en.wikipedia.org/wiki/Markdown), aplica um tema a ele e gera páginas HTML estáticas que podem ser facilmente implantadas em qualquer lugar. + +
+ +Quer apenas experimentar? Pule para o [Início Rápido](./getting-started). + +
+ +## Casos de Uso {#use-cases} + +- **Documentação** + + VitePress vem com um tema padrão projetado para documentação técnica. Ele alimenta esta página que você está lendo agora, juntamente com a documentação [Vite](https://vitejs.dev/), [Rollup](https://rollupjs.org/), [Pinia](https://pinia.vuejs.org/), [VueUse](https://vueuse.org/), [Vitest](https://vitest.dev/), [D3](https://d3js.org/), [UnoCSS](https://unocss.dev/), [Iconify](https://iconify.design/) e [muitos outros](https://www.vuetelescope.com/explore?framework.slug=vitepress). + + A [documentação oficial Vue.js](https://vuejs.org/) também é baseada em VitePress, mas usa um tema personalizado compartilhado entre várias traduções. + +- **Blogs, Portfólios e Sites de Marketing** + + VitePress suporta [temas totalmente personalizáveis](./custom-theme), com a experiência de desenvolvedor padrão de uma aplicação Vite + Vue. A construção com Vite significa que você pode aproveitar diretamente plugins Vite de seu rico ecossistema. Adicionalmente, VitePress fornece APIs flexíveis para [carregar dados](./data-loading) (locais ou remotos) e [gerar rotas dinamicamente](./routing#dynamic-routes). Você pode usá-lo para construir praticamente qualquer coisa desde que os dados possam ser determinados no momento da construção. + + O [blog oficial Vue.js](https://blog.vuejs.org/) é um blog simples que gera sua página inicial baseada em conteúdo local. + +## Experiência de Desenvolvedor {#developer-experience} + +VitePress visa proporcionar excelente Experiência de Desenvolvedor (DX) ao trabalhar com conteúdo em Markdown. + +- **[Alimentado por Vite:](https://vitejs.dev/)** inicialização instantânea do servidor, com edições sempre refletidas instantaneamente (<100ms) sem recarregamento de página. + +- **[Extensões Markdown Integradas:](./markdown)** Frontmatter, tabelas, destaque de sintaxe... você escolhe. Especificamente, VitePress fornece muitos recursos avançados para trabalhar com blocos de código, tornando-o ideal para documentação altamente técnica. + +- **[Markdown Aprimorado por Vue:](./using-vue)** cada página Markdown é também um [Componente de Arquivo Único Vue](https://pt.vuejs.org/guide/scaling-up/sfc.html), graças à compatibilidade de sintaxe de 100% do template Vue com HTML. Você pode incorporar interatividade em seu conteúdo estático usando recursos de template Vue ou componentes Vue importados. + +## Desempenho {#performance} + +Ao contrário de muitos SSGs tradicionais, um site gerado pelo VitePress é na verdade uma [Aplicação de Página Única](https://en.wikipedia.org/wiki/Single-page_application) (SPA). + +- **Carregamento Inicial Rápido** + + A visita inicial a qualquer página será servida com o HTML estático pré-renderizado para velocidade de carregamento rápida e SEO otimizado. A página então carrega um pacote JavaScript que transforma a página em uma SPA Vue ("hidratação"). O processo de hidratação é extremamente rápido: no [PageSpeed Insights](https://pagespeed.web.dev/report?url=https%3A%2F%2Fvitepress.dev%2F), sites típicos VitePress alcançam pontuações de desempenho quase perfeitas, mesmo em dispositivos móveis de baixo desempenho com uma rede lenta. + +- **Navegação Rápida pós-carregamento** + + Mais importante ainda, o modelo SPA leva a uma melhor experiência do usuário **após** o carregamento inicial. A navegação subsequente dentro do site não causará mais uma recarga completa da página. Em vez disso, o conteúdo da página de entrada será buscado e atualizado dinamicamente. VitePress também pré-carrega automaticamente pedaços de página para links que estão dentro do viewport. Na maioria dos casos, a navegação pós-carregamento parecerá instantânea. + +- **Interatividade Sem Penalidades** + + Para ser capaz de hidratar as partes dinâmicas Vue incorporadas dentro do Markdown estático, cada página Markdown é processada como um componente Vue e compilada em JavaScript. Isso pode parecer ineficiente, mas o compilador Vue é inteligente o suficiente para separar as partes estáticas e dinâmicas, minimizando tanto o custo de hidratação quanto o tamanho da carga. Para o carregamento inicial da página, as partes estáticas são automaticamente eliminadas da carga JavaScript e puladas durante a hidratação. + +## E o VuePress? {#what-about-vuepress} + +VitePress é o sucessor espiritual de VuePress. VuePress era orginalmente baseado em Vue 2 e webpack. Com Vue 3 e Vite, VitePress oferece uma experiência de desenvolvedor significativamente melhor, melhor desempenho em produção, um tema padrão mais polido e uma API de personalização mais flexível. + +A diferença da API entre VitePress e VuePress reside principalmente em temas e personalização. Se você estiver usando VuePress 1 com o tema padrão, a migração para VitePress deve ser relativamente simples. + +Também houve esforço investido em VuePress 2, que também suporta Vue 3 e Vite com melhor compatibilidade do que VuePress 1. No entanto, manter dois SSGs em paralelo não é sustentável, então a equipe Vue decidiu focar em VitePress como o principal SSG recomendado a longo prazo. \ No newline at end of file diff --git a/docs/pt/index.md b/docs/pt/index.md new file mode 100644 index 00000000..3f979dca --- /dev/null +++ b/docs/pt/index.md @@ -0,0 +1,60 @@ +--- +layout: home + +title: VitePress +titleTemplate: Gerador de Site Estático desenvolvido com Vite & Vue + +hero: + name: VitePress + text: Gerador de Site Estático Vite & Vue + tagline: Markdown para Lindos Documentos em Minutos + actions: + - theme: brand + text: O que é VitePress? + link: /pt/guide/what-is-vitepress + - theme: alt + text: Iniciar + link: /pt/guide/getting-started + - theme: alt + text: GitHub + link: https://github.com/vuejs/vitepress + image: + src: /vitepress-logo-large.webp + alt: VitePress + +features: + - icon: 📝 + title: Foco no seu conteúdo + details: Cria sites de documentação belos e sem esforço apenas com markdown. + - icon: + title: Aproveite a experiência Vite + details: Início de servidor instantâneo, atualizações ultrarrápidas, e plugins do ecossistema Vite. + - icon: + title: Personalize com Vue + details: Use sintaxe e componentes Vue diretamente em markdown, ou construa temas personalizados com Vue. + - icon: 🚀 + title: Entregue Sites Rápidos + details: Carregamento inicial rápido com HTML estático, navegação rápida com roteamento no lado do cliente. +--- + + diff --git a/docs/pt/reference/cli.md b/docs/pt/reference/cli.md new file mode 100644 index 00000000..6d7f0006 --- /dev/null +++ b/docs/pt/reference/cli.md @@ -0,0 +1,74 @@ +# Interface de Linha de Comando {#command-line-interface} + +## `vitepress dev` + +Inicia o servidor de desenvolvimento VitePress com o diretório designado como raiz. Por padrão usa o diretório atual. O comando `dev` pode também ser omitido ao rodar no diretório atual. + +### Uso + +```sh +# inicia no diretório atual, omitindo `dev` +vitepress + +# inicia em um subdiretório +vitepress dev [root] +``` + +### Opções {#options} + +| Opção | Descrição | +| --------------- | ----------------------------------------------------------------- | +| `--open [path]` | Abre o navegador na inicialização (`boolean \| string`) | +| `--port ` | Especifica porta (`number`) | +| `--base ` | Caminho base público (padrão: `/`) (`string`) | +| `--cors` | Habilita CORS | +| `--strictPort` | Interrompe se a porta especificada já está em uso (`boolean`) | +| `--force` | Força o otimizador a ignorar o cache e reempacotar (`boolean`) | + +## `vitepress build` + +Compila o site VitePress para produção. + +### Uso + +```sh +vitepress build [root] +``` + +### Opções + +| Opção | Descrição | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------- | +| `--mpa` (experimental) | Compila no [Modo MPA](../guide/mpa-mode) sem hidratação no lado do cliente (`boolean`) | +| `--base ` | Caminho base público (padrão: `/`) (`string`) | +| `--target ` | Transpila o alvo (padrão: `"modules"`) (`string`) | +| `--outDir ` | Diretório de saída relativo ao **cwd** (padrão: `/.vitepress/dist`) (`string`) | +| `--minify [minifier]` | Habilita/desabilita minificação, ou especifica um minificador para usar (padrão: `"esbuild"`) (`boolean \| "terser" \| "esbuild"`) | +| `--assetsInlineLimit ` | Limite em bytes para alinhar ativos em base64 (padrão: `4096`) (`number`) | + +## `vitepress preview` + +Prevê localmente a compilação de produção. + +### Uso + +```sh +vitepress preview [root] +``` + +### Opções + +| Opção | Descrição | +| --------------- | ------------------------------------------ | +| `--base ` | Caminho base público (padrão: `/`) (`string`) | +| `--port ` | Especifica porta (`number`) | + +## `vitepress init` + +Inicia o [Assistente de Instalação](../guide/getting-started#setup-wizard) no diretório atual. + +### Uso + +```sh +vitepress init +``` diff --git a/docs/pt/reference/default-theme-badge.md b/docs/pt/reference/default-theme-badge.md new file mode 100644 index 00000000..a96955a0 --- /dev/null +++ b/docs/pt/reference/default-theme-badge.md @@ -0,0 +1,69 @@ +# Emblema {#badge} + +O emblema permite adicionar status aos seus cabeçalhos. Por exemplo, pode ser útil especificar o tipo da seção ou a versão suportada. + +## Uso {#usage} + +Você pode usar o componente `Badge` que está disponível globalmente. + +```html +### Title +### Title +### Title +### Title +``` + +O código acima é apresentado como: + +### Title +### Title +### Title +### Title + +## Filiação Personalizada {#custom-children} + +`` aceita `children` (filhos), que serão exibidos no emblema. + +```html +### Title custom element +``` + +### Title custom element + +## Personalize o Tipo de Cor {#customize-type-color} + +Você pode personalizar o estilo dos emblemas sobrepondo variáveis ​​CSS. Os seguintes são os valores padrão: + +```css +:root { + --vp-badge-info-border: transparent; + --vp-badge-info-text: var(--vp-c-text-2); + --vp-badge-info-bg: var(--vp-c-default-soft); + + --vp-badge-tip-border: transparent; + --vp-badge-tip-text: var(--vp-c-brand-1); + --vp-badge-tip-bg: var(--vp-c-brand-soft); + + --vp-badge-warning-border: transparent; + --vp-badge-warning-text: var(--vp-c-warning-1); + --vp-badge-warning-bg: var(--vp-c-warning-soft); + + --vp-badge-danger-border: transparent; + --vp-badge-danger-text: var(--vp-c-danger-1); + --vp-badge-danger-bg: var(--vp-c-danger-soft); +} +``` + +## `` + +O componente `` aceita as seguintes propriedades: + +```ts +interface Props { + // Quando `` é passado, esse valor é ignorado. + text?: string + + // O padrão é `tip`. + type?: 'info' | 'tip' | 'warning' | 'danger' +} +``` diff --git a/docs/pt/reference/default-theme-carbon-ads.md b/docs/pt/reference/default-theme-carbon-ads.md new file mode 100644 index 00000000..1c4d4e60 --- /dev/null +++ b/docs/pt/reference/default-theme-carbon-ads.md @@ -0,0 +1,22 @@ +# Carbon Ads {#carbon-ads} + +VitePress tem suporte embutido para [Carbon Ads](https://www.carbonads.net/). Ao definir as credenciais Carbon Ads na configuração, VitePress mostrará anúncios na página. + +```js +export default { + themeConfig: { + carbonAds: { + code: 'seu-código-carbon', + placement: 'sua-veiculação-carbon' + } + } +} +``` + +Esses valores são usados para chamar o sript em CDN do carbon como mostrado abaixo. + +```js +`//cdn.carbonads.com/carbon.js?serve=${code}&placement=${placement}` +``` + +Para aprender mais sobre a configuração Carbon Ads, por favor visite [Site Carbon Ads](https://www.carbonads.net/). diff --git a/docs/pt/reference/default-theme-config.md b/docs/pt/reference/default-theme-config.md new file mode 100644 index 00000000..417cbc30 --- /dev/null +++ b/docs/pt/reference/default-theme-config.md @@ -0,0 +1,452 @@ +# Configuração do Tema Padrão {#default-theme-config} + +A configuração do tema permite que você personalize seu tema. Você pode definir a configuração do tema através da opção `themeConfig` no arquivo de configuração: + +```ts +export default { + lang: 'pt-BR', + title: 'VitePress', + description: 'Gerador de site estático Vite & Vue.', + + // Configurações relacionadas ao tema. + themeConfig: { + logo: '/logo.svg', + nav: [...], + sidebar: { ... } + } +} +``` + +**As opções documentadas nesta página se aplicam apenas ao tema padrão.** Temas diferentes esperam configurações de tema diferentes. Ao usar um tema personalizado, o objeto de configuração do tema será passado para o tema para que se possam definir comportamentos condicionais. + +## i18nRouting + +- Tipo: `boolean` + +Alterar o local para, por exemplo, `zh` alterará a URL de `/foo` (ou `/en/foo/`) para `/zh/foo`. Você pode desativar esse comportamento definindo `themeConfig.i18nRouting` como `false`. + +## logo + +- Tipo: `ThemeableImage` + +Arquivo de logo a ser exibido na barra de navegação, logo antes do título do site. Aceita um caminho em string, ou um objeto para definir um logo diferente para os modos claro/escuro. + +```ts +export default { + themeConfig: { + logo: '/logo.svg' + } +} +``` + +```ts +type ThemeableImage = + | string + | { src: string; alt?: string } + | { light: string; dark: string; alt?: string } +``` + +## siteTitle + +- Tipo: `string | false` + +Você pode personalizar este item para substituir o título padrão do site (`title` na configuração da aplicação) na navegação. Quando definido como `false`, o título na navegação será desativado. Útil quando você tem um `logo` que já contém o título do site. + +```ts +export default { + themeConfig: { + siteTitle: 'Olá Mundo' + } +} +``` + +## nav + +- Tipo: `NavItem` + +A configuração para o item do menu de navegação. Mais detalhes em [Tema Padrão: Navegação](./default-theme-nav#navigation-links). + +```ts +export default { + themeConfig: { + nav: [ + { text: 'Guia', link: '/guide' }, + { + text: 'Menu Dropdown', + items: [ + { text: 'Item A', link: '/item-1' }, + { text: 'Item B', link: '/item-2' }, + { text: 'Item C', link: '/item-3' } + ] + } + ] + } +} +``` + +```ts +type NavItem = NavItemWithLink | NavItemWithChildren + +interface NavItemWithLink { + text: string + link: string + activeMatch?: string + target?: string + rel?: string + noIcon?: boolean +} + +interface NavItemChildren { + text?: string + items: NavItemWithLink[] +} + +interface NavItemWithChildren { + text?: string + items: (NavItemChildren | NavItemWithLink)[] + activeMatch?: string +} +``` + +## sidebar + +- Tipo: `Sidebar` + +A configuração para o item do menu da barra lateral. Mais detalhes em [Tema Padrão: Barra Lateral](./default-theme-sidebar). + +```ts +export default { + themeConfig: { + sidebar: [ + { + text: 'Guia', + items: [ + { text: 'Introdução', link: '/introduction' }, + { text: 'Começando', link: '/getting-started' }, + ... + ] + } + ] + } +} +``` + +```ts +export type Sidebar = SidebarItem[] | SidebarMulti + +export interface SidebarMulti { + [path: string]: SidebarItem[] +} + +export type SidebarItem = { + /** + * O rótulo de texto do item. + */ + text?: string + + /** + * O link do item. + */ + link?: string + + /** + * Os filhos do item. + */ + items?: SidebarItem[] + + /** + * Se não especificado, o grupo não é retrátil. + * + * Se `true`, o grupo é retrátil e é colapsado por padrão. + * + * Se `false`, o grupo é retrátil, mas expandido por padrão. + */ + collapsed?: boolean +} +``` + +## aside + +- Tipo: `boolean | 'left'` +- Padrão: `true` +- Pode ser anulado por página via [frontmatter](./frontmatter-config#aside) + +Definir este valor como `false` impede a apresentação do elemento aside.\ +Definir este valor como `true` apresenta o aside à direita.\ +Definir este valor como `left` apresenta o aside à esquerda. + +Se você quiser desativá-lo para todas as visualizações, você deve usar `outline: false` em vez disso. + +## outline + +- Tipo: `Outline | Outline['level'] | false` +- O nível pode ser sobreposto por página via [frontmatter](./frontmatter-config#outline) + +Definir este valor como `false` impede a apresentação do elemento _outline_. Consulte a interface para obter mais detalhes: + +```ts +interface Outline { + /** + * Os níveis de títulos a serem exibidos na outline. + * Um único número significa que apenas os títulos desse nível serão exibidos. + * Se uma tupla for passada, o primeiro número é o nível mínimo e o segundo número é o nível máximo. + * `'deep'` é o mesmo que `[2, 6]`, o que significa que todos os títulos de `

` a `

` serão exibidos. + * + * @default 2 + */ + level?: number | [number, number] | 'deep' + + /** + * O título a ser exibido na outline. + * + * @default 'On this page' + */ + label?: string +} +``` + +## socialLinks + +- Tipo: `SocialLink[]` + +Você pode definir esta opção para mostrar os links de redes sociais com ícones na navegação. + +```ts +export default { + themeConfig: { + socialLinks: [ + { icon: 'github', link: 'https://github.com/vuejs/vitepress' }, + { icon: 'twitter', link: '...' }, + // Você também pode adicionar ícones personalizados passando SVG como string: + { + icon: { + svg: 'Dribbble' + }, + link: '...', + // Você também pode incluir um rótulo personalizado para acessibilidade (opcional mas recomendado): + ariaLabel: 'cool link' + } + ] + } +} +``` + +```ts +interface SocialLink { + icon: SocialLinkIcon + link: string + ariaLabel?: string +} + +type SocialLinkIcon = + | 'discord' + | 'facebook' + | 'github' + | 'instagram' + | 'linkedin' + | 'mastodon' + | 'npm' + | 'slack' + | 'twitter' + | 'x' + | 'youtube' + | { svg: string } +``` + +## footer + +- Tipo: `Footer` +- Pode ser sobreposto por página via [frontmatter](./frontmatter-config#footer) + +Configuração do rodapé. Você pode adicionar uma mensagem ou texto de direitos autorais no rodapé, no entanto, ela só será exibida quando a página não contiver uma barra lateral. Isso se deve a preocupações de design. + +```ts +export default { + themeConfig: { + footer: { + message: 'Lançado sob a Licença MIT.', + copyright: 'Direitos autorais © 2019-presente Evan You' + } + } +} +``` + +```ts +export interface Footer { + message?: string + copyright?: string +} +``` + +## editLink + +- Tipo: `EditLink` +- Pode ser sobreposto por página via [frontmatter](./frontmatter-config#editlink) + +O _EditLink_ permite exibir um link para editar a página em serviços de gerenciamento Git, como GitHub ou GitLab. Consulte [Tema Padrão: Editar Link](./default-theme-edit-link) para mais detalhes. + +```ts +export default { + themeConfig: { + editLink: { + pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path', + text: 'Editar esta página no GitHub' + } + } +} +``` + +```ts +export interface EditLink { + pattern: string + text?: string +} +``` + +## lastUpdated + +- Tipo: `LastUpdatedOptions` + +Permite personalização para o texto de última atualização e o formato de data. + +```ts +export default { + themeConfig: { + lastUpdated: { + text: 'Atualizado em', + formatOptions: { + dateStyle: 'full', + timeStyle: 'medium' + } + } + } +} +``` + +```ts +export interface LastUpdatedOptions { + /** + * @default 'Last updated' + */ + text?: string + + /** + * @default + * { dateStyle: 'short', timeStyle: 'short' } + */ + formatOptions?: Intl.DateTimeFormatOptions & { forceLocale?: boolean } +} +``` + +## algolia + +- Tipo: `AlgoliaSearch` + +Uma opção para dar suporte à pesquisa em seu site de documentação usando [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch). Saiba mais em [Tema Padrão: Pesquisa](./default-theme-search). + +```ts +export interface AlgoliaSearchOptions extends DocSearchProps { + locales?: Record> +} +``` + +Veja todas as opções [aqui](https://github.com/vuejs/vitepress/blob/main/types/docsearch.d.ts). + +## carbonAds {#carbon-ads} + +- Tipo: `CarbonAdsOptions` + +Uma opção para mostrar [Carbon Ads](https://www.carbonads.net/). + +```ts +export default { + themeConfig: { + carbonAds: { + code: 'seu-código-carbon', + placement: 'sua-veiculação-carbon' + } + } +} +``` + +```ts +export interface CarbonAdsOptions { + code: string + placement: string +} +``` + +Saiba mais em [Tema Padrão: Carbon Ads](./default-theme-carbon-ads). + +## docFooter + +- Tipo: `DocFooter` + +Pode ser usado para personalizar o texto que aparece acima dos links anterior e próximo. Útil se não estiver escrevendo documentação em inglês. Também pode ser usado para desabilitar globalmente os links anterior/próximo. Se você quiser ativar/desativar seletivamente os links anterior/próximo, pode usar [frontmatter](./default-theme-prev-next-links). + +```ts +export default { + themeConfig: { + docFooter: { + prev: 'Página anterior', + next: 'Próxima página' + } + } +} +``` + +```ts +export interface DocFooter { + prev?: string | false + next?: string | false +} +``` + +## darkModeSwitchLabel + +- Tipo: `string` +- Padrão: `Appearance` + +Pode ser usado para personalizar o rótulo do botão de modo escuro. Esse rótulo é exibido apenas na visualização móvel. + +## lightModeSwitchTitle + +- Tipo: `string` +- Padrão: `Switch to light theme` + +Pode ser usado para personalizar o título do botão de modo claro que aparece ao passar o mouse. + +## darkModeSwitchTitle + +- Tipo: `string` +- Padrão: `Switch to dark theme` + +Pode ser usado para personalizar o título do botão de modo escuro que aparece ao passar o mouse. + +## sidebarMenuLabel + +- Tipo: `string` +- Padrão: `Menu` + +Pode ser usado para personalizar o rótulo do menu da barra lateral. Esse rótulo é exibido apenas na visualização móvel. + +## returnToTopLabel + +- Tipo: `string` +- Padrão: `Return to top` + +Pode ser usado para personalizar o rótulo do botão de retorno ao topo. Esse rótulo é exibido apenas na visualização móvel. + +## langMenuLabel + +- Tipo: `string` +- Padrão: `Change language` + +Pode ser usado para personalizar o aria-label do botão de idioma na barra de navegação. Isso é usado apenas se você estiver usando [i18n](../guide/i18n). + +## externalLinkIcon + +- Tipo: `boolean` +- Padrão: `false` + +Se deve mostrar um ícone de link externo ao lado de links externos no markdown. diff --git a/docs/pt/reference/default-theme-edit-link.md b/docs/pt/reference/default-theme-edit-link.md new file mode 100644 index 00000000..6b1e8793 --- /dev/null +++ b/docs/pt/reference/default-theme-edit-link.md @@ -0,0 +1,60 @@ +# Editar Link {#edit-link} + +## Configuração a nível de Site {#site-level-config} + +Editar Link permite que você mostre um link para editar a página com serviços de gerenciamento Git, como GitHub ou GitLab. Para habilitar, adicione a opção `themeConfig.editLink` na sua configuração. + +```js +export default { + themeConfig: { + editLink: { + pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path' + } + } +} +``` + +A opção `pattern` define a estrutura da URL para o link, e `:path` será substituído com o mesmo caminho de página. + +Você também pode colocar uma função pura que aceita [`PageData`](./runtime-api#usedata) como argumento e retorna uma URL em string. + +```js +export default { + themeConfig: { + editLink: { + pattern: ({ filePath }) => { + if (filePath.startsWith('packages/')) { + return `https://github.com/acme/monorepo/edit/main/${filePath}` + } else { + return `https://github.com/acme/monorepo/edit/main/docs/${filePath}` + } + } + } + } +} +``` + +Isso não deve gerar efeitos colaterais ou acessar qualquer coisa fora do seu escopo, uma vez que será serializado e executado no navegador. + +Por padrão, isso irá adicionar o link com texto "Edite essa página" no final da página de documentação. Você pode personalizar esse texto ao definir a opção `text`. + +```js +export default { + themeConfig: { + editLink: { + pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path', + text: 'Edite essa página no GitHub' + } + } +} +``` + +## Configuração Frontmatter {#frontmatter-config} + +A funcionalidade pode ser desabilitada por página usando a opção `editLink` no frontmatter: + +```yaml +--- +editLink: false +--- +``` diff --git a/docs/pt/reference/default-theme-footer.md b/docs/pt/reference/default-theme-footer.md new file mode 100644 index 00000000..98b02b2c --- /dev/null +++ b/docs/pt/reference/default-theme-footer.md @@ -0,0 +1,53 @@ +# Rodapé {#footer} + +VitePress irá mostrar o rodapé global na parte inferior da página quando `themeConfig.footer` está presente. + +```ts +export default { + themeConfig: { + footer: { + message: 'Lançado sob Licença MIT.', + copyright: 'Direitos Reservados © 2019-present Evan You' + } + } +} +``` + +```ts +export interface Footer { + // A mensagem mostrada logo antes do copyright. + message?: string + + // O próprio texto de copyright. + copyright?: string +} +``` + +A configuração acima também suporta strings HTML. Então, por exemplo, se você quiser configurar o texto de rodapé para ter alguns links, você pode ajustar a configuração como o seguinte: + +```ts +export default { + themeConfig: { + footer: { + message: 'Lançado sob Licença MIT.', + copyright: 'Direitos Reservados © 2019-present Evan You' + } + } +} +``` + +::: warning +Apenas elementos _inline_ serão usados em `message` e `copyright` conforme eles são apresentados dentro do elemento `

`. Se você quiser adicionar elementos de tipo _block_, considere usar o _slot_ [`layout-bottom`](../guide/extending-default-theme#layout-slots). +::: + +Note que o rodapé não será mostrado quando a [Barra Lateral](./default-theme-sidebar) estiver visível. + +## Configuração Frontmatter {#frontmatter-config} + +Isso pode ser desabilitado por página usando a opção `footer` em frontmatter: + +```yaml +--- +footer: false +--- +``` \ No newline at end of file diff --git a/docs/pt/reference/default-theme-home-page.md b/docs/pt/reference/default-theme-home-page.md new file mode 100644 index 00000000..460c55bf --- /dev/null +++ b/docs/pt/reference/default-theme-home-page.md @@ -0,0 +1,168 @@ +# Página Inicial {#home-page} + +O tema padrão VitePress fornece um layout de página inicial, que você também pode ver em uso [na página inicial deste site](../). Você pode usá-lo em qualquer uma de suas páginas especificando `layout: home` em [frontmatter](./frontmatter-config). + +```yaml +--- +layout: home +--- +``` + +No entanto, essa opção sozinha não faz muito. Você pode adicionar várias "seções" diferentes pré-modeladas à página inicial definindo opções adicionais como `hero` e `features`. + +## Seção Hero {#hero-section} + +A seção _Hero_ fica no topo da página inicial. Aqui segue como você pode configurar a seção _Hero_. + +```yaml +--- +layout: home + +hero: + name: VitePress + text: Gerador de site estático com Vite & Vue. + tagline: Lorem ipsum... + image: + src: /logo.png + alt: VitePress + actions: + - theme: brand + text: Iniciar + link: /guide/what-is-vitepress + - theme: alt + text: Ver no GitHub + link: https://github.com/vuejs/vitepress +--- +``` + +```ts +interface Hero { + // A string mostrada acima de `text`. Vem com a cor da marca + // e espera-se que seja curta, como o nome do produto. + name?: string + + // O texto principal para a seção hero. + // Isso será definido como uma tag `h1`. + text: string + + // Slogan exibido abaixo de `text`. + tagline?: string + + // A imagem é exibida ao lado da área de texto e slogan. + image?: ThemeableImage + + // Botões acionáveis para exibir na seção hero da página inicial. + actions?: HeroAction[] +} + +type ThemeableImage = + | string + | { src: string; alt?: string } + | { light: string; dark: string; alt?: string } + +interface HeroAction { + // Tema de cor do botão. Padrão: `brand`. + theme?: 'brand' | 'alt' + + // Rótulo do botão. + text: string + + // Destino do link do botão. + link: string + + // Atributo target do link. + target?: string + + // Atributo rel do link. + rel?: string +} +``` + +### Personalizando a cor do nome {#customizing-the-name-color} + +VitePress usa a cor da marca (`--vp-c-brand-1`) para `name`. No entanto, você pode personalizar essa cor sobrescrevendo a variável `--vp-home-hero-name-color`. + +```css +:root { + --vp-home-hero-name-color: blue; +} +``` + +Você também pode personalizá-la ainda mais combinando `--vp-home-hero-name-background` para dar ao `name` uma cor degradê. + +```css +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe, #41d1ff); +} +``` + +## Seção de Funcionalidades {#features-section} + +Na seção de funcionalidades, você pode listar qualquer número de funcionalidades que deseja mostrar imediatamente após a seção _Hero_. Para configurá-la, passe a opção `features` para o frontmatter. + +Você pode fornecer um ícone para cada funcionalidade, que pode ser um emoji ou qualquer tipo de imagem. Quando o ícone configurado é uma imagem (svg, png, jpeg...), você deve fornecer o ícone com a largura e altura apropriadas; você também pode fornecer a descrição, seu tamanho intrínseco, bem como suas variantes para temas escuros e claros quando necessário. + +```yaml +--- +layout: home + +features: + - icon: 🛠️ + title: Simples e minimalista, sempre + details: Lorem ipsum... + - icon: + src: /cool-feature-icon.svg + title: Outro recurso legal + details: Lorem ipsum... + - icon: + dark: /dark-feature-icon.svg + light: /light-feature-icon.svg + title: Outro recurso legal + details: Lorem ipsum... +--- +``` + +```ts +interface Feature { + // Mostra ícone em cada bloco de funcionalide. + icon?: FeatureIcon + + // Título da funcionalidade. + title: string + + // Detalhes da funcionalidade. + details: string + + // Link quando clicado no componente de funcionalidade. + // O link pode ser interno ou externo. + // + // ex. `guide/reference/default-theme-home-page` ou `https://example.com` + link?: string + + // Texto do link a ser exibido dentro do componente de funcionalidade. + // Melhor usado com a opção `link`. + // + // ex. `Saiba mais`, `Visitar página`, etc. + linkText?: string + + // Atributo rel do link para a opção `link`. + // + // ex. `external` + rel?: string + + // Atributo target do link para a opção `link`. + target?: string +} + +type FeatureIcon = + | string + | { src: string; alt?: string; width?: string; height: string } + | { + light: string + dark: string + alt?: string + width?: string + height: string + } +``` diff --git a/docs/pt/reference/default-theme-last-updated.md b/docs/pt/reference/default-theme-last-updated.md new file mode 100644 index 00000000..5bc782e1 --- /dev/null +++ b/docs/pt/reference/default-theme-last-updated.md @@ -0,0 +1,27 @@ +# Última Atualização {#last-updated} + +O tempo em que o conteúdo foi atualizado pela última vez será mostrado no canto inferior direito da página. Para habilitar, adicione a opção `lastUpdated` na sua configuração. + +::: tip +Você precisa fazer _commit_ no arquivo markdown para ver o tempo atualizado. +::: + +## Configuração a nível de Site {#site-level-config} + +```js +export default { + lastUpdated: true +} +``` + +## Configuração Frontmatter {#frontmatter-config} + +Isso pode ser desabilitado por página usando a opção `lastUpdated` no frontmatter: + +```yaml +--- +lastUpdated: false +--- +``` + +Refira-se ao [Tema Padrão: Última Atualização](./default-theme-config#lastupdated) para mais detalhes. Qualquer valor positivo a nível de tema também habilitará a funcionalidade a não ser que esteja explicitamente desabilitada a nível de página ou de site. diff --git a/docs/pt/reference/default-theme-layout.md b/docs/pt/reference/default-theme-layout.md new file mode 100644 index 00000000..0e4d0162 --- /dev/null +++ b/docs/pt/reference/default-theme-layout.md @@ -0,0 +1,62 @@ +# Layout {#layout} + +Você pode escolher o layout da página definindo a opção de `layout` para o [frontmatter](./frontmatter-config) da página. Há três opções de layout: `doc`, `page` e `home`. Se nada for especificado, a página será tratada como página `doc`. + +```yaml +--- +layout: doc +--- +``` + +## Layout do documento {#doc-layout} + +A opção `doc` é o layout padrão e estiliza todo o conteúdo Markdown com o visual de "documentação". Ela funciona agrupando todo o conteúdo na classe CSS `vp-doc`, e aplicando os estilos aos elementos abaixo dela. + +Quase todos os elementos genéricos, como `p` ou `h2`, recebem um estilo especial. Portanto, lembre-se de que se você adicionar qualquer HTML personalizado dentro de um conteúdo Markdown, ele também será afetado por esses estilos. + +Ele também fornece recursos específicos de documentação listados abaixo. Esses recursos estão habilitados apenas neste layout. + +- Editar link +- Links Anterior e Próximo +- _Outline_ +- [Carbon Ads](./default-theme-carbon-ads) + +## Layout da Página {#page-layout} + +A opção `page` é tratada como "página em branco". O Markdown ainda será processado e todas as [Extensões Markdown](../guide/markdown) funcionarão da mesma forma que o layout `doc`, mas este não receberá nenhum estilo padrão. + +O layout da página permitirá que você estilize tudo sem que o tema VitePress afete a marcação. Isso é útil quando você deseja criar sua própria página personalizada. + +Observe que mesmo neste layout, a barra lateral ainda aparecerá se a página tiver uma configuração de barra lateral correspondente. + +## Layout da Home {#home-layout} + +A opção `home` gerará um modelo de _"Homepage"_. Nesse layout você pode definir opções extras, como `hero` e `features`, para personalizar ainda mais o conteúdo. Visite [Tema padrão: Página Inicial](./default-theme-home-page) para obter mais detalhes. + +## Sem Layout {#no-layout} + +Se você não quiser nenhum layout, pode passar `layout: false` pelo frontmatter. Esta opção é útil se você deseja uma página de destino totalmente personalizável (sem barra lateral, barra de navegação ou rodapé por padrão). + +## Layout Personalizado {#custom-layout} + +Você também pode usar um layout personalizado: + +```md +--- +layout: foo +--- +``` + +Isto irá procurar um componente chamado `foo` registrado no contexto. Por exemplo, você pode registrar seu componente globalmente em `.vitepress/theme/index.ts`: + +```ts +import DefaultTheme from 'vitepress/theme' +import Foo from './Foo.vue' + +export default { + extends: DefaultTheme, + enhanceApp({ app }) { + app.component('foo', Foo) + } +} +``` diff --git a/docs/pt/reference/default-theme-nav.md b/docs/pt/reference/default-theme-nav.md new file mode 100644 index 00000000..5f0d2399 --- /dev/null +++ b/docs/pt/reference/default-theme-nav.md @@ -0,0 +1,162 @@ +# Navegação {#nav} + +Referente a barra de navegação exibida no topo da página. Ela contém o título do site, links do menu global, e etc. + +## Título do Site e Logo {#site-title-and-logo} + +Por padrão, a navegação mostra o título do site referenciando o valor de [`config.title`](./site-config#title). Se desejar alterar o que é exibido na navegação, você pode definir um texto personalizado na opção `themeConfig.siteTitle`. + +```js +export default { + themeConfig: { + siteTitle: 'Meu Título Personalizado' + } +} +``` + +Se você tiver um logo para seu site, pode mostrá-lo passando o caminho para a imagem. Você deve colocar o logo diretamente dentro da pasta `public`, e definir o caminho absoluto para ele. + +```js +export default { + themeConfig: { + logo: '/my-logo.svg' + } +} +``` + +Ao adicionar um logo, ele é mostrado juntamente com o título do site. Se seu logo tem tudo o que você precisa e se você desejar ocultar o texto do título, defina `false` na opção `siteTitle`. + +```js +export default { + themeConfig: { + logo: '/my-logo.svg', + siteTitle: false + } +} +``` + +Você também pode passar um objeto como logo se quiser adicionar um atributo `alt` ou personalizá-lo com base no modo claro/escuro. Consulte [`themeConfig.logo`](./default-theme-config#logo) para obter detalhes. + +## Links de Navegação {#navigation-links} + +Você pode definir a opção `themeConfig.nav` para adicionar links à sua navegação. + +```js +export default { + themeConfig: { + nav: [ + { text: 'Guia', link: '/guide' }, + { text: 'Configuração', link: '/config' }, + { text: 'Registro de Alterações', link: 'https://github.com/...' } + ] + } +} +``` + +`text` é o próprio texto mostrado na navegação, e o `link` é o link para o qual será navegado quando o texto for clicado. Para o link, defina o caminho para o próprio arquivo sem o prefixo `.md` e sempre comece com `/`. + +Links de navegação também podem ser menus _dropdown_. Para fazer isso, defina a chave `items` na opção do link. + +```js +export default { + themeConfig: { + nav: [ + { text: 'Guia', link: '/guide' }, + { + text: 'Menu Dropdown', + items: [ + { text: 'Item A', link: '/item-1' }, + { text: 'Item B', link: '/item-2' }, + { text: 'Item C', link: '/item-3' } + ] + } + ] + } +} +``` + +Note que o título do menu _dropdown_ (`Menu Dropdown` no exemplo acima) não pode ter a propriedade `link`, pois ele se torna um botão para abrir o diálogo dropdown. + +Você também pode adicionar "seções" aos itens do menu _dropdown_ passando mais itens aninhados. + +```js +export default { + themeConfig: { + nav: [ + { text: 'Guia', link: '/guia' }, + { + text: 'Menu Dropdown', + items: [ + { + // Título da seção. + text: 'Título da Seção A', + items: [ + { text: 'Item A da Seção A', link: '...' }, + { text: 'Item B da Seção B', link: '...' } + ] + } + ] + }, + { + text: 'Menu Dropdown', + items: [ + { + // Você também pode omitir o título. + items: [ + { text: 'Item A da Seção A', link: '...' }, + { text: 'Item B da Seção B', link: '...' } + ] + } + ] + } + ] + } +} +``` + +### Personalizar o estado "ativo" do link {#customize-link-s-active-state} + +Os itens do menu de navegação serão destacados quando a página atual estiver no caminho correspondente. Se desejar personalizar o caminho a ser correspondido, defina a propriedade `activeMatch` e regex como um valor em string. + +```js +export default { + themeConfig: { + nav: [ + // Este link fica no estado ativo quando + // o usuário está no caminho `/config/`. + { + text: 'Guia', + link: '/guide', + activeMatch: '/config/' + } + ] + } +} +``` + +::: warning +`activeMatch` deve ser uma string regex, mas você deve defini-la como uma string. Não podemos usar um objeto RegExp real aqui porque ele não é serializável durante o momento de construção. +::: + +### Personalizar os atributos "target" e "rel" de links {#customize-link-s-target-and-rel-attributes} + +Por padrão, VitePress determina automaticamente os atributos `target` e `rel` baseado em um link externo ou não. Mas se você quiser, também pode personalizá-los. + +```js +export default { + themeConfig: { + nav: [ + { + text: 'Merchandise', + link: 'https://www.thegithubshop.com/', + target: '_self', + rel: 'sponsored' + } + ] + } +} +``` + +## Links Sociais {#social-links} + +Consulte [`socialLinks`](./default-theme-config#sociallinks). diff --git a/docs/pt/reference/default-theme-prev-next-links.md b/docs/pt/reference/default-theme-prev-next-links.md new file mode 100644 index 00000000..c9472a24 --- /dev/null +++ b/docs/pt/reference/default-theme-prev-next-links.md @@ -0,0 +1,43 @@ +# Links Anterior e Próximo {#prev-next-links} + +Você pode personalizar o texto e o link para os botões de Anterior e Próximo mostrados ao fim da página. Isso é útil quando você quer mostrar um texto diferente daquele que você tem na barra lateral. Além disso, você pode achar útil desabilitar o rodapé ou link para a página para ela não ser incluída na sua barra lateral. + +## prev + +- Tipo: `string | false | { text?: string; link?: string }` + +- Detalhes: + + Especifica o texto/link para mostrar no link para a página anterior. Se você não ver isso no frontmatter, o texto/link será inferido da configuração da barra lateral. + +- Exemplos: + + - Para personalizar apenas o texto: + + ```yaml + --- + prev: 'Iniciar | Markdown' + --- + ``` + + - Para personalizar ambos texto e link: + + ```yaml + --- + prev: + text: 'Markdown' + link: '/guide/markdown' + --- + ``` + + - Para esconder a página anterior: + + ```yaml + --- + prev: false + --- + ``` + +## next + +O mesmo que `prev` mas para a próxima página. diff --git a/docs/pt/reference/default-theme-search.md b/docs/pt/reference/default-theme-search.md new file mode 100644 index 00000000..35b0d812 --- /dev/null +++ b/docs/pt/reference/default-theme-search.md @@ -0,0 +1,379 @@ +--- +outline: deep +--- + +# Pesquisa {#search} + +## Pesquisa Local {#local-search} + +VitePress oferece suporte à pesquisa de texto completa usando um índice no navegador graças ao [minisearch](https://github.com/lucaong/minisearch/). Para habilitar esse recurso, basta definir a opção `themeConfig.search.provider` como `'local'` no arquivo `.vitepress/config.ts`: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local' + } + } +}) +``` + +Exemplo de resultado: + +![captura de tela do modal de pesquisa](/search.png) + +Alternativamente, você pode usar [Algolia DocSearch](#algolia-search) ou alguns plugins da comunidade como ou . + +### i18n {#local-search-i18n} + +Você pode usar uma configuração como esta para usar a pesquisa multilínguas: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + locales: { + zh: { + translations: { + button: { + buttonText: '搜索文档', + buttonAriaLabel: '搜索文档' + }, + modal: { + noResultsText: '无法找到相关结果', + resetButtonTitle: '清除查询条件', + footer: { + selectText: '选择', + navigateText: '切换' + } + } + } + } + } + } + } + } +}) +``` + +### Opções MiniSearch {#mini-search-options} + +Você pode configurar o MiniSearch assim: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + miniSearch: { + /** + * @type {Pick} + */ + options: { + /* ... */ + }, + /** + * @type {import('minisearch').SearchOptions} + * @default + * { fuzzy: 0.2, prefix: true, boost: { title: 4, text: 2, titles: 1 } } + */ + searchOptions: { + /* ... */ + } + } + } + } + } +}) +``` + +Saiba mais na [documentação do MiniSearch](https://lucaong.github.io/minisearch/classes/MiniSearch.MiniSearch.html). + +### Apresentador de Conteúdo Personalizado {#custom-content-renderer} + +Você pode personalizar a função usada para apresentar o conteúdo markdown antes de indexá-lo: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + /** + * @param {string} src + * @param {import('vitepress').MarkdownEnv} env + * @param {import('markdown-it')} md + */ + _render(src, env, md) { + // retorne a string HTML + } + } + } + } +}) +``` + +Essa função será removida dos dados do site no lado do cliente, então você pode usar APIs do Node.js nela. + +#### Exemplo: Excluindo páginas da pesquisa {#example-excluding-pages-from-search} + +Você pode excluir páginas da pesquisa adicionando `search: false` ao frontmatter da página. Alternativamente: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + _render(src, env, md) { + const html = md.render(src, env) + if (env.frontmatter?.search === false) return '' + if (env.relativePath.startsWith('algum/caminho')) return '' + return html + } + } + } + } +}) +``` + +::: warning Nota +No caso uma função `_render` personalizada ser fornecida, você precisa manipular o `search: false` do frontmatter por conta própria. Além disso, o objeto `env` não estará completamente populado antes que `md.render` seja chamado, então verificações em propriedades opcionais `env`, como `frontmatter`, devem ser feitas após isso. +::: + +#### Exemplo: Transformando conteúdo - adicionando âncoras {#example-transforming-content-adding-anchors} + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + _render(src, env, md) { + const html = md.render(src, env) + if (env.frontmatter?.title) + return md.render(`# ${env.frontmatter.title}`) + html + return html + } + } + } + } +}) +``` + +## Pesquisa Algolia {#algolia-search} + +VitePress oferece suporte à pesquisa em seu site de documentação usando [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch). Consulte o guia de início deles. Em seu arquivo `.vitepress/config.ts`, você precisará fornecer pelo menos o seguinte para que funcione: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'algolia', + options: { + appId: '...', + apiKey: '...', + indexName: '...' + } + } + } +}) +``` + +### i18n {#algolia-search-i18n} {#algolia-search-i18n} + +Você pode usar uma configuração como esta para usar a pesquisa multilínguas: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'algolia', + options: { + appId: '...', + apiKey: '...', + indexName: '...', + locales: { + zh: { + placeholder: '搜索文档', + translations: { + button: { + buttonText: '搜索文档', + buttonAriaLabel: '搜索文档' + }, + modal: { + searchBox: { + resetButtonTitle: '清除查询条件', + resetButtonAriaLabel: '清除查询条件', + cancelButtonText: '取消', + cancelButtonAriaLabel: '取消' + }, + startScreen: { + recentSearchesTitle: '搜索历史', + noRecentSearchesText: '没有搜索历史', + saveRecentSearchButtonTitle: '保存至搜索历史', + removeRecentSearchButtonTitle: '从搜索历史中移除', + favoriteSearchesTitle: '收藏', + removeFavoriteSearchButtonTitle: '从收藏中移除' + }, + errorScreen: { + titleText: '无法获取结果', + helpText: '你可能需要检查你的网络连接' + }, + footer: { + selectText: '选择', + navigateText: '切换', + closeText: '关闭', + searchByText: '搜索提供者' + }, + noResultsScreen: { + noResultsText: '无法找到相关结果', + suggestedQueryText: '你可以尝试查询', + reportMissingResultsText: '你认为该查询应该有结果?', + reportMissingResultsLinkText: '点击反馈' + } + } + } + } + } + } + } + } +}) +``` + +[Essas opções](https://github.com/vuejs/vitepress/blob/main/types/docsearch.d.ts) podem ser sobrepostas. Consulte a documentação oficial Algolia para obter mais informações sobre elas. + +### Configuração _Crawler_ {#crawler-config} + +Aqui está um exemplo de configuração baseado na qual este site usa: + +```ts +new Crawler({ + appId: '...', + apiKey: '...', + rateLimit: 8, + startUrls: ['https://vitepress.dev/'], + renderJavaScript: false, + sitemaps: [], + exclusionPatterns: [], + ignoreCanonicalTo: false, + discoveryPatterns: ['https://vitepress.dev/**'], + schedule: 'at 05:10 on Saturday', + actions: [ + { + indexName: 'vitepress', + pathsToMatch: ['https://vitepress.dev/**'], + recordExtractor: ({ $, helpers }) => { + return helpers.docsearch({ + recordProps: { + lvl1: '.content h1', + content: '.content p, .content li', + lvl0: { + selectors: '', + defaultValue: 'Documentation' + }, + lvl2: '.content h2', + lvl3: '.content h3', + lvl4: '.content h4', + lvl5: '.content h5' + }, + indexHeadings: true + }) + } + } + ], + initialIndexSettings: { + vitepress: { + attributesForFaceting: ['type', 'lang'], + attributesToRetrieve: ['hierarchy', 'content', 'anchor', 'url'], + attributesToHighlight: ['hierarchy', 'hierarchy_camel', 'content'], + attributesToSnippet: ['content:10'], + camelCaseAttributes: ['hierarchy', 'hierarchy_radio', 'content'], + searchableAttributes: [ + 'unordered(hierarchy_radio_camel.lvl0)', + 'unordered(hierarchy_radio.lvl0)', + 'unordered(hierarchy_radio_camel.lvl1)', + 'unordered(hierarchy_radio.lvl1)', + 'unordered(hierarchy_radio_camel.lvl2)', + 'unordered(hierarchy_radio.lvl2)', + 'unordered(hierarchy_radio_camel.lvl3)', + 'unordered(hierarchy_radio.lvl3)', + 'unordered(hierarchy_radio_camel.lvl4)', + 'unordered(hierarchy_radio.lvl4)', + 'unordered(hierarchy_radio_camel.lvl5)', + 'unordered(hierarchy_radio.lvl5)', + 'unordered(hierarchy_radio_camel.lvl6)', + 'unordered(hierarchy_radio.lvl6)', + 'unordered(hierarchy_camel.lvl0)', + 'unordered(hierarchy.lvl0)', + 'unordered(hierarchy_camel.lvl1)', + 'unordered(hierarchy.lvl1)', + 'unordered(hierarchy_camel.lvl2)', + 'unordered(hierarchy.lvl2)', + 'unordered(hierarchy_camel.lvl3)', + 'unordered(hierarchy.lvl3)', + 'unordered(hierarchy_camel.lvl4)', + 'unordered(hierarchy.lvl4)', + 'unordered(hierarchy_camel.lvl5)', + 'unordered(hierarchy.lvl5)', + 'unordered(hierarchy_camel.lvl6)', + 'unordered(hierarchy.lvl6)', + 'content' + ], + distinct: true, + attributeForDistinct: 'url', + customRanking: [ + 'desc(weight.pageRank)', + 'desc(weight.level)', + 'asc(weight.position)' + ], + ranking: [ + 'words', + 'filters', + 'typo', + 'attribute', + 'proximity', + 'exact', + 'custom' + ], + highlightPreTag: '', + highlightPostTag: '', + minWordSizefor1Typo: 3, + minWordSizefor2Typos: 7, + allowTyposOnNumericTokens: false, + minProximity: 1, + ignorePlurals: true, + advancedSyntax: true, + attributeCriteriaComputedByMinProximity: true, + removeWordsIfNoResults: 'allOptional' + } + } +}) +``` + + diff --git a/docs/pt/reference/default-theme-sidebar.md b/docs/pt/reference/default-theme-sidebar.md new file mode 100644 index 00000000..62c3b3b1 --- /dev/null +++ b/docs/pt/reference/default-theme-sidebar.md @@ -0,0 +1,215 @@ +# Barra Lateral {#sidebar} + +A barra lateral é o bloco principal de navegação da sua documentação. Você pode configurar o menu da barra lateral em [`themeConfig.sidebar`](./default-theme-config#sidebar). + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Guia', + items: [ + { text: 'Introdução', link: '/introduction' }, + { text: 'Iniciando', link: '/getting-started' }, + ... + ] + } + ] + } +} +``` + +## O Básico {#the-basics} + +A forma mais simples do menu da barra lateral é passar um único _array_ de links. O item do primeiro nível define a "seção" da barra lateral. Ele deve conter `text`, que é o título da seção, e `items` que são os próprios links de navegação. + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Título da Seção A', + items: [ + { text: 'Item A', link: '/item-a' }, + { text: 'Item B', link: '/item-b' }, + ... + ] + }, + { + text: 'Título da Seção B', + items: [ + { text: 'Item C', link: '/item-c' }, + { text: 'Item D', link: '/item-d' }, + ... + ] + } + ] + } +} +``` + +Cada `link` deve especificar o caminho para o próprio arquivo começando com `/`. Se você adicionar uma barra no final do link, será mostrado o `index.md` do diretório correspondente. + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Guia', + items: [ + // Isso mostra a página `/guide/index.md`. + { text: 'Introdução', link: '/guide/' } + ] + } + ] + } +} +``` + +Você pode aninhar ainda mais os itens da barra lateral até 6 níveis de profundidade contando a partir do nível raiz. Note que níveis mais profundos que 6 serão ignorados e não serão exibidos na barra lateral. + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Nível 1', + items: [ + { + text: 'Nível 2', + items: [ + { + text: 'Nível 3', + items: [ + ... + ] + } + ] + } + ] + } + ] + } +} +``` + +## Múltiplas Barras Laterais {#multiple-sidebars} + +Você pode mostrar uma barra lateral diferente dependendo do caminho da página. Por exemplo, como mostrado neste site, você pode querer criar seções separadas de conteúdo em sua documentação, como a página "Guia" e a página "Configuração". + +Para fazer isso, primeiro organize suas páginas em diretórios para cada seção desejada: + +``` +. +├─ guide/ +│ ├─ index.md +│ ├─ one.md +│ └─ two.md +└─ config/ + ├─ index.md + ├─ three.md + └─ four.md +``` + +Em seguida, atualize sua configuração para definir sua barra lateral para cada seção. Desta vez, você deve passar um objeto em vez de um array. + +```js +export default { + themeConfig: { + sidebar: { + // Esta barra lateral é exibida quando um usuário + // está no diretório `guide`. + '/guide/': [ + { + text: 'Guia', + items: [ + { text: 'Índice', link: '/guide/' }, + { text: 'Um', link: '/guide/one' }, + { text: 'Dois', link: '/guide/two' } + ] + } + ], + + // Esta barra lateral é exibida quando um usuário + // está no diretório `config`. + '/config/': [ + { + text: 'Configuração', + items: [ + { text: 'Índice', link: '/config/' }, + { text: 'Três', link: '/config/three' }, + { text: 'Quatro', link: '/config/four' } + ] + } + ] + } + } +} +``` + +## Grupos Retráteis na Barra Lateral {#collapsible-sidebar-groups} + +Adicionando a opção `collapsed` ao grupo da barra lateral, ela mostra um botão para ocultar/mostrar cada seção. + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Título da Seção A', + collapsed: false, + items: [...] + } + ] + } +} +``` + +Todas as seções são "abertas" por padrão. Se você deseja que elas estejam "fechadas" na carga inicial da página, defina a opção `collapsed` como `true`. + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Título da Seção A', + collapsed: true, + items: [...] + } + ] + } +} +``` + +## `useSidebar` + +Retorna dados relacionados à barra lateral. O objeto retornado tem o seguinte tipo: + +```ts +export interface DocSidebar { + isOpen: Ref + sidebar: ComputedRef + sidebarGroups: ComputedRef + hasSidebar: ComputedRef + hasAside: ComputedRef + leftAside: ComputedRef + isSidebarEnabled: ComputedRef + open: () => void + close: () => void + toggle: () => void +} +``` + +**Exemplo:** + +```vue + + + +``` diff --git a/docs/pt/reference/default-theme-team-page.md b/docs/pt/reference/default-theme-team-page.md new file mode 100644 index 00000000..9021b959 --- /dev/null +++ b/docs/pt/reference/default-theme-team-page.md @@ -0,0 +1,258 @@ + + +# Página da Equipe {#team-page} + +Se você quiser apresentar sua equipe, você pode usar componentes de equipe para construir a Página da Equipe. Existem duas maneiras de usar esses componentes. Uma é incorporá-lo na página de documento, e outra é criar uma Página de Equipe completa. + +## Mostrar membros da equipe em uma página {#show-team-members-in-a-page} + +Você pode usar o componente `` exposto em `vitepress/theme` para exibir uma lista de membros da equipe em qualquer página. + +```html + + +# Nosso time + +Diga olá à nossa equipe incrível. + + +``` + +O código acima exibirá um membro da equipe em um elemento tipo cartão. Ele deve exibir algo semelhante ao abaixo. + + + +O componente `` vem em 2 tamanhos diferentes, pequeno `small` e médio `medium`. Enquanto é uma questão de preferência, geralmente o tamanho `small` deve encaixar melhor quando usado na página de documento. Além disso, você pode adicionar mais propriedades a cada membro, como adicionar o botão "descrição" ou "patrocinador". Saiba mais sobre em [``](#vpteammembers). + +Incorporar membros da equipe na página de documento é bom para equipes de pequeno porte, onde ter uma página de equipe inteira dedicada pode ser demais, ou introduzir membros parciais como uma referência ao contexto da documentação. + +Se você tiver um grande número de membros, ou simplesmente quiser ter mais espaço para mostrar os membros da equipe, considere [criar uma página de equipe completa.](#create-a-full-team-page) + +## Criando uma página de equipe completa {#create-a-full-team-page} + +Em vez de adicionar membros da equipe à página de documento, você também pode criar uma Página de Equipe completa, da mesma forma que pode criar uma [Página Inicial](./default-theme-home-page) personalizada. + +Para criar uma página de equipe, primeiro crie um novo arquivo md. O nome do arquivo não importa, mas aqui vamos chamá-lo de `team.md`. Neste arquivo, defina a opção `layout: page` do frontmatter, e então você poderá compor a estrutura da sua página usando componentes `TeamPage`. + +```html +--- +layout: page +--- + + + + + + + + + +``` + +Ao criar uma página de equipe completa, lembre-se de agrupar todos os componentes com o componente ``. Este componente garantirá que todos os componentes aninhados relacionados à equipe obtenham a estrutura de layout adequada, como espaçamentos. + +O componente `` adiciona a seção de título da página. O título é `

`. Use os _slots_ `#title` e `#lead`para documentar sobre sua equipe. + +`` funciona da mesma forma que quando usado em uma página de documento. Ele exibirá a lista de membros. + +### Adicione seções para dividir os membros da equipe {#add-sections-to-divide-team-members} + +Você pode adicionar "seções" à página da equipe. Por exemplo, você pode ter diferentes tipos de membros da equipe, como membros da Equipe Principal e Parceiros da Comunidade. Você pode dividir esses membros em seções para explicar melhor os papéis de cada grupo. + +Para fazer isso, adicione o componente `` ao arquivo `team.md` que criamos anteriormente. + +```html +--- +layout: page +--- + + + + + + + + + + + + + + +``` + +O componente `` pode ter os _slots_ `#title` e `#lead` similar ao componente `VPTeamPageTitle`, e também o _slot_ `#members` para exibir os membros da equipe. + +Lembre-se de colocar o componente `` dentro do _slot_ `#members`. + +## `` + +O componente `` exibe uma determinada lista de membros. + +```html + +``` + +```ts +interface Props { + // Tamanho de cada membro. O padrão é `medium`. + size?: 'small' | 'medium' + + // Lista de membros a serem exibidos. + members: TeamMember[] +} + +interface TeamMember { + // Imagem avatar do membro + avatar: string + + // Nome do membro. + name: string + + // Título a ser mostrado abaixo do nome do membro. + // Ex.: Desenvolvedor, Engenheiro de Software, etc. + title?: string + + // Organização a qual o membro pertence. + org?: string + + // URL da organização. + orgLink?: string + + // Descrição do membro. + desc?: string + + // Links sociais, por exemplo, GitHub, Twitter, etc. + // Você pode passar o objeto de Links Sociais aqui. + // Veja: https://vitepress.dev/reference/default-theme-config.html#sociallinks + links?: SocialLink[] + + // URL da página de patrocinador do membro. + sponsor?: string + + // Texto para o link do patrocinador. O padrão é 'Sponsor'. + actionText?: string +} +``` + +## `` + +O componente raiz ao criar uma página de equipe completa. Ele aceita apenas um único _slot_. Ele estilizará todos os componentes relacionados à equipe passados. + +## `` + +Adiciona a seção "título" da página. Melhor usar logo no início sob ``. Aceita os _slots_ `#title` e `#lead`. + +```html + + + + + + +``` + +## `` + +Cria uma "seção" na página da equipe. Aceita os _slots_ `#title`, `#lead` e `#members`. Você pode adicionar quantas seções quiser dentro de ``. + +```html + + ... + + + + + + +``` diff --git a/docs/pt/reference/frontmatter-config.md b/docs/pt/reference/frontmatter-config.md new file mode 100644 index 00000000..41ccad66 --- /dev/null +++ b/docs/pt/reference/frontmatter-config.md @@ -0,0 +1,221 @@ +--- +outline: deep +--- + +# Configuração Frontmatter {#frontmatter-config} + +Frontmatter permite a configuração baseada em páginas. Em cada arquivo markdown, você pode usar a configuração frontmatter para sobrepor opções de configuração a nível de site ou de tema. Além disso, existem opções de configuração que só podem ser definidas em frontmatter. + +Exemplo de uso: + +```md +--- +title: Documentação com VitePress +editLink: true +--- +``` + +Você pode acessar os dados do frontmatter através da variável global `$frontmatter` em expressões Vue: + +```md +{{ $frontmatter.title }} +``` + +## title + +- Tipo: `string` + +Título para a página. É o mesmo que [config.title](./site-config#title), e sobrepõe a configuração a nível de site. + +```yaml +--- +title: VitePress +--- +``` + +## titleTemplate + +- Tipo: `string | boolean` + +O sufixo para o título. É o mesmo que [config.titleTemplate](./site-config#titletemplate), e sobrepõe a configuração a nível de site. + +```yaml +--- +title: VitePress +titleTemplate: Gerador de site estático com Vite & Vue +--- +``` + +## description + +- Tipo: `string` + +Descrição para a página. É o mesmo que [config.description](./site-config#description), e sobrepõe a configuração a nível de site. + +```yaml +--- +description: VitePress +--- +``` + +## head + +- Tipo: `HeadConfig[]` + +Especifica tags head adicionais a serem injetadas na página atual. Elas serão acrescentadas após as tags head injetadas pela configuração a nível de site. + +```yaml +--- +head: + - - meta + - name: description + content: hello + - - meta + - name: keywords + content: super duper SEO +--- +``` + +```ts +type HeadConfig = + | [string, Record] + | [string, Record, string] +``` + +## Somente no Tema Padrão {#default-theme-only} + +As seguintes opções frontmatter são aplicáveis apenas ao usar o tema padrão. + +### layout + +- Tipo: `doc | home | page` +- Padrão: `doc` + +Determina o layout da página. + +- `doc` - Aplica estilos de documentação padrão ao conteúdo markdown. +- `home` - Layout especial para a "Página Inicial". Você pode adicionar opções extras como `hero` e `features` para criar rapidamente uma bela página inicial. +- `page` - Comporta-se de maneira semelhante a `doc`, mas não aplica estilos ao conteúdo. Útil quando você deseja criar uma página totalmente personalizada. + +```yaml +--- +layout: doc +--- +``` + +### hero + +Define o conteúdo da seção _hero_ na página inicial quando `layout` está definido como `home`. Mais detalhes em [Tema Padrão: Página Inicial](./default-theme-home-page). + +### features + +Define os itens a serem exibidos na seção de funcionalidades quando `layout` está definido como `home`. Mais detalhes em [Tema Padrão: Página Inicial](./default-theme-home-page). + +### navbar + +- Tipo: `boolean` +- Padrão: `true` + +Se deve exibir a [barra de navegação](./default-theme-nav). + +```yaml +--- +navbar: false +--- +``` + +### sidebar + +- Tipo: `boolean` +- Padrão: `true` + +Se deve exibir a [barra lateral](./default-theme-sidebar). + +```yaml +--- +sidebar: false +--- +``` + +### aside + +- Tipo: `boolean | 'left'` +- Padrão: `true` + +Define a localização do componente aside no layout `doc`. + +Configurar este valor como `false` impede a apresentação do elemento aside.\ +Configurar este valor como `true` apresenta o aside à direita.\ +Configurar este valor como `'left'` apresenta o aside à esquerda. + +```yaml +--- +aside: false +--- +``` + +### outline + +- Tipo: `number | [number, number] | 'deep' | false` +- Padrão: `2` + +Os níveis do cabeçalho no _outline_ a serem exibidos para a página. É o mesmo que [config.themeConfig.outline.level](./default-theme-config#outline), e sobrepõe o valor definido na configuração no nível do site. + +### lastUpdated + +- Tipo: `boolean | Date` +- Padrão: `true` + +Se deve mostrar o texto de [última atualização](./default-theme-last-updated) no rodapé da página atual. Se uma data e hora específica forem especificadas, ela será exibida em vez do último horário de modificação do git. + +```yaml +--- +lastUpdated: false +--- +``` + +### editLink + +- Tipo: `boolean` +- Padrão: `true` + +Se deve exibir o [link de edição](./default-theme-edit-link) no rodapé da página atual. + +```yaml +--- +editLink: false +--- +``` + +### footer + +- Tipo: `boolean` +- Padrão: `true` + +Se deve exibir o [rodapé](./default-theme-footer). + +```yaml +--- +footer: false +--- +``` + +### pageClass + +- Tipo: `string` + +Adiciona um nome de classe extra a uma página específica. + +```yaml +--- +pageClass: custom-page-class +--- +``` + +Em seguida, você pode personalizar os estilos desta página específica no arquivo `.vitepress/theme/custom.css`: + +```css +.custom-page-class { +  /* estilos específicos da página */ +} +``` diff --git a/docs/pt/reference/runtime-api.md b/docs/pt/reference/runtime-api.md new file mode 100644 index 00000000..a04458a1 --- /dev/null +++ b/docs/pt/reference/runtime-api.md @@ -0,0 +1,165 @@ +# API em Tempo de Execução {#runtime-api} + +VitePress oferece várias APIs embutidas para permitir o acesso aos dados da aplicação. VitePress vem também com alguns componentes embutidos que podem ser usados globalmente. + +Os métodos auxiliares são importáveis globais de `vitepress` e geralmente são usados em componentes Vue de temas personalizados. No entanto, eles também podem ser usados dentro de páginas `.md` porque os arquivos markdown são compilados em [Componentes de Arquivo Único Vue (SFC)](https://vuejs.org/guide/scaling-up/sfc.html). + +Métodos que começam com `use*` indicam que é uma função da [API de Composição Vue 3](https://vuejs.org/guide/introduction.html#composition-api) ("Composable") que só pode ser usada dentro de `setup()` ou ` + + +``` + +## `useRoute` + +Retorna o objeto de rota atual com o seguinte tipo: + +```ts +interface Route { + path: string + data: PageData + component: Component | null +} +``` + +## `useRouter` + +Retorna a instância do roteador VitePress para que você possa navegar programaticamente para outra página. + +```ts +interface Router { + /** + * Rota atual. + */ + route: Route + /** + * Navegar para uma nova URL. + */ + go: (to?: string) => Promise + /** + * Chamado antes da mudança de rota. Retorne `false` para cancelar a navegação. + */ + onBeforeRouteChange?: (to: string) => Awaitable + /** + * Chamado antes do carregamento do componente da página (depois que o estado do histórico é + * atualizado). Retorne `false` para cancelar a navegação. + */ + onBeforePageLoad?: (to: string) => Awaitable + /** + * Chamado após a mudança de rota. + */ + onAfterRouteChanged?: (to: string) => Awaitable +} +``` + +## `withBase` + +- **Tipo**: `(path: string) => string` + +Anexa o [`base`](./site-config#base) configurado a um caminho de URL fornecido. Veja também [Base URL](../guide/asset-handling#base-url). + +## `` + +O componente `` exibe o conteúdo markdown renderizado. Útil [ao criar seu próprio tema](../guide/custom-theme). + +```vue + +``` + +## `` + +O componente `` revela seu _slot_ apenas no lado do cliente. + +Como as aplicações VitePress são interpretadas no lado do servidor em Node.js ao gerar builds estáticos, qualquer uso do Vue deve seguir os requisitos de código universal. Em resumo, certifique-se de acessar apenas APIs do Navegador / DOM em ganchos `beforeMount` ou `mounted`. + +Se você estiver usando ou demonstrando componentes que não são compatíveis com SSR (por exemplo, contêm diretivas personalizadas), você pode envolvê-los dentro do componente `ClientOnly`. + +```vue-html + + + +``` + +- Relacionado: [Compatibilidade SSR](../guide/ssr-compat) + +## `$frontmatter` + +Acesse diretamente os dados [frontmatter](../guide/frontmatter) da página atual em expressões Vue. + +```md +--- +title: Olá +--- + +# {{ $frontmatter.title }} +``` + +## `$params` + +Acesse diretamente os [parâmetros de rota dinâmica](../guide/routing#dynamic-routes) da página atual em expressões Vue. + +```md +- nome do pacote: {{ $params.pkg }} +- versão: {{ $params.version }} +``` diff --git a/docs/pt/reference/site-config.md b/docs/pt/reference/site-config.md new file mode 100644 index 00000000..013ee7d9 --- /dev/null +++ b/docs/pt/reference/site-config.md @@ -0,0 +1,705 @@ +--- +outline: deep +--- + +# Configuração do Site {#site-config} + +A configuração do site é onde você pode definir as configurações globais do site. As opções de configuração do aplicativo definem configurações que se aplicam a todos os sites VitePress, independentemente do tema que estão usando. Por exemplo, o diretório base ou o título do site. + +## Visão geral {#overview} + +### Resolução de Configuração {#config-resolution} + +O arquivo de configuração é sempre resolvido a partir de `/.vitepress/config.[ext]`, onde `` é a [raiz do projeto](../guide/routing#root-and-source-directory) VitePress e `[ext]` é uma das extensões de arquivo suportadas. O TypeScript é suportado de fábrica. As extensões suportadas incluem `.js`, `.ts`, `.mjs` e `.mts`. + +Recomenda-se usar a sintaxe de módulos ES nos arquivos de configuração. O arquivo de configuração deve exportar por padrão um objeto: + +```ts +export default { + // opções de configuração de nível da aplicação + lang: 'pt-BR', + title: 'VitePress', + description: 'Gerador de site estático Vite & Vue.', + ... +} +``` + +:::details Configuração Dinâmica (Assíncrona) + +Se você precisar gerar dinamicamente a configuração, também pode exportar por padrão uma função. Por exemplo: + +```ts +import { defineConfig } from 'vitepress' + +export default async () => { + const posts = await (await fetch('https://my-cms.com/blog-posts')).json() + + return defineConfig({ + // opções de configuração de nível da aplicação + lang: 'pt-BR', + title: 'VitePress', + description: 'Gerador de site estático Vite & Vue.', + + // opções de configuração de nível do tema + themeConfig: { + sidebar: [ + ...posts.map((post) => ({ + text: post.name, + link: `/posts/${post.name}` + })) + ] + } + }) +} +``` + +Você também pode usar o `await` no nível superior. Como: + +```ts +import { defineConfig } from 'vitepress' + +const posts = await (await fetch('https://my-cms.com/blog-posts')).json() + +export default defineConfig({ + // opções de configuração de nível da aplicação + lang: 'pt-BR', + title: 'VitePress', + description: 'Gerador de site estático Vite & Vue.', + + // opções de configuração de nível do tema + themeConfig: { + sidebar: [ + ...posts.map((post) => ({ + text: post.name, + link: `/posts/${post.name}` + })) + ] + } +}) +``` + +::: + +### Configuração Intellisense {#config-intellisense} + +Usar o auxiliar `defineConfig` fornecerá Intellisense alimentado por TypeScript para as opções de configuração. Supondo que seu IDE o suporte, isso deve funcionar tanto em JavaScript quanto em TypeScript. + +```js +import { defineConfig } from 'vitepress' + +export default defineConfig({ + // ... +}) +``` + +### Configuração de Tema Tipada {#typed-theme-config} + +Por padrão, o auxiliar `defineConfig` espera o tipo de configuração de tema do tema padrão: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + // O tipo é `DefaultTheme.Config` + } +}) +``` + +Se você estiver usando um tema personalizado e desejar verificações de tipo para a configuração do tema, será necessário usar `defineConfigWithTheme` em vez disso, e passar o tipo de configuração para o seu tema personalizado por meio de um argumento genérico: + +```ts +import { defineConfigWithTheme } from 'vitepress' +import type { ThemeConfig } from 'your-theme' + +export default defineConfigWithTheme({ + themeConfig: { + // O tipo é `ThemeConfig` + } +}) +``` + +### Configuração Vite, Vue & Markdown + +- **Vite** + + Você pode configurar a instância subjacente do Vite usando a opção [vite](#vite) em sua configuração VitePress. Não é necessário criar um arquivo de configuração Vite separado. + +- **Vue** + + VitePress já inclui o plugin Vue oficial para Vite ([@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue)). Você pode configurar suas opções usando a opção [vue](#vue) em sua configuração VitePress. + +- **Markdown** + + Você pode configurar a instância subjacente de [Markdown-It](https://github.com/markdown-it/markdown-it) usando a opção [markdown](#markdown) em sua configuração VitePress. + +## Metadados do Site {#site-metadata} + +### title + +- Tipo: `string` +- Padrão: `VitePress` +- Pode ser substituído por página via [frontmatter](./frontmatter-config#title) + +Título do site. Ao usar o tema padrão, isso será exibido na barra de navegação. + +Ele também será usado como o sufixo padrão para todos os títulos individuais das páginas, a menos que [`titleTemplate`](#titletemplate) seja definido. O título final de uma página individual será o conteúdo textual do seu primeiro cabeçalho `

`, combinado com o título global como sufixo. Por exemplo, com a seguinte configuração e conteúdo da página: + +```ts +export default { + title: 'Meu Site Incrível' +} +``` + +```md +# Olá +``` + +O título da página será `Olá | Meu Site Incrível`. + +### titleTemplate + +- Tipo: `string | boolean` +- Pode ser substituído por página via [frontmatter](./frontmatter-config#titletemplate) + +Permite personalizar o sufixo do título de cada página ou o título inteiro. Por exemplo: + +```ts +export default { + title: 'Meu Site Incrível', + titleTemplate: 'Sufixo Personalizado' +} +``` + +```md +# Olá +``` + +O título da página será `Olá | Sufixo Personalizado`. + +Para personalizar completamente como o título deve ser renderizado, você pode usar o símbolo `:title` em `titleTemplate`: + +```ts +export default { + titleTemplate: ':title - Sufixo Personalizado' +} +``` + +Aqui, `:title` será substituído pelo texto inferido do primeiro cabeçalho `

` da página. O título do exemplo anterior da página será `Olá - Sufixo Personalizado`. + +A opção pode ser definida como `false` para desativar sufixos de título. + +### description + +- Tipo: `string` +- Padrão: `Um site VitePress` +- Pode ser substituído por página via [frontmatter](./frontmatter-config#descrição) + +Descrição para o site. Isso será apresentado como uma tag `` na página HTML. + +```ts +export default { + descrição: 'Um site VitePress' +} +``` + +### head + +- Tipo: `HeadConfig[]` +- Padrão: `[]` +- Pode ser acrescentado por página via [frontmatter](./frontmatter-config#head) + +Elementos adicionais para adicionar na tag `` da página HTML. As tags adicionadas pelo usuário são mostradas antes da tag `head` de fechamento, após as tags VitePress. + +```ts +type HeadConfig = + | [string, Record] + | [string, Record, string] +``` + +#### Exemplo: Adicionando um favicon {#example-adding-a-favicon} + +```ts +export default { + cabeça: [['link', { rel: 'icon', href: '/favicon.ico' }]] +} // coloque o favicon.ico no diretório public, se a base estiver definida, use /base/favicon.ico + +/* Mostraria: + +*/ +``` + +#### Exemplo: Adicionando Fontes do Google {#example-adding-google-fonts} + +```ts +export default { + head: [ + [ + 'link', + { rel: 'preconnect', href: 'https://fonts.googleapis.com' } + ], + [ + 'link', + { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' } + ], + [ + 'link', + { href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap', rel: 'stylesheet' } + ] + ] +} + +/* Mostraria: + + + +*/ +``` + +#### Exemplo: Registrando um _service worker_ {#example-registering-a-service-worker} + +```ts +export default { + head: [ + [ + 'script', + { id: 'register-sw' }, + `;(() => { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.register('/sw.js') + } + })()` + ] + ] +} + +/* Mostraria: + +*/ +``` + +#### Exemplo: Usando o Google Analytics {#example-using-google-analytics} + +```ts +export default { + head: [ + [ + 'script', + { async: '', src: 'https://www.googletagmanager.com/gtag/js?id=TAG_ID' } + ], + [ + 'script', + {}, + `window.dataLayer = window.dataLayer || []; + function gtag(){dataLayer.push(arguments);} + gtag('js', new Date()); + gtag('config', 'TAG_ID');` + ] + ] +} + +/* Mostraria: + + +*/ +``` + +### lang + +- Tipo: `string` +- Padrão: `en-US` + +O atributo de idioma para o site. Isso será mostrado como uma tag `` na página HTML. + +```ts +export default { + lang: 'en-US' +} +``` + +### base + +- Tipo: `string` +- Padrão: `/` + +A URL base em que o site será implantado. Você precisará definir isso se planeja implantar seu site em um subdiretório, por exemplo, no GitHub pages. Se você planeja implantar seu site em `https://foo.github.io/bar/` então você deve definir a base como `'/bar/'`. Deve sempre começar e terminar com uma barra. + +A base é automaticamente adicionada a todos as URLs que começam com / em outras opções, então você só precisa especificá-la uma vez. + +```ts +export default { + base: '/base/' +} +``` + +## Roteamento {#routing} + +### cleanUrls + +- Tipo: `boolean` +- Padrão: `false` + +Quando definido como `true`, VitePress removerá o `.html` no final dos URLs. Veja também [Gerando URL Limpa](../guide/routing#generating-clean-url). + +::: alerta Suporte do Servidor Necessário +Ativar isso pode exigir configurações adicionais em sua plataforma de hospedagem. Para funcionar, seu servidor deve ser capaz de servir `/foo.html` ao visitar `/foo` **sem redirecionamento**. +::: + +### rewrites + +- Tipo: `Record` + +Define mapeamentos personalizados de diretório <-> URL. Veja [Roteamento: Reescrever Rotas](../guide/routing#route-rewrites) para mais detalhes. + +```ts +export default { + rewrites: { + 'source/:page': 'destination/:page' + } +} +``` + +## Construção {#build} + +### srcDir + +- Tipo: `string` +- Padrão: `.` + +O diretório onde suas páginas de markdown são armazenadas, relativo à raiz do projeto. Veja também [Diretório Raiz e Fonte](../guide/routing#root-and-source-directory). + +```ts +export default { + srcDir: './src' +} +``` + +### srcExclude + +- Tipo: `string` +- Padrão: `undefined` + +Um [padrão glob](https://github.com/mrmlnc/fast-glob#pattern-syntax) para corresponder a arquivos markdown que devem ser excluídos como conteúdo fonte. + +```ts +export default { + srcExclude: ['**/README.md', '**/TODO.md'] +} +``` + +### outDir + +- Tipo: `string` +- Padrão: `./.vitepress/dist` + +A localização da saída da compilação para o site, relativa à [raiz do projeto](../guide/routing#root-and-source-directory). + +```ts +export default { + outDir: '../public' +} +``` + +### assetsDir + +- Tipo: `string` +- Padrão: `assets` + +Especifica o diretório para aninhar ativos gerados. O caminho deve estar dentro de [`outDir`](#outdir) e é resolvido em relação a ele. + +```ts +export default { + assetsDir: 'static' +} +``` + +### cacheDir + +- Tipo: `string` +- Padrão: `./.vitepress/cache` + +O diretório para arquivos de cache, relativo à [raiz do projeto](../guide/routing#root-and-source-directory). Veja também: [cacheDir](https://vitejs.dev/config/shared-options.html#cachedir). + +```ts +export default { + cacheDir: './.vitepress/.vite' +} +``` + +### ignoreDeadLinks + +- Tipo: `boolean | 'localhostLinks' | (string | RegExp | ((link: string) => boolean))[]` +- Padrão: `false` + +Quando definido como `true`, VitePress não falhará na compilação devido a links quebrados. + +Quando definido como `'localhostLinks'`, a compilação falhará em links quebrados, mas não verificará links `localhost`. + +```ts +export default { + ignoreDeadLinks: true +} +``` + +Também pode ser um _array_ de uma exata URL em string, padrões regex, ou funções de filtro personalizadas. + +```ts +export default { + ignoreDeadLinks: [ + // ignora URL exata "/playground" + '/playground', + // ignora todos os links localhost + /^https?:\/\/localhost/, + // ignora todos os links incluindo "/repl/"" + /\/repl\//, + // função personalizada, ignora todos os links incluindo "ignore" + (url) => { + return url.toLowerCase().includes('ignore') + } + ] +} +``` + +### mpa + +- Tipo: `boolean` +- Padrão: `false` + +Quando definido como `true`, a aplicação em produção será compilada no [Modo MPA](../guide/mpa-mode). O modo MPA envia 0kb de JavaScript por padrão, às custas de desabilitar a navegação no lado do cliente e exigir permissão explícita para interatividade. + +## Tematização {#theming} + +### appearance + +- Tipo: `boolean | 'dark' | 'force-dark' | import('@vueuse/core').UseDarkOptions` +- Padrão: `true` + +Se habilitar o modo escuro (adicionando a classe `.dark` ao elemento ``). + +- Se a opção estiver definida como `true` o tema padrão é determinado pelo esquema de cores preferido do usuário. +- Se a opção estiver definida como `dark` o tema é escuro por padrão, a menos que o usuário mude manualmente. +- Se a opção estiver definida como `false` os usuários não poderão mudar o tema. + +Esta opção injeta um script em linha que restaura as configurações dos usuários do armazenamento local (_local storage_) usando a chave `vitepress-theme-appearance`. Isso garante que a classe `.dark` seja aplicada antes de a página ser mostrada para evitar oscilações. + +`appearance.initialValue` só pode ser `'dark' | undefined`. Refs ou getters não são suportados. + +### lastUpdated + +- Tipo: `boolean` +- Padrão: `false` + +Para obter o selo de tempo da última atualização para cada página usando o Git. O selo de data será incluído nos dados de cada página, acessíveis via [`useData`](./runtime-api#usedata). + +Ao usar o tema padrão, habilitar esta opção exibirá o horário da última atualização de cada página. Você pode personalizar o texto via opção [`themeConfig.lastUpdatedText`](./default-theme-config#lastupdatedtext). + +## Personalização {#customization} + +### markdown + +- Tipo: `MarkdownOption` + +Configure as opções do processador Markdown. VitePress usa [Markdown-it](https://github.com/markdown-it/markdown-it) como processador e [Shiki](https://github.com/shikijs/shiki) para destacar sintaxe de linguagem. Dentro desta opção, você pode passar várias opções Markdown relacionadas para atender às suas necessidades. + +```js +export default { + markdown: {...} +} +``` + +Verifique a [declaração de tipo e jsdocs](https://github.com/vuejs/vitepress/blob/main/src/node/markdown/markdown.ts) para todas as opções disponíveis. + +### vite + +- Tipo: `import('vite').UserConfig` + +Passe a [Configuração Vite](https://vitejs.dev/config/) crua para o servidor interno / empacotador Vite. + +```js +export default { + vite: { + // Opções de configuração Vite + } +} +``` + +### vue + +- Tipo: `import('@vitejs/plugin-vue').Options` + +Passe as opções [`@vitejs/plugin-vue`](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue#options) cruas para a instância interna do plugin. + +```js +export default { + vue: { + // Opções @vitejs/plugin-vue + } +} +``` + +## Ganchos de Compilação {#build-hooks} + +Os ganchos de compilação VitePress permitem adicionar novas funcionalidades ao seu site: + +- Sitemap +- Indexação de Pesquisa +- PWA +- _Teleports_ + +## buildEnd +- Tipo: `(siteConfig: SiteConfig) => Awaitable` +`buildEnd` é um gancho de compilação CLI (Interface de Linha de Comando), ele será executado após a conclusão da compilação (SSG), mas antes que o processo VitePress CLI termine. + +```ts +export default { + async buildEnd(siteConfig) { + // ... + } +} +``` + +## postRender +- Tipo: `(context: SSGContext) => Awaitable` +- `postRender` é um gancho de compilação, chamado quando a interpretação SSG é concluída. Ele permitirá que você manipule o conteúdo de _teleports_ durante a geração de site estático. + + ```ts + export default { + async postRender(context) { + // ... + } + } + ``` + + ```ts + interface SSGContext { + content: string + teleports?: Record + [key: string]: any + } + ``` + +## transformHead +- Tipo: `(context: TransformContext) => Awaitable` + +`transformHead` é um gancho de compilação para transformar o cabeçalho antes de gerar cada página. Isso permite adicionar entradas no cabeçalho que não podem ser adicionadas estaticamente à configuração VitePress. Você só precisa retornar entradas extras, que serão mescladas automaticamente com as existentes. + +:::warning +Não faça mutações em qualquer item dentro de `context`. +::: + +```ts +export default { + async transformHead(context) { + // ... + } +} +``` + +```ts +interface TransformContext { + page: string // e.g. index.md (relativo a srcDir) + assets: string[] // todos os ativos não-js/css com URL pública completamente resolvida + siteConfig: SiteConfig + siteData: SiteData + pageData: PageData + title: string + description: string + head: HeadConfig[] + content: string +} +``` + +Note que este gancho só é chamado ao gerar o site estaticamente. Não é chamado durante o desenvolvimento. Se você precisar adicionar entradas de cabeçalho dinâmicas durante o desenvolvimento, pode usar o gancho [`transformPageData`](#transformpagedata) em seu lugar. + + ```ts + export default { + transformPageData(pageData) { + pageData.frontmatter.head ??= [] + pageData.frontmatter.head.push([ + 'meta', + { + name: 'og:title', + content: + pageData.frontmatter.layout === 'home' + ? `VitePress` + : `${pageData.title} | VitePress` + } + ]) + } + } + ``` + +#### Exemplo: Adicionar URL canônica `` {#example-adding-a-canonical-url-link} + +```ts +export default { + transformPageData(pageData) { + const canonicalUrl = `https://example.com/${pageData.relativePath}` + .replace(/index\.md$/, '') + .replace(/\.md$/, '.html') + + pageData.frontmatter.head ??= [] + pageData.frontmatter.head.push([ + 'link', + { rel: 'canonical', href: canonicalUrl } + ]) + } +} +``` + +### transformHtml +- Tipo: `(code: string, id: string, context: TransformContext) => Awaitable` +`transformHtml` é um gancho de compilação para transformar o conteúdo de cada página antes de salvá-lo no disco. + +:::warning +Não faça mutações em qualquer item dentro de `context`. Além disso, modificar o conteúdo HTML pode causar problemas de hidratação em tempo de execução. +::: + +```ts +export default { + async transformHtml(code, id, context) { + // ... + } +} +``` + +### transformPageData +- Tipo: `(pageData: PageData, context: TransformPageContext) => Awaitable | { [key: string]: any } | void>` + +`transformPageData` é um gancho para transformar os dados de cada página. Você pode fazer mutações diretamente em `pageData` ou retornar valores alterados que serão mesclados nos dados da página. + +:::warning +Não faça mutações em qualquer item dentro de `context` e tenha cuidado pois isso pode impactar no desempenho do servidor de desenvolvimento, especialmente se você tiver algumas solicitações de rede ou computações pesadas (como gerar imagens) no gancho. Você pode verificar `process.env.NODE_ENV === 'production'` para lógica condicional. +::: + +```ts +export default { + async transformPageData(pageData, { siteConfig }) { + pageData.contributors = await getPageContributors(pageData.relativePath) + } + + // ou retorne dados a serem mesclados + async transformPageData(pageData, { siteConfig }) { + return { + contributors: await getPageContributors(pageData.relativePath) + } + } +} +``` + +```ts +interface TransformPageContext { + siteConfig: SiteConfig +} +``` diff --git a/docs/public/_headers b/docs/public/_headers index f7fa3afc..5d2850dd 100644 --- a/docs/public/_headers +++ b/docs/public/_headers @@ -1,3 +1,6 @@ /assets/* cache-control: max-age=31536000 - cache-control: immutable \ No newline at end of file + cache-control: immutable + +/_translations/* + x-robots-tag: noindex diff --git a/docs/reference/default-theme-config.md b/docs/reference/default-theme-config.md index 8402dc08..4a431538 100644 --- a/docs/reference/default-theme-config.md +++ b/docs/reference/default-theme-config.md @@ -93,6 +93,7 @@ interface NavItemWithLink { activeMatch?: string target?: string rel?: string + noIcon?: boolean } interface NavItemChildren { @@ -134,7 +135,7 @@ export default { export type Sidebar = SidebarItem[] | SidebarMulti export interface SidebarMulti { - [path: string]: SidebarItem[] + [path: string]: SidebarItem[] | { items: SidebarItem[]; base: string } } export type SidebarItem = { @@ -161,6 +162,19 @@ export type SidebarItem = { * If `false`, group is collapsible but expanded by default */ collapsed?: boolean + + /** + * Base path for the children items. + */ + base?: string + + /** + * Customize text that appears on the footer of previous/next page. + */ + docFooterText?: string + + rel?: string + target?: string } ``` @@ -244,8 +258,10 @@ type SocialLinkIcon = | 'instagram' | 'linkedin' | 'mastodon' + | 'npm' | 'slack' | 'twitter' + | 'x' | 'youtube' | { svg: string } ``` @@ -406,6 +422,20 @@ export interface DocFooter { Can be used to customize the dark mode switch label. This label is only displayed in the mobile view. +## lightModeSwitchTitle + +- Type: `string` +- Default: `Switch to light theme` + +Can be used to customize the light mode switch title that appears on hovering. + +## darkModeSwitchTitle + +- Type: `string` +- Default: `Switch to dark theme` + +Can be used to customize the dark mode switch title that appears on hovering. + ## sidebarMenuLabel - Type: `string` diff --git a/docs/reference/default-theme-home-page.md b/docs/reference/default-theme-home-page.md index bbded876..f7baecca 100644 --- a/docs/reference/default-theme-home-page.md +++ b/docs/reference/default-theme-home-page.md @@ -69,6 +69,12 @@ interface HeroAction { // Destination link of the button. link: string + + // Link target attribute. + target?: string + + // Link rel attribute. + rel?: string } ``` @@ -131,7 +137,7 @@ interface Feature { // Link when clicked on feature component. The link can // be both internal or external. // - // e.g. `guid/reference/default-theme-home-page` or `htttps://example.com` + // e.g. `guide/reference/default-theme-home-page` or `https://example.com` link?: string // Link text to be shown inside feature component. Best @@ -144,6 +150,9 @@ interface Feature { // // e.g. `external` rel?: string + + // Link target attribute for the `link` option. + target?: string } type FeatureIcon = @@ -157,3 +166,30 @@ type FeatureIcon = height: string } ``` + +## Markdown Content + +You can add additional content to your site's homepage just by adding Markdown below the `---` frontmatter divider. + +````md +--- +layout: home + +hero: + name: VitePress + text: Vite & Vue powered static site generator. +--- + +## Getting Started + +You can get started using VitePress right away using `npx`! + +```sh +npm init +npx vitepress init +``` +```` + +::: info +VitePress didn't always auto-style the extra content of the `layout: home` page. To revert to older behavior, you can add `markdownStyles: false` to the frontmatter. +::: diff --git a/docs/reference/default-theme-team-page.md b/docs/reference/default-theme-team-page.md index 5a6e2a9e..29b071ff 100644 --- a/docs/reference/default-theme-team-page.md +++ b/docs/reference/default-theme-team-page.md @@ -212,6 +212,9 @@ interface TeamMember { // URL for the sponsor page for the member. sponsor?: string + + // Text for the sponsor link. Defaults to 'Sponsor'. + actionText?: string } ``` diff --git a/docs/reference/runtime-api.md b/docs/reference/runtime-api.md index 03bb6160..b65c2661 100644 --- a/docs/reference/runtime-api.md +++ b/docs/reference/runtime-api.md @@ -38,6 +38,10 @@ interface VitePressData { isDark: Ref dir: Ref localeIndex: Ref + /** + * Current location hash + */ + hash: Ref } interface PageData { diff --git a/docs/reference/site-config.md b/docs/reference/site-config.md index b5e124d2..e11f42b9 100644 --- a/docs/reference/site-config.md +++ b/docs/reference/site-config.md @@ -24,6 +24,62 @@ export default { } ``` +:::details Dynamic (Async) Config + +If you need to dynamically generate the config, you can also default export a function. For example: + +```ts +import { defineConfig } from 'vitepress' + +export default async () => { + const posts = await (await fetch('https://my-cms.com/blog-posts')).json() + + return defineConfig({ + // app level config options + lang: 'en-US', + title: 'VitePress', + description: 'Vite & Vue powered static site generator.', + + // theme level config options + themeConfig: { + sidebar: [ + ...posts.map((post) => ({ + text: post.name, + link: `/posts/${post.name}` + })) + ] + } + }) +} +``` + +You can also use top-level `await`. For example: + +```ts +import { defineConfig } from 'vitepress' + +const posts = await (await fetch('https://my-cms.com/blog-posts')).json() + +export default defineConfig({ + // app level config options + lang: 'en-US', + title: 'VitePress', + description: 'Vite & Vue powered static site generator.', + + // theme level config options + themeConfig: { + sidebar: [ + ...posts.map((post) => ({ + text: post.name, + link: `/posts/${post.name}` + })) + ] + } +}) +``` + +::: + ### Config Intellisense Using the `defineConfig` helper will provide TypeScript-powered intellisense for config options. Assuming your IDE supports it, this should work in both JavaScript and TypeScript. @@ -415,6 +471,13 @@ export default { } ``` +### metaChunk + +- Type: `boolean` +- Default: `false` + +When set to `true`, extract pages metadata to a separate JavaScript chunk instead of inlining it in the initial HTML. This makes each page's HTML payload smaller and makes the pages metadata cacheable, thus reducing server bandwidth when you have many pages in the site. + ### mpa - Type: `boolean` @@ -454,7 +517,7 @@ When using the default theme, enabling this option will display each page's last - Type: `MarkdownOption` -Configure Markdown parser options. VitePress uses [Markdown-it](https://github.com/markdown-it/markdown-it) as the parser, and [Shikiji](https://github.com/antfu/shikiji) (an improved version of [Shiki](https://shiki.matsu.io/)) to highlight language syntax. Inside this option, you may pass various Markdown related options to fit your needs. +Configure Markdown parser options. VitePress uses [Markdown-it](https://github.com/markdown-it/markdown-it) as the parser, and [Shiki](https://github.com/shikijs/shiki) to highlight language syntax. Inside this option, you may pass various Markdown related options to fit your needs. ```js export default { @@ -589,6 +652,24 @@ export default { } ``` +#### Example: Adding a canonical URL `` + +```ts +export default { + transformPageData(pageData) { + const canonicalUrl = `https://example.com/${pageData.relativePath}` + .replace(/index\.md$/, '') + .replace(/\.md$/, '.html') + + pageData.frontmatter.head ??= [] + pageData.frontmatter.head.push([ + 'link', + { rel: 'canonical', href: canonicalUrl } + ]) + } +} +``` + ### transformHtml - Type: `(code: string, id: string, context: TransformContext) => Awaitable` diff --git a/docs/ru/components/ModalDemo.vue b/docs/ru/components/ModalDemo.vue new file mode 100644 index 00000000..85c9dec1 --- /dev/null +++ b/docs/ru/components/ModalDemo.vue @@ -0,0 +1,80 @@ + + + + + diff --git a/docs/ru/guide/asset-handling.md b/docs/ru/guide/asset-handling.md new file mode 100644 index 00000000..c24bfa73 --- /dev/null +++ b/docs/ru/guide/asset-handling.md @@ -0,0 +1,63 @@ +# Обработка ресурсов {#asset-handling} + +## Ссылки на статические ресурсы {#referencing-static-assets} + +Все файлы Markdown компилируются в компоненты Vue и обрабатываются [Vite](https://vitejs.dev/guide/assets.html). Вы можете, **и должны**, ссылаться на любые ресурсы, используя относительные URL: + +```md +![Изображение](./image.png) +``` + +Вы можете ссылаться на статические ресурсы в ваших файлах разметки, компоненты `*.vue` в теме, стили и обычные файлы `.css`, используя абсолютные пути (основанные на корне проекта) или относительные пути (основанные на вашей файловой системе). Последнее похоже на поведение, к которому вы привыкли, если использовали Vite, Vue CLI или `file-loader` в webpack. + +Распространенные типы файлов изображений, мультимедиа и шрифтов определяются и включаются в качестве ресурсов автоматически. + +::: tip Связанные файлы не рассматриваются как ресурсы +PDF-файлы или другие документы, на которые есть ссылки в файлах с разметкой, не рассматриваются автоматически как ресурсы. Чтобы сделать связанные файлы доступными, вы должны вручную поместить их в каталог [`public`](#the-public-directory) вашего проекта. +::: + +Все ссылающиеся ресурсы, включая те, которые используют абсолютные пути, будут скопированы в выходной каталог с хэшированным именем файла в производственной сборке. Ресурсы, на которые никогда не ссылались, не будут скопированы. Изображения размером менее 4 КБ будут вставляться в формате base64 — это можно настроить с помощью опции конфигурации [`vite`](../reference/site-config#vite). + +Все **статические** ссылки на пути, включая абсолютные пути, должны быть основаны на структуре ваших рабочих каталогов. + +## Директория `public` {#the-public-directory} + +Иногда вам может понадобиться предоставить статические ресурсы, на которые нет прямых ссылок ни в одном из компонентов Markdown или темы, или вы можете захотеть предоставить определённые файлы с оригинальным именем. Примерами таких файлов являются `robots.txt`, `favicon.ico` и иконки PWA. + +Вы можете поместить эти файлы в директорию `public` в [директории с исходными файлами](./routing#source-directory). Например, если корень вашего проекта — `./docs`, и вы используете стандартное расположение исходного каталога, то ваш публичный каталог будет `./docs/public`. + +Ресурсы, размещённые в `public`, будут скопированы в корень выходного каталога как есть. + +Обратите внимание, что вы должны ссылаться на файлы, размещённые в `public`, используя корневой абсолютный путь — например, `public/icon.png` всегда должен упоминаться в исходном коде как `/icon.png`. + +## Базовый URL {#base-url} + +Если ваш сайт развёрнут на URL-адресе, не являющемся корневым, вам нужно установить параметр `base` в файле `.vitepress/config.js`. Например, если вы планируете развернуть свой сайт на `https://foo.github.io/bar/`, то параметр `base` следует установить на `'/bar/'` (он всегда должен начинаться и заканчиваться слэшем). + +Все пути к статическим ресурсам автоматически обрабатываются с учётом различных значений конфигурации `base`. Например, если в вашей разметке есть абсолютная ссылка на ресурс в директории `public`: + +```md +![Изображение](/image-inside-public.png) +``` + +В этом случае вам **не** нужно обновлять его при изменении значения конфигурации `base`. + +Однако если вы создаете компонент темы, который динамически ссылается на активы, например, изображение, атрибут `src` которого основан на значении конфигурации темы: + +```vue + +``` + +В этом случае рекомендуется обернуть путь с помощью [хелпера `withBase`](../reference/runtime-api#withbase), предоставляемого VitePress: + +```vue + + + +``` diff --git a/docs/ru/guide/cms.md b/docs/ru/guide/cms.md new file mode 100644 index 00000000..81542d2b --- /dev/null +++ b/docs/ru/guide/cms.md @@ -0,0 +1,58 @@ +--- +outline: deep +--- + +# Подключение к CMS {#connecting-to-a-cms} + +## Общий рабочий процесс {#general-workflow} + +Подключение VitePress к CMS в значительной степени зависит от [динамических маршрутов](./routing#dynamic-routes). Прежде чем приступить к работе, убедитесь, что вы понимаете, как это работает. + +Поскольку каждая CMS работает по-своему, здесь мы можем предоставить лишь общую схему работы, которую вам нужно будет адаптировать под свой конкретный сценарий. + +1. Если ваша CMS требует аутентификации, создайте файл `.env` для хранения токенов API и загрузите его таким образом: + + ```js + // posts/[id].paths.js + import { loadEnv } from 'vitepress' + + const env = loadEnv('', process.cwd()) + ``` + +2. Получите необходимые данные из CMS и преобразуйте их в соответствующие пути: + + ```js + export default { + async paths() { + // при необходимости используйте соответствующую клиентскую библиотеку CMS + const data = await ( + await fetch('https://my-cms-api', { + headers: { + // токен, если необходимо + } + }) + ).json() + + return data.map((entry) => { + return { + params: { id: entry.id /* заголовок, автор, дата и т. д. */ }, + content: entry.content + } + }) + } + } + ``` + +3. Отрисуйте содержимое страницы: + + ```md + # {{ $params.title }} + + - Автор: {{ $params.author }}, {{ $params.date }} + + + ``` + +## Руководства по интеграции {#integration-guides} + +Если вы написали руководство по интеграции VitePress с конкретной CMS, воспользуйтесь ссылкой «Редактировать эту страницу», чтобы добавить его сюда! diff --git a/docs/ru/guide/custom-theme.md b/docs/ru/guide/custom-theme.md new file mode 100644 index 00000000..05ca3b23 --- /dev/null +++ b/docs/ru/guide/custom-theme.md @@ -0,0 +1,222 @@ +# Пользовательская тема {#using-a-custom-theme} + +## Разрешение темы {#theme-resolving} + +Вы можете включить пользовательскую тему, создав файл `.vitepress/theme/index.js` или `.vitepress/theme/index.ts` («файл входа темы»): + +``` +. +├─ docs # корень проекта +│ ├─ .vitepress +│ │ ├─ theme +│ │ │ └─ index.js # файл входа темы +│ │ └─ config.js # файл конфигурации +│ └─ index.md +└─ package.json +``` + +VitePress всегда будет использовать пользовательскую тему вместо темы по умолчанию, если обнаружит наличие входного файла темы. Однако вы можете [расширить тему по умолчанию](./extending-default-theme), чтобы выполнить расширенные настройки поверх нее. + +## Интерфейс темы {#theme-interface} + +Пользовательская тема VitePress определяется как объект со следующим интерфейсом: + +```ts +interface Theme { + /** + * Корневой компонент макета для каждой страницы + * @required + */ + Layout: Component + /** + * Улучшение экземпляра приложения Vue + * @optional + */ + enhanceApp?: (ctx: EnhanceAppContext) => Awaitable + /** + * Расширяем другую тему, вызывая её `enhanceApp` перед нашей + * @optional + */ + extends?: Theme +} + +interface EnhanceAppContext { + app: App // Экземпляр приложения Vue + router: Router // Экземпляр маршрутизатора VitePress + siteData: Ref // Метаданные на уровне сайта +} +``` + +Файл входа темы должен экспортировать тему по умолчанию: + +```js +// .vitepress/theme/index.js + +// Вы можете напрямую импортировать файлы Vue в файле входа темы. +// VitePress предварительно настроен с помощью @vitejs/plugin-vue. +import Layout from './Layout.vue' + +export default { + Layout, + enhanceApp({ app, router, siteData }) { + // ... + } +} +``` + +Экспорт по умолчанию является единственным контрактом для пользовательской темы, и только свойство `Layout` является обязательным. Таким образом, технически тема VitePress может быть простой, как один компонент Vue. + +Внутри компонент макета работает так же, как и обычное приложение Vite + Vue 3. Обратите внимание, что тема также должна быть [SSR-совместимой](./ssr-compat). + +## Создание макета {#building-a-layout} + +Самый базовый компонент макета должен содержать компонент [``](../reference/runtime-api#content): + +```vue + + +``` + +Приведённая выше схема просто отображает разметку каждой страницы в виде HTML. Добавим обработку 404 ошибки в качестве первого улучшения: + +```vue{1-4,9-12} + + + +``` + +Хелпер [`useData()`](../reference/runtime-api#usedata) предоставляет нам все данные во время выполнения, необходимые для условной отрисовки различных макетов. Среди различных данных, к которым мы можем получить доступ, являются метаданные текущей страницы. Мы можем использовать это, чтобы позволить конечному пользователю управлять макетом на каждой странице. Например, пользователь может указать, что страница должна использовать специальный макет главной страницы: + +```md +--- +layout: home +--- +``` + +И мы можем настроить нашу тему, чтобы справиться с этим: + +```vue{3,12-14} + + + +``` + +Конечно, вы можете разделить макет на большее количество компонентов: + +```vue{3-5,12-15} + + + +``` + +Обратитесь к [Справочнику Runtime API](../reference/runtime-api), чтобы узнать обо всём, что доступно в компонентах темы. Кроме того, вы можете использовать [загрузку данных в режиме реального времени](./data-loading) для создания макета, управляемого данными — например, страницы со списком всех записей в блоге текущего проекта. + +## Распространение пользовательской темы {#distributing-a-custom-theme} + +Самый простой способ распространить пользовательскую тему — предоставить её в виде [репозитория шаблонов на GitHub](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository). + +Если вы хотите распространить тему в виде пакета npm, выполните следующие действия: + +1. Экспортируйте объект темы в качестве экспорта по умолчанию в записи пакета. + +2. Если есть возможность, экспортируйте определение типа конфигурации темы как `ThemeConfig`. + +3. Если ваша тема требует настройки конфигурации VitePress, экспортируйте эту конфигурацию в подпапку пакета (например. `my-theme/config`), чтобы пользователь мог расширить её. + +4. Документируйте параметры конфигурации темы (как через файл конфигурации, так и через метаданные). + +5. Предоставьте чёткие инструкции по использованию вашей темы (см. ниже). + +## Использование пользовательской темы {#consuming-a-custom-theme} + +Чтобы использовать внешнюю тему, импортируйте и реэкспортируйте её из элемента пользовательской темы: + +```js +// .vitepress/theme/index.js +import Theme from 'awesome-vitepress-theme' + +export default Theme +``` + +Если тема требует расширения: + +```js +// .vitepress/theme/index.js +import Theme from 'awesome-vitepress-theme' + +export default { + extends: Theme, + enhanceApp(ctx) { + // ... + } +} +``` + +Если тема требует специальных настроек VitePress, вам нужно будет также расширить их в своем собственном конфиге: + +```ts +// .vitepress/config.ts +import baseConfig from 'awesome-vitepress-theme/config' + +export default { + // расширить базовый конфиг темы (если необходимо) + extends: baseConfig +} +``` + +Наконец, если тема предоставляет типы для своего конфига темы: + +```ts +// .vitepress/config.ts +import baseConfig from 'awesome-vitepress-theme/config' +import { defineConfigWithTheme } from 'vitepress' +import type { ThemeConfig } from 'awesome-vitepress-theme' + +export default defineConfigWithTheme({ + extends: baseConfig, + themeConfig: { + // Тип `ThemeConfig` + } +}) +``` diff --git a/docs/ru/guide/data-loading.md b/docs/ru/guide/data-loading.md new file mode 100644 index 00000000..a611dc88 --- /dev/null +++ b/docs/ru/guide/data-loading.md @@ -0,0 +1,258 @@ +# Загрузка данных в режиме реального времени {#build-time-data-loading} + +VitePress предоставляет функцию **загрузчиков данных**, которая позволяет загружать произвольные данные и импортировать их со страниц или компонентов. Загрузка данных выполняется **только во время сборки**: Полученные данные будут сериализованы в виде JSON в финальной сборке JavaScript. + +Загрузчики данных могут использоваться для получения удалённых данных или генерирования метаданных на основе локальных файлов. Например, вы можете использовать загрузчики данных для анализа всех локальных страниц API и автоматического создания индекса всех записей API. + +## Пример использования {#basic-usage} + +Файл загрузчика данных должен заканчиваться либо `.data.js`, либо `.data.ts`. Файл должен предоставлять экспорт объекта по умолчанию с помощью метода `load()`: + +```js +// example.data.js +export default { + load() { + return { + hello: 'мир' + } + } +} +``` + +Модуль загрузчика выполняется только в Node.js, поэтому вы можете импортировать любые API Node и зависимости npm по мере необходимости. + +Затем вы можете импортировать данные из этого файла в страницы `.md` и компоненты `.vue` с помощью экспорта с именем `data`: + +```vue + + +
{{ data }}
+``` + +Результат: + +```json +{ + "hello": "мир" +} +``` + +Вы заметите, что сам загрузчик данных не экспортирует `data`. Это VitePress вызывает метод `load()` за кулисами и неявно раскрывает результат через именованный экспорт `data`. + +Это работает, даже если загрузчик асинхронный: + +```js +export default { + async load() { + // получение удалённых данных + return (await fetch('...')).json() + } +} +``` + +## Данные из локальных файлов {#data-from-local-files} + +Если вам нужно генерировать данные на основе локальных файлов, используйте опцию `watch` в загрузчике данных, чтобы изменения, внесённые в эти файлы, вызывали горячие обновления. + +Опция `watch` удобна ещё и тем, что вы можете использовать [шаблоны glob](https://github.com/mrmlnc/fast-glob#pattern-syntax) для соответствия нескольким файлам. Шаблоны могут быть относительными к самому файлу загрузчика, а функция `load()` будет получать совпадающие файлы в виде абсолютных путей. + +В следующем примере показана загрузка CSV-файлов и их преобразование в JSON с помощью [csv-parse](https://github.com/adaltas/node-csv/tree/master/packages/csv-parse/). Поскольку этот файл выполняется только во время сборки, вы не будете передавать CSV-парсер клиенту! + +```js +import fs from 'node:fs' +import { parse } from 'csv-parse/sync' + +export default { + watch: ['./data/*.csv'], + load(watchedFiles) { + // watchedFiles будет представлять собой массив абсолютных путей к найденным файлам. + // Формируем массив метаданных записи блога, которые можно использовать для визуализации списка в макете темы + return watchedFiles.map((file) => { + return parse(fs.readFileSync(file, 'utf-8'), { + columns: true, + skip_empty_lines: true + }) + }) + } +} +``` + +## `createContentLoader` {#createcontentloader} + +При создании сайта, ориентированного на контент, нам часто приходится создавать страницы типа «архив», или «индекс», на которых мы перечисляем все доступные записи в нашей коллекции контента. Например, записи в блоге или страницы API. Мы **можем** реализовать это напрямую с помощью API загрузчика данных, но поскольку это очень распространённый случай использования, VitePress также предоставляет функцию `createContentLoader`, чтобы упростить эту задачу: + +```js +// posts.data.js +import { createContentLoader } from 'vitepress' + +export default createContentLoader('posts/*.md' /* параметры */) +``` + +Эта функция принимает шаблон glob относительно [исходного каталога](./routing#source-directory) и возвращает объект `{ watch, load }` загрузчика данных, который может быть использован в качестве экспорта по умолчанию в файле загрузчика данных. В нем также реализовано кэширование на основе временных меток изменения файлов для повышения производительности dev. + +Обратите внимание, что загрузчик работает только с файлами Markdown — совпадающие файлы, не относящиеся к Markdown, будут пропущены. + +Загруженные данные будут представлять собой массив с типом `ContentData[]`: + +```ts +interface ContentData { + // отображаемый URL-адрес страницы, например: /posts/hello.html (не включает `base`) + // выполните итерацию вручную или используйте пользовательскую `трансформацию` для нормализации путей + url: string + // метаданные страницы + frontmatter: Record + + // следующие параметры присутствуют только в том случае, если соответствующие опции включены + // мы рассмотрим их ниже + src: string | undefined + html: string | undefined + excerpt: string | undefined +} +``` + +По умолчанию указываются только `url` и `frontmatter`. Это связано с тем, что загруженные данные будут вложены в клиентский пакет в виде JSON, поэтому нам нужно быть осторожными с их размером. Вот пример использования этих данных для создания минимальной индексной страницы блога: + +```vue + + + +``` + +### Параметры {#options} + +Данные по умолчанию могут не соответствовать всем требованиям — вы можете изменить данные с помощью параметров: + +```js +// posts.data.js +import { createContentLoader } from 'vitepress' + +export default createContentLoader('posts/*.md', { + includeSrc: true, // включить исходный текст в формате Markdown? + render: true, // включать в себя полный HTML страницы? + excerpt: true, // включить отрывок? + transform(rawData) { + // составляйте карты, сортируйте или фильтруйте исходные данные по своему усмотрению. + // конечный результат — это то, что будет отправлено клиенту. + return rawData + .sort((a, b) => { + return +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date) + }) + .map((page) => { + page.src // исходный текст в формате Markdown + page.html // отображение полной страницы HTML + page.excerpt // отображаемый отрывок HTML (содержимое выше первого `---`) + return { + /* ... */ + } + }) + } +}) +``` + +Посмотрите, как он используется в [блоге Vue.js](https://github.com/vuejs/blog/blob/main/.vitepress/theme/posts.data.ts). + +API `createContentLoader` также можно использовать внутри [хуков сборки](../reference/site-config#build-hooks): + +```js +// .vitepress/config.js +export default { + async buildEnd() { + const posts = await createContentLoader('posts/*.md').load() + // генерируем файлы на основе метаданных сообщений, например, RSS-канал + } +} +``` + +**Types** + +```ts +interface ContentOptions { + /** + * Включаем src? + * @default false + */ + includeSrc?: boolean + + /** + * Преобразовываем src в HTML и включаем в данные? + * @default false + */ + render?: boolean + + /** + * Если `boolean`, то следует ли разбирать и включать отрывок? (отображается как HTML) + * + * Если `function`, то управляйте тем, как отрывок извлекается из содержимого. + * + * Если `string`, определите пользовательский разделитель, который будет использоваться для извлечения + * отрывка. Разделителем по умолчанию является `---`, если `excerpt` имеет значение `true`. + * + * @see https://github.com/jonschlinkert/gray-matter#optionsexcerpt + * @see https://github.com/jonschlinkert/gray-matter#optionsexcerpt_separator + * + * @default false + */ + excerpt?: + | boolean + | (( + file: { + data: { [key: string]: any } + content: string + excerpt?: string + }, + options?: any + ) => void) + | string + + /** + * Преобразуйте данные. Обратите внимание, что при импорте из компонентов или файлов + * с разметкой данные будут вложены в клиентский пакет в виде JSON. + */ + transform?: (data: ContentData[]) => T | Promise +} +``` + +## Загрузчики типизированных данных {#typed-data-loaders} + +При использовании TypeScript вы можете ввести свой загрузчик и экспортировать `data` следующим образом: + +```ts +import { defineLoader } from 'vitepress' + +export interface Data { + // тип данных +} + +declare const data: Data +export { data } + +export default defineLoader({ + // тип проверенных опций загрузчика + watch: ['...'], + async load(): Promise { + // ... + } +}) +``` + +## Конфигурация {#configuration} + +Чтобы получить информацию о конфигурации внутри загрузчика, вы можете использовать код, подобный этому: + +```ts +import type { SiteConfig } from 'vitepress' + +const config: SiteConfig = (globalThis as any).VITEPRESS_CONFIG +``` diff --git a/docs/ru/guide/deploy.md b/docs/ru/guide/deploy.md new file mode 100644 index 00000000..c54c1dc9 --- /dev/null +++ b/docs/ru/guide/deploy.md @@ -0,0 +1,337 @@ +--- +outline: deep +--- + +# Развёртывание вашего сайта VitePress {#deploy-your-vitepress-site} + +Следующие руководства основаны на некоторых общих предположениях: + +- Сайт VitePress находится в директории `docs` вашего проекта. +- Вы используете выходной каталог сборки по умолчанию (`.vitepress/dist`). +- VitePress установлен как локальная зависимость в вашем проекте, и вы установили следующие скрипты в вашем `package.json`: + + ```json + { + "scripts": { + "docs:build": "vitepress build docs", + "docs:preview": "vitepress preview docs" + } + } + ``` + +## Создание и локальное тестирование {#build-and-test-locally} + +1. Выполните эту команду, чтобы собрать документацию: + + ```sh + $ npm run docs:build + ``` + +2. После сборки просмотрите её локально, запустив команду: + + ```sh + $ npm run docs:preview + ``` + + Команда `preview` загрузит локальный статический веб-сервер, который будет обслуживать выходной каталог `.vitepress/dist` по адресу `http://localhost:4173`. Вы можете использовать это, чтобы убедиться, что всё выглядит хорошо, прежде чем отправлять в производство. + +3. Вы можете настроить порт сервера, передав `--port` в качестве аргумента. + + ```json + { + "scripts": { + "docs:preview": "vitepress preview docs --port 8080" + } + } + ``` + + Теперь метод `docs:preview` запустит сервер по адресу `http://localhost:8080`. + +## Установка публичного базового пути {#setting-a-public-base-path} + +По умолчанию предполагается, что сайт будет развёрнут по корневому пути домена (`/`). Если ваш сайт будет обслуживаться по подпути, например, `https://mywebsite.com/blog/`, то в конфигурации VitePress необходимо установить для опции [`base`](../reference/site-config#base) значение `'/blog/'`. + +**Пример:** Если вы используете Github (или GitLab) Pages и развёртываете на `user.github.io/repo/`, то установите `base` на `/repo/`. + +## Заголовки кэша HTTP {#http-cache-headers} + +Если вы контролируете HTTP-заголовки на своем рабочем сервере, вы можете настроить заголовки `cache-control` для достижения лучшей производительности при повторных посещениях. + +В производственной сборке используются хэшированные имена файлов для статических ресурсов (JavaScript, CSS и другие импортированные ресурсы, не находящиеся в `public`). Если вы просмотрите предварительную версию с помощью сетевой вкладки devtools вашего браузера, вы увидите файлы типа `app.4f283b18.js`. + +Этот хэш `4f283b18` генерируется из содержимого этого файла. Один и тот же хэшированный URL гарантированно обслуживает одно и то же содержимое файла — если содержимое меняется, то и URL тоже. Это означает, что вы можете смело использовать самые сильные заголовки кэша для этих файлов. Все такие файлы будут помещены в каталог `assets/` в выходном каталоге, поэтому вы можете настроить для них следующий заголовок: + +``` +Cache-Control: max-age=31536000,immutable +``` + +::: details Пример файла Netlify `_headers` + +``` +/assets/* + cache-control: max-age=31536000 + cache-control: immutable +``` + +Примечание: файл `_headers` должен быть помещён в [директорию `public`](./asset-handling#the-public-directory) — в нашем случае `docs/public/_headers` — так, чтобы он был скопирован в выходной каталог. + +[Netlify custom headers documentation](https://docs.netlify.com/routing/headers/) + +::: + +::: details Пример конфигурации Vercel в файле `vercel.json` + +```json +{ + "headers": [ + { + "source": "/assets/(.*)", + "headers": [ + { + "key": "Cache-Control", + "value": "max-age=31536000, immutable" + } + ] + } + ] +} +``` + +Примечание: Файл `vercel.json` должен быть помещен в корень вашего **репозитория**. + +[Документация Vercel по конфигурации заголовков](https://vercel.com/docs/concepts/projects/project-configuration#headers) + +::: + +## Руководства по платформам {#platform-guides} + +### Netlify / Vercel / Cloudflare Pages / AWS Amplify / Render {#netlify-vercel-cloudflare-pages-aws-amplify-render} + +Создайте новый проект и измените эти настройки с помощью панели управления: + +- **Build Command:** `npm run docs:build` +- **Output Directory:** `docs/.vitepress/dist` +- **Node Version:** `18` (или выше) + +::: warning ПРЕДУПРЕЖДЕНИЕ +Не включайте такие опции, как _Auto Minify_ для HTML-кода. Он удалит из вывода комментарии, которые имеют значение для Vue. При их удалении могут возникать ошибки несоответствия гидратации. +::: + +### GitHub Pages {#github-pages} + +1. Создайте файл с именем `deploy.yml` в директории `.github/workflows` вашего проекта с примерно таким содержанием: + + ```yaml + # Пример рабочего процесса для создания и развёртывания сайта VitePress на GitHub Pages + # + name: Deploy VitePress site to Pages + + on: + # Выполняется при пушах, направленных в ветку `main`. Измените это значение на `master`, если вы + # используете ветку `master` в качестве ветки по умолчанию. + push: + branches: [main] + + # Позволяет запустить этот рабочий процесс вручную на вкладке «Actions». + workflow_dispatch: + + # Устанавливает разрешения GITHUB_TOKEN, чтобы разрешить развёртывание на страницах GitHub. + permissions: + contents: read + pages: write + id-token: write + + # Разрешите только одно одновременное развёртывание, пропуская запуски, стоящие в очереди. + # Однако НЕ отменяйте текущие запуски, поскольку мы хотим дать возможность завершить производственные развёртывания. + concurrency: + group: pages + cancel-in-progress: false + + jobs: + # Сборка + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Не требуется, если функция lastUpdated не включена + # - uses: pnpm/action-setup@v3 # Раскомментируйте, если вы используете pnpm + # - uses: oven-sh/setup-bun@v1 # Раскомментируйте, если вы используете Bun + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm # или pnpm / yarn + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Install dependencies + run: npm ci # или pnpm install / yarn install / bun install + - name: Build with VitePress + run: npm run docs:build # или pnpm docs:build / yarn docs:build / bun run docs:build + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs/.vitepress/dist + + # Развёртывание + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + name: Deploy + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 + ``` + + ::: warning ПРЕДУПРЕЖДЕНИЕ + Убедитесь, что опция `base` в вашем VitePress настроена правильно. Дополнительные сведения см. в секции [Установка публичного базового пути](#setting-a-public-base-path). + ::: + +2. В настройках вашего репозитория в разделе «Pages» выберите пункт меню «GitHub Actions» в секции «Build and deployment > Source». + +3. Внесите свои изменения в ветку `main` и дождитесь завершения процесса GitHub Actions. Вы должны увидеть, что ваш сайт развёрнут по адресу `https://.github.io/[repository]/` или `https:///` в зависимости от ваших настроек. Ваш сайт будет автоматически разворачиваться при каждом внесении изменений в ветке `main`. + +### GitLab Pages {#gitlab-pages} + +1. Установите `outDir` в конфигурации VitePress на `../public`. Настройте опцию `base` на `'/<репозиторий>/'`, если вы хотите развернуть ваш проект по адресу на `https://<имя пользователя>.gitlab.io/<репозиторий>/`. + +2. Создайте файл с именем `.gitlab-ci.yml` в корне вашего проекта с приведённым ниже содержимым. Это позволит создавать и развёртывать ваш сайт каждый раз, когда вы вносите изменения в его содержимое: + + ```yaml + image: node:18 + pages: + cache: + paths: + - node_modules/ + script: + # - apk add git # Отметьте это, если вы используете небольшие докер-образы, такие как alpine, и у вас включен lastUpdated + - npm install + - npm run docs:build + artifacts: + paths: + - public + only: + - main + ``` + +### Статические веб-приложения Azure {#azure-static-web-apps} + +1. Следуйте [официальной документации](https://docs.microsoft.com/ru-ru/azure/static-web-apps/build-configuration). + +2. Установите эти значения в вашем конфигурационном файле (и удалите те, которые вам не нужны, например, `api_location`): + + - **`app_location`**: `/` + - **`output_location`**: `docs/.vitepress/dist` + - **`app_build_command`**: `npm run docs:build` + +### Firebase {#firebase} + +1. Создайте `firebase.json` и `.firebaserc` в корне вашего проекта: + + `firebase.json`: + + ```json + { + "hosting": { + "public": "docs/.vitepress/dist", + "ignore": [] + } + } + ``` + + `.firebaserc`: + + ```json + { + "projects": { + "default": "" + } + } + ``` + +2. После запуска `npm run docs:build` выполните эту команду для развёртывания: + + ```sh + firebase deploy + ``` + +### Surge {#surge} + +1. После запуска `npm run docs:build` выполните эту команду для развёртывания: + + ```sh + npx surge docs/.vitepress/dist + ``` + +### Heroku {#heroku} + +1. Следуйте документации и руководству, приведённому в [`heroku-buildpack-static`](https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-static). + +2. Создайте файл `static.json` в корне вашего проекта со следующим содержимым: + + ```json + { + "root": "docs/.vitepress/dist" + } + ``` + +### Edgio {#edgio} + +См. [Создание и развёртывание приложения VitePress в Edgio](https://docs.edg.io/applications/v6/sites_frameworks/getting_started/vitepress). + +### Хостинг статических файлов Kinsta {#kinsta-static-site-hosting} + +Вы можете развернуть свой сайт Vitepress на [Kinsta](https://kinsta.com/static-site-hosting/), следуя этим [инструкциям](https://kinsta.com/docs/vitepress-static-site-example/). + +### Stormkit + +Вы можете развернуть свой проект VitePress на [Stormkit](https://www.stormkit.io), следуя следующим [инструкциям](https://stormkit.io/blog/how-to-deploy-vitepress). + +### Nginx + +Вот пример конфигурации блока сервера Nginx. Эта настройка включает сжатие gzip для общих текстовых ресурсов, правила обслуживания статических файлов вашего сайта VitePress с правильными заголовками кэширования и обработку параметра `cleanUrls: true`. + +```nginx +server { + gzip on; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + listen 80; + server_name _; + index index.html; + + location / { + # расположение контента + root /app; + + # точные совпадения -> обратные чистые URL-адреса -> папки -> не найдены + try_files $uri $uri.html $uri/ =404; + + # несуществующие страницы + error_page 404 /404.html; + + # папка без index.html вызывает ошибку 403 в этой настройке + error_page 403 /404.html; + + # настройка заголовков кэширования + # файлы в папке с ресурсами имеют хэши имён файлов + location ~* ^/assets/ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + } +} +``` + +Эта конфигурация предполагает, что ваш собранный сайт VitePress находится в директории `/app`. При необходимости измените директиву `root`, если файлы вашего сайта расположены в другом месте. + +::: warning Не используйте index.html по умолчанию +Разрешение try_files не должно использовать index.html, как это делается в других приложениях Vue. Это может привести к недопустимому состоянию страницы. +::: + +Дополнительную информацию можно найти в официальной документации [Nginx](https://nginx.org/ru/docs/), а также в следующих обсуждениях: [#2837](https://github.com/vuejs/vitepress/discussions/2837), [#3235](https://github.com/vuejs/vitepress/issues/3235), а также в [блоге Mehdi Merah](https://blog.mehdi.cc/articles/vitepress-cleanurls-on-nginx-environment#readings). diff --git a/docs/ru/guide/extending-default-theme.md b/docs/ru/guide/extending-default-theme.md new file mode 100644 index 00000000..818f4399 --- /dev/null +++ b/docs/ru/guide/extending-default-theme.md @@ -0,0 +1,342 @@ +--- +outline: deep +--- + +# Расширение темы по умолчанию {#extending-the-default-theme} + +Тема VitePress по умолчанию оптимизирована для документации и может быть настроена по своему усмотрению. Полный список опций можно найти в главе [Настройки темы по умолчанию](../reference/default-theme-config). + +Однако есть ряд случаев, когда одной лишь конфигурации будет недостаточно. Например: + +1. Вам нужно изменить стили CSS; +2. Вам нужно изменить экземпляр приложения Vue, например, чтобы зарегистрировать глобальные компоненты; +3. Вам нужно внедрить пользовательский контент в тему через слоты макета. + +Эти расширенные настройки потребуют использования пользовательской темы, которая «расширяет» тема по умолчанию. + +::: tip СОВЕТ +Прежде чем приступить к работе, обязательно прочитайте главу [Пользовательская тема](./custom-theme), чтобы понять, как работают пользовательские темы. +::: + +## Настройка CSS {#customizing-css} + +CSS темы по умолчанию можно настроить, переопределив переменные CSS корневого уровня: + +```js +// .vitepress/theme/index.js +import DefaultTheme from 'vitepress/theme' +import './custom.css' + +export default DefaultTheme +``` + +```css +/* .vitepress/theme/custom.css */ +:root { + --vp-c-brand-1: #646cff; + --vp-c-brand-2: #747bff; +} +``` + +См. [переменные CSS темы по умолчанию](https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css), которые можно переопределить. + +## Использование различных шрифтов {#using-different-fonts} + +VitePress использует [Inter](https://rsms.me/inter/) в качестве шрифта по умолчанию, и будет включать шрифты в вывод сборки. Шрифт также автоматически загружается в производство. Однако это может быть нежелательно, если вы хотите использовать другой основной шрифт. + +Чтобы не включать Inter в вывод сборки, импортируйте тему из `vitepress/theme-without-fonts`: + +```js +// .vitepress/theme/index.js +import DefaultTheme from 'vitepress/theme-without-fonts' +import './my-fonts.css' + +export default DefaultTheme +``` + +```css +/* .vitepress/theme/custom.css */ +:root { + --vp-font-family-base: /* normal text font */ --vp-font-family-mono: + /* code font */; +} +``` + +::: warning ПРЕДУПРЕЖДЕНИЕ +Если вы используете дополнительные компоненты, такие как [Страница команды](../reference/default-theme-team-page), убедитесь, что они также импортированы из `vitepress/theme-without-fonts`! +::: + +Если ваш шрифт — это локальный файл, на который ссылаются через `@font-face`, он будет обработан как ресурс и включён в каталог `.vitepress/dist/assets` с хэшированным именем файла. Чтобы предварительно загрузить этот файл, используйте хук сборки [transformHead](../reference/site-config#transformhead): + +```js +// .vitepress/config.js +export default { + transformHead({ assets }) { + // настраиваем regex соответствующим образом, чтобы он соответствовал вашему шрифту + const myFontFile = assets.find((file) => /font-name\.\w+\.woff2/) + if (myFontFile) { + return [ + [ + 'link', + { + rel: 'preload', + href: myFontFile, + as: 'font', + type: 'font/woff2', + crossorigin: '' + } + ] + ] + } + } +} +``` + +## Регистрация глобальных компонентов {#registering-global-components} + +```js +// .vitepress/theme/index.js +import DefaultTheme from 'vitepress/theme' + +/** @type {import('vitepress').Theme} */ +export default { + extends: DefaultTheme, + enhanceApp({ app }) { + // регистрируем пользовательские глобальные компоненты + app.component('MyGlobalComponent' /* ... */) + } +} +``` + +Если вы используете TypeScript: + +```ts +// .vitepress/theme/index.ts +import type { Theme } from 'vitepress' +import DefaultTheme from 'vitepress/theme' + +export default { + extends: DefaultTheme, + enhanceApp({ app }) { + // регистрируем пользовательские глобальные компоненты + app.component('MyGlobalComponent' /* ... */) + } +} satisfies Theme +``` + +Поскольку мы используем Vite, вы также можете использовать [глобальную функцию импорта](https://vitejs.dev/guide/features.html#glob-import) Vite для автоматической регистрации каталога компонентов. + +## Слоты макета {#layout-slots} + +Компонент `` темы по умолчанию имеет несколько слотов, которые можно использовать для вставки содержимого в определённые места страницы. Вот пример внедрения компонента в структуру before: + +```js +// .vitepress/theme/index.js +import DefaultTheme from 'vitepress/theme' +import MyLayout from './MyLayout.vue' + +export default { + extends: DefaultTheme, + // переопределяем макет с помощью компонента-обёртки, который + // вводит слоты + Layout: MyLayout +} +``` + +```vue + + + + +``` + +Также можно использовать функцию рендеринга. + +```js +// .vitepress/theme/index.js +import { h } from 'vue' +import DefaultTheme from 'vitepress/theme' +import MyComponent from './MyComponent.vue' + +export default { + extends: DefaultTheme, + Layout() { + return h(DefaultTheme.Layout, null, { + 'aside-outline-before': () => h(MyComponent) + }) + } +} +``` + +Полный список слотов, доступных в макете темы по умолчанию: + +- Когда `layout: 'doc'` (по умолчанию) включен через метаданные: + - `doc-top` + - `doc-bottom` + - `doc-footer-before` + - `doc-before` + - `doc-after` + - `sidebar-nav-before` + - `sidebar-nav-after` + - `aside-top` + - `aside-bottom` + - `aside-outline-before` + - `aside-outline-after` + - `aside-ads-before` + - `aside-ads-after` +- Когда `layout: 'home'` включен через метаданные: + - `home-hero-before` + - `home-hero-info-before` + - `home-hero-info` + - `home-hero-info-after` + - `home-hero-actions-after` + - `home-hero-image` + - `home-hero-after` + - `home-features-before` + - `home-features-after` +- Когда `layout: 'page'` включен через метаданные: + - `page-top` + - `page-bottom` +- На странице «Не найдено (404)»: + - `not-found` +- Всегда: + - `layout-top` + - `layout-bottom` + - `nav-bar-title-before` + - `nav-bar-title-after` + - `nav-bar-content-before` + - `nav-bar-content-after` + - `nav-screen-content-before` + - `nav-screen-content-after` + +## Использование View Transitions API {#using-view-transitions-api} + +### Переключение внешнего вида {#on-appearance-toggle} + +Вы можете расширить стандартную тему, чтобы обеспечить пользовательский переход при переключении цветового режима. Пример: + +```vue + + + + + + + +``` + +Результат (**предупреждение!**: мигающие цвета, резкие движения, яркий свет): + +
+Демонстрация + +![Демонстрация переходов](/appearance-toggle-transition.webp) + +
+ +Более подробно о переходах между представлениями читайте в [документации Chrome](https://developer.chrome.com/docs/web-platform/view-transitions/). + +### Изменение маршрута {#on-route-change} + +Скоро будет. + +## Переопределение внутренних компонентов {#overriding-internal-components} + +Вы можете использовать [псевдонимы](https://vitejs.dev/config/shared-options.html#resolve-alias) Vite, чтобы заменить стандартные компоненты темы на свои собственные: + +```ts +import { fileURLToPath, URL } from 'node:url' +import { defineConfig } from 'vitepress' + +export default defineConfig({ + vite: { + resolve: { + alias: [ + { + find: /^.*\/VPNavBar\.vue$/, + replacement: fileURLToPath( + new URL('./components/CustomNavBar.vue', import.meta.url) + ) + } + ] + } + } +}) +``` + +Чтобы узнать точное название компонента, обратитесь к [нашему исходному коду](https://github.com/vuejs/vitepress/tree/main/src/client/theme-default/components). Поскольку компоненты являются внутренними, есть небольшая вероятность того, что их название будет обновлено между минорными выпусками. diff --git a/docs/ru/guide/frontmatter.md b/docs/ru/guide/frontmatter.md new file mode 100644 index 00000000..967338f8 --- /dev/null +++ b/docs/ru/guide/frontmatter.md @@ -0,0 +1,48 @@ +# Метаданные {#frontmatter} + +## Использование {#usage} + +VitePress поддерживает метаданные YAML во всех Markdown-файлах, разбирая их с помощью [gray-matter](https://github.com/jonschlinkert/gray-matter). Метаданные должны находиться в верхней части Markdown-файла (перед любыми элементами, включая теги ` + + +``` + +## Поддержка RTL (экспериментально) {#rtl-support-experimental} + +Для поддержки языков с написанием справа налево укажите `dir: 'rtl'` в конфиге и используйте какой-нибудь плагин RTLCSS PostCSS, например , или . Вам нужно настроить плагин PostCSS на использование `:where([dir="ltr"])` и `:where([dir="rtl"])` в качестве префиксов, чтобы избежать проблем со спецификой CSS. diff --git a/docs/ru/guide/markdown.md b/docs/ru/guide/markdown.md new file mode 100644 index 00000000..05eb4ad3 --- /dev/null +++ b/docs/ru/guide/markdown.md @@ -0,0 +1,933 @@ +# Расширения Markdown {#markdown-extensions} + +VitePress поставляется со встроенными расширениями Markdown. + +## Якоря заголовков {#header-anchors} + +К заголовкам автоматически применяются якорные ссылки. Отрисовку якорей можно настроить с помощью опции `markdown.anchor`. + +### Пользовательские якоря {#custom-anchors} + +Чтобы указать пользовательский тег якоря для заголовка, а не использовать автоматически сгенерированный, добавьте суффикс к заголовку: + +``` +# Использование пользовательских якорей {#мой-якорь} +``` + +Это позволит вам ссылаться на заголовок как `#мой-якорь` вместо стандартного `#использование-пользовательских-якорей`. + +## Ссылки {#links} + +Особое внимание уделяется как внутренним, так и внешним ссылкам. + +### Внутренние ссылки {#internal-links} + +Внутренние ссылки преобразуются в ссылки маршрутизатора для навигации SPA. Кроме того, каждый `index.md`, содержащийся в каждом подкаталоге, будет автоматически преобразован в `index.html`, с соответствующим URL `/`. + +Например, при следующей структуре каталогов: + +``` +. +├─ index.md +├─ foo +│ ├─ index.md +│ ├─ one.md +│ └─ two.md +└─ bar + ├─ index.md + ├─ three.md + └─ four.md +``` + +И при условии, что вы находитесь в `foo/one.md`: + +```md +[Home](/) +[foo](/foo/) +[foo heading](./#heading) +[bar - three](../bar/three) +[bar - three](../bar/three.md) +[bar - four](../bar/four.html) +``` + +### Суффикс страницы {#page-suffix} + +Страницы и внутренние ссылки по умолчанию генерируются с суффиксом `.html`. + +### Внешние ссылки {#external-links} + +Исходящие ссылки автоматически получают значение `target="_blank" rel="noreferrer"`: + +- [vuejs.org](https://vuejs.org) +- [VitePress on GitHub](https://github.com/vuejs/vitepress) + +## Метаданные {#frontmatter} + +[Метаданные YAML](https://jekyllrb.com/docs/front-matter/) поддерживаются из коробки: + +```yaml +--- +title: Веду блог как хакер +lang: ru-RU +--- +``` + +Эти данные будут доступны остальной части страницы, а также всем пользовательским и тематическим компонентам. + +Более подробную информацию можно найти в главе [Метаданные](../reference/frontmatter-config). + +## Таблицы в стиле GitHub {#github-style-tables} + +**Разметка** + +```md +| Таблицы | это | круто | +| ---------------- | :----------------------: | ----: | +| столбец 3 | выровнен по правому краю | $1600 | +| столбец 2 | отцентрован | $12 | +| полосатые строки | как полоски у зебры | $1 | +``` + +**Результат** + +| Таблицы | это | круто | +| ---------------- | :----------------------: | -----: | +| столбец 3 | выровнен по правому краю | \$1600 | +| столбец 2 | отцентрован | \$12 | +| полосатые строки | как полоски у зебры | \$1 | + +## Эмодзи :tada: {#emoji} + +**Разметка** + +``` +:tada: :100: +``` + +**Результат** + +:tada: :100: + +[Список всех эмодзи](https://github.com/markdown-it/markdown-it-emoji/blob/master/lib/data/full.mjs). + +## Оглавление {#table-of-contents} + +**Разметка** + +``` +[[toc]] +``` + +**Результат** + +[[toc]] + +Отрисовка TOC может быть настроена с помощью опции `markdown.toc`. + +## Пользовательские контейнеры {#custom-containers} + +Пользовательские контейнеры можно определить по их типам, заголовкам и содержимому. + +### Заголовок по умолчанию {#default-title} + +**Разметка** + +```md +::: info +Это информация. +::: + +::: tip +Это совет. +::: + +::: warning +Это предупреждение. +::: + +::: danger +Это сигнал об опасности. +::: + +::: details +Это блок-спойлер. +::: +``` + +**Результат** + +::: info +Это информация. +::: + +::: tip +Это совет. +::: + +::: warning +Это предупреждение. +::: + +::: danger +Это сигнал об опасности. +::: + +::: details +Это блок-спойлер. +::: + +### Пользовательский заголовок {#custom-title} + +Вы можете задать собственный заголовок, добавив текст сразу после «типа» контейнера. + +**Разметка** + +````md +::: danger СТОП +Опасная зона, остановитесь +::: + +::: details Нажмите на меня, чтобы просмотреть код + +```js +console.log('Привет, VitePress!') +``` + +::: +```` + +**Результат** + +::: danger СТОП +Опасная зона, остановитесь +::: + +::: details Нажмите на меня, чтобы просмотреть код + +```js +console.log('Привет, VitePress!') +``` + +::: + +Кроме того, вы можете установить пользовательские заголовки глобально, добавив следующее содержимое в конфигурацию сайта, полезное, если вы пишете не на английском языке: + +```ts +// config.ts +export default defineConfig({ + // ... + markdown: { + container: { + tipLabel: 'СОВЕТ', + warningLabel: 'ПРЕДУПРЕЖДЕНИЕ', + dangerLabel: 'ОПАСНОСТЬ', + infoLabel: 'ИНФОРМАЦИЯ', + detailsLabel: 'Подробная информация' + } + } + // ... +}) +``` + +### `raw` {#raw} + +Это специальный контейнер, который можно использовать для предотвращения конфликтов стилей и маршрутизаторов с VitePress. Это особенно полезно при документировании библиотек компонентов. Вы также можете посмотреть [whyframe](https://whyframe.dev/docs/integrations/vitepress) для лучшей изоляции. + +**Syntax** + +```md +::: raw +Заворачивается в
+::: +``` + +Класс `vp-raw` можно использовать и непосредственно на элементах. Изоляция стиля в настоящее время осуществляется по желанию: + +- Установите `postcss` с помощью предпочитаемого менеджера пакетов: + + ```sh + $ npm add -D postcss + ``` + +- Создайте файл с именем `docs/postcss.config.mjs` и добавьте в него следующее: + + ```js + import { postcssIsolateStyles } from 'vitepress' + + export default { + plugins: [postcssIsolateStyles()] + } + ``` + + Он использует [`postcss-prefix-selector`](https://github.com/postcss/postcss-load-config) под капотом. Вы можете передать ему параметры следующим образом: + + ```js + postcssIsolateStyles({ + includeFiles: [/vp-doc\.css/] // по умолчанию /base\.css/ + }) + ``` + +## Оповещения в стиле GitHub {#github-flavored-alerts} + +VitePress также поддерживает [Оповещения в стиле GitHub](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts) для отображения в виде призывов. Они будут отображаться так же, как и [пользовательские контейнеры](#custom-containers). + +```md +> [!NOTE] +> Выделяет информацию, на которую пользователи должны обратить внимание, даже при беглом просмотре. + +> [!TIP] +> Дополнительная информация, которая поможет пользователю добиться большего успеха. + +> [!IMPORTANT] +> Важнейшая информация, необходимая пользователям для достижения успеха. + +> [!WARNING] +> Критический контент, требующий немедленного внимания пользователей из-за потенциальных рисков. + +> [!CAUTION] +> Негативные потенциальные последствия того или иного действия. +``` + +> [!NOTE] +> Выделяет информацию, на которую пользователи должны обратить внимание, даже при беглом просмотре. + +> [!TIP] +> Дополнительная информация, которая поможет пользователю добиться большего успеха. + +> [!IMPORTANT] +> Важнейшая информация, необходимая пользователям для достижения успеха. + +> [!WARNING] +> Критический контент, требующий немедленного внимания пользователей из-за потенциальных рисков. + +> [!CAUTION] +> Негативные потенциальные последствия того или иного действия. + +## Подсветка синтаксиса в блоках кода {#syntax-highlighting-in-code-blocks} + +VitePress использует [Shiki](https://github.com/shikijs/shiki) для выделения синтаксиса языка в блоках кода Markdown с помощью цветного текста. Shiki поддерживает широкий спектр языков программирования. Всё, что вам нужно сделать, это добавить правильный псевдоним языка к начальным значкам блока кода: + +**Разметка** + +```` +```js +export default { + name: 'MyComponent', + // ... +} +``` +```` + +```` +```html +
    +
  • + {{ todo.text }} +
  • +
+``` +```` + +**Результат** + +```js +export default { + name: 'MyComponent' + // ... +} +``` + +```html +
    +
  • {{ todo.text }}
  • +
+``` + +[Список всех поддерживаемых языков](https://shiki.style/languages). + +Вы также можете настроить тему подсветки синтаксиса в конфигурации приложения. Более подробную информацию см. в секции [`markdown`](../reference/site-config#markdown). + +## Выделение строк в блоках кода {#line-highlighting-in-code-blocks} + +**Разметка** + +```` +```js{4} +export default { + data () { + return { + msg: 'Подсвечено!' + } + } +} +``` +```` + +**Результат** + +```js{4} +export default { + data () { + return { + msg: 'Подсвечено!' + } + } +} +``` + +Помимо одной строки, вы можете указать несколько отдельных строк, диапазонов или и то, и другое: + +– Диапазоны строк, например: `{5-8}`, `{3-10}`, `{10-17}` + +- Несколько одиночных строк, например: `{4,7,9}` +- Диапазоны строк и отдельные строки, например: `{4,7-13,16,23-27,40}` + +**Разметка** + +```` +```js{1,4,6-8} +export default { // Подсвечено + data () { + return { + msg: `Подсвечено! + Эта строка не выделена, + но эта и две следующих - да.`, + motd: 'VitePress - это потрясающе', + lorem: 'ipsum' + } + } +} +``` +```` + +**Результат** + +```js{1,4,6-8} +export default { // Подсвечено + data () { + return { + msg: `Подсвечено! + Эта строка не выделена, + но эта и две следующих - да.`, + motd: 'VitePress - это потрясающе', + lorem: 'ipsum', + } + } +} +``` + +Кроме того, можно выделять непосредственно в строке, используя комментарий `// [!code highlight]`. + +**Разметка** + +```` +```js +export default { + data () { + return { + msg: 'Подсвечено!' // [!!code highlight] + } + } +} +``` +```` + +**Результат** + +```js +export default { + data() { + return { + msg: 'Подсвечено!' // [!code highlight] + } + } +} +``` + +## Фокус в блоках кода {#focus-in-code-blocks} + +Добавление комментария `// [!code focus]` к строке сфокусирует её и размоет остальные части кода. + +Кроме того, вы можете задать количество строк для фокусировки с помощью `// [!code focus:]`. + +**Разметка** + +```` +```js +export default { + data () { + return { + msg: 'Фокус!' // [!!code focus] + } + } +} +``` +```` + +**Результат** + +```js +export default { + data() { + return { + msg: 'Фокус!' // [!code focus] + } + } +} +``` + +## Подсветка различий в блоках кода {#colored-diffs-in-code-blocks} + +Добавление в строку комментариев `// [!code --]` или `// [!code ++]` создаст diff этой строки, сохраняя цвета блока кода. + +**Разметка** + +```` +```js +export default { + data () { + return { + msg: 'Удалено' // [!!code --] + msg: 'Добавлено' // [!!code ++] + } + } +} +``` +```` + +**Результат** + +```js +export default { + data () { + return { + msg: 'Удалено' // [!code --] + msg: 'Добавлено' // [!code ++] + } + } +} +``` + +## Ошибки и предупреждения в блоках кода {#errors-and-warnings-in-code-blocks} + +Добавление в строку комментариев `// [!code warning]` или `// [!code error]` окрасит её соответствующим образом. + +**Разметка** + +```` +```js +export default { + data () { + return { + msg: 'Ошибка', // [!!code error] + msg: 'Предупреждение' // [!!code warning] + } + } +} +``` +```` + +**Результат** + +```js +export default { + data() { + return { + msg: 'Ошибка', // [!code error] + msg: 'Предупреждение' // [!code warning] + } + } +} +``` + +## Номера строк {#line-numbers} + +Вы можете включить нумерацию строк для каждого блока кода в конфигурации: + +```js +export default { + markdown: { + lineNumbers: true + } +} +``` + +Более подробную информацию см. в секции [`markdown`](../reference/site-config#markdown). + +Вы можете добавить метки `:line-numbers` / `:no-line-numbers` в ваши ограждённые блоки кода, чтобы переопределить значение, установленное в конфиге. + +Вы также можете настроить номер начальной строки, добавив `=` после `:line-numbers`. Например, `:line-numbers=2` означает, что номера строк в блоках кода будут начинаться с `2`. + +**Разметка** + +````md +```ts {1} +// опция line-numbers по умолчанию отключена +const line2 = 'Строка 2' +const line3 = 'Строка 3' +``` + +```ts:line-numbers {1} +// опция line-numbers включена +const line2 = 'Строка 2' +const line3 = 'Строка 3' +``` + +```ts:line-numbers=2 {1} +// опция line-numbers включена, нумерация начинается с 2 +const line3 = 'Строка 3' +const line4 = 'Строка 4' +``` +```` + +**Результат** + +```ts {1} +// опция line-numbers по умолчанию отключена +const line2 = 'Строка 2' +const line3 = 'Строка 3' +``` + +```ts:line-numbers {1} +// опция line-numbers включена +const line2 = 'Строка 2' +const line3 = 'Строка 3' +``` + +```ts:line-numbers=2 {1} +// опция line-numbers включена, нумерация начинается с 2 +const line3 = 'Строка 3' +const line4 = 'Строка 4' +``` + +## Импорт фрагментов кода {#import-code-snippets} + +Вы можете импортировать фрагменты кода из существующих файлов, используя следующий синтаксис: + +```md +<<< @/filepath +``` + +[Выделение строк](#line-highlighting-in-code-blocks) тоже поддерживается: + +```md +<<< @/filepath{highlightLines} +``` + +**Разметка** + +```md +<<< @/snippets/snippet.js{2} +``` + +**Файл с кодом** + +<<< @/snippets/snippet.js + +**Результат** + +<<< @/snippets/snippet.js{2} + +::: tip СОВЕТ +Значение `@` соответствует корню источника. По умолчанию это корень проекта VitePress, если не настроен `srcDir`. Альтернативно вы также можете импортировать из относительных путей: + +```md +<<< ../snippets/snippet.js +``` + +::: + +Вы также можете использовать [регион VS Code](https://code.visualstudio.com/docs/editor/codebasics#_folding), чтобы включить только соответствующую часть файла кода. Имя пользовательского региона начинается с `#` после пути к файлу: + +**Разметка** + +```md +<<< @/snippets/snippet-with-region.js#snippet{1} +``` + +**Файл с кодом** + +<<< @/snippets/snippet-with-region.js + +**Результат** + +<<< @/snippets/snippet-with-region.js#snippet{1} + +Вы также можете указать язык внутри фигурных скобок (`{}`) следующим образом: + +```md +<<< @/snippets/snippet.cs{c#} + + + +<<< @/snippets/snippet.cs{1,2,4-6 c#} + + + +<<< @/snippets/snippet.cs{1,2,4-6 c#:line-numbers} +``` + +Это полезно, если исходный язык нельзя определить по расширению вашего файла. + +## Группы кодов {#code-groups} + +Вы можете сгруппировать несколько блоков кода следующим образом: + +**Разметка** + +````md +::: code-group + +```js [config.js] +/** + * @type {import('vitepress').UserConfig} + */ +const config = { + // ... +} + +export default config +``` + +```ts [config.ts] +import type { UserConfig } from 'vitepress' + +const config: UserConfig = { + // ... +} + +export default config +``` + +::: +```` + +**Результат** + +::: code-group + +```js [config.js] +/** + * @type {import('vitepress').UserConfig} + */ +const config = { + // ... +} + +export default config +``` + +```ts [config.ts] +import type { UserConfig } from 'vitepress' + +const config: UserConfig = { + // ... +} + +export default config +``` + +::: + +Вы также можете [импортировать фрагменты](#import-code-snippets) в группы кода: + +**Разметка** + +```md +::: code-group + + + +<<< @/snippets/snippet.js + + + +<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [фрагмент с регионом] + +::: +``` + +**Результат** + +::: code-group + +<<< @/snippets/snippet.js + +<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [фрагмент с регионом] + +::: + +## Включение файла Markdown {#markdown-file-inclusion} + +Вы можете включить файл Markdown в другой файл Markdown, даже вложенный. + +::: tip СОВЕТ +Вы также можете добавить в префикс пути к Markdown символ `@`, он будет выступать в качестве корня источника. По умолчанию это корень проекта VitePress, если не настроена опция `srcDir`. +::: + +Например, вы можете включить относительный файл Markdown следующим образом: + +**Разметка** + +```md +# Документация + +## Основы + + +``` + +**Файл части** (`parts/basics.md`) + +```md +Некоторые вещи для начала. + +### Конфигурация + +Может быть создана с помощью `.foorc.json`. +``` + +**Эквивалентный код** + +```md +# Документация + +## Основы + +Некоторые вещи для начала. + +### Конфигурация + +Может быть создана с помощью `.foorc.json`. +``` + +Он также поддерживает выбор диапазона строк: + +**Разметка** + +```md +# Документация + +## Основы + + +``` + +**Файл части** (`parts/basics.md`) + +```md +Некоторые вещи для начала. + +### Конфигурация + +Может быть создана с помощью `.foorc.json`. +``` + +**Эквивалентный код** + +```md +# Документация + +## Основы + +### Конфигурация + +Может быть создана с помощью `.foorc.json`. +``` + +Формат выбранного диапазона строк может быть следующим: `{3,}`, `{,10}`, `{1,10}` + +::: warning ПРЕДУПРЕЖДЕНИЕ +Обратите внимание, что это не приводит к ошибкам, если ваш файл отсутствует. Поэтому при использовании этой функции убедитесь, что содержимое отображается так, как ожидается. +::: + +## Математические уравнения {#math-equations} + +В настоящее время эта фича предоставляется по желанию. Чтобы включить её, вам нужно установить `markdown-it-mathjax3` и установить значение `true` для опции `markdown.math` в вашем файле конфигурации: + +```sh +npm add -D markdown-it-mathjax3 +``` + +```ts +// .vitepress/config.ts +export default { + markdown: { + math: true + } +} +``` + +**Разметка** + +```md +Когда $a \ne 0$, существует два решения $(ax^2 + bx + c = 0)$: +$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$ + +**Уравнения Максвелла:** + +| уравнение | описание | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | +| $\nabla \cdot \vec{\mathbf{B}} = 0$ | дивергенция $\vec{\mathbf{B}}$ равна нулю | +| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | искривление $\vec{\mathbf{E}}$ пропорционально скорости изменения $\vec{\mathbf{B}}$ | +| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _что?_ | +``` + +**Результат** + +Когда $a \ne 0$, существует два решения $(ax^2 + bx + c = 0)$: +$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$ + +**Уравнения Максвелла:** + +| уравнение | описание | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | +| $\nabla \cdot \vec{\mathbf{B}} = 0$ | дивергенция $\vec{\mathbf{B}}$ равна нулю | +| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | искривление $\vec{\mathbf{E}}$ пропорционально скорости изменения $\vec{\mathbf{B}}$ | +| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _что?_ | + +## Ленивая загрузка изображений {#image-lazy-loading} + +Вы можете включить ленивую загрузку для каждого изображения, добавленного через markdown, установив значение `true` для опции `lazyLoading` в вашем файле конфигурации: + +```js +export default { + markdown: { + image: { + // ленивая загрузка изображений отключена по умолчанию + lazyLoading: true + } + } +} +``` + +## Расширенная конфигурация {#advanced-configuration} + +VitePress использует [markdown-it](https://github.com/markdown-it/markdown-it) для отрисовки Markdown. Многие из вышеперечисленных расширений реализованы с помощью пользовательских плагинов. Вы можете дополнительно настроить экземпляр `markdown-it` с помощью опции `markdown` в файле `.vitepress/config.js`: + +```js +import { defineConfig } from 'vitepress' +import markdownItAnchor from 'markdown-it-anchor' +import markdownItFoo from 'markdown-it-foo' + +export default defineConfig({ + markdown: { + // опции для markdown-it-anchor + // https://github.com/valeriangalliat/markdown-it-anchor#usage + anchor: { + permalink: markdownItAnchor.permalink.headerLink() + }, + + // опции для @mdit-vue/plugin-toc + // https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options + toc: { level: [1, 2] }, + + config: (md) => { + // используйте любые плагины для markdown-it! + md.use(markdownItFoo) + } + } +}) +``` + +Полный список настраиваемых свойств см. в секции [`markdown`](../reference/site-config#markdown). diff --git a/docs/ru/guide/migration-from-vitepress-0.md b/docs/ru/guide/migration-from-vitepress-0.md new file mode 100644 index 00000000..4d5c7426 --- /dev/null +++ b/docs/ru/guide/migration-from-vitepress-0.md @@ -0,0 +1,23 @@ +# Переход с VitePress 0.x + +Если вы переходите с версии VitePress 0.x, то в ней есть несколько изменений, связанных с новыми функциями и улучшениями. Следуйте этому руководству, чтобы узнать, как перенести ваше приложение на последнюю версию VitePress. + +## Конфигурация приложения + +- Функция интернационализации ещё не реализована. + +## Конфигурация темы + +- Опция `sidebar` изменила свою структуру. + - Ключ `children` теперь называется `items`. + - Элемент верхнего уровня может не содержать `link` в данный момент. Мы планируем вернуть его обратно. +- `repo`, `repoLabel`, `docsDir`, `docsBranch`, `editLinks`, `editLinkText` удалены в пользу более гибкого api. + - Для добавления ссылки GitHub с иконкой в навигацию используйте функцию [Социальные ссылки](../reference/default-theme-nav#navigation-links). + - Для добавления ссылки «Редактировать эту страницу» используйте функцию [Ссылка для редактирования](../reference/default-theme-edit-link). +- Опция `lastUpdated` теперь разделена на `config.lastUpdated` и `themeConfig.lastUpdatedText`. +- Опция `carbonAds.carbon` заменена на `carbonAds.code`. + +## Конфигурация метаданных + +- Опция `home: true` заменена на `layout: home`. Кроме того, многие настройки, связанные с главной страницей, были изменены для обеспечения дополнительных возможностей. Подробности см. в разделе [Главная страница](../reference/default-theme-home-page). +- Опция `footer` перенесена в [`themeConfig.footer`](../reference/default-theme-config#footer). diff --git a/docs/ru/guide/migration-from-vuepress.md b/docs/ru/guide/migration-from-vuepress.md new file mode 100644 index 00000000..afacc630 --- /dev/null +++ b/docs/ru/guide/migration-from-vuepress.md @@ -0,0 +1,30 @@ +# Переход с VuePress + +## Конфигурация + +### Сайдбар + +Боковая панель больше не заполняется автоматически из метаданных. Вы можете [самостоятельно прочитать вступление](https://github.com/vuejs/vitepress/issues/572#issuecomment-1170116225), чтобы научиться динамически заполнять боковую панель. [Дополнительные утилиты для этого](https://github.com/vuejs/vitepress/issues/96) могут быть предоставлены в будущем. + +## Markdown + +### Изображения + +В отличие от VuePress, VitePress автоматически обрабатывает опцию [`base`](./asset-handling#base-url) вашего конфига, когда вы используете статическое изображение. + +Таким образом, теперь вы можете выводить изображения без тега `img`. + +```diff +- foo ++ ![foo](/foo.png) +``` + +::: warning ПРЕДУПРЕЖДЕНИЕ +Для динамических изображений вам всё ещё нужно использовать `withBase`, как показано в [Руководстве по базовому URL](./asset-handling#base-url). +::: + +Используйте регулярное выражение `` для поиска всех изображений с синтаксисом `![](...)` и замены на `![$2]($1)`. + +--- + +продолжение следует... diff --git a/docs/ru/guide/mpa-mode.md b/docs/ru/guide/mpa-mode.md new file mode 100644 index 00000000..81843708 --- /dev/null +++ b/docs/ru/guide/mpa-mode.md @@ -0,0 +1,23 @@ +# Режим MPA {#mpa-mode} + +Режим MPA (Multi-Page Application — «Многостраничное приложение») можно включить через командную строку с помощью команды `vitepress build --mpa`, или через конфигурацию с помощью опции `mpa: true`. + +В режиме MPA все страницы по умолчанию отображаются без включенного JavaScript. В результате производственный сайт, скорее всего, получит более высокую оценку эффективности первых посещений с помощью инструментов аудита. + +Однако из-за отсутствия навигации SPA межстраничные ссылки будут приводить к полной перезагрузке страницы. После загрузки навигация в режиме MPA будет не такой мгновенной, как в режиме SPA. + +Также обратите внимание, что «no-JS-by-default» («без JS по умолчанию») означает, что вы используете Vue исключительно как серверный язык шаблонов. Никаких обработчиков событий в браузере не будет, поэтому интерактивности не будет. Чтобы загрузить JavaScript со стороны клиента, вам нужно использовать специальный тег ` + +# Привет +``` + +` +``` + +### Рендеринг необработанного содержимого {#rendering-raw-content} + +Параметры, передаваемые странице, будут сериализованы в полезной нагрузке клиентского JavaScript, поэтому вам следует избегать передачи в параметрах больших объемов данных, например, необработанного Markdown или HTML-контента, полученного из удаленной CMS. + +Вместо этого вы можете передавать такое содержимое на каждую страницу с помощью свойства `content` каждого объекта path: + +```js +export default { + async paths() { + const posts = await (await fetch('https://my-cms.com/blog-posts')).json() + + return posts.map((post) => { + return { + params: { id: post.id }, + content: post.content // необработанный Markdown или HTML + } + }) + } +} +``` + +Затем используйте следующий специальный синтаксис, чтобы отобразить содержимое как часть самого файла Markdown: + +```md + +``` diff --git a/docs/ru/guide/sitemap-generation.md b/docs/ru/guide/sitemap-generation.md new file mode 100644 index 00000000..da79a5be --- /dev/null +++ b/docs/ru/guide/sitemap-generation.md @@ -0,0 +1,53 @@ +# Генерация карты сайта {#sitemap-generation} + +VitePress поставляется с готовой поддержкой генерации файла `sitemap.xml` для вашего сайта. Чтобы включить её, добавьте следующее в файл `.vitepress/config.js`: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + sitemap: { + hostname: 'https://example.com' + } +}) +``` + +Чтобы теги `` присутствовали в вашем файле `sitemap.xml`, вы можете включить опцию [`lastUpdated`](../reference/default-theme-last-updated). + +## Параметры {#options} + +Поддержка карты сайта осуществляется с помощью модуля [`sitemap`](https://www.npmjs.com/package/sitemap). Вы можете передать любые поддерживаемые им параметры в опцию `sitemap` в вашем конфигурационном файле. Они будут переданы непосредственно в конструктор `SitemapStream`. Более подробную информацию см. в документации [`sitemap`](https://www.npmjs.com/package/sitemap#options-you-can-pass). Пример: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + sitemap: { + hostname: 'https://example.com', + lastmodDateOnly: false + } +}) +``` + +## Хук `transformItems` {#transformitems-hook} + +Вы можете использовать хук `sitemap.transformItems` для изменения элементов карты сайта перед их записью в файл `sitemap.xml`. Этот хук вызывается с массивом элементов sitemap и ожидает возвращения массива элементов sitemap. Пример: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + sitemap: { + hostname: 'https://example.com', + transformItems: (items) => { + // добавляем новые элементы или изменяем/фильтруем существующие + items.push({ + url: '/extra-page', + changefreq: 'monthly', + priority: 0.8 + }) + return items + } + } +}) +``` diff --git a/docs/ru/guide/ssr-compat.md b/docs/ru/guide/ssr-compat.md new file mode 100644 index 00000000..fd8c6ae8 --- /dev/null +++ b/docs/ru/guide/ssr-compat.md @@ -0,0 +1,137 @@ +--- +outline: deep +--- + +# Совместимость с SSR {#ssr-compatibility} + +VitePress предварительно рендерит приложение в Node.js во время производственной сборки, используя возможности Vue по рендерингу на стороне сервера (SSR). Это означает, что весь пользовательский код в компонентах темы подлежит проверке на совместимость с SSR. + +Глава [Рендеринг на стороне сервера](https://ru.vuejs.org/guide/scaling-up/ssr.html) в документации Vue содержит более подробную информацию о том, что такое SSR, взаимосвязь между SSR и SSG, а также общие указания по написанию кода, дружественного к SSR. Правило заключается в том, чтобы обращаться к API браузера / DOM только в хуках `beforeMount` или `mounted` компонентов Vue. + +## `` {#clientonly} + +Если вы используете или демонстрируете компоненты, которые не являются SSR-дружественными (например, содержат пользовательские директивы), вы можете обернуть их внутри встроенного компонента ``: + +```md + + + +``` + +## Библиотеки, обращающиеся к API браузера при импорте {#libraries-that-access-browser-api-on-import} + +Некоторые компоненты или библиотеки получают доступ к API браузера **при импорте**. Чтобы использовать код, предполагающий наличие среды браузера при импорте, необходимо динамически импортировать их. + +### Импорт в хуке `onMounted` {#importing-in-mounted-hook} + +```vue + +``` + +### Условный импорт {#conditional-import} + +Вы также можете условно импортировать зависимость с помощью флага `import.meta.env.SSR` (часть [env-переменных Vite](https://vitejs.dev/guide/env-and-mode.html#env-variables)): + +```js +if (!import.meta.env.SSR) { + import('./lib-that-access-window-on-import').then((module) => { + // используем код + }) +} +``` + +Поскольку [`Theme.enhanceApp`](./custom-theme#theme-interface) может быть асинхронным, вы можете условно импортировать и регистрировать плагины Vue, которые получают доступ к API браузера при импорте: + +```js +// .vitepress/theme/index.js +/** @type {import('vitepress').Theme} */ +export default { + // ... + async enhanceApp({ app }) { + if (!import.meta.env.SSR) { + const plugin = await import('plugin-that-access-window-on-import') + app.use(plugin.default) + } + } +} +``` + +Если вы используете TypeScript: + +```ts +// .vitepress/theme/index.ts +import type { Theme } from 'vitepress' + +export default { + // ... + async enhanceApp({ app }) { + if (!import.meta.env.SSR) { + const plugin = await import('plugin-that-access-window-on-import') + app.use(plugin.default) + } + } +} satisfies Theme +``` + +### `defineClientComponent` {#defineclientcomponent} + +VitePress предоставляет удобный помощник для импорта компонентов Vue, которые получают доступ к API браузера при импорте. + +```vue + + + +``` + +Вы также можете передавать параметры/дочерние элементы/слоты целевому компоненту: + +```vue + + + +``` + +Целевой компонент будет импортирован только в смонтированный хук компонента-обёртки. diff --git a/docs/ru/guide/using-vue.md b/docs/ru/guide/using-vue.md new file mode 100644 index 00000000..4a4c830f --- /dev/null +++ b/docs/ru/guide/using-vue.md @@ -0,0 +1,253 @@ +# Использование Vue в Markdown {#using-vue-in-markdown} + +В VitePress каждый Markdown-файл компилируется в HTML, а затем обрабатывается как [однофайловый компонент Vue](https://ru.vuejs.org/guide/scaling-up/sfc.html). Это означает, что вы можете использовать любые возможности Vue внутри Markdown, включая динамический шаблонизатор, использование компонентов Vue или произвольную логику компонентов Vue на странице, добавив тег ` + +## Содержание в формате Markdown. Счётчик: {{ count }} + + + + +``` + +::: warning Избегайте ` +``` + +## Использование телепортов {#using-teleports} + +В настоящее время Vitepress поддерживает SSG только для телепортов к элементу `body`. Для других целей вы можете обернуть их внутри встроенного компонента `` или внедрить разметку телепортации в нужное место HTML конечной страницы через [хук `postRender`](../reference/site-config#postrender). + + + +::: details Исходный код +<<< @/ru/components/ModalDemo.vue +::: + +```md + + +
+ // ... +
+
+
+``` + + + + diff --git a/docs/ru/guide/what-is-vitepress.md b/docs/ru/guide/what-is-vitepress.md new file mode 100644 index 00000000..1bcc3e18 --- /dev/null +++ b/docs/ru/guide/what-is-vitepress.md @@ -0,0 +1,57 @@ +# Что такое VitePress? {#what-is-vitepress} + +VitePress — это [Генератор статических сайтов](https://en.wikipedia.org/wiki/Static_site_generator) (ГСС), предназначенный для быстрого создания сайтов, ориентированных на контент. В двух словах, VitePress берёт ваш исходный контент, написанный в [Markdown](https://ru.wikipedia.org/wiki/Markdown), применяет к нему тему и генерирует статические HTML-страницы, которые можно легко развернуть в любом месте. + +
+ +Хотите попробовать прямо сейчас? Перейдите к главе [Первые шаги](./getting-started). + +
+ +## Примеры использования {#use-cases} + +- **Документация** + + VitePress поставляется с темой по умолчанию, предназначенной для технической документации. Она содержит эту страницу, которую вы сейчас читаете, а также документацию по [Vite](https://vitejs.dev/), [Rollup](https://rollupjs.org/), [Pinia](https://pinia.vuejs.org/), [VueUse](https://vueuse.org/), [Vitest](https://vitest.dev/), [D3](https://d3js.org/), [UnoCSS](https://unocss.dev/), [Iconify](https://iconify.design/) и [многое другое](https://www.vuetelescope.com/explore?framework.slug=vitepress). + + [Официальная документация Vue.js](https://vuejs.org/) также основана на VitePress, но использует пользовательскую тему, разделяемую между несколькими переводами. + +- **Блоги, портфолио и маркетинговые сайты** + + VitePress поддерживает [полностью кастомизированные темы](./custom-theme), при этом разработчики могут использовать стандартное приложение Vite + Vue. То, что он построен на базе Vite, также означает, что вы можете напрямую использовать плагины Vite из его богатой экосистемы. Кроме того, VitePress предоставляет гибкие API для [загрузки данных](./data-loading) (локальной или удаленной) и [динамической генерации маршрутов](./routing#dynamic-routes). С его помощью можно построить практически всё, что угодно, если данные могут быть определены во время сборки. + + Официальный [блог Vue.js](https://blog.vuejs.org/) — это простой блог, который генерирует свою индексную страницу на основе локального контента. + +## Опыт разработчика {#developer-experience} + +VitePress стремится обеспечить отличные возможности для разработчиков при работе с содержимым в формате Markdown. + +- **[На базе Vite:](https://vitejs.dev/)** мгновенный запуск сервера, правки всегда отражаются мгновенно (<100 мс) без перезагрузки страницы. + +- **[Встроенные расширения Markdown:](./markdown)** Frontmatter, таблицы, подсветка синтаксиса... называйте как хотите. В частности, VitePress предоставляет множество расширенных возможностей для работы с блоками кода, что делает его идеальным для создания технической документации. + +- **[Markdown с возможностями Vue:](./using-vue)** каждая Markdown-страница также является [однофайловым компонентом](https://ru.vuejs.org/guide/scaling-up/sfc.html) Vue, благодаря 100% синтаксической совместимости шаблона Vue с HTML. Вы можете внедрить интерактивность в статический контент, используя шаблонизаторы Vue или импортированные компоненты Vue. + +## Производительность {#performance} + +В отличие от многих традиционных ГСС, где каждая навигация приводит к полной перезагрузке страницы, сайт, созданный VitePress, обслуживает статический HTML при первом посещении, но становится [Одностраничным приложением](https://ru.wikipedia.org/wiki/%D0%9E%D0%B4%D0%BD%D0%BE%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5) (SPA) для последующей навигации по сайту. Эта модель, на наш взгляд, обеспечивает оптимальный баланс производительности: + +- **Быстрая начальная загрузка** + + При первом посещении любой страницы будет использоваться статичный, предварительно отрендеренный HTML для быстрой загрузки и оптимального SEO. Затем на страницу загружается пакет JavaScript, который превращает страницу в Vue SPA («гидратация»). Вопреки распространённому мнению о медленной гидратации SPA, этот процесс на самом деле чрезвычайно быстр благодаря высокой производительности Vue 3 и оптимизациям компилятора. По данным [PageSpeed Insights](https://pagespeed.web.dev/report?url=https%3A%2F%2Fvitepress.dev%2F), типичные сайты VitePress достигают почти идеальных показателей производительности даже на мобильных устройствах с низкой скоростью передачи данных. + +- **Быстрая навигация после загрузки** + + Что ещё более важно, модель SPA приводит к улучшению пользовательского опыта **после** первоначальной загрузки. Последующая навигация по сайту больше не будет приводить к полной перезагрузке страницы. Вместо этого содержимое входящей страницы будет получено и динамически обновлено. VitePress также автоматически выполняет предварительную выборку фрагментов страницы для ссылок, которые находятся в пределах области просмотра. В большинстве случаев навигация после загрузки будет ощущаться мгновенно. + +- **Интерактивность без штрафов** + + Для того чтобы динамические части Vue, встроенные в статический Markdown, могли работать в режиме гидратации, каждая страница Markdown обрабатывается как компонент Vue и компилируется в JavaScript. Это может показаться неэффективным, но компилятор Vue достаточно умён, чтобы разделить статическую и динамическую части, минимизируя как стоимость гидратации, так и размер полезной нагрузки. При первоначальной загрузке страницы статические части автоматически исключаются из полезной нагрузки JavaScript и пропускаются во время гидратации. + +## Что насчёт VuePress? {#what-about-vuepress} + +VitePress — это духовный наследник VuePress. Оригинальный VuePress был основан на Vue 2 и webpack. Благодаря Vue 3 и Vite под капотом, VitePress обеспечивает значительно лучший опыт разработки, лучшую производительность, более отточенную тему по умолчанию и более гибкий API для настройки. + +Разница в API между VitePress и VuePress заключается в основном в тематическом оформлении и настройке. Если вы используете VuePress 1 с темой по умолчанию, то переход на VitePress будет относительно простым. + +Также были приложены усилия для создания VuePress 2, который также поддерживает Vue 3 и Vite с большей совместимостью с VuePress 1. Однако поддерживать два генератора параллельно не представляется возможным, поэтому команда Vue решила сосредоточиться на VitePress как основном рекомендуемом генераторе статических сайтов в долгосрочной перспективе. diff --git a/docs/ru/index.md b/docs/ru/index.md new file mode 100644 index 00000000..5d2e52e5 --- /dev/null +++ b/docs/ru/index.md @@ -0,0 +1,60 @@ +--- +layout: home + +title: VitePress +titleTemplate: Генератор статических сайтов на основе Vite и Vue + +hero: + name: VitePress + text: Генератор статических сайтов на основе Vite и Vue + tagline: Из Markdown в красивую документацию за считанные минуты + actions: + - theme: brand + text: Что такое VitePress? + link: /ru/guide/what-is-vitepress + - theme: alt + text: Первые шаги + link: /ru/guide/getting-started + - theme: alt + text: GitHub + link: https://github.com/vuejs/vitepress + image: + src: /vitepress-logo-large.webp + alt: VitePress + +features: + - icon: 📝 + title: Сосредоточьтесь на своем контенте + details: Легко создавайте красивые сайты с документацией, используя только Markdown. + - icon: + title: Наслаждайтесь опытом разработчиков Vite + details: Мгновенный запуск сервера, молниеносные горячие обновления и использование плагинов экосистемы Vite. + - icon: + title: Настройка с помощью Vue + details: Используйте синтаксис Vue и компоненты прямо в Markdown или создавайте собственные темы с помощью Vue. + - icon: 🚀 + title: Быстрый запуск веб-сайтов + details: Быстрая начальная загрузка с помощью статического HTML, быстрая навигация после загрузки с помощью маршрутизации на стороне клиента. +--- + + diff --git a/docs/ru/reference/cli.md b/docs/ru/reference/cli.md new file mode 100644 index 00000000..93954da2 --- /dev/null +++ b/docs/ru/reference/cli.md @@ -0,0 +1,74 @@ +# Интерфейс командной строки {#command-line-interface} + +## `vitepress dev` {#vitepress-dev} + +Запуск сервера разработки VitePress, с использованием указанного каталога в качестве корневого. По умолчанию используется текущий каталог. Команду `dev` также можно опустить при работе в текущем каталоге. + +### Использование {#usage} + +```sh +# запуск в текущем каталоге, опускаем `dev` +vitepress + +# запуск в подкаталоге +vitepress dev [root] +``` + +### Параметры {#options} + +| Параметр | Описание | +| --------------- | ------------------------------------------------------------------------------ | +| `--open [path]` | Открытие браузера при запуске (`boolean \| string`) | +| `--port ` | Номер порта (`number`) | +| `--base ` | Публичный базовый путь (по умолчанию: `/`) (`string`) | +| `--cors` | Включить CORS | +| `--strictPort` | Выйти, если указанный порт уже используется (`boolean`) | +| `--force` | Заставить оптимизатор игнорировать кэш и повторно объединять файлы (`boolean`) | + +## `vitepress build` {#vitepress-build} + +Создание производственной сборки текущего сайта VitePress. + +### Использование {#usage-1} + +```sh +vitepress build [root] +``` + +### Параметры {#options-1} + +| Параметр | Описание | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | +| `--mpa` (экспериментально) | Сборка в режиме [MPA](../guide/mpa-mode) без гидратации на стороне клиента (`boolean`) | +| `--base ` | Публичный базовый путь (по умолчанию: `/`) (`string`) | +| `--target ` | Транспилировать цель (по умолчанию: `"modules"`) (`string`) | +| `--outDir ` | Выходной каталог относительно **cwd** (по умолчанию: `/.vitepress/dist`) (`string`) | +| `--minify [minifier]` | Включить/выключить минификацию или задать используемый минификатор (по умолчанию: `"esbuild"`) (`boolean \| "terser" \| "esbuild"`) | +| `--assetsInlineLimit ` | Статический встроенный порог ресурса base64 в байтах (по умолчанию: `4096`) (`number`) | + +## `vitepress preview` {#vitepress-preview} + +Локальный предварительный просмотр производственной сборки. + +### Использование {#usage-2} + +```sh +vitepress preview [root] +``` + +### Параметры {#options-2} + +| Параметр | Описание | +| --------------- | ----------------------------------------------------- | +| `--base ` | Публичный базовый путь (по умолчанию: `/`) (`string`) | +| `--port ` | Номер порта (`number`) | + +## `vitepress init` {#vitepress-init} + +Запуск [Мастера настройки](../guide/getting-started#setup-wizard) в текущем каталоге. + +### Использование {#usage-3} + +```sh +vitepress init +``` diff --git a/docs/ru/reference/default-theme-badge.md b/docs/ru/reference/default-theme-badge.md new file mode 100644 index 00000000..fc546436 --- /dev/null +++ b/docs/ru/reference/default-theme-badge.md @@ -0,0 +1,72 @@ +# Значки {#badge} + +С помощью значков удобно добавлять статус к заголовкам. Например, может быть полезно указать тип раздела или поддерживаемую версию. + +## Использование {#usage} + +Вы можете использовать компонент `Badge`, который доступен глобально. + +```html +### Заголовок ### Заголовок + ### Заголовок + ### Заголовок + +``` + +Приведённый выше код даёт такой результат: + +### Заголовок {#title} + +### Заголовок {#title-1} + +### Заголовок {#title-2} + +### Заголовок {#title-3} + +## Дочерние элементы {#custom-children} + +`` принимает параметр `children`, который будет отображаться внутри значка. + +```html +### Заголовок вложенный элемент +``` + +### Заголовок вложенный элемент + +## Настройка стиля значков {#customize-type-color} + +Вы можете настроить стиль значков, переопределив переменные CSS. Ниже приведены значения по умолчанию: + +```css +:root { + --vp-badge-info-border: transparent; + --vp-badge-info-text: var(--vp-c-text-2); + --vp-badge-info-bg: var(--vp-c-default-soft); + + --vp-badge-tip-border: transparent; + --vp-badge-tip-text: var(--vp-c-brand-1); + --vp-badge-tip-bg: var(--vp-c-brand-soft); + + --vp-badge-warning-border: transparent; + --vp-badge-warning-text: var(--vp-c-warning-1); + --vp-badge-warning-bg: var(--vp-c-warning-soft); + + --vp-badge-danger-border: transparent; + --vp-badge-danger-text: var(--vp-c-danger-1); + --vp-badge-danger-bg: var(--vp-c-danger-soft); +} +``` + +## `` {#badge-1} + +Компонент `` принимает следующие параметры: + +```ts +interface Props { + // Когда передается ``, это значение игнорируется. + text?: string + + // По умолчанию: `tip`. + type?: 'info' | 'tip' | 'warning' | 'danger' +} +``` diff --git a/docs/ru/reference/default-theme-carbon-ads.md b/docs/ru/reference/default-theme-carbon-ads.md new file mode 100644 index 00000000..457b92b1 --- /dev/null +++ b/docs/ru/reference/default-theme-carbon-ads.md @@ -0,0 +1,22 @@ +# Carbon Ads {#carbon-ads} + +В VitePress встроена встроенная поддержка [Carbon Ads](https://www.carbonads.net/). Определив в конфиге учётные данные Carbon Ads, VitePress будет отображать рекламу на странице. + +```js +export default { + themeConfig: { + carbonAds: { + code: 'код-рекламы', + placement: 'место-размещения-рекламы' + } + } +} +``` + +Эти значения используются для вызова сценария carbon CDN, как показано ниже: + +```js +;`//cdn.carbonads.com/carbon.js?serve=${code}&placement=${placement}` +``` + +Чтобы узнать больше о конфигурации Carbon Ads, посетите [веб-сайт Carbon Ads](https://www.carbonads.net/). diff --git a/docs/ru/reference/default-theme-config.md b/docs/ru/reference/default-theme-config.md new file mode 100644 index 00000000..265d17f1 --- /dev/null +++ b/docs/ru/reference/default-theme-config.md @@ -0,0 +1,452 @@ +# Настройка темы по умолчанию {#default-theme-config} + +Конфигурация темы позволяет настроить её под себя. Вы можете настроить тему с помощью опции `themeConfig` в файле конфигурации: + +```ts +export default { + lang: 'ru-RU', + title: 'VitePress', + description: 'Генератор статического сайта на базе Vite и Vue.', + + // Конфигурации, связанные с темой. + themeConfig: { + logo: '/logo.svg', + nav: [...], + sidebar: { ... } + } +} +``` + +**Параметры, описанные на этой странице, применимы только к теме по умолчанию.** Разные темы предполагают разные конфигурации темы. При использовании пользовательской темы объект конфигурации темы будет передан теме, чтобы она могла определить условное поведение на его основе. + +## i18nRouting {#i18nrouting} + +- Тип: `boolean` + +При смене локали на `ru` URL изменится с `/foo` (или `/en/foo/`) на `/ru/foo`. Вы можете отключить это поведение, установив для параметра `themeConfig.i18nRouting` значение `false`. + +## logo {#logo} + +- Тип: `ThemeableImage` + +Файл логотипа для отображения в навигационной панели, прямо перед заголовком сайта. Принимает строку пути или объект, чтобы установить другой логотип для светлого/тёмного режима. + +```ts +export default { + themeConfig: { + logo: '/logo.svg' + } +} +``` + +```ts +type ThemeableImage = + | string + | { src: string; alt?: string } + | { light: string; dark: string; alt?: string } +``` + +## siteTitle {#sitetitle} + +- Тип: `string | false` + +Вы можете настроить этот элемент для замены стандартного заголовка сайта (`title` в конфигурации приложения) в nav. При установке значения `false` заголовок в панели навигации будет отключен. Пригодится, если у вас есть `logo`, который уже содержит текст названия сайта. + +```ts +export default { + themeConfig: { + siteTitle: 'Привет, мир' + } +} +``` + +## nav {#nav} + +- Тип: `NavItem` + +Конфигурация для пункта навигационного меню. Подробнее в главе [Тема по умолчанию: Навигация](./default-theme-nav#navigation-links). + +```ts +export default { + themeConfig: { + nav: [ + { text: 'Руководство', link: '/guide' }, + { + text: 'Выпадающее меню', + items: [ + { text: 'Пункт A', link: '/item-1' }, + { text: 'Пункт B', link: '/item-2' }, + { text: 'Пункт C', link: '/item-3' } + ] + } + ] + } +} +``` + +```ts +type NavItem = NavItemWithLink | NavItemWithChildren + +interface NavItemWithLink { + text: string + link: string + activeMatch?: string + target?: string + rel?: string + noIcon?: boolean +} + +interface NavItemChildren { + text?: string + items: NavItemWithLink[] +} + +interface NavItemWithChildren { + text?: string + items: (NavItemChildren | NavItemWithLink)[] + activeMatch?: string +} +``` + +## sidebar {#sidebar} + +- Тип: `Sidebar` + +Конфигурация для пунктов меню боковой панели. Подробнее в главе [Тема по умолчанию: Сайдбар](./default-theme-sidebar). + +```ts +export default { + themeConfig: { + sidebar: [ + { + text: 'Руководство', + items: [ + { text: 'Введение', link: '/introduction' }, + { text: 'Первые шаги', link: '/getting-started' }, + ... + ] + } + ] + } +} +``` + +```ts +export type Sidebar = SidebarItem[] | SidebarMulti + +export interface SidebarMulti { + [path: string]: SidebarItem[] +} + +export type SidebarItem = { + /** + * Текстовая метка элемента + */ + text?: string + + /** + * Ссылка на элемент + */ + link?: string + + /** + * Потомки элемента + */ + items?: SidebarItem[] + + /** + * Если не указано, группа не будет сворачиваться + * + * Если `true`, то группа будет сворачиваться и разворачиваться по умолчанию + * + * Если `false`, группа сворачивается, но по умолчанию разворачивается + */ + collapsed?: boolean +} +``` + +## aside {#aside} + +- Тип: `boolean | 'left'` +- По умолчанию: `true` +- Можно переопределить для каждой страницы с помощью [метаданных](./frontmatter-config#aside) + +Установка этого значения в `false` предотвращает отрисовку контейнера сайдбара.\ +Установка этого значения в `true` приведёт к отображению сайдбара справа.\ +Установка этого значения в `left` приведёт к отображению сайдбара слева. + +Если вы хотите отключить его для всех режимов просмотра, используйте `aside: false`. + +## outline {#outline} + +- Тип: `Outline | Outline['level'] | false` +- Уровень можно переопределить для каждой страницы с помощью [метаданных](./frontmatter-config#outline) + +Установка этого значения в `false` предотвращает отрисовку оглавления. Для получения более подробной информации обратитесь к этому интерфейсу: + +```ts +interface Outline { + /** + * Уровни заголовков, которые будут отображаться в оглавлении. + * Одиночное число означает, что будут отображаться только заголовки этого уровня. + * Если передается кортеж, то первое число — это минимальный уровень, а второе — максимальный. + * `'deep'` то же самое, что `[2, 6]`, что означает, что будут отображены все заголовки от `

` до `

`. + * + * @default 2 + */ + level?: number | [number, number] | 'deep' + + /** + * Заголовок, который будет отображаться в оглавлении. + * + * @default 'На этой странице' + */ + label?: string +} +``` + +## socialLinks {#sociallinks} + +- Тип: `SocialLink[]` + +Вы можете задать эту опцию, чтобы показывать ссылки на ваши социальные аккаунты с помощью иконок в панели навигации. + +```ts +export default { + themeConfig: { + socialLinks: [ + { icon: 'github', link: 'https://github.com/vuejs/vitepress' }, + { icon: 'twitter', link: '...' }, + // Вы также можете добавить пользовательские иконки, передав SVG в виде строки: + { + icon: { + svg: 'Dribbble' + }, + link: '...', + // Вы также можете включить пользовательский ярлык для доступности (необязательно, но рекомендуется): + ariaLabel: 'классная ссылка' + } + ] + } +} +``` + +```ts +interface SocialLink { + icon: SocialLinkIcon + link: string + ariaLabel?: string +} + +type SocialLinkIcon = + | 'discord' + | 'facebook' + | 'github' + | 'instagram' + | 'linkedin' + | 'mastodon' + | 'npm' + | 'slack' + | 'twitter' + | 'x' + | 'youtube' + | { svg: string } +``` + +## footer {#footer} + +- Тип: `Footer` +- Можно переопределить для каждой страницы с помощью [метаданных](./frontmatter-config#footer) + +Настройка подвала. Вы можете разместить в подвале сообщение или текст об авторских правах, однако он будет отображаться только в том случае, если страница не содержит боковой панели. Это объясняется соображениями дизайна. + +```ts +export default { + themeConfig: { + footer: { + message: 'Опубликовано под лицензией MIT.', + copyright: '© 2019 – настоящее время, Эван Ю' + } + } +} +``` + +```ts +export interface Footer { + message?: string + copyright?: string +} +``` + +## editLink {#editlink} + +- Тип: `EditLink` +- Можно переопределить для каждой страницы с помощью [метаданных](./frontmatter-config#editlink) + +Ссылка для редактирования позволяет отобразить ссылку для редактирования страницы на сервисах управления Git, таких как GitHub или GitLab. См. секцию [Тема по умолчанию: Ссылка для редактирования](./default-theme-edit-link) для получения более подробной информации. + +```ts +export default { + themeConfig: { + editLink: { + pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path', + text: 'Редактировать эту страницу на GitHub' + } + } +} +``` + +```ts +export interface EditLink { + pattern: string + text?: string +} +``` + +## lastUpdated {#lastupdated} + +- Тип: `LastUpdatedOptions` + +Позволяет настраивать текст и формат даты последнего обновления. + +```ts +export default { + themeConfig: { + lastUpdated: { + text: 'Обновлено', + formatOptions: { + dateStyle: 'full', + timeStyle: 'medium' + } + } + } +} +``` + +```ts +export interface LastUpdatedOptions { + /** + * @default 'Last updated' + */ + text?: string + + /** + * @default + * { dateStyle: 'short', timeStyle: 'short' } + */ + formatOptions?: Intl.DateTimeFormatOptions & { forceLocale?: boolean } +} +``` + +## algolia {#algolia} + +- Тип: `AlgoliaSearch` + +Опция для поддержки поиска на вашем сайте документации с помощью [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch). Подробнее в главе [Тема по умолчанию: Поиск](./default-theme-search) + +```ts +export interface AlgoliaSearchOptions extends DocSearchProps { + locales?: Record> +} +``` + +Посмотреть все доступные опции можно [здесь](https://github.com/vuejs/vitepress/blob/main/types/docsearch.d.ts). + +## carbonAds {#carbon-ads} + +- Тип: `CarbonAdsOptions` + +Возможность отображения [Carbon Ads](https://www.carbonads.net/). + +```ts +export default { + themeConfig: { + carbonAds: { + code: 'код-рекламы', + placement: 'место-размещения-рекламы' + } + } +} +``` + +```ts +export interface CarbonAdsOptions { + code: string + placement: string +} +``` + +Подробнее в главе [Тема по умолчанию: Carbon Ads](./default-theme-carbon-ads) + +## docFooter {#docfooter} + +- Тип: `DocFooter` + +Можно использовать для настройки текста, отображаемого над ссылками на предыдущую и следующую страницы. Полезно, если вы не пишете документы только на английском языке. Также можно использовать для глобального отключения подобных ссылок. Если вы хотите выборочно включить/выключить эти ссылки на отдельной странице, воспользуйтесь [метаданными](./default-theme-prev-next-links). + +```ts +export default { + themeConfig: { + docFooter: { + prev: 'Предыдущая страница', + next: 'Следующая страница' + } + } +} +``` + +```ts +export interface DocFooter { + prev?: string | false + next?: string | false +} +``` + +## darkModeSwitchLabel {#darkmodeswitchlabel} + +- Тип: `string` +- По умолчанию: `Appearance` + +Можно использовать для настройки надписи переключателя тёмного режима. Этот ярлык отображается только в мобильном представлении. + +## lightModeSwitchTitle {#lightmodeswitchtitle} + +- Тип: `string` +- По умолчанию: `Switch to light theme` + +Может использоваться для настройки заголовка переключателя светлого режима, который появляется при наведении курсора. + +## darkModeSwitchTitle {#darkmodeswitchtitle} + +- Тип: `string` +- По умолчанию: `Switch to dark theme` + +Можно использовать для настройки заголовка переключателя тёмного режима, который появляется при наведении курсора. + +## sidebarMenuLabel {#sidebarmenulabel} + +- Тип: `string` +- По умолчанию: `Menu` + +Может использоваться для настройки метки бокового меню. Эта метка отображается только в мобильном представлении. + +## returnToTopLabel {#returntotoplabel} + +- Тип: `string` +- По умолчанию: `Return to top` + +Может использоваться для настройки метки кнопки возврата наверх. Эта метка отображается только в мобильном представлении. + +## langMenuLabel {#langmenulabel} + +- Тип: `string` +- По умолчанию: `Change language` + +Можно использовать для настройки aria-метки кнопки переключения языка в панели навигации. Это используется только в том случае, если вы используете [i18n](../guide/i18n). + +## externalLinkIcon {#externallinkicon} + +- Тип: `boolean` +- По умолчанию: `false` + +Отображать ли значок внешней ссылки рядом с внешними ссылками в Markdown. diff --git a/docs/ru/reference/default-theme-edit-link.md b/docs/ru/reference/default-theme-edit-link.md new file mode 100644 index 00000000..a2cd6b00 --- /dev/null +++ b/docs/ru/reference/default-theme-edit-link.md @@ -0,0 +1,60 @@ +# Ссылка для редактирования {#edit-link} + +## Настройка в файле конфигурации {#site-level-config} + +Ссылка на редактирование позволяет отобразить ссылку для редактирования страницы на сервисах управления Git, таких как GitHub или GitLab. Чтобы включить её, добавьте опции `themeConfig.editLink` в свой конфиг: + +```js +export default { + themeConfig: { + editLink: { + pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path' + } + } +} +``` + +Параметр `pattern` задает структуру URL для ссылки, а `:path` будет заменён на путь к странице. + +Вы также можете поместить чистую функцию, которая принимает [`PageData`](./runtime-api#usedata) в качестве аргумента и возвращает строку URL. + +```js +export default { + themeConfig: { + editLink: { + pattern: ({ filePath }) => { + if (filePath.startsWith('packages/')) { + return `https://github.com/acme/monorepo/edit/main/${filePath}` + } else { + return `https://github.com/acme/monorepo/edit/main/docs/${filePath}` + } + } + } + } +} +``` + +Она не должна иметь побочных эффектов или доступа к чему-либо за пределами своей области, поскольку будет сериализована и выполнена в браузере. + +По умолчанию это добавит текст ссылки «Редактировать страницу» в нижней части документа. Вы можете настроить этот текст, определив опцию `text`. + +```js +export default { + themeConfig: { + editLink: { + pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path', + text: 'Редактировать эту страницу на GitHub' + } + } +} +``` + +## Настройка в метаданных {#frontmatter-config} + +Эту ссылку можно отключить на конкретной странице с помощью опции `editLink` в метаданных: + +```yaml +--- +editLink: false +--- +``` diff --git a/docs/ru/reference/default-theme-footer.md b/docs/ru/reference/default-theme-footer.md new file mode 100644 index 00000000..2222f436 --- /dev/null +++ b/docs/ru/reference/default-theme-footer.md @@ -0,0 +1,55 @@ +# Подвал {#footer} + +VitePress будет отображать блок подвала внизу страницы, если присутствует объект `themeConfig.footer`. + +```ts +export default { + themeConfig: { + footer: { + message: 'Опубликовано под лицензией MIT.', + copyright: '© 2019 – настоящее время, Эван Ю' + } + } +} +``` + +```ts +export interface Footer { + // Сообщение, отображаемое прямо перед копирайтом. + message?: string + + // Уведомление об авторских правах. + copyright?: string +} +``` + +Приведённая выше конфигурация также поддерживает строки HTML. Так, например, если вы хотите разместить в подвале несколько ссылок, можно настроить конфигурацию следующим образом: + +```ts +export default { + themeConfig: { + footer: { + message: + 'Опубликовано под лицензией MIT.', + copyright: + '© 2019 – настоящее время, Эван Ю' + } + } +} +``` + +::: warning ПРЕДУПРЕЖДЕНИЕ +В `message` и `copyright` можно использовать только встроенные элементы, поскольку они отображаются внутри элемента `

`. Если вы хотите добавить блочные элементы, рассмотрите возможность использования слота [`layout-bottom`](../guide/extending-default-theme#layout-slots). +::: + +Обратите внимание, что подвал не будет отображаться, если виден [Сайдбар](./default-theme-sidebar). + +## Настройка в метаданных {#frontmatter-config} + +Отображение подвала можно отключить на конкретной странице с помощью опции `footer` в метаданных: + +```yaml +--- +footer: false +--- +``` diff --git a/docs/ru/reference/default-theme-home-page.md b/docs/ru/reference/default-theme-home-page.md new file mode 100644 index 00000000..fedf2b53 --- /dev/null +++ b/docs/ru/reference/default-theme-home-page.md @@ -0,0 +1,196 @@ +# Главная страница {#home-page} + +Тема VitePress по умолчанию предоставляет макет главной страницы, который вы также можете увидеть на [главной странице этого сайта](../). Вы можете использовать его на любой из своих страниц, указав `layout: home` в [метаданных](./frontmatter-config) страницы. + +```yaml +--- +layout: home +--- +``` + +Однако сам по себе этот вариант мало что даст. Вы можете добавить несколько различных готовых «секций» на главную страницу, установив дополнительные опции, такие как `hero` и `features`. + +## Секция `hero` {#hero-section} + +Секция `hero` находится в верхней части главной страницы. Вот как можно её настроить: + +```yaml +--- +layout: home + +hero: + name: VitePress + text: Генератор статических сайтов на основе Vite и Vue. + tagline: Lorem ipsum... + image: + src: /logo.png + alt: VitePress + actions: + - theme: brand + text: Начать + link: /guide/what-is-vitepress + - theme: alt + text: Посмотреть на GitHub + link: https://github.com/vuejs/vitepress +--- +``` + +```ts +interface Hero { + // Строка, отображаемая поверх `text`. Поставляется в фирменном цвете и, + // как ожидается, будет короткой — например, название продукта + name?: string + + // Основной текст секции. Будет использоваться внутри тега `h1` + text: string + + // Заголовок, отображаемый под `text` + tagline?: string + + // Изображение отображается рядом с `text` и `tagline` + image?: ThemeableImage + + // Кнопки действий для отображения в секции + actions?: HeroAction[] +} + +type ThemeableImage = + | string + | { src: string; alt?: string } + | { light: string; dark: string; alt?: string } + +interface HeroAction { + // Цветовая тема кнопки. По умолчанию принимает значение `brand`. + theme?: 'brand' | 'alt' + + // Метка кнопки. + text: string + + // Ссылка назначения кнопки. + link: string + + // Атрибут цели ссылки. + target?: string + + // Атрибут rel ссылки. + rel?: string +} +``` + +### Настройка цвета заголовка секции {#customizing-the-name-color} + +VitePress использует фирменный цвет (`--vp-c-brand-1`) для атрибута `name` в секции `hero`. Однако вы можете настроить этот цвет, переопределив переменную `--vp-home-hero-name-color`. + +```css +:root { + --vp-home-hero-name-color: blue; +} +``` + +Также вы можете настроить его ещё больше, комбинируя `--vp-home-hero-name-background`, чтобы придать `name` градиентный цвет. + +```css +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + #bd34fe, + #41d1ff + ); +} +``` + +## Секция `features` {#features-section} + +В секции `features` можно перечислить любое количество функций, которые вы хотели бы показать сразу после секции `hero`. Чтобы настроить её, передайте опцию `features` в метаданных страницы. + +Для каждой функции можно указать иконку, который может быть эмодзи или любым другим изображением. Если настраиваемая иконка представляет собой изображение (svg, png, jpeg...), вы должны предоставить ей соответствующую ширину и высоту. При необходимости можно указать описание, собственный размер, а также варианты для тёмной и светлой темы. + +```yaml +--- +layout: home + +features: + - icon: 🛠️ + title: Просто и минималистично, всегда + details: Lorem ipsum... + - icon: + src: /cool-feature-icon.svg + title: Ещё одна интересная функция + details: Lorem ipsum... + - icon: + dark: /dark-feature-icon.svg + light: /light-feature-icon.svg + title: Ещё одна интересная функция + details: Lorem ipsum... +--- +``` + +```ts +interface Feature { + // Иконка + icon?: FeatureIcon + + // Заголовок фичи + title: string + + // Описание фичи + details: string + + // Ссылка при нажатии на компонент функции. Ссылка может быть как внутренней, так и внешней. + // + // например, `guide/reference/default-theme-home-page` или `https://example.com` + link?: string + + // Текст ссылки, который будет отображаться внутри компонента функции. Лучше всего использовать с опцией `link`. + // + // например, `Узнать подробнее`, `Посетить страницу` и т. д. + linkText?: string + + // Атрибут rel для опции `link` + // + // например, `external` + rel?: string + + // Атрибут target для опции `link` + target?: string +} + +type FeatureIcon = + | string + | { src: string; alt?: string; width?: string; height: string } + | { + light: string + dark: string + alt?: string + width?: string + height: string + } +``` + +## Содержимое Markdown {#markdown-content} + +Вы можете добавить дополнительный контент на главную страницу вашего сайта, просто добавив Markdown под разделителем `---`. + +````md +--- +layout: home + +hero: + name: VitePress + text: Генератор статических сайтов на основе Vite и Vue. +--- + +## Начало работы + +Вы можете начать использовать VitePress прямо сейчас, используя `npx`! + +```sh +npm init +npx vitepress init +``` +```` + +::: info ПРИМЕЧАНИЕ +VitePress не всегда автоматически стилизовал дополнительный контент страницы с макетом `layout: home`. Чтобы вернуться к старому поведению, добавьте `markdownStyles: false` в метаданных. +::: diff --git a/docs/ru/reference/default-theme-last-updated.md b/docs/ru/reference/default-theme-last-updated.md new file mode 100644 index 00000000..7d926dc5 --- /dev/null +++ b/docs/ru/reference/default-theme-last-updated.md @@ -0,0 +1,27 @@ +# Последнее обновление {#last-updated} + +Время последнего обновления содержимого будет отображаться в правом нижнем углу страницы. Чтобы включить его, добавьте опцию `lastUpdated` в свой конфиг. + +::: tip Совет +Чтобы увидеть обновленное время, необходимо зафиксировать файл Markdown. +::: + +## Настройка в файле конфигурации {#site-level-config} + +```js +export default { + lastUpdated: true +} +``` + +## Настройка в метаданных {#frontmatter-config} + +Эту информацию можно отключить на конкретной странице с помощью опции `lastUpdated` в метаданных: + +```yaml +--- +lastUpdated: false +--- +``` + +Также смотрите [Тема по умолчанию: `lastUpdated`](./default-theme-config#lastupdated) для получения более подробной информации. Любое истинное значение на уровне темы также включит функцию, если только она не будет явно отключена на уровне сайта или страницы. diff --git a/docs/ru/reference/default-theme-layout.md b/docs/ru/reference/default-theme-layout.md new file mode 100644 index 00000000..f02af7d5 --- /dev/null +++ b/docs/ru/reference/default-theme-layout.md @@ -0,0 +1,62 @@ +# Макет {#layout} + +Вы можете выбрать макет страницы, установив опцию `layout` в [метаданных](./frontmatter-config). Изначально есть 3 макета: `doc`, `page` и `home`. Если ничего не указано, то страница будет использовать макет `doc`. + +```yaml +--- +layout: doc +--- +``` + +## Макет `doc` {#doc-layout} + +Вариант `doc` — это макет по умолчанию, который стилизует всё содержимое Markdown в виде «документации». Он работает, оборачивая весь контент в CSS-класс `vp-doc` и применяя стили к вложенным элементам. + +Почти все общие элементы, такие как `p` или `h2`, получают специальную стилизацию. Поэтому имейте в виду, что если вы добавите какой-либо пользовательский HTML внутри Markdown-контента, то он также будет подвержен влиянию этих стилей. + +Кроме того, в нём предусмотрены специальные функции, перечисленные ниже. Эти функции включены только в данном макете. + +- Ссылка «Редактировать» +- Ссылки предыдущая/следующая +- Оглавление +- Реклама [Carbon Ads](./default-theme-carbon-ads) + +## Макет `page` {#page-layout} + +Вариант `page` сгенерирует «пустую страницу». Markdown всё равно будет разобран, и все [расширения Markdown](../guide/markdown) будут работать так же, как и с макетом `doc`, но никаких стилей по умолчанию применено не будет. + +Макет `page` позволит вам оформить всё самостоятельно, без влияния темы VitePress на разметку. Это удобно, когда вы хотите создать свою собственную страницу. + +Обратите внимание, что даже при таком раскладе сайдбар всё равно будет отображаться, если у страницы есть соответствующая конфигурация сайдбара. + +## Макет `home` {#home-layout} + +Вариант `home` сгенерирует шаблонную «домашнюю страницу». В этом макете вы можете установить дополнительные параметры, такие как `hero` и `features`, для дальнейшей настройки контента. Посетите секцию [Тема по умолчанию: Домашняя страница](./default-theme-home-page) для получения более подробной информации. + +## Без макета {#no-layout} + +Если вам не нужен макет, вы можете указать `layout: false` в метаданных. Этот параметр полезен, если вам нужна полностью настраиваемая целевая страница (по умолчанию без сайдбара, панели навигации или подвала). + +## Свой макет {#custom-layout} + +Вы также можете использовать собственный макет: + +```md +--- +layout: foo +--- +``` + +Будет выполнен поиск компонента с именем `foo`, зарегистрированного в контексте. Например, вы можете зарегистрировать свой компонент глобально в `.vitepress/theme/index.ts`: + +```ts +import DefaultTheme from 'vitepress/theme' +import Foo from './Foo.vue' + +export default { + extends: DefaultTheme, + enhanceApp({ app }) { + app.component('foo', Foo) + } +} +``` diff --git a/docs/ru/reference/default-theme-nav.md b/docs/ru/reference/default-theme-nav.md new file mode 100644 index 00000000..9ff77659 --- /dev/null +++ b/docs/ru/reference/default-theme-nav.md @@ -0,0 +1,162 @@ +# Навигация {#nav} + +Ключ `nav` в конфигурации — это панель навигации, отображаемая в верхней части страницы. Она содержит заголовок сайта, ссылки глобального меню и т. д. + +## Название и логотип сайта {#site-title-and-logo} + +По умолчанию навигация отображает название сайта, ссылаясь на значение [`config.title`](./site-config#title). Если вы хотите изменить то, что отображается в панели навигации, задайте пользовательский текст в опции `themeConfig.siteTitle`. + +```js +export default { + themeConfig: { + siteTitle: 'Мой заголовок' + } +} +``` + +Если у вас есть логотип для вашего сайта, вы можете отобразить его, передав путь к изображению. Вы должны поместить логотип непосредственно в директорию `public` и указать абсолютный путь к нему. + +```js +export default { + themeConfig: { + logo: '/my-logo.svg' + } +} +``` + +При добавлении логотипа он отображается вместе с названием сайта. Если вам нужен только логотип и вы хотите скрыть текст заголовка сайта, установите `false` для параметра `SiteTitle`. + +```js +export default { + themeConfig: { + logo: '/my-logo.svg', + siteTitle: false + } +} +``` + +Вы также можете передать объект в качестве логотипа, если хотите добавить атрибут `alt` или настроить его в зависимости от тёмного/светлого режима. Подробности смотрите в [`themeConfig.logo`](./default-theme-config#logo). + +## Навигационные ссылки {#navigation-links} + +Вы можете определить опцию `themeConfig.nav`, чтобы добавить ссылки в панель навигации: + +```js +export default { + themeConfig: { + nav: [ + { text: 'Руководство', link: '/guide' }, + { text: 'Настройка', link: '/config' }, + { text: 'Изменения', link: 'https://github.com/...' } + ] + } +} +``` + +`text` — это текст, отображаемый в навигации, а `link` — это ссылка, на которую будет осуществлён переход при нажатии на текст. Для ссылки задайте путь к фактическому файлу без префикса `.md` и всегда начинайте с `/`. + +Навигационные ссылки также могут быть выпадающими меню. Для этого установите ключ `items` вместо ключа `link`: + +```js +export default { + themeConfig: { + nav: [ + { text: 'Руководство', link: '/guide' }, + { + text: 'Выпадающее меню', + items: [ + { text: 'Пункт A', link: '/item-1' }, + { text: 'Пункт B', link: '/item-2' }, + { text: 'Пункт C', link: '/item-3' } + ] + } + ] + } +} +``` + +Обратите внимание, что заголовок выпадающего меню (`Выпадающее меню` в примере выше) не может иметь свойство `link`, так как он становится кнопкой для открытия выпадающего диалога. + +Вы можете добавить «секции» в пункты выпадающего меню, передавая больше вложенных элементов: + +```js +export default { + themeConfig: { + nav: [ + { text: 'Руководство', link: '/guide' }, + { + text: 'Выпадающее меню', + items: [ + { + // Заголовок секции + text: 'Секция A', + items: [ + { text: 'Пункт A в секции A', link: '...' }, + { text: 'Пункт B в секции A', link: '...' } + ] + } + ] + }, + { + text: 'Выпадающее меню', + items: [ + { + // Заголовок можно опустить + items: [ + { text: 'Пункт A в секции A', link: '...' }, + { text: 'Пункт B в секции A', link: '...' } + ] + } + ] + } + ] + } +} +``` + +### Настройка «активного» состояния ссылки {#customize-link-s-active-state} + +Пункты меню навигации будут выделены, если текущая страница находится под соответствующим путём. Если вы хотите настроить сопоставление путей, определите свойство `activeMatch` и регулярное выражение в качестве строкового значения. + +```js +export default { + themeConfig: { + nav: [ + // Эта ссылка получает активное состояние, когда пользователь + // переходит по пути `/config/`. + { + text: 'Руководство', + link: '/guide', + activeMatch: '/config/' + } + ] + } +} +``` + +::: warning ПРЕДУПРЕЖДЕНИЕ +Ожидается, что `activeMatch` будет регулярным выражением, но вы должны определить его как строку. Мы не можем использовать здесь реальный объект RegExp, потому что он не сериализуется во время сборки. +::: + +### Настройка атрибутов «target» и «rel» {#customize-link-s-target-and-rel-attributes} + +По умолчанию VitePress автоматически определяет атрибуты `target` и `rel` в зависимости от того, является ли ссылка внешней. Но при желании их можно настроить и вручную. + +```js +export default { + themeConfig: { + nav: [ + { + text: 'Товары', + link: 'https://www.thegithubshop.com/', + target: '_self', + rel: 'sponsored' + } + ] + } +} +``` + +## Социальные ссылки {#social-links} + +См. [`socialLinks`](./default-theme-config#sociallinks). diff --git a/docs/ru/reference/default-theme-prev-next-links.md b/docs/ru/reference/default-theme-prev-next-links.md new file mode 100644 index 00000000..e2da9501 --- /dev/null +++ b/docs/ru/reference/default-theme-prev-next-links.md @@ -0,0 +1,43 @@ +# Предыдущая и следующая страницы {#prev-next-links} + +Вы можете настроить текст и ссылку для предыдущей и следующей страниц (отображаются в нижней части страницы). Это полезно, если вы хотите, чтобы текст отличался от того, что находится в сайдбаре. Кроме того, вы можете счесть полезным отключить подвал или ссылку на страницу, которая не включена в сайдбар. + +## prev {#prev} + +- Тип: `string | false | { text?: string; link?: string }` + +- Подробности: + + Указывает текст/ссылку, который должен отображаться при переходе на предыдущую страницу. Если вы не зададите это в метаданных, текст/ссылка будет определяться из конфигурации сайдбара. + +- Примеры: + + - Для настройки только текста: + + ```yaml + --- + prev: 'Начать | Markdown' + --- + ``` + + - Для настройки текста и ссылки: + + ```yaml + --- + prev: + text: 'Markdown' + link: '/guide/markdown' + --- + ``` + + - Для скрытия предыдущей страницы: + + ```yaml + --- + prev: false + --- + ``` + +## next {#next} + +Аналогично параметру `prev`, но для следующей страницы. diff --git a/docs/ru/reference/default-theme-search.md b/docs/ru/reference/default-theme-search.md new file mode 100644 index 00000000..dae85f47 --- /dev/null +++ b/docs/ru/reference/default-theme-search.md @@ -0,0 +1,382 @@ +--- +outline: deep +--- + +# Поиск {#search} + +## Локальный поиск {#local-search} + +VitePress поддерживает нечёткий полнотекстовый поиск с использованием внутрибраузерного индекса благодаря [MiniSearch](https://github.com/lucaong/minisearch/). Чтобы включить эту функцию, просто установите значение `'local'` для опции `themeConfig.search.provider` в файле `.vitepress/config.ts`: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local' + } + } +}) +``` + +Пример результата: + +![скриншот модального окна поиска](/search.png) + +В качестве альтернативы можно использовать [Algolia DocSearch](#algolia-search) или некоторые плагины сообщества, например или . + +### i18n {#local-search-i18n} + +Вы можете использовать подобную конфигурацию для использования многоязычного поиска: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + locales: { + ru: { + translations: { + button: { + buttonText: 'Поиск', + buttonAriaLabel: 'Поиск' + }, + modal: { + noResultsText: 'Нет результатов для', + resetButtonTitle: 'Сбросить поиск', + footer: { + selectText: 'выбрать', + navigateText: 'перейти' + } + } + } + } + } + } + } + } +}) +``` + +### Параметры MiniSearch {#minisearch-options} + +Вы можете настроить MiniSearch следующим образом: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + miniSearch: { + /** + * @type {Pick} + */ + options: { + /* ... */ + }, + /** + * @type {import('minisearch').SearchOptions} + * @default + * { fuzzy: 0.2, prefix: true, boost: { title: 4, text: 2, titles: 1 } } + */ + searchOptions: { + /* ... */ + } + } + } + } + } +}) +``` + +Подробнее в [документации MiniSearch](https://lucaong.github.io/minisearch/classes/MiniSearch.MiniSearch.html). + +### Пользовательский рендерер содержимого {#custom-content-renderer} + +Вы можете настроить функцию, используемую для отображения содержимого в формате Markdown перед его индексацией: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + /** + * @param {string} src + * @param {import('vitepress').MarkdownEnv} env + * @param {import('markdown-it')} md + */ + _render(src, env, md) { + // возвращаем html + } + } + } + } +}) +``` + +Эта функция будет очищена от данных сайта на стороне клиента, поэтому вы можете использовать в ней API Node.js. + +#### Пример: Исключение страниц из поиска {#example-excluding-pages-from-search} + +Вы можете исключить страницы из поиска, добавив `search: false` в блок метаданных страницы. Альтернативный вариант: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + _render(src, env, md) { + const html = md.render(src, env) + if (env.frontmatter?.search === false) return '' + if (env.relativePath.startsWith('some/path')) return '' + return html + } + } + } + } +}) +``` + +::: warning ПРИМЕЧАНИЕ +В случае, если предоставляется пользовательская функция `_render`, вам нужно самостоятельно обработать заголовок `search: false`. Кроме того, объект `env` не будет полностью заполнен до вызова `md.render`, поэтому любые проверки необязательных свойств `env`, таких как `frontmatter`, должны быть выполнены после этого. +::: + +#### Пример: Преобразование содержимого - добавление якорей {#example-transforming-content-adding-anchors} + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + _render(src, env, md) { + const html = md.render(src, env) + if (env.frontmatter?.title) + return md.render(`# ${env.frontmatter.title}`) + html + return html + } + } + } + } +}) +``` + +## Поиск Algolia {#algolia-search} + +VitePress поддерживает поиск в вашей документации с помощью [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch). Обратитесь к руководству по началу работы. В файле `.vitepress/config.ts` вам нужно будет указать, по крайней мере, следующее, чтобы всё работало: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'algolia', + options: { + appId: '...', + apiKey: '...', + indexName: '...' + } + } + } +}) +``` + +### i18n {#algolia-search-i18n} + +Вы можете использовать подобную конфигурацию для использования многоязычного поиска: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'algolia', + options: { + appId: '...', + apiKey: '...', + indexName: '...', + locales: { + ru: { + placeholder: 'Поиск в документации', + translations: { + button: { + buttonText: 'Поиск', + buttonAriaLabel: 'Поиск' + }, + modal: { + searchBox: { + resetButtonTitle: 'Сбросить поиск', + resetButtonAriaLabel: 'Сбросить поиск', + cancelButtonText: 'Отменить поиск', + cancelButtonAriaLabel: 'Отменить поиск' + }, + startScreen: { + recentSearchesTitle: 'История поиска', + noRecentSearchesText: 'Нет истории поиска', + saveRecentSearchButtonTitle: 'Сохранить в истории поиска', + removeRecentSearchButtonTitle: 'Удалить из истории поиска', + favoriteSearchesTitle: 'Избранное', + removeFavoriteSearchButtonTitle: 'Удалить из избранного' + }, + errorScreen: { + titleText: 'Невозможно получить результаты', + helpText: + 'Вам может потребоваться проверить подключение к Интернету' + }, + footer: { + selectText: 'выбрать', + navigateText: 'перейти', + closeText: 'закрыть', + searchByText: 'поставщик поиска' + }, + noResultsScreen: { + noResultsText: 'Нет результатов для', + suggestedQueryText: 'Вы можете попытаться узнать', + reportMissingResultsText: + 'Считаете, что поиск даёт ложные результаты?', + reportMissingResultsLinkText: + 'Нажмите на кнопку «Обратная связь»' + } + } + } + } + } + } + } + } +}) +``` + +[Эти параметры](https://github.com/vuejs/vitepress/blob/main/types/docsearch.d.ts) можно переопределить. Чтобы узнать о них больше, обратитесь к официальной документации Algolia. + +### Конфигурация поискового робота {#crawler-config} + +Вот пример конфигурации, основанной на той, что используется на этом сайте: + +```ts +new Crawler({ + appId: '...', + apiKey: '...', + rateLimit: 8, + startUrls: ['https://vitepress.dev/'], + renderJavaScript: false, + sitemaps: [], + exclusionPatterns: [], + ignoreCanonicalTo: false, + discoveryPatterns: ['https://vitepress.dev/**'], + schedule: 'at 05:10 on Saturday', + actions: [ + { + indexName: 'vitepress', + pathsToMatch: ['https://vitepress.dev/**'], + recordExtractor: ({ $, helpers }) => { + return helpers.docsearch({ + recordProps: { + lvl1: '.content h1', + content: '.content p, .content li', + lvl0: { + selectors: '', + defaultValue: 'Documentation' + }, + lvl2: '.content h2', + lvl3: '.content h3', + lvl4: '.content h4', + lvl5: '.content h5' + }, + indexHeadings: true + }) + } + } + ], + initialIndexSettings: { + vitepress: { + attributesForFaceting: ['type', 'lang'], + attributesToRetrieve: ['hierarchy', 'content', 'anchor', 'url'], + attributesToHighlight: ['hierarchy', 'hierarchy_camel', 'content'], + attributesToSnippet: ['content:10'], + camelCaseAttributes: ['hierarchy', 'hierarchy_radio', 'content'], + searchableAttributes: [ + 'unordered(hierarchy_radio_camel.lvl0)', + 'unordered(hierarchy_radio.lvl0)', + 'unordered(hierarchy_radio_camel.lvl1)', + 'unordered(hierarchy_radio.lvl1)', + 'unordered(hierarchy_radio_camel.lvl2)', + 'unordered(hierarchy_radio.lvl2)', + 'unordered(hierarchy_radio_camel.lvl3)', + 'unordered(hierarchy_radio.lvl3)', + 'unordered(hierarchy_radio_camel.lvl4)', + 'unordered(hierarchy_radio.lvl4)', + 'unordered(hierarchy_radio_camel.lvl5)', + 'unordered(hierarchy_radio.lvl5)', + 'unordered(hierarchy_radio_camel.lvl6)', + 'unordered(hierarchy_radio.lvl6)', + 'unordered(hierarchy_camel.lvl0)', + 'unordered(hierarchy.lvl0)', + 'unordered(hierarchy_camel.lvl1)', + 'unordered(hierarchy.lvl1)', + 'unordered(hierarchy_camel.lvl2)', + 'unordered(hierarchy.lvl2)', + 'unordered(hierarchy_camel.lvl3)', + 'unordered(hierarchy.lvl3)', + 'unordered(hierarchy_camel.lvl4)', + 'unordered(hierarchy.lvl4)', + 'unordered(hierarchy_camel.lvl5)', + 'unordered(hierarchy.lvl5)', + 'unordered(hierarchy_camel.lvl6)', + 'unordered(hierarchy.lvl6)', + 'content' + ], + distinct: true, + attributeForDistinct: 'url', + customRanking: [ + 'desc(weight.pageRank)', + 'desc(weight.level)', + 'asc(weight.position)' + ], + ranking: [ + 'words', + 'filters', + 'typo', + 'attribute', + 'proximity', + 'exact', + 'custom' + ], + highlightPreTag: '', + highlightPostTag: '', + minWordSizefor1Typo: 3, + minWordSizefor2Typos: 7, + allowTyposOnNumericTokens: false, + minProximity: 1, + ignorePlurals: true, + advancedSyntax: true, + attributeCriteriaComputedByMinProximity: true, + removeWordsIfNoResults: 'allOptional' + } + } +}) +``` + + diff --git a/docs/ru/reference/default-theme-sidebar.md b/docs/ru/reference/default-theme-sidebar.md new file mode 100644 index 00000000..92fd89c1 --- /dev/null +++ b/docs/ru/reference/default-theme-sidebar.md @@ -0,0 +1,213 @@ +# Сайдбар {#sidebar} + +Сайдбар (боковая панель) — основной навигационный блок вашей документации. Меню боковой панели можно настроить в секции [`themeConfig.sidebar`](./default-theme-config#sidebar). + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Руководство', + items: [ + { text: 'Введение', link: '/ru/introduction' }, + { text: 'Первые шаги', link: '/ru/getting-started' }, + ... + ] + } + ] + } +} +``` + +## Основы {#the-basics} + +Простейшая форма сайдбара — это передача массива ссылок. Элемент первого уровня определяет «секцию» сайдбара. Он должен содержать `text`, который является заголовком секции, и `items`, которые являются фактическими навигационными ссылками. + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Заголовок секции A', + items: [ + { text: 'Пункт A', link: '/item-a' }, + { text: 'Пункт B', link: '/item-b' }, + ... + ] + }, + { + text: 'Заголовок секции B', + items: [ + { text: 'Пункт C', link: '/item-c' }, + { text: 'Пункт D', link: '/item-d' }, + ... + ] + } + ] + } +} +``` + +Каждый элемент `link` должен указывать путь к фактическому файлу, начинающийся с `/`. Если добавить в конец ссылки косую черту, то будет показан `index.md` соответствующего каталога. + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Руководство', + items: [ + // Ссылка на страницу `/ru/guide/index.md` + { text: 'Введение', link: '/ru/guide/' } + ] + } + ] + } +} +``` + +Вы можете вложить элементы боковой панели на 6 уровней вглубь, считая от корневого уровня. Обратите внимание, что более 6 уровней вложенных элементов будут игнорироваться и не отображаться на боковой панели. + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Уровень 1', + items: [ + { + text: 'Уровень 2', + items: [ + { + text: 'Уровень 3', + items: [ + ... + ] + } + ] + } + ] + } + ] + } +} +``` + +## Несколько сайдбаров {#multiple-sidebars} + +Вы можете показывать разные боковые панели в зависимости от текущего маршрута. Например, как показано на этом сайте, вы можете создать в документации отдельные разделы, например, «Руководство» и «Настройка». + +Для этого сначала организуйте страницы в каталоги для каждого нужного раздела: + +``` +. +├─ guide/ +│ ├─ index.md +│ ├─ one.md +│ └─ two.md +└─ config/ + ├─ index.md + ├─ three.md + └─ four.md +``` + +Затем обновите конфигурацию, чтобы определить боковую панель для каждого раздела. На этот раз вместо массива нужно передать объект. + +```js +export default { + themeConfig: { + sidebar: { + // Эта боковая панель отображается, когда пользователь находится в директории `guide` + '/guide/': [ + { + text: 'Руководство', + items: [ + { text: 'Index', link: '/guide/' }, + { text: 'One', link: '/guide/one' }, + { text: 'Two', link: '/guide/two' } + ] + } + ], + + // Эта боковая панель отображается, когда пользователь находится в директории `config` + '/config/': [ + { + text: 'Настройка', + items: [ + { text: 'Index', link: '/config/' }, + { text: 'Three', link: '/config/three' }, + { text: 'Four', link: '/config/four' } + ] + } + ] + } + } +} +``` + +## Сворачиваемые группы {#collapsible-sidebar-groups} + +Добавив опцию `collapsed` внутри группы `sidebar`, вы увидите кнопку переключения для скрытия/показа каждой секции. + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Заголовок секции A', + collapsed: false, + items: [...] + } + ] + } +} +``` + +Все секции «развёрнуты» по умолчанию. Если вы хотите, чтобы они были «свёрнуты» при первоначальной загрузке страницы, установите для опции `collapsed` значение `true`. + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Заголовок секции A', + collapsed: true, + items: [...] + } + ] + } +} +``` + +## `useSidebar` {#usesidebar} + +Возвращает данные, связанные с сайдбаром. Возвращаемый объект имеет следующий тип: + +```ts +export interface DocSidebar { + isOpen: Ref + sidebar: ComputedRef + sidebarGroups: ComputedRef + hasSidebar: ComputedRef + hasAside: ComputedRef + leftAside: ComputedRef + isSidebarEnabled: ComputedRef + open: () => void + close: () => void + toggle: () => void +} +``` + +**Пример:** + +```vue + + + +``` diff --git a/docs/ru/reference/default-theme-team-page.md b/docs/ru/reference/default-theme-team-page.md new file mode 100644 index 00000000..0eebaa24 --- /dev/null +++ b/docs/ru/reference/default-theme-team-page.md @@ -0,0 +1,252 @@ + + +# Страница команды {#team-page} + +Если вы хотите представить свою команду, вы можете использовать компоненты Team для создания страницы команды. Есть два варианта использования этих компонентов. Один из вариантов — встроить их в страницу с макетом `doc`, а другой — создать полноценную страницу команды. + +## Отображение членов команды на странице {#show-team-members-in-a-page} + +Вы можете использовать компонент ``, доступный из `vitepress/theme`, для отображения списка членов команды на любой странице. + +```html + + +# Поприветствуйте нашу замечательную команду + + +``` + +Вышеуказанное отобразит члена команды в виде карточки. Должно отобразиться что-то похожее на то, что показано ниже. + + + +Компонент `` поставляется в двух различных размерах, `small` и `medium`. Хотя это зависит от ваших предпочтений, обычно размер `small` лучше подходит для использования на странице с макетом `doc`. Кроме того, вы можете добавить дополнительные свойства для карточки члена команды, например, добавить «описание» или кнопку «спонсировать». Подробнее об этом в секции [``](#vpteammembers). + +Встраивание членов команды в страницу документа хорошо подходит для небольших команд, где наличие полной страницы команды может быть слишком большим, или для представления частичных членов команды в качестве ссылки на контекст документации. + +Если у вас большое количество участников или вы просто хотите иметь больше места для отображения членов команды, подумайте о [создании отдельной страницы команды](#create-a-full-team-page). + +## Создание отдельной страницы команды {#create-a-full-team-page} + +Вместо того чтобы добавлять членов команды на страницу с макетом `doc`, вы можете создать полноценную страницу команды, подобно созданию пользовательской [главной страницы](./default-theme-home-page). + +Чтобы создать страницу команды, сначала создайте новый md-файл. Имя файла не имеет значения, но здесь мы назовем его `team.md`. В этом файле установите в блоке метаданных параметр `layout: page`, а затем вы можете организовать структуру страницы, используя компоненты `TeamPage`. + +```html +--- +layout: page +--- + + + + + + + + + + +``` + +При создании полной страницы команды не забудьте обернуть все компоненты компонентом ``. Этот компонент обеспечит всем вложенным компонентам, связанным с командой, правильную структуру макета, например, расстояние между ними. + +Компонент `` добавляет блок заголовка страницы. Заголовок — это тег `

`. Используйте слоты `#title` и `#lead`, чтобы рассказать о своей команде. + +`` работает так же, как и при использовании в doc-странице. Отобразится список участников. + +### Добавление секций для разделения членов команды {#add-sections-to-divide-team-members} + +Вы можете добавить «секции» на страницу команды. Например, у вас могут быть разные типы членов команды, такие как члены основной команды и партнёры сообщества. Вы можете разделить этих членов на секции, чтобы лучше объяснить роли каждой группы. + +Для этого добавьте компонент `` в файл `team.md`, который мы создали ранее. + +```html +--- +layout: page +--- + + + + + + + + + + + + + + + +``` + +Компонент `` может иметь слоты `#title` и `#lead`, аналогичные компоненту `VPTeamPageTitle`, а также слот `#members` для отображения членов команды. + +Не забудьте поместить компонент `` в слот `#members`. + +## `` {#vpteammembers} + +Компонент `` отображает заданный список членов команды. + +```html + +``` + +```ts +interface Props { + // Размер карточки каждого члена команды. По умолчанию `medium`. + size?: 'small' | 'medium' + + // Список членов команды для отображения. + members: TeamMember[] +} + +interface TeamMember { + // Изображение аватара. + avatar: string + + // Имя члена команды. + name: string + + // Заголовок, отображаемый под именем члена команды. + // например: разработчик, инженер-программист и т. д. + title?: string + + // Организация, в которой состоит текущий член команды. + org?: string + + // URL-адрес сайта организации. + orgLink?: string + + // Описание члена команды. + desc?: string + + // Социальные ссылки: GitHub, Twitter и т. д. + // Могут быть переданы в виде объекта. + // См. https://vitepress.dev/reference/default-theme-config.html#sociallinks + links?: SocialLink[] + + // URL-адрес спонсорской страницы члена команды. + sponsor?: string + + // Текст спонсорской ссылки. По умолчанию 'Sponsor'. + actionText?: string +} +``` + +## `` {#vpteampage} + +Корневой компонент при создании отдельной страницы команды. Принимает только один слот. Он будет стилизовать все передаваемые компоненты, связанные с командой. + +## `` {#vpteampagetitle} + +Добавляет блок «заголовка» страницы. Лучше всего использовать в самом начале внутри ``. Принимает слоты `#title` и `#lead`. + +```html + + + + + + +``` + +## `` {#vpteampagesection} + +Создает «секцию» на странице команды. Принимает слоты `#title`, `#lead` и `#members`. Внутри `` вы можете добавить столько секций, сколько захотите. + +```html + + ... + + + + + + +``` diff --git a/docs/ru/reference/frontmatter-config.md b/docs/ru/reference/frontmatter-config.md new file mode 100644 index 00000000..5c4b3a93 --- /dev/null +++ b/docs/ru/reference/frontmatter-config.md @@ -0,0 +1,221 @@ +--- +outline: deep +--- + +# Конфигурация метаданных {#frontmatter-config} + +Метаданные обеспечивают настройку отдельных страниц. В каждом файле Markdown можно использовать метаданные, чтобы переопределить параметры конфигурации сайта или темы. Кроме того, есть параметры конфигурации, которые можно задать только через метаданные. + +Пример использования: + +```md +--- +title: Документация с VitePress +editLink: true +--- +``` + +Вы можете получить доступ к метаданным через глобальный объект `$frontmatter` в выражениях Vue: + +```md +{{ $frontmatter.title }} +``` + +## title {#title} + +- Тип: `string` + +Заголовок страницы. Это то же самое, что [config.title](./site-config#title), и оно переопределяет конфигурацию сайта. + +```yaml +--- +title: VitePress +--- +``` + +## titleTemplate {#titletemplate} + +- Тип: `string | boolean` + +Суффикс для названия. Это то же самое, что и [config.titleTemplate](./site-config#titletemplate), и оно переопределяет конфигурацию сайта. + +```yaml +--- +title: VitePress +titleTemplate: Генератор статических сайтов на основе Vite и Vue +--- +``` + +## description {#description} + +- Тип: `string` + +Описание для страницы. Это то же самое, что и [config.description](./site-config#description), и оно переопределяет конфигурацию сайта. + +```yaml +--- +description: VitePress +--- +``` + +## head {#head} + +- Тип: `HeadConfig[]` + +Укажите дополнительные теги, которые будут выводиться для текущей страницы. Они будут добавляться после других тегов внутри блока head, введённых в конфигурации сайта. + +```yaml +--- +head: + - - meta + - name: description + content: привет + - - meta + - name: keywords + content: супер-пупер SEO +--- +``` + +```ts +type HeadConfig = + | [string, Record] + | [string, Record, string] +``` + +## Только для темы по умолчанию {#default-theme-only} + +Следующие параметры метаданных применимы только при использовании темы по умолчанию. + +### layout {#layout} + +- Тип: `doc | home | page` +- По умолчанию: `doc` + +Определяет макет страницы. + +- `doc` - Применяет стили документации по умолчанию к содержимому Markdown. +- `home` - Вы можете добавить дополнительные параметры, такие как `hero` и `features`, чтобы быстро создать красивую целевую страницу. +- `page` - Ведет себя аналогично `doc`, но не применяет стили к содержимому. Полезно, если вы хотите создать полностью настраиваемую страницу. + +```yaml +--- +layout: doc +--- +``` + +### hero {#hero} + +Определяет содержимое секции `hero`, когда `layout` имеет значение `home`. Подробнее в главе [Тема по умолчанию: Главная страница](./default-theme-home-page). + +### features {#features} + +Определяет элементы для отображения в секции `features`, когда `layout` имеет значение `home`. Подробнее в главе [Тема по умолчанию: Главная страница](./default-theme-home-page). + +### navbar {#navbar} + +- Тип: `boolean` +- По умолчанию: `true` + +Отображать ли [панель навигации](./default-theme-nav). + +```yaml +--- +navbar: false +--- +``` + +### sidebar {#sidebar} + +- Тип: `boolean` +- По умолчанию: `true` + +Отображать ли [сайдбар](./default-theme-sidebar). + +```yaml +--- +sidebar: false +--- +``` + +### aside {#aside} + +- Тип: `boolean | 'left'` +- По умолчанию: `true` + +Определяет расположение компонента aside в макете `doc`. + +Установка этого значения в `false` предотвращает отрисовку контейнера сайдбара.\ +Установка этого значения в `true` приведёт к отображению сайдбара справа.\ +Установка этого значения в `left` приведёт к отображению сайдбара слева. + +```yaml +--- +aside: false +--- +``` + +### outline {#outline} + +- Тип: `number | [number, number] | 'deep' | false` +- По умолчанию: `2` + +Уровни заголовков в оглавлении для отображения на странице. Это то же самое, что и [config.themeConfig.outline.level](./default-theme-config#outline), и оно переопределяет значение, установленное в конфигурации сайта. + +### lastUpdated {#lastupdated} + +- Тип: `boolean | Date` +- По умолчанию: `true` + +Отображать ли текст [Обновлено](./default-theme-last-updated) в нижнем колонтитуле текущей страницы. Если указано время даты, оно будет отображаться вместо временной метки последнего изменения git. + +```yaml +--- +lastUpdated: false +--- +``` + +### editLink {#editlink} + +- Тип: `boolean` +- По умолчанию: `true` + +Отображать ли [ссылку для редактирования](./default-theme-edit-link) в нижнем колонтитуле текущей страницы. + +```yaml +--- +editLink: false +--- +``` + +### footer {#footer} + +- Тип: `boolean` +- По умолчанию: `true` + +Отображать ли [подвал](./default-theme-footer). + +```yaml +--- +footer: false +--- +``` + +### pageClass {#pageclass} + +- Тип: `string` + +Добавьте дополнительное имя класса на определённую страницу. + +```yaml +--- +pageClass: custom-page-class +--- +``` + +Вы также можете настроить стили этой конкретной страницы в файле `.vitepress/theme/custom.css`: + +```css +.custom-page-class { +  /* стили для конкретной страницы */ +} +``` diff --git a/docs/ru/reference/runtime-api.md b/docs/ru/reference/runtime-api.md new file mode 100644 index 00000000..5d21d29a --- /dev/null +++ b/docs/ru/reference/runtime-api.md @@ -0,0 +1,165 @@ +# Runtime API {#runtime-api} + +VitePress предлагает несколько встроенных API, позволяющих получить доступ к данным приложения. VitePress также поставляется с несколькими встроенными компонентами, которые можно использовать глобально. + +Вспомогательные методы глобально импортируются из `vitepress` и обычно используются в компонентах Vue для пользовательских тем. Однако их можно использовать и внутри страниц `.md`, так как файлы markdown компилируются в [однофайловые компоненты](https://ru.vuejs.org/guide/scaling-up/sfc.html) Vue. + +Методы, начинающиеся с `use*`, указывают на то, что это функция [Vue 3 Composition API](https://ru.vuejs.org/guide/introduction.html#composition-api) («композабл»), которая может быть использована только внутри `setup()` или ` + + +``` + +## `useRoute` {#useroute} + +Возвращает текущий объект маршрута со следующим типом: + +```ts +interface Route { + path: string + data: PageData + component: Component | null +} +``` + +## `useRouter` {#userouter} + +Возвращает экземпляр маршрутизатора VitePress, чтобы вы могли программно перейти на другую страницу. + +```ts +interface Router { + /** + * Текущий маршрут. + */ + route: Route + /** + * Переход к новому URL-адресу. + */ + go: (to?: string) => Promise + /** + * Вызывается перед изменением маршрута. Верните `false`, чтобы отменить навигацию. + */ + onBeforeRouteChange?: (to: string) => Awaitable + /** + * Вызывается перед загрузкой компонента страницы (после того, как состояние истории + * обновлено). Верните `false`, чтобы отменить навигацию. + */ + onBeforePageLoad?: (to: string) => Awaitable + /** + * Вызывается после изменения маршрута. + */ + onAfterRouteChanged?: (to: string) => Awaitable +} +``` + +## `withBase` {#withbase} + +- **Тип**: `(path: string) => string` + +Добавляет настроенный [`base`](./site-config#base) к заданному URL-пути. Также смотрите секцию [Базовый URL](../guide/asset-handling#base-url). + +## `` {#content} + +Компонент `` отображает отрисованное содержимое Markdown. Полезно [при создании собственной темы](../guide/custom-theme). + +```vue + +``` + +## `` {#clientonly} + +Компонент `` отображает свой слот только на стороне клиента. + +Поскольку приложения VitePress при генерации статических сборок рендерятся в Node.js, любое использование Vue должно соответствовать универсальным требованиям к коду. Короче говоря, убедитесь, что доступ к API Browser / DOM осуществляется только в хуках `beforeMount` или `mounted`. + +Если вы используете или демонстрируете компоненты, которые не являются SSR-дружественными (например, содержат пользовательские директивы), вы можете обернуть их внутри компонента `ClientOnly`. + +```vue-html + + + +``` + +- См. также: [Совместимость с SSR](../guide/ssr-compat) + +## `$frontmatter` {#frontmatter} + +Прямой доступ к [метаданным](../guide/frontmatter) текущей страницы в выражениях Vue. + +```md +--- +title: Привет +--- + +# {{ $frontmatter.title }} +``` + +## `$params` {#params} + +Прямой доступ к параметрам [динамических маршрутов](../guide/routing#dynamic-routes) текущей страницы в выражениях Vue. + +```md +- имя пакета: {{ $params.pkg }} +- версия: {{ $params.version }} +``` diff --git a/docs/ru/reference/site-config.md b/docs/ru/reference/site-config.md new file mode 100644 index 00000000..5068bf84 --- /dev/null +++ b/docs/ru/reference/site-config.md @@ -0,0 +1,720 @@ +--- +outline: deep +--- + +# Конфигурация сайта {#site-config} + +Конфигурация сайта — это место, где вы можете определить глобальные настройки сайта. Параметры конфигурации приложения определяют настройки, которые применяются к каждому сайту VitePress, независимо от того, какая тема на нем используется. Например, базовый каталог или название сайта. + +## Обзор {#overview} + +### Разрешение конфигурации {#config-resolution} + +Файл конфигурации всегда разрешается из `/.vitepress/config.[ext]`, где `` — это корень вашего [проекта](../guide/routing#root-and-source-directory) VitePress, а `[ext]` — одно из поддерживаемых расширений файла. TypeScript поддерживается из коробки. Поддерживаемые расширения включают `.js`, `.ts`, `.mjs` и `.mts`. + +В файлах конфигурации рекомендуется использовать синтаксис ES-модулей. Файл конфигурации должен по умолчанию экспортировать объект: + +```ts +export default { + // параметры конфигурации на уровне приложения + lang: 'ru-RU', + title: 'VitePress', + description: 'Генератор статических сайтов на основе Vite и Vue.', + ... +} +``` + +:::details Динамическая (асинхронная) конфигурация + +Если вам нужно генерировать конфигурацию динамически, вы также можете экспортировать функцию по умолчанию. Например: + +```ts +import { defineConfig } from 'vitepress' + +export default async () => { + const posts = await (await fetch('https://my-cms.com/blog-posts')).json() + + return defineConfig({ + // параметры конфигурации на уровне приложения + lang: 'ru-RU', + title: 'VitePress', + description: 'Генератор статических сайтов на основе Vite и Vue.', + + // параметры конфигурации на уровне темы + themeConfig: { + sidebar: [ + ...posts.map((post) => ({ + text: post.name, + link: `/posts/${post.name}` + })) + ] + } + }) +} +``` + +Вы также можете использовать `await` верхнего уровня. Например: + +```ts +import { defineConfig } from 'vitepress' + +const posts = await (await fetch('https://my-cms.com/blog-posts')).json() + +export default defineConfig({ + // параметры конфигурации на уровне приложения + lang: 'ru-RU', + title: 'VitePress', + description: 'Генератор статических сайтов на основе Vite и Vue.', + + // параметры конфигурации на уровне темы + themeConfig: { + sidebar: [ + ...posts.map((post) => ({ + text: post.name, + link: `/posts/${post.name}` + })) + ] + } +}) +``` + +::: + +### Интеллектуальная настройка {#config-intellisense} + +Использование помощника `defineConfig` обеспечит интеллектуальный анализ опций конфигурации на основе TypeScript. Если ваша IDE поддерживает эту функцию, она должна работать как в JavaScript, так и в TypeScript. + +```js +import { defineConfig } from 'vitepress' + +export default defineConfig({ + // ... +}) +``` + +### Типизированная конфигурация темы {#typed-theme-config} + +По умолчанию помощник `defineConfig` ожидает тип конфигурации темы из темы по умолчанию: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + // Тип `DefaultTheme.Config` + } +}) +``` + +Если вы используете пользовательскую тему и хотите проверять типы для конфигурации темы, вам нужно использовать `defineConfigWithTheme`, и передавать тип конфигурации для вашей пользовательской темы через общий аргумент: + +```ts +import { defineConfigWithTheme } from 'vitepress' +import type { ThemeConfig } from 'your-theme' + +export default defineConfigWithTheme({ + themeConfig: { + // Tип `ThemeConfig` + } +}) +``` + +### Настройка Vite, Vue и Markdown {#vite-vue-markdown-config} + +- **Vite** + + Вы можете настроить базовый экземпляр Vite с помощью опции [vite](#vite) в конфигурации VitePress. Нет необходимости создавать отдельный файл конфигурации Vite. + +- **Vue** + + VitePress уже включает в себя официальный плагин Vue для Vite ([@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue)). Вы можете настроить его параметры с помощью опции [vue](#vue) в конфигурации VitePress. + +- **Markdown** + + Вы можете настроить базовый экземпляр [Markdown-It](https://github.com/markdown-it/markdown-it) с помощью опции [markdown](#markdown) в конфигурации VitePress. + +## Метаданные сайта {#site-metadata} + +### title {#title} + +- Тип: `string` +- По умолчанию: `VitePress` +- Можно переопределить для каждой страницы с помощью [метаданных](./frontmatter-config#title) + +Название для сайта. При использовании темы по умолчанию оно будет отображаться в панели навигации. + +Оно также будет использоваться в качестве суффикса по умолчанию для всех заголовков отдельных страниц, если не определен [`titleTemplate`](#titletemplate). Окончательный заголовок отдельной страницы будет представлять собой текстовое содержимое её первого заголовка `

`, объединённое с глобальным `title` в качестве суффикса. Например, со следующей конфигурацией и содержимым страницы: + +```ts +export default { + title: 'Мой замечательный сайт' +} +``` + +```md +# Привет +``` + +Заголовок страницы будет таким: `Привет | Мой замечательный сайт`. + +### titleTemplate {##titletemplate} + +- Тип: `string | boolean` +- Можно переопределить для каждой страницы с помощью [метаданных](./frontmatter-config#titletemplate) + +Позволяет настраивать суффикс заголовка каждой страницы или весь заголовок. Например: + +```ts +export default { + title: 'Мой замечательный сайт', + titleTemplate: 'Пользовательский суффикс' +} +``` + +```md +# Привет +``` + +Заголовок страницы будет таким: `Привет | Пользовательский суффикс`. + +Чтобы полностью настроить отображение заголовка, вы можете использовать символ `:title` в `titleTemplate`: + +```ts +export default { + titleTemplate: ':title - Пользовательский суффикс' +} +``` + +Здесь `:title` будет заменён текстом, выведенным из первого заголовка страницы `

`. Заголовок страницы предыдущего примера будет `Привет - Пользовательский суффикс`. + +Опция может быть установлена в значение `false`, чтобы отключить суффиксы заголовков. + +### description {#description} + +- Тип: `string` +- По умолчанию: `A VitePress site` +- Можно переопределить для каждой страницы с помощью [метаданных](./frontmatter-config#description) + +Описание для сайта. Это будет отображаться как тег `` в HTML-странице. + +```ts +export default { + description: 'A VitePress site' +} +``` + +### head {#head} + +- Тип: `HeadConfig[]` +- По умолчанию: `[]` +- Можно добавлять на страницу через [метаданные](./frontmatter-config#head) + +Дополнительные элементы для отображения в теге `` в HTML-странице. Добавленные пользователем теги выводятся перед закрывающим тегом `head`, после тегов VitePress. + +```ts +type HeadConfig = + | [string, Record] + | [string, Record, string] +``` + +#### Пример: Добавление значка сайта {#example-adding-a-favicon} + +```ts +export default { + head: [['link', { rel: 'icon', href: '/favicon.ico' }]] +} // поместите favicon.ico в публичную директорию; если установлен параметр base, используйте /base/favicon.ico + +/* Отрисуется так: + +*/ +``` + +#### Пример: Добавление шрифтов Google {#example-adding-google-fonts} + +```ts +export default { + head: [ + ['link', { rel: 'preconnect', href: 'https://fonts.googleapis.com' }], + [ + 'link', + { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' } + ], + [ + 'link', + { + href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap', + rel: 'stylesheet' + } + ] + ] +} + +/* Отрисуется так: + + + +*/ +``` + +#### Пример: Регистрация сервис-воркера {#example-registering-a-service-worker} + +```ts +export default { + head: [ + [ + 'script', + { id: 'register-sw' }, + `;(() => { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.register('/sw.js') + } + })()` + ] + ] +} + +/* Отрисуется так: + +*/ +``` + +#### Пример: Использование Google Analytics {#example-using-google-analytics} + +```ts +export default { + head: [ + [ + 'script', + { async: '', src: 'https://www.googletagmanager.com/gtag/js?id=TAG_ID' } + ], + [ + 'script', + {}, + `window.dataLayer = window.dataLayer || []; + function gtag(){dataLayer.push(arguments);} + gtag('js', new Date()); + gtag('config', 'TAG_ID');` + ] + ] +} + +/* Отрисуется так: + + +*/ +``` + +### lang {#lang} + +- Тип: `string` +- По умолчанию: `en-US` + +Атрибут lang для сайта. Будет выглядеть как тег `` в HTML-странице. + +```ts +export default { + lang: 'en-US' +} +``` + +### base {#base} + +- Тип: `string` +- По умолчанию: `/` + +Базовый URL-адрес, по которому будет развёрнут сайт. Этот параметр необходимо задать, если вы планируете развернуть свой сайт по подпути, например, для страниц GitHub. Если вы планируете развернуть свой сайт на `https://foo.github.io/bar/`, то вам следует установить base на `'/bar/'`. Он всегда должен начинаться и заканчиваться косой чертой. + +Параметр `base` автоматически добавляется ко всем URL, которые начинаются с `/` в других опциях, поэтому вам нужно указать его только один раз. + +```ts +export default { + base: '/base/' +} +``` + +## Маршрутизация {#routing} + +### cleanUrls {#cleanurls} + +- Тип: `boolean` +- По умолчанию: `false` + +Если установить значение `true`, VitePress будет удалять из URL-адресов завершающий `.html`. Также смотрите [Создание чистого URL-адреса](../guide/routing#generating-clean-url). + +::: warning Требуется поддержка сервера +Для включения этой функции может потребоваться дополнительная настройка на вашей хостинговой платформе. Чтобы это сработало, ваш сервер должен быть способен обслуживать `/foo.html` при посещении `/foo` **без редиректа**. +::: + +### rewrites {#rewrites} + +- Тип: `Record` + +Определяет сопоставление пользовательских каталогов с URL-адресами. Дополнительную информацию см. в секции [Маршрутизация: перезапись маршрутов](../guide/routing#route-rewrites). + +```ts +export default { + rewrites: { + 'source/:page': 'destination/:page' + } +} +``` + +## Сборка {#build} + +### srcDir {#srcdir} + +- Тип: `string` +- По умолчанию: `.` + +Каталог, в котором хранятся ваши страницы в формате Markdown, относительно корня проекта. Также смотрите [Корневая директория и директория с исходными файлами](../guide/routing#root-and-source-directory). + +```ts +export default { + srcDir: './src' +} +``` + +### srcExclude {#srcexclude} + +- Тип: `string` +- По умолчанию: `undefined` + +[Шаблон](https://github.com/mrmlnc/fast-glob#pattern-syntax) для поиска файлов, которые должны быть исключены из исходного содержимого. + +```ts +export default { + srcExclude: ['**/README.md', '**/TODO.md'] +} +``` + +### outDir {#outdir} + +- Тип: `string` +- По умолчанию: `./.vitepress/dist` + +Расположение вывода сборки для сайта, относительно [корня проекта](../guide/routing#root-and-source-directory). + +```ts +export default { + outDir: '../public' +} +``` + +### assetsDir {#assetsdir} + +- Тип: `string` +- По умолчанию: `assets` + +Укажите каталог, в котором будут храниться сгенерированные ресурсы. Путь должен находиться внутри [`outDir`](#outdir) и разрешается относительно него. + +```ts +export default { + assetsDir: 'static' +} +``` + +### cacheDir {#cachedir} + +- Тип: `string` +- По умолчанию: `./.vitepress/cache` + +Каталог для файлов кэша, относительно [корня проекта](../guide/routing#root-and-source-directory). См. также: [cacheDir](https://vitejs.dev/config/shared-options.html#cachedir). + +```ts +export default { + cacheDir: './.vitepress/.vite' +} +``` + +### ignoreDeadLinks {#ignoredeadlinks} + +- Тип: `boolean | 'localhostLinks' | (string | RegExp | ((link: string) => boolean))[]` +- По умолчанию: `false` + +Если установлено значение `true`, VitePress не будет завершать сборку из-за неработающих ссылок. + +Если установить значение `'localhostLinks'`, сборка будет завершаться при наличии неработающих ссылок, но не будет проверять ссылки `localhost`. + +```ts +export default { + ignoreDeadLinks: true +} +``` + +Это также может быть массив точных строк url, шаблонов regex или пользовательских функций фильтрации. + +```ts +export default { + ignoreDeadLinks: [ + // игнорировать url "/playground" + '/playground', + // игнорировать все ссылки на localhost + /^https?:\/\/localhost/, + // игнорировать все ссылки, включающие "/repl/"" + /\/repl\//, + // пользовательская функция, игнорирует все ссылки, включающие "ignore" + (url) => { + return url.toLowerCase().includes('ignore') + } + ] +} +``` + +### metaChunk {#metachunk} + +- Тип: `boolean` +- По умолчанию: `false` + +Если установлено значение `true`, метаданные страницы извлекаются в отдельный фрагмент JavaScript, а не вставляются в исходный HTML. Это уменьшает полезную нагрузку HTML каждой страницы и делает метаданные страниц кэшируемыми, что позволяет снизить пропускную способность сервера при наличии большого количества страниц на сайте. + +### mpa {#mpa} + +- Тип: `boolean` +- По умолчанию: `false` + +Если установлено значение `true`, производственное приложение будет создано в [режиме MPA](../guide/mpa-mode). В режиме MPA по умолчанию используется 0 КБ JavaScript, что приводит к отключению навигации на стороне клиента и требует явного согласия на интерактивность. + +## Тема {#theming} + +### appearance {#appearance} + +- Тип: `boolean | 'dark' | 'force-dark' | import('@vueuse/core').UseDarkOptions` +- По умолчанию: `true` + +Включать ли тёмный режим (путём добавления класса `.dark` к элементу ``). + +- Если опция имеет значение `true`, тема по умолчанию будет определяться цветовой гаммой, предпочитаемой пользователем. +- Если опция имеет значение `dark`, тема по умолчанию будет тёмной, если пользователь не переключит её вручную. +- Если установить значение `false`, пользователи не смогут переключать тему. + +Эта опция вставляет встроенный скрипт, который восстанавливает настройки пользователей из локального хранилища с помощью ключа `vitepress-theme-appearance`. Это гарантирует, что класс `.dark` будет применён до отрисовки страницы, чтобы избежать мерцания. + +`appearance.initialValue` может быть только `'dark' | undefined`. Ссылки или геттеры не поддерживаются. + +### lastUpdated {#lastupdated} + +- Тип: `boolean` +- По умолчанию: `false` + +Получать ли временную метку последнего обновления для каждой страницы с помощью Git. Временная метка будет включена в данные каждой страницы, доступные через [`useData`](./runtime-api#usedata). + +При использовании темы по умолчанию включение этой опции приведёт к отображению времени последнего обновления каждой страницы. Вы можете настроить текст с помощью опции [`themeConfig.lastUpdatedText`](./default-theme-config#lastupdatedtext). + +## Кастомизация {#customization} + +### markdown {#markdown} + +- Тип: `MarkdownOption` + +Настройте параметры парсера Markdown. VitePress использует [Markdown-it](https://github.com/markdown-it/markdown-it) в качестве парсера и [Shiki](https://github.com/shikijs/shiki) для подсветки синтаксиса языка. Внутри этой опции вы можете передать различные параметры, связанные с Markdown, в соответствии с вашими потребностями. + +```js +export default { + markdown: {...} +} +``` + +Проверьте [объявление типа и jsdocs](https://github.com/vuejs/vitepress/blob/main/src/node/markdown/markdown.ts) на наличие всех доступных опций. + +### vite {#vite} + +- Тип: `import('vite').UserConfig` + +Передаёт необработанную [конфигурацию Vite](https://vitejs.dev/config/) внутреннему серверу разработки / сборщику Vite. + +```js +export default { + vite: { + // параметры конфигурации Vite + } +} +``` + +### vue {#vue} + +- Тип: `import('@vitejs/plugin-vue').Options` + +Передаёт необработанные [параметры `@vitejs/plugin-vue`](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue#options) внутреннему экземпляру плагина. + +```js +export default { + vue: { + // параметры @vitejs/plugin-vue + } +} +``` + +## Хуки сборки {#build-hooks} + +Хуки для сборки VitePress позволяют добавлять на сайт новую функциональность и поведение: + +- Карта сайта +- Поисковая индексация +- PWA +- Телепорты + +### buildEnd {#buildend} + +- Тип: `(siteConfig: SiteConfig) => Awaitable` + +`buildEnd` — это хук CLI сборки, который будет запущен после завершения сборки (SSG), но до выхода из процесса VitePress CLI. + +```ts +export default { + async buildEnd(siteConfig) { + // ... + } +} +``` + +### postRender {#postrender} + +- Тип: `(context: SSGContext) => Awaitable` + +`postRender` — это хук сборки, вызываемый после завершения рендеринга SSG. Это позволит вам обрабатывать содержимое телепортов во время SSG. + +```ts +export default { + async postRender(context) { + // ... + } +} +``` + +```ts +interface SSGContext { + content: string + teleports?: Record + [key: string]: any +} +``` + +### transformHead {#transformhead} + +- Тип: `(context: TransformContext) => Awaitable` + +`transformHead` — это хук сборки для преобразования заголовка перед генерацией каждой страницы. Это позволит вам добавить в конфигурацию VitePress записи, которые не могут быть добавлены статически. Вам нужно только вернуть дополнительные записи, они будут автоматически объединены с существующими. + +::: warning ПРЕДУПРЕЖДЕНИЕ +Не мутируйте ничего внутри `context`. +::: + +```ts +export default { + async transformHead(context) { + // ... + } +} +``` + +```ts +interface TransformContext { + page: string // например, index.md (относительно srcDir) + assets: string[] // все ресурсы, не относящиеся к js/css, в виде полностью разрешённых публичных URL-адресов + siteConfig: SiteConfig + siteData: SiteData + pageData: PageData + title: string + description: string + head: HeadConfig[] + content: string +} +``` + +Обратите внимание, что этот хук вызывается только при статической генерации сайта. Он не вызывается во время разработки. Если вам нужно добавить динамические записи в голову во время разработки, вместо этого вы можете использовать хук [`transformPageData`](#transformpagedata): + +```ts +export default { + transformPageData(pageData) { + pageData.frontmatter.head ??= [] + pageData.frontmatter.head.push([ + 'meta', + { + name: 'og:title', + content: + pageData.frontmatter.layout === 'home' + ? `VitePress` + : `${pageData.title} | VitePress` + } + ]) + } +} +``` + +#### Пример: Добавление канонического URL-адреса `` {#example-adding-a-canonical-url-link} + +```ts +export default { + transformPageData(pageData) { + const canonicalUrl = `https://example.com/${pageData.relativePath}` + .replace(/index\.md$/, '') + .replace(/\.md$/, '.html') + + pageData.frontmatter.head ??= [] + pageData.frontmatter.head.push([ + 'link', + { rel: 'canonical', href: canonicalUrl } + ]) + } +} +``` + +### transformHtml {#transformhtml} + +- Тип: `(code: string, id: string, context: TransformContext) => Awaitable` + +`transformHtml` — это хук сборки для преобразования содержимого каждой страницы перед сохранением на диск. + +::: warning ПРЕДУПРЕЖДЕНИЕ +Не мутируйте ничего внутри `контекста`. Кроме того, изменение html-содержимого может вызвать проблемы с гидратацией во время выполнения. +::: + +```ts +export default { + async transformHtml(code, id, context) { + // ... + } +} +``` + +### transformPageData {#transformpagedata} + +- Тип: `(pageData: PageData, context: TransformPageContext) => Awaitable | { [key: string]: any } | void>` + +`transformPageData` — это хук для преобразования `pageData` каждой страницы. Вы можете напрямую изменять `pageData` или возвращать изменённые значения, которые будут объединены с данными страницы. + +::: warning ПРЕДУПРЕЖДЕНИЕ +Не мутируйте ничего внутри `context` и будьте осторожны, это может повлиять на производительность dev-сервера, особенно если у вас есть некоторые сетевые запросы или тяжёлые вычисления (например, генерация изображений) в хуке. Вы можете проверить `process.env.NODE_ENV === 'production'` для условной логики. +::: + +```ts +export default { + async transformPageData(pageData, { siteConfig }) { + pageData.contributors = await getPageContributors(pageData.relativePath) + } + + // или возвращаем данные для объединения + async transformPageData(pageData, { siteConfig }) { + return { + contributors: await getPageContributors(pageData.relativePath) + } + } +} +``` + +```ts +interface TransformPageContext { + siteConfig: SiteConfig +} +``` diff --git a/docs/zh/guide/asset-handling.md b/docs/zh/guide/asset-handling.md new file mode 100644 index 00000000..69259a6a --- /dev/null +++ b/docs/zh/guide/asset-handling.md @@ -0,0 +1,63 @@ +# 资源处理 {#asset-handling} + +## 引用静态资源 {#referencing-static-assets} + +所有的 Markdown 文件都会被编译成 Vue 组件,并由 [Vite](https://cn.vitejs.dev/guide/assets.html) 处理。可以**并且应该**使用相对路径来引用资源: + +```md +![An image](./image.png) +``` + +可以在 Markdown 文件、主题中的 `*.vue` 组件、样式和普通的 `.css` 文件中引用静态资源,可以使用绝对路径 (基于项目根目录) 或者相对路径 (基于文件系统)。后者类似于 Vite、Vue CLI 或者 webpack 的 `file-loader` 的行为。 + +常见的图像,媒体和字体文件会被自动检测并视作资源。 + +::: tip 通过链接引用的文件不会视作资源 +在 Markdown 内,通过链接引用的 PDF 或者其他文档不会被自动视作资源。要使这些文件可用,你必须手动将其放在项目的 [`public`](#the-public-directory) 目录内。 +::: + +所有引用的资源,包括那些使用绝对路径的,都会在生产构建过程中被复制到输出目录,并使用哈希文件名。从未使用过的资源将不会被复制。小于 4kb 的图像资源将会采用 base64 内联——这可以通过 [`vite`](../reference/site-config#vite) 配置选项进行配置。 + +所有**静态**路径引用,包括绝对路径,都应基于你的工作目录的结构。 + +## public 目录 {#the-public-directory} + +有时可能需要一些静态资源,但这些资源没有直接被 Markdown 或主题组件直接引用,或者你可能想以原始文件名提供某些文件,像 `robots.txt`,favicons 和 PWA 图标这样的文件。 + +可以将这些文件放置在[源目录](./routing#source-directory)的 `public` 目录中。例如,如果项目根目录是 `./docs`,并且使用默认源目录位置,那么 public 目录将是 `./docs/public`。 + +放置在 `public` 中的资源将按原样复制到输出目录的根目录中。 + +请注意,应使用根绝对路径来引用放置在 `public` 中的文件——例如,`public/icon.png` 应始终在源代码中使用 `/icon.png` 引用。 + +## 根 URL {#base-url} + +如果站点没有部署在根 URL 上,则需要在 `.vitepress/config.js` 中设置 `base` 选项。例如,如果计划将站点部署到 `https://foo.github.io/bar/`,则 `base` 应设置为 `'/bar/'`(它应始终以斜杠开头和结尾)。 + +所有静态资源路径都会被自动处理,来适应不同的 `base` 配置值。例如,如果 markdown 中有一个对 `public` 中的资源的绝对引用: + +```md +![An image](/image-inside-public.png) +``` + +在这种情况下,更改 `base` 配置值时,**无需**更新该引用。 + +但是如果你正在编写一个主题组件,它动态地链接到资源,例如一个图片,它的 `src` 基于主题配置: + +```vue + +``` + +在这种情况下,建议使用 VitePress 提供的 [`withBase` helper](../reference/runtime-api#withbase) 来包括路径: + +```vue + + + +``` diff --git a/docs/zh/guide/cms.md b/docs/zh/guide/cms.md new file mode 100644 index 00000000..916ba050 --- /dev/null +++ b/docs/zh/guide/cms.md @@ -0,0 +1,56 @@ +--- +outline: deep +--- + +# 连接到 CMS {#connecting-to-a-cms} + +## 一般的工作流 {#general-workflow} + +将 VitePress 连接到 CMS 主要围绕[动态路由](./routing#dynamic-routes)展开。在继续阅读之前,请确保了解它的工作原理。 + +由于每个 CMS 的工作方式都不同,因此我们只能提供一个通用的工作流,你需要根据具体情况进行调整。 + +1. 如果你的 CMS 需要身份验证,请创建一个 `.env` 文件来存储你的 API token: + + ```js + // posts/[id].paths.js + import { loadEnv } from 'vitepress' + + const env = loadEnv('', process.cwd()) + ``` + +2. 从 CMS 获取必要的数据并将其格式调整为合适的路径数据: + + ```js + export default { + async paths() { + // 如有需要,使用相应的 CMS 客户端库 + const data = await (await fetch('https://my-cms-api', { + headers: { + // 如有必要,可使用 token + } + })).json() + + return data.map(entry => { + return { + params: { id: entry.id, /* title, authors, date 等 */ }, + content: entry.content + } + }) + } + } + ``` + +3. 在页面中渲染内容: + + ```md + # {{ $params.title }} + + - by {{ $params.author }} on {{ $params.date }} + + + ``` + +## 整合指南 {#integration-guides} + +如果你已经写了一篇关于如何将 VitePress 与特定的 CMS 集成的指南,请点击下面的“在 GitHub 上编辑此页面”链接将它提交到这里! diff --git a/docs/zh/guide/custom-theme.md b/docs/zh/guide/custom-theme.md new file mode 100644 index 00000000..e5eb760b --- /dev/null +++ b/docs/zh/guide/custom-theme.md @@ -0,0 +1,222 @@ +# 自定义主题 {#using-a-custom-theme} + +## 解析主题 {#theme-resolving} + +可以通过创建一个 `.vitepress/theme/index.js` 或 `.vitepress/theme/index.ts` 文件 (即“主题入口文件”) 来启用自定义主题: + +``` +. +├─ docs # 项目根目录 +│ ├─ .vitepress +│ │ ├─ theme +│ │ │ └─ index.js # 主题入口 +│ │ └─ config.js # 配置文件 +│ └─ index.md +└─ package.json +``` + +当检测到存在主题入口文件时,VitePress 总会使用自定义主题而不是默认主题。但你可以[扩展默认主题](./extending-default-theme)来在其基础上实现更高级的自定义。 + +## 主题接口 {#theme-interface} + +VitePress 自定义主题是一个对象,该对象具有如下接口: + +```ts +interface Theme { + /** + * 每个页面的根布局组件 + * @required + */ + Layout: Component + /** + * 增强 Vue 应用实例 + * @optional + */ + enhanceApp?: (ctx: EnhanceAppContext) => Awaitable + /** + * 扩展另一个主题,在我们的主题之前调用它的 `enhanceApp` + * @optional + */ + extends?: Theme +} + +interface EnhanceAppContext { + app: App // Vue 应用实例 + router: Router // VitePress 路由实例 + siteData: Ref // 站点级元数据 +} +``` + +主题入口文件需要将主题作为默认导出来导出: + +```js +// .vitepress/theme/index.js + +// 可以直接在主题入口导入 Vue 文件 +// VitePress 已预先配置 @vitejs/plugin-vue +import Layout from './Layout.vue' + +export default { + Layout, + enhanceApp({ app, router, siteData }) { + // ... + } +} +``` + +默认导出是自定义主题的唯一方式,并且只有 `Layout` 属性是必须的。所以从技术上讲,一个 VitePress 主题可以是一个单独的 Vue 组件。 + +在组件内部,它的工作方式就像是一个普通的 Vite + Vue 3 应用。请注意,主题还需要保证 [SSR 兼容](./ssr-compat)。 + +## 构建布局 {#building-a-layout} + +最基本的布局组件需要包含一个 [``](../reference/runtime-api#content) 组件: + +```vue + + +``` + +上面的布局只是将每个页面的 markdown 渲染为 HTML。我们添加的第一个改进是处理 404 错误: + +```vue{1-4,9-12} + + + +``` + +[`useData()`](../reference/runtime-api#usedata) 为我们提供了所有的运行时数据,以便我们根据不同条件渲染不同的布局。我们可以访问的另一个数据是当前页面的 frontmatter。通过利用这个数据,可以让用户单独控制每个页面的布局。例如,用户可以指定一个页面是否使用特殊的主页布局: + +```md +--- +layout: home +--- +``` + +并且我们可以调整主题进行处理: + +```vue{3,12-14} + + + +``` + +当然你可以将布局切分为不同的组件: + +```vue{3-5,12-15} + + + +``` + +请查看[运行时 API 参考](../reference/runtime-api)获取主题组件中所有可用内容。此外,可以利用[构建时数据加载](./data-loading)来生成数据驱动布局——例如,一个列出当前项目中所有博客文章的页面。 + +## 分发自定义主题 {#distributing-a-custom-theme} + +分发自定义主题最简单的方式是通过将其作为 [GitHub 模版仓库](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository)。 + +如果你希望将主题作为 npm 包来分发,请按照下面的步骤操作: + +1. 在包入口将主题对象使用默认导出。 + +2. 如果合适的话,将主题配置类型定义作为 `ThemeConfig` 导出。 + +3. 如果主题需要调整 VitePress 配置,请在包的子路径下 (例如 `my-theme/config`) 下导出该配置,以便用户扩展。 + +4. 记录主题配置选项 (通过配置文件和 frontmatter)。 + +5. 提供清晰的说明,告诉用户如何使用主题 (见下文)。 + +## 使用自定义主题 {#consuming-a-custom-theme} + +要使用外部主题,请导入它并重新导出: + +```js +// .vitepress/theme/index.js +import Theme from 'awesome-vitepress-theme' + +export default Theme +``` + +如果主题需要扩展: + +```js +// .vitepress/theme/index.js +import Theme from 'awesome-vitepress-theme' + +export default { + extends: Theme, + enhanceApp(ctx) { + // ... + } +} +``` + +如果主题需要特殊的 VitePress 配置,也需要在配置中扩展: + +```ts +// .vitepress/config.ts +import baseConfig from 'awesome-vitepress-theme/config' + +export default { + // 扩展主题的基本配置(如需要) + extends: baseConfig +} +``` + +最后,如果主题为其主题配置提供了类型: + +```ts +// .vitepress/config.ts +import baseConfig from 'awesome-vitepress-theme/config' +import { defineConfigWithTheme } from 'vitepress' +import type { ThemeConfig } from 'awesome-vitepress-theme' + +export default defineConfigWithTheme({ + extends: baseConfig, + themeConfig: { + // 类型为 `ThemeConfig` + } +}) +``` diff --git a/docs/zh/guide/data-loading.md b/docs/zh/guide/data-loading.md new file mode 100644 index 00000000..ae23b0d1 --- /dev/null +++ b/docs/zh/guide/data-loading.md @@ -0,0 +1,247 @@ +# 构建时数据加载 {#build-time-data-loading} + +VitePress 提供了**数据加载**的功能,它允许加载任意数据并从页面或组件中导入它。数据加载**只在构建时**执行:最终的数据将被序列化为 JavaScript 包中的 JSON。 + +数据加载可以被用于获取远程数据,也可以基于本地文件生成元数据。例如,可以使用数据加载来解析所有本地 API 页面并自动生成所有 API 入口的索引。 + +## 基本用法 {#basic-usage} + +一个用于数据加载的文件必须以 `.data.js` 或 `.data.ts` 结尾。该文件应该提供一个默认导出的对象,该对象具有 `load()` 方法: + +```js +// example.data.js +export default { + load() { + return { + hello: 'world' + } + } +} +``` + +数据加载模块只在 Node.js 中执行,因此可以按需导入 Node API 和 npm 依赖。 + +然后,可以在 `.md` 页面和 `.vue` 组件中使用 `data` 具名导出从该文件中导入数据: + +```vue + + +
{{ data }}
+``` + +输出: + +```json +{ + "hello": "world" +} +``` + +你会注意到 data loader 本身并没有导出 `data`。这是因为 VitePress 在后台调用了 `load()` 方法,并通过名为 `data` 的具名导出隐式地暴露了结果。 + +即使它是异步的,这也是有效的: + +```js +export default { + async load() { + // 获取远程数据 + return (await fetch('...')).json() + } +} +``` + +## 使用本地文件生成数据 {#data-from-local-files} + +当需要基于本地文件生成数据时,需要在 data loader 中使用 `watch` 选项,以便这些文件改动时可以触发热更新。 + +`watch` 选项也很方便,因为可以使用 [glob 模式](https://github.com/mrmlnc/fast-glob#pattern-syntax) 匹配多个文件。模式可以相对于数据加载文件本身,`load()` 函数将接收匹配文件的绝对路径。 + +下面的例子展示了如何使用 [csv-parse](https://github.com/adaltas/node-csv/tree/master/packages/csv-parse/) 加载 CSV 文件并将其转换为 JSON。因为此文件仅在构建时执行,因此不会将 CSV 解析器发送到客户端。 + +```js +import fs from 'node:fs' +import { parse } from 'csv-parse/sync' + +export default { + watch: ['./data/*.csv'], + load(watchedFiles) { + // watchFiles 是一个所匹配文件的绝对路径的数组。 + // 生成一个博客文章元数据数组 + // 可用于在主题布局中呈现列表。 + return watchedFiles.map((file) => { + return parse(fs.readFileSync(file, 'utf-8'), { + columns: true, + skip_empty_lines: true + }) + }) + } +} +``` + +## `createContentLoader` + +当构建一个内容为主的站点时,我们经常需要创建一个“归档”或“索引”页面:一个我们可以列出内容中的所有可用条目的页面,例如博客文章或 API 页面。我们**可以**直接使用数据加载 API 实现这一点,但由于这会经常使用,VitePress 还提供了一个 `createContentLoader` 辅助函数来简化这个过程: + +```js +// posts.data.js +import { createContentLoader } from 'vitepress' + +export default createContentLoader('posts/*.md', /* options */) +``` + +该辅助函数接受一个相对于[源目录](./routing#source-directory)的 glob 模式,并返回一个 `{ watch, load }` 数据加载对象,该对象可以用作数据加载文件中的默认导出。它还基于文件修改时间戳实现了缓存以提高开发性能。 + +请注意,数据加载仅适用于 Markdown 文件——匹配的非 Markdown 文件将被跳过。 + +加载的数据将是一个类型为 `ContentData[]` 的数组: + +```ts +interface ContentData { + // 页面的映射 URL,如 /posts/hello.html(不包括 base) + // 手动迭代或使用自定义 `transform` 来标准化路径 + url: string + // 页面的 frontmatter 数据 + frontmatter: Record + + // 只有启用了相关选项,才会出现以下内容 + // 我们将在下面讨论它们 + src: string | undefined + html: string | undefined + excerpt: string | undefined +} +``` + +默认情况下只提供 `url` 和 `frontmatter`。这是因为加载的数据将作为 JSON 内联在客户端 bundle 中,我们需要谨慎考虑其大小。下面的例子展示了如何使用数据构建最小的博客索引页面: + +```vue + + + +``` + +### 选项 {#options} + +默认数据可能不适合所有需求——可以选择使用选项转换数据: + +```js +// posts.data.js +import { createContentLoader } from 'vitepress' + +export default createContentLoader('posts/*.md', { + includeSrc: true, // 包含原始 markdown 源? + render: true, // 包含渲染的整页 HTML? + excerpt: true, // 包含摘录? + transform(rawData) { + // 根据需要对原始数据进行 map、sort 或 filter + // 最终的结果是将发送给客户端的内容 + return rawData.sort((a, b) => { + return +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date) + }).map((page) => { + page.src // 原始 markdown 源 + page.html // 渲染的整页 HTML + page.excerpt // 渲染的摘录 HTML(第一个 `---` 上面的内容) + return {/* ... */} + }) + } +}) +``` + +查看它在 [Vue.js 博客](https://github.com/vuejs/blog/blob/main/.vitepress/theme/posts.data.ts)中是如何使用的。 + +`createContentLoader` API 也可以在[构建钩子](/reference/site-config#build-hooks)中使用: + +```js +// .vitepress/config.js +export default { + async buildEnd() { + const posts = await createContentLoader('posts/*.md').load() + // 根据 posts 元数据生成文件,如 RSS 订阅源 + } +} +``` + +**类型** + +```ts +interface ContentOptions { + /** + * 包含 src? + * @default false + */ + includeSrc?: boolean + + /** + * 将 src 渲染为 HTML 并包含在数据中? + * @default false + */ + render?: boolean + + /** + * 如果为 `boolean`,是否解析并包含摘录? (呈现为 HTML) + * + * 如果为 `function`,则控制如何从内容中提取摘录 + * + * 如果为 `string`,则定义用于提取摘录的自定义分隔符 + * 如果 `excerpt` 为 `true`,则默认分隔符为 `---` + * + * @see https://github.com/jonschlinkert/gray-matter#optionsexcerpt + * @see https://github.com/jonschlinkert/gray-matter#optionsexcerpt_separator + * + * @default false + */ + excerpt?: + | boolean + | ((file: { data: { [key: string]: any }; content: string; excerpt?: string }, options?: any) => void) + | string + + /** + * 转换数据。请注意,如果从组件或 Markdown 文件导入,数据将以 JSON 形式内联到客户端包中 + */ + transform?: (data: ContentData[]) => T | Promise +} +``` + +## 为 data loader 导出类型 {#typed-data-loaders} + +当使用 TypeScript 时,可以像这样为 loader 和 `data` 导出类型: + +```ts +import { defineLoader } from 'vitepress' + +export interface Data { + // data 类型 +} + +declare const data: Data +export { data } + +export default defineLoader({ + // 类型检查加载器选项 + watch: ['...'], + async load(): Promise { + // ... + } +}) +``` + +## 配置 {#configuration} + +要获取 data loader 中的配置信息,可以使用如下代码: + +```ts +import type { SiteConfig } from 'vitepress' + +const config: SiteConfig = (globalThis as any).VITEPRESS_CONFIG +``` diff --git a/docs/zh/guide/deploy.md b/docs/zh/guide/deploy.md new file mode 100644 index 00000000..cb479305 --- /dev/null +++ b/docs/zh/guide/deploy.md @@ -0,0 +1,289 @@ +--- +outline: deep +--- + +# 部署 VitePress 站点 {#deploy-your-vitepress-site} + +以下指南基于一些前提: + +- VitePress 站点位于项目的 `docs` 目录中。 +- 你使用的是默认的生成输出目录 (`.vitepress/dist`)。 +- VitePress 作为本地依赖项安装在项目中,并且你已在 `package.json` 中设置以下脚本: + + ```json + { + "scripts": { + "docs:build": "vitepress build docs", + "docs:preview": "vitepress preview docs" + } + } + ``` + +## 本地构建与测试 {#build-and-test-locally} + +1. 可以运行以下命令来构建文档: + + ```sh + $ npm run docs:build + ``` + +2. 构建文档后,通过运行以下命令可以在本地预览它: + + ```sh + $ npm run docs:preview + ``` + + `preview` 命令将启动一个本地静态 Web 服务 `http://localhost:4173`,该服务以 `.vitepress/dist` 作为源文件。这是检查生产版本在本地环境中是否正常的一种简单方法。 + +3. 可以通过传递 `--port` 作为参数来配置服务器的端口。 + + ```json + { + "scripts": { + "docs:preview": "vitepress preview docs --port 8080" + } + } + ``` + + 现在 `docs:preview` 方法将会在 `http://localhost:8080` 启动服务。 + +## 设定 public 根目录 {#setting-a-public-base-path} + +默认情况下,我们假设站点将部署在域名 (`/`) 的根路径上。如果站点在子路径中提供服务,例如 `https://mywebsite.com/blog/`,则需要在 VitePress 配置中将 [`base`](../reference/site-config#base) 选项设置为 `'/blog/'`。 + +**例**:如果你使用的是 Github(或 GitLab)页面并部署到 `user.github.io/repo/`,请将 `base` 设置为 `/repo/`。 + +## HTTP 缓存标头 {#http-cache-headers} + +如果可以控制生产服务器上的 HTTP 标头,则可以配置 `cache-control` 标头以在重复访问时获得更好的性能。 + +生产版本对静态资源 (JavaScript、CSS 和其他非 `public` 目录中的导入资源) 使用哈希文件名。如果你使用浏览器开发工具的网络选项卡查看生产预览,你将看到类似 `app.4f283b18.js` 的文件。 + +此哈希 `4f283b18` 是从此文件的内容生成的。相同的哈希 URL 保证提供相同的文件内容——如果内容更改,URL 也会更改。这意味着你可以安全地为这些文件使用最强的缓存标头。所有此类文件都将放置在输出目录的 `assets/` 中,因此你可以为它们配置以下标头: + +``` +Cache-Control: max-age=31536000,immutable +``` + +::: details Netlify 示例 `_headers` 文件 + +``` +/assets/* + cache-control: max-age=31536000 + cache-control: immutable +``` + +注意:该 `_headers` 文件应放置在 [public 目录](/guide/asset-handling#the-public-directory)中 (在我们的例子中是 `docs/public/_headers`),以便将其逐字复制到输出目录。 + +[Netlify 自定义标头文档](https://docs.netlify.com/routing/headers/) + +::: + +::: details Vercel 配置示例 `vercel.json` + +```json +{ + "headers": [ + { + "source": "/assets/(.*)", + "headers": [ + { + "key": "Cache-Control", + "value": "max-age=31536000, immutable" + } + ] + } + ] +} +``` + +注意:`vercel.json` 文件应放在存储库的根目录中。 + +[Vercel 关于标头配置的文档](https://vercel.com/docs/concepts/projects/project-configuration#headers) + +::: + +## 各平台部署指南 {#platform-guides} + +### Netlify / Vercel / Cloudflare Pages / AWS Amplify / Render + +使用仪表板创建新项目并更改这些设置: + +- **构建命令:** `npm run docs:build` +- **输出目录:** `docs/.vitepress/dist` +- **node 版本:** `18` (或更高版本) + +::: warning +不要为 HTML 代码启用 _Auto Minify_ 等选项。它将从输出中删除对 Vue 有意义的注释。如果被删除,你可能会看到激活不匹配错误。 +::: + +### GitHub Pages + +1. 在项目的 `.github/workflows` 目录中创建一个名为 `deploy.yml` 的文件,其中包含这样的内容: + + ```yaml + # 构建 VitePress 站点并将其部署到 GitHub Pages 的示例工作流程 + # + name: Deploy VitePress site to Pages + + on: + # 在针对 `main` 分支的推送上运行。如果你 + # 使用 `master` 分支作为默认分支,请将其更改为 `master` + push: + branches: [main] + + # 允许你从 Actions 选项卡手动运行此工作流程 + workflow_dispatch: + + # 设置 GITHUB_TOKEN 的权限,以允许部署到 GitHub Pages + permissions: + contents: read + pages: write + id-token: write + + # 只允许同时进行一次部署,跳过正在运行和最新队列之间的运行队列 + # 但是,不要取消正在进行的运行,因为我们希望允许这些生产部署完成 + concurrency: + group: pages + cancel-in-progress: false + + jobs: + # 构建工作 + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # 如果未启用 lastUpdated,则不需要 + # - uses: pnpm/action-setup@v3 # 如果使用 pnpm,请取消注释 + # - uses: oven-sh/setup-bun@v1 # 如果使用 Bun,请取消注释 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm # 或 pnpm / yarn + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Install dependencies + run: npm ci # 或 pnpm install / yarn install / bun install + - name: Build with VitePress + run: npm run docs:build # 或 pnpm docs:build / yarn docs:build / bun run docs:build + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs/.vitepress/dist + + # 部署工作 + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + name: Deploy + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 + ``` + + ::: warning + 确保 VitePress 中的 `base` 选项配置正确。有关更多详细信息,请参阅[设置根路径](#setting-a-public-base-path)。 + ::: + +2. 在存储库设置中的“Pages”菜单项下,选择“Build and deployment > Source > GitHub Actions”。 + +3. 将更改推送到 `main` 分支并等待 GitHub Action 工作流完成。你应该看到站点部署到 `https://.github.io/[repository]/` 或 `https:///`,这取决于你的设置。你的站点将在每次推送到 `main` 分支时自动部署。 + +### GitLab Pages + +1. 如果你想部署到 `https:// .gitlab.io/ /`,将 VitePress 配置中的 `outDir` 设置为 `../public`。将 `base` 选项配置为 `'//'`。 + +2. 在项目的根目录中创建一个名为 `.gitlab-ci.yml` 的文件,其中包含以下内容。每当你更改内容时,这都会构建和部署你的站点: + + ```yaml + image: node:18 + pages: + cache: + paths: + - node_modules/ + script: + # - apk add git # 如果你使用的是像 alpine 这样的小型 docker 镜像,并且启用了 lastUpdated,请取消注释 + - npm install + - npm run docs:build + artifacts: + paths: + - public + only: + - main + ``` + +### Azure 静态 web 应用 {#azure-static-web-apps} + +1. 参考[官方文档](https://docs.microsoft.com/en-us/azure/static-web-apps/build-configuration)。 + +2. 在配置文件中设置这些值 (并删除不需要的值,如 `api_location`): + + - **`app_location`**: `/` + - **`output_location`**: `docs/.vitepress/dist` + - **`app_build_command`**: `npm run docs:build` + +### Firebase {#firebase} + +1. 在项目的根目录下创建 `firebase.json` 和 `.firebaserc`: + + `firebase.json`: + + ```json + { + "hosting": { + "public": "docs/.vitepress/dist", + "ignore": [] + } + } + ``` + + `.firebaserc`: + + ```json + { + "projects": { + "default": "" + } + } + ``` + +2. 运行 `npm run docs:build` 后,运行此命令进行部署: + + ```sh + firebase deploy + ``` + +### Surge + +1. 运行 `npm run docs:build` 后,运行此命令进行部署: + + ```sh + npx surge docs/.vitepress/dist + ``` + +### Heroku + +1. 参考 [`heroku-buildpack-static`](https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-static) 中给出的文档和指南。 + +2. 使用以下内容在项目的根目录中创建一个名为 `static.json` 的文件: + + ```json + { + "root": "docs/.vitepress/dist" + } + ``` + +### Edgio + +请参阅[创建并部署 VitePress 应用程序到 Edgio](https://docs.edg.io/guides/vitepress)。 + +### Kinsta 静态站点托管 {#kinsta-static-site-hosting} + +你可以按照这些[说明](https://kinsta.com/docs/vitepress-static-site-example/) 在 [Kinsta](https://kinsta.com/static-site-hosting/) 上部署 Vitepress 站点。 diff --git a/docs/zh/guide/extending-default-theme.md b/docs/zh/guide/extending-default-theme.md new file mode 100644 index 00000000..4bb495fa --- /dev/null +++ b/docs/zh/guide/extending-default-theme.md @@ -0,0 +1,340 @@ +--- +outline: deep +--- + +# 扩展默认主题 {#extending-the-default-theme} + +VitePress 默认的主题已经针对文档进行了优化,并且可以进行自定义。请参考[默认主题配置概览](../reference/default-theme-config)获取完整的选项列表。 + +但是有一些情况仅靠配置是不够的。例如: + +1. 需要调整 CSS 样式; +2. 需要修改 Vue 应用实例,例如注册全局组件; +3. 需要通过 layout 插槽将自定义内容注入到主题中; + +这些高级自定义配置将需要使用自定义主题来“拓展”默认主题。 + +:::tip +在继续之前,请确保首先阅读[自定义主题](./custom-theme)以了解其工作原理。 +::: + +## 自定义 CSS {#customizing-css} + +可以通过覆盖根级别的 CSS 变量来自定义默认主题的 CSS: + +```js +// .vitepress/theme/index.js +import DefaultTheme from 'vitepress/theme' +import './custom.css' + +export default DefaultTheme +``` + +```css +/* .vitepress/theme/custom.css */ +:root { + --vp-c-brand-1: #646cff; + --vp-c-brand-2: #747bff; +} +``` + +查看[默认主题 CSS 变量](https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css)来获取可以被覆盖的变量。 + +## 使用自定义字体 {#using-different-fonts} + +VitePress 使用 [Inter](https://rsms.me/inter/) 作为默认字体,并且将其包含在生成的输出中。该字体在生产环境中也会自动预加载。但是如果要使用不同的字体,这可能不是很好。 + +为了避免在生成后的输出中包含 Inter 字体,请从 `vitepress/theme-without-fonts` 中导入主题: + +```js +// .vitepress/theme/index.js +import DefaultTheme from 'vitepress/theme-without-fonts' +import './my-fonts.css' + +export default DefaultTheme +``` + +```css +/* .vitepress/theme/custom.css */ +:root { + --vp-font-family-base: /* normal text font */ + --vp-font-family-mono: /* code font */ +} +``` + +::: warning +如果你在使用像是[团队页](/reference/default-theme-team-page)这样的组件,请确保也从 `vitepress/theme-without-fonts` 中导入它们! +::: + +如果字体是通过 `@font-face` 引用的本地文件,它将会被作为资源被包含在 `.vitepress/dist/asset` 目录下,并且使用哈希后的文件名。为了预加载这个文件,请使用 [transformHead](/reference/site-config#transformhead) 构建钩子: + +```js +// .vitepress/config.js +export default { + transformHead({ assets }) { + // 相应地调整正则表达式以匹配字体 + const myFontFile = assets.find(file => /font-name\.\w+\.woff2/) + if (myFontFile) { + return [ + [ + 'link', + { + rel: 'preload', + href: myFontFile, + as: 'font', + type: 'font/woff2', + crossorigin: '' + } + ] + ] + } + } +} +``` + +## 注册全局组件 {#registering-global-components} + +```js +// .vitepress/theme/index.js +import DefaultTheme from 'vitepress/theme' + +/** @type {import('vitepress').Theme} */ +export default { + extends: DefaultTheme, + enhanceApp({ app }) { + // 注册自定义全局组件 + app.component('MyGlobalComponent' /* ... */) + } +} +``` + +如果使用 TypeScript: +```ts +// .vitepress/theme/index.ts +import type { Theme } from 'vitepress' +import DefaultTheme from 'vitepress/theme' + +export default { + extends: DefaultTheme, + enhanceApp({ app }) { + // 注册自定义全局组件 + app.component('MyGlobalComponent' /* ... */) + } +} satisfies Theme +``` + +因为我们使用 Vite,还可以利用 Vite 的 [glob 导入功能](https://cn.vitejs.dev/guide/features.html#glob-import)来自动注册一个组件目录。 + +## 布局插槽 {#layout-slots} + +默认主题的 `` 组件有一些插槽,能够被用来在页面的特定位置注入内容。下面这个例子展示了将一个组件注入到 outline 之前: + +```js +// .vitepress/theme/index.js +import DefaultTheme from 'vitepress/theme' +import MyLayout from './MyLayout.vue' + +export default { + extends: DefaultTheme, + // 使用注入插槽的包装组件覆盖 Layout + Layout: MyLayout +} +``` + +```vue + + + + +``` + +也可以使用渲染函数。 + +```js +// .vitepress/theme/index.js +import { h } from 'vue' +import DefaultTheme from 'vitepress/theme' +import MyComponent from './MyComponent.vue' + +export default { + extends: DefaultTheme, + Layout() { + return h(DefaultTheme.Layout, null, { + 'aside-outline-before': () => h(MyComponent) + }) + } +} +``` + +默认主题布局的全部可用插槽如下: + +- 当 `layout: 'doc'` (默认) 在 frontmatter 中被启用时: + - `doc-top` + - `doc-bottom` + - `doc-footer-before` + - `doc-before` + - `doc-after` + - `sidebar-nav-before` + - `sidebar-nav-after` + - `aside-top` + - `aside-bottom` + - `aside-outline-before` + - `aside-outline-after` + - `aside-ads-before` + - `aside-ads-after` +- 当 `layout: 'home'` 在 frontmatter 中被启用时: + - `home-hero-before` + - `home-hero-info-before` + - `home-hero-info` + - `home-hero-info-after` + - `home-hero-actions-after` + - `home-hero-image` + - `home-hero-after` + - `home-features-before` + - `home-features-after` +- 当 `layout: 'page'` 在 frontmatter 中被启用时: + - `page-top` + - `page-bottom` +- 当未找到页面 (404) 时: + - `not-found` +- 总是启用: + - `layout-top` + - `layout-bottom` + - `nav-bar-title-before` + - `nav-bar-title-after` + - `nav-bar-content-before` + - `nav-bar-content-after` + - `nav-screen-content-before` + - `nav-screen-content-after` + +## 使用视图过渡 API + +### 关于外观切换 {#on-appearance-toggle} + +可以扩展默认主题以在切换颜色模式时提供自定义过渡动画。例如: + +```vue + + + + + + + +``` + +Result (**warning!**: flashing colors, sudden movements, bright lights): + +
+Demo + +![Appearance Toggle Transition Demo](/appearance-toggle-transition.webp) + +
+ +有关视图过渡动画的更多详细信息,请参阅 [Chrome 文档](https://developer.chrome.com/docs/web-platform/view-transitions/)。 + +### 路由切换时 {#on-route-change} + +即将到来。 + +## 重写内部组件 {#overriding-internal-components} + +可以使用 Vite 的 [aliases](https://vitejs.dev/config/shared-options.html#resolve-alias) 来用自定义组件替换默认主题的组件: + +```ts +import { fileURLToPath, URL } from 'node:url' +import { defineConfig } from 'vitepress' + +export default defineConfig({ + vite: { + resolve: { + alias: [ + { + find: /^.*\/VPNavBar\.vue$/, + replacement: fileURLToPath( + new URL('./components/CustomNavBar.vue', import.meta.url) + ) + } + ] + } + } +}) +``` + +想要了解组件的确切名称请参考我们的[源代码](https://github.com/vuejs/vitepress/tree/main/src/client/theme-default/components)。因为组件是内部的,因此在小版本更迭中,它们名字改动的可能性很小。 diff --git a/docs/zh/guide/frontmatter.md b/docs/zh/guide/frontmatter.md new file mode 100644 index 00000000..4bcec7ea --- /dev/null +++ b/docs/zh/guide/frontmatter.md @@ -0,0 +1,48 @@ +# frontmatter + +## 用法 {#usage} + +VitePress 支持在所有 Markdown 文件中使用 YAML frontmatter,并使用 [gray-matter](https://github.com/jonschlinkert/gray-matter) 解析。frontmatter 必须位于 Markdown 文件的顶部 (在任何元素之前,包括 ` + + +``` + +## RTL 支持 (实验性功能) {#rtl-support-experimental} + +支持 RTL 需要在配置中指定 `dir: 'rtl'` 并且使用一些 RTLCSS PostCSS 插件,例如 , 或者 。需要配置 PostCSS 插件,使用 `:where([dir="ltr"])` 和 `:where([dir="rtl"])` 作为前缀,以防止 CSS 特异性问题。 diff --git a/docs/zh/guide/markdown.md b/docs/zh/guide/markdown.md new file mode 100644 index 00000000..b5dc779d --- /dev/null +++ b/docs/zh/guide/markdown.md @@ -0,0 +1,928 @@ +# Markdown 扩展 {#markdown-extensions} + +VitePress 带有内置的 Markdown 扩展。 + +## 标题锚点 {#header-anchors} + +标题会自动应用锚点。可以使用 `markdown.anchor` 选项配置锚点的渲染。 + +### 自定义锚点 {#custom-anchors} + +要为标题指定自定义锚点而不是使用自动生成的锚点,请向标题添加后缀: + +``` +# 使用自定义锚点 {#my-anchor} +``` + +这允许将标题链接为 `#my-anchor`,而不是默认的 `#使用自定义锚点`。 + +## 链接 {#links} + +内部和外部链接都会被特殊处理。 + +### 内部链接 {#internal-links} + +内部链接将转换为单页导航的路由链接。此外,子目录中包含的每个 `index.md` 都会自动转换为 `index.html`,并带有相应的 URL `/`。 + +例如,给定以下目录结构: + +``` +. +├─ index.md +├─ foo +│ ├─ index.md +│ ├─ one.md +│ └─ two.md +└─ bar + ├─ index.md + ├─ three.md + └─ four.md +``` + +假设现在处于 `foo/one.md` 文件中: + +```md +[Home](/) +[foo](/foo/) +[foo heading](./#heading) +[bar - three](../bar/three) +[bar - three](../bar/three.md) +[bar - four](../bar/four.html) +``` + +### 页面后缀 {#page-suffix} + +默认情况下,生成的页面和内部链接带有 `.html` 后缀。 + +### 外部链接 {#external-links} + +外部链接带有 `target="_blank" rel="noreferrer"`: + +- [vuejs.org](https://cn.vuejs.org) +- [VitePress on GitHub](https://github.com/vuejs/vitepress) + +## frontmatter {#frontmatter} + +[YAML 格式的 frontmatter](https://jekyllrb.com/docs/front-matter/) 开箱即用: + +```yaml +--- +title: Blogging Like a Hacker +lang: en-US +--- +``` + +此数据将可用于页面的其余部分,以及所有自定义和主题组件。 + +更多信息,参见 [frontmatter](../reference/frontmatter-config)。 + +## GitHub 风格的表格 {#github-style-tables} + +**输入** + +``` +| Tables | Are | Cool | +| ------------- | :-----------: | ----: | +| col 3 is | right-aligned | $1600 | +| col 2 is | centered | $12 | +| zebra stripes | are neat | $1 | +``` + +**输出** + +| Tables | Are | Cool | +| ------------- | :-----------: | -----: | +| col 3 is | right-aligned | \$1600 | +| col 2 is | centered | \$12 | +| zebra stripes | are neat | \$1 | + +## Emoji :tada: + +**输入** + +``` +:tada: :100: +``` + +**输出** + +:tada: :100: + +这里可以找到[所有支持的 emoji 列表](https://github.com/markdown-it/markdown-it-emoji/blob/master/lib/data/full.mjs)。 + +## 目录表 (TOC) {#table-of-contents} + +**输入** + +``` +[[toc]] +``` + +**输出** + +[[toc]] + +可以使用 `markdown.toc` 选项配置 TOC 的呈现效果。 + +## 自定义容器 {#custom-containers} + +自定义容器可以通过它们的类型、标题和内容来定义。 + +### 默认标题 {#default-title} + +**输入** + +```md +::: info +This is an info box. +::: + +::: tip +This is a tip. +::: + +::: warning +This is a warning. +::: + +::: danger +This is a dangerous warning. +::: + +::: details +This is a details block. +::: +``` + +**输出** + +::: info +This is an info box. +::: + +::: tip +This is a tip. +::: + +::: warning +This is a warning. +::: + +::: danger +This is a dangerous warning. +::: + +::: details +This is a details block. +::: + +### 自定义标题 {#custom-title} + +可以通过在容器的 "type" 之后附加文本来设置自定义标题。 + +**输入** + +````md +::: danger STOP +危险区域,请勿继续 +::: + +::: details 点我查看代码 +```js +console.log('Hello, VitePress!') +``` +::: +```` + +**输出** + +::: danger STOP +危险区域,请勿继续 +::: + +::: details 点我查看代码 +```js +console.log('Hello, VitePress!') +``` +::: + +此外,可以通过在站点配置中添加以下内容来全局设置自定义标题,如果不是用英语书写,这会很有帮助: + +```ts +// config.ts +export default defineConfig({ + // ... + markdown: { + container: { + tipLabel: '提示', + warningLabel: '警告', + dangerLabel: '危险', + infoLabel: '信息', + detailsLabel: '详细信息' + } + } + // ... +}) +``` + +### `raw` + +这是一个特殊的容器,可以用来防止与 VitePress 的样式和路由冲突。这在记录组件库时特别有用。可能还想查看 [whyframe](https://whyframe.dev/docs/integrations/vitepress) 以获得更好的隔离。 + +**语法** + +```md +::: raw +Wraps in a
+::: +``` + +`vp-raw` class 也可以直接用于元素。样式隔离目前是可选的: + +- 使用喜欢的包管理器来安装需要的依赖项: + + ```sh + $ npm add -D postcss + ``` + +- 创建 `docs/.postcssrc.cjs` 文件并将以下内容添加到其中: + + ```js + import { postcssIsolateStyles } from 'vitepress' + + export default { + plugins: [postcssIsolateStyles()] + } + ``` + + 它在底层使用 [`postcss-prefix-selector`](https://github.com/postcss/postcss-load-config)。你可以像这样传递它的选项: + + ```js + postcssIsolateStyles({ + includeFiles: [/vp-doc\.css/] // 默认为 /base\.css/ + }) + ``` + +## GitHub 风格的警报 {#github-flavored-alerts} + +VitePress 同样支持以标注的方式渲染 [GitHub 风格的警报](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts)。它们和[自定义容器](#custom-containers)的渲染方式相同。 + +```md +> [!NOTE] +> 强调用户在快速浏览文档时也不应忽略的重要信息。 + +> [!TIP] +> 有助于用户更顺利达成目标的建议性信息。 + +> [!IMPORTANT] +> 对用户达成目标至关重要的信息。 + +> [!WARNING] +> 因为可能存在风险,所以需要用户立即关注的关键内容。 + +> [!CAUTION] +> 行为可能带来的负面影响。 +``` + +> [!NOTE] +> 强调用户在快速浏览文档时也不应忽略的重要信息。 + +> [!TIP] +> 有助于用户更顺利达成目标的建议性信息。 + +> [!IMPORTANT] +> 对用户达成目标至关重要的信息。 + +> [!WARNING] +> 因为可能存在风险,所以需要用户立即关注的关键内容。 + +> [!CAUTION] +> 行为可能带来的负面影响。 + +## 代码块中的语法高亮 {#syntax-highlighting-in-code-blocks} + +VitePress 使用 [Shiki](https://github.com/shikijs/shiki) 在 Markdown 代码块中使用彩色文本实现语法高亮。Shiki 支持多种编程语言。需要做的就是将有效的语言别名附加到代码块的开头: + +**输入** + +```` +```js +export default { + name: 'MyComponent', + // ... +} +``` +```` + +```` +```html +
    +
  • + {{ todo.text }} +
  • +
+``` +```` + +**输出** + +```js +export default { + name: 'MyComponent' + // ... +} +``` + +```html +
    +
  • + {{ todo.text }} +
  • +
+``` + +在 Shiki 的代码仓库中,可以找到[合法的编程语言列表](https://shiki.style/languages)。 + +还可以全局配置中自定义语法高亮主题。有关详细信息,参见 [`markdown` 选项](../reference/site-config#markdown)得到更多信息。 + +## 在代码块中实现行高亮 {#line-highlighting-in-code-blocks} + +**输入** + +```` +```js{4} +export default { + data () { + return { + msg: 'Highlighted!' + } + } +} +``` +```` + +**输出** + +```js{4} +export default { + data () { + return { + msg: 'Highlighted!' + } + } +} +``` + +除了单行之外,还可以指定多个单行、多行,或两者均指定: + +- 多行:例如 `{5-8}`、`{3-10}`、`{10-17}` +- 多个单行:例如 `{4,7,9}` +- 多行与单行:例如 `{4,7-13,16,23-27,40}` + +**输入** + +```` +```js{1,4,6-8} +export default { // Highlighted + data () { + return { + msg: `Highlighted! + This line isn't highlighted, + but this and the next 2 are.`, + motd: 'VitePress is awesome', + lorem: 'ipsum' + } + } +} +``` +```` + +**输出** + +```js{1,4,6-8} +export default { // Highlighted + data () { + return { + msg: `Highlighted! + This line isn't highlighted, + but this and the next 2 are.`, + motd: 'VitePress is awesome', + lorem: 'ipsum', + } + } +} +``` + +也可以使用 `// [!code highlight]` 注释实现行高亮。 + +**输入** + +```` +```js +export default { + data () { + return { + msg: 'Highlighted!' // [!!code highlight] + } + } +} +``` +```` + +**输出** + +```js +export default { + data() { + return { + msg: 'Highlighted!' // [!code highlight] + } + } +} +``` + +## 代码块中聚焦 {#focus-in-code-blocks} + +在某一行上添加 `// [!code focus]` 注释将聚焦它并模糊代码的其他部分。 + +此外,可以使用 `// [!code focus:]` 定义要聚焦的行数。 + +**输入** + +```` +```js +export default { + data () { + return { + msg: 'Focused!' // [!!code focus] + } + } +} +``` +```` + +**输出** + +```js +export default { + data() { + return { + msg: 'Focused!' // [!code focus] + } + } +} +``` + +## 代码块中的颜色差异 {#colored-diffs-in-code-blocks} + +在某一行添加 `// [!code --]` 或 `// [!code ++]` 注释将会为该行创建 diff,同时保留代码块的颜色。 + +**输入** + +```` +```js +export default { + data () { + return { + msg: 'Removed' // [!!code --] + msg: 'Added' // [!!code ++] + } + } +} +``` +```` + +**输出** + +```js +export default { + data () { + return { + msg: 'Removed' // [!code --] + msg: 'Added' // [!code ++] + } + } +} +``` + +## 高亮“错误”和“警告” {#errors-and-warnings-in-code-blocks} + +在某一行添加 `// [!code warning]` 或 `// [!code error]` 注释将会为该行相应的着色。 + +**输入** + +```` +```js +export default { + data () { + return { + msg: 'Error', // [!!code error] + msg: 'Warning' // [!!code warning] + } + } +} +``` +```` + +**输出** + +```js +export default { + data() { + return { + msg: 'Error', // [!code error] + msg: 'Warning' // [!code warning] + } + } +} +``` + +## 行号 {#line-numbers} + +可以通过以下配置为每个代码块启用行号: + +```js +export default { + markdown: { + lineNumbers: true + } +} +``` + +查看 [`markdown` 选项](../reference/site-config#markdown) 获取更多信息。 + +可以在代码块中添加 `:line-numbers` / `:no-line-numbers` 标记来覆盖在配置中的设置。 + +还可以通过在 `:line-numbers` 之后添加 `=` 来自定义起始行号,例如 `:line-numbers=2` 表示代码块中的行号从 2 开始。 + +**输入** + +````md +```ts {1} +// 默认禁用行号 +const line2 = 'This is line 2' +const line3 = 'This is line 3' +``` + +```ts:line-numbers {1} +// 启用行号 +const line2 = 'This is line 2' +const line3 = 'This is line 3' +``` + +```ts:line-numbers=2 {1} +// 行号已启用,并从 2 开始 +const line3 = 'This is line 3' +const line4 = 'This is line 4' +``` +```` + +**输出** + +```ts {1} +// 默认禁用行号 +const line2 = 'This is line 2' +const line3 = 'This is line 3' +``` + +```ts:line-numbers {1} +// 启用行号 +const line2 = 'This is line 2' +const line3 = 'This is line 3' +``` + +```ts:line-numbers=2 {1} +// 行号已启用,并从 2 开始 +const line3 = 'This is line 3' +const line4 = 'This is line 4' +``` + +## 导入代码片段 {#import-code-snippets} + +可以通过下面的语法来从现有文件中导入代码片段: + +```md +<<< @/filepath +``` + +此语法同时支持[行高亮](#line-highlighting-in-code-blocks): + +```md +<<< @/filepath{highlightLines} +``` + +**输入** + +```md +<<< @/snippets/snippet.js{2} +``` + +**Code file** + +<<< @/snippets/snippet.js + +**输出** + +<<< @/snippets/snippet.js{2} + +::: tip +`@` 的值对应于源代码根目录,默认情况下是 VitePress 项目根目录,除非配置了 `srcDir`。或者也可以从相对路径导入: + +```md +<<< ../snippets/snippet.js +``` + +::: + +也可以使用 [VS Code region](https://code.visualstudio.com/docs/editor/codebasics#_folding) 来只包含代码文件的相应部分。可以在文件目录后面的 `#` 符号后提供一个自定义的区域名: + +**输入** + +```md +<<< @/snippets/snippet-with-region.js#snippet{1} +``` + +**Code file** + +<<< @/snippets/snippet-with-region.js + +**输出** + +<<< @/snippets/snippet-with-region.js#snippet{1} + +也可以像这样在大括号内(`{}`)指定语言: + +```md +<<< @/snippets/snippet.cs{c#} + + + +<<< @/snippets/snippet.cs{1,2,4-6 c#} + + + +<<< @/snippets/snippet.cs{1,2,4-6 c#:line-numbers} +``` + +如果无法从文件扩展名推测出源语言,这将会很有帮助 + +## 代码组 {#code-groups} + +可以像这样对多个代码块进行分组: + +**输入** + +````md +::: code-group + +```js [config.js] +/** + * @type {import('vitepress').UserConfig} + */ +const config = { + // ... +} + +export default config +``` + +```ts [config.ts] +import type { UserConfig } from 'vitepress' + +const config: UserConfig = { + // ... +} + +export default config +``` + +::: +```` + +**输出** + +::: code-group + +```js [config.js] +/** + * @type {import('vitepress').UserConfig} + */ +const config = { + // ... +} + +export default config +``` + +```ts [config.ts] +import type { UserConfig } from 'vitepress' + +const config: UserConfig = { + // ... +} + +export default config +``` + +::: + +也可以在代码组中[导入代码片段](#import-code-snippets): + +**输入** + +```md +::: code-group + + + +<<< @/snippets/snippet.js + + + +<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region] + +::: +``` + +**输出** + +::: code-group + +<<< @/snippets/snippet.js + +<<< @/snippets/snippet-with-region.js#snippet{1,2 ts:line-numbers} [snippet with region] + +::: + +## 包含 markdown 文件 {#markdown-file-inclusion} + +可以像这样在一个 markdown 文件中包含另一个 markdown 文件,甚至是内嵌的。 + +::: tip +也可以使用 `@`,它的值对应于源代码根目录,默认情况下是 VitePress 项目根目录,除非配置了 `srcDir`。 +::: + +例如,可以这样用相对路径包含 Markdown 文件: + +**输入** + +```md +# Docs + +## Basics + + +``` + +**Part file** (`parts/basics.md`) + +```md +Some getting started stuff. + +### Configuration + +Can be created using `.foorc.json`. +``` + +**等价代码** + +```md +# Docs + +## Basics + +Some getting started stuff. + +### Configuration + +Can be created using `.foorc.json`. +``` + +它还支持选择行范围: + +**输入** + +```md +# Docs + +## Basics + + +``` + +**Part file** (`parts/basics.md`) + +```md +Some getting started stuff. + +### Configuration + +Can be created using `.foorc.json`. +``` + +**等价代码** + +```md +# Docs + +## Basics + +### Configuration + +Can be created using `.foorc.json`. +``` + +所选行范围的格式可以是: `{3,}`、 `{,10}`、`{1,10}` + +::: warning +如果指定的文件不存在,这将不会产生错误。因此,在使用这个功能的时候请保证内容按预期呈现。 +::: + +## 数学方程 {#math-equations} + +现在这是可选的。要启用它, 需要安装 `markdown-it-mathjax3`,在配置文件中设置`markdown.math` 为 `true`: + +```sh +npm add -D markdown-it-mathjax3 +``` + +```ts +// .vitepress/config.ts +export default { + markdown: { + math: true + } +} +``` + +**输入** + +```md +When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are +$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$ + +**Maxwell's equations:** + +| equation | description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| $\nabla \cdot \vec{\mathbf{B}} = 0$ | divergence of $\vec{\mathbf{B}}$ is zero | +| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$ | +| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _wha?_ | +``` + +**输出** + +When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are +$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$ + +**Maxwell's equations:** + +| equation | description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| $\nabla \cdot \vec{\mathbf{B}} = 0$ | divergence of $\vec{\mathbf{B}}$ is zero | +| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$ | +| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _wha?_ | + +## 图片懒加载 {#image-lazy-loading} + +通过在配置文件中将 `lazyLoading` 设置为 `true`,可以为通过 markdown 添加的每张图片启用懒加载。 + +```js +export default { + markdown: { + image: { + // 默认禁用图片懒加载 + lazyLoading: true + } + } +} +``` + +## 高级配置 {#advanced-configuration} + +VitePress 使用 [markdown-it](https://github.com/markdown-it/markdown-it) 作为 Markdown 渲染器。上面提到的很多扩展功能都是通过自定义插件实现的。可以使用 `.vitepress/config.js` 中的 `markdown` 选项来进一步自定义 `markdown-it` 实例。 + +```js +import { defineConfig } from 'vitepress' +import markdownItAnchor from 'markdown-it-anchor' +import markdownItFoo from 'markdown-it-foo' + +export default defineConfig({ + markdown: { + // markdown-it-anchor 的选项 + // https://github.com/valeriangalliat/markdown-it-anchor#usage + anchor: { + permalink: markdownItAnchor.permalink.headerLink() + }, + // @mdit-vue/plugin-toc 的选项 + // https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options + toc: { level: [1, 2] }, + config: (md) => { + // 使用更多的 Markdown-it 插件! + md.use(markdownItFoo) + } + } +}) +``` + +请查看[配置参考:站点配置](../reference/site-config#markdown)来获取完整的可配置属性列表。 diff --git a/docs/zh/guide/migration-from-vitepress-0.md b/docs/zh/guide/migration-from-vitepress-0.md new file mode 100644 index 00000000..fc2bf97a --- /dev/null +++ b/docs/zh/guide/migration-from-vitepress-0.md @@ -0,0 +1,23 @@ +n# 从 VitePress 0.x 迁移 {#migration-from-vitepress-0-x} + +如果你来自 VitePress 0.x 版本,VitePress 有了一些重大更改。请按照本指南了解如何将应用程序迁移到最新的 VitePress。 + +## 应用配置 {#app-config} + +- 国际化功能尚未实现。 + +## 主题配置 {#theme-config} + +- `sidebar` 选项改变了它的结构。 + - `children` 现在命名为 `items`。 + - 顶级侧边栏不包含 `link`。我们打算把它改回来。 +- 删除了 `repo`、`repoLabel`、`docsDir`、`docsBranch`、`editLinks`、`editLinkText`,以支持更灵活的api。 + - 要将带有图标的 GitHub 链接添加到导航,请使用 [社交链接](../reference/default-theme-config#nav) 功能。 + - 要添加“编辑此页面”功能,请使用 [编辑链接](../reference/default-theme-edit-link) 功能。 +- `lastUpdated` 选项现在分为` config.lastUpdated` 和 `themeConfig.lastUpdatedText`。 +- `carbonAds.carbon` 更改为 `carbonAds.code`. + +## frontmatter 配置 {#frontmatter-config} + +- `home: true` 选项已更改为 `layout: home`。此外,还修改了许多与主页相关的设置以提供附加功能。详情请参阅 [主页指南](../reference/default-theme-home-page)。 +- `footer` 选项移至 [`themeConfig.footer`](../reference/default-theme-footer). diff --git a/docs/zh/guide/migration-from-vuepress.md b/docs/zh/guide/migration-from-vuepress.md new file mode 100644 index 00000000..c21000cc --- /dev/null +++ b/docs/zh/guide/migration-from-vuepress.md @@ -0,0 +1,30 @@ +# 从 VuePress 迁移 {#migration-from-vuepress} + +## 配置 {#config} + +### 侧边栏 {#sidebar} + +侧边栏不再从 frontmatter 中自动获取。你可以自行阅读 [`frontmatter`](https://github.com/vuejs/vitepress/issues/572#issuecomment-1170116225) 来动态填充侧边栏。[迁移工具](https://github.com/vuejs/vitepress/issues/96)将来可能会提供。 + +## Markdown {#markdown} + +### 图片 {#images} + +与 VuePress 不同,在使用静态图片时,VitePress 会根据配置自动处理这些 [`base`](./asset-handling#base-url)。 + +因此,现在可以在没有 `img` 标签的情况下渲染图像。 + +```diff +- foo ++ ![foo](/foo.png) +``` + +::: warning +对于动态图像,仍然需要 `withBase`,如 [Base URL](./asset-handling#base-url) 中所示。 +::: + +使用 `` 正则表达式查找并替换为 `![$2]($1)` 用 `![](...)` 语法替换所有图像。 + +--- + +更多请继续关注... diff --git a/docs/zh/guide/mpa-mode.md b/docs/zh/guide/mpa-mode.md new file mode 100644 index 00000000..80bf92f7 --- /dev/null +++ b/docs/zh/guide/mpa-mode.md @@ -0,0 +1,23 @@ +# MPA 模式 {#mpa-mode} + +可以通过命令行输入 `vitepress build --mpa` 或在配置文件中指定 `mpa: true` 配置选项来启用 MPA (Multi-Page Application) 模式。 + +在 MPA 模式下,所有页面都默认不会包含任何 JavaScript。因此,站点也许可以在评估工具中获得更好的初始访问性能分数。 + +但是,由于缺少 SPA 路由,在 MPA 模式下切换页面时会重新加载整个页面,而不会像 SPA 模式那样立即响应。 + +同时请注意,默认情况下不使用 JavaScript 意味着你实际上只是将 Vue 作为服务器端模板语言。浏览器不会附加任何事件处理程序,因此将不会有任何交互性。要加载客户端 JavaScript,需要使用特殊的 ` + +# Hello +``` + +` +``` + +### 渲染原始内容 {#rendering-raw-content} + +传递给页面的参数将在客户端 JavaScript payload 中序列化,因此应该避免在参数中传递大量数据,例如从远程 CMS 获取的原始 Markdown 或 HTML 内容。 + +相反,可以使用每个路径对象上的 `content` 属性将此类内容传递到每个页面: + +```js +export default { + async paths() { + const posts = await (await fetch('https://my-cms.com/blog-posts')).json() + + return posts.map((post) => { + return { + params: { id: post.id }, + content: post.content // 原始 Markdown 或 HTML + } + }) + } +} +``` + +然后,使用以下特殊语法将内容呈现为 Markdown 文件本身的一部分: + +```md + +``` diff --git a/docs/zh/guide/sitemap-generation.md b/docs/zh/guide/sitemap-generation.md new file mode 100644 index 00000000..94d83d25 --- /dev/null +++ b/docs/zh/guide/sitemap-generation.md @@ -0,0 +1,53 @@ +# 生成 sitemap {#sitemap-generation} + +VitePress 提供开箱即用的配置,为站点生成 `sitemap.xml` 文件。要启用它,请将以下内容添加到 `.vitepress/config.js` 中: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + sitemap: { + hostname: 'https://example.com' + } +}) +``` + +要在 `sitemap.xml` 中包含 `` 标签,可以启用 [`lastUpdated`](../reference/default-theme-last-updated) 选项。 + +## 选项 {#options} + +VitePress 的 sitemap 由 [`sitemap`](https://www.npmjs.com/package/sitemap) 模块提供支持。可以将该模块支持的选项传递给配置文件中的 `sitemap` 选项。这些选项将直接传递给 `SitemapStream` 构造函数。有关更多详细信息,请参阅 [`sitemap` 文档](https://www.npmjs.com/package/sitemap#options-you-can-pass)。例如: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + sitemap: { + hostname: 'https://example.com', + lastmodDateOnly: false + } +}) +``` + +## `transformItems` Hook + +在将 sitemap 写入 `sitemap.xml` 文件之前,可以使用 `sitemap.transformItems` 钩子来修改 sitemap。使用 sitemap 调用该钩子,应返回 sitemap 数组。例如: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + sitemap: { + hostname: 'https://example.com', + transformItems: (items) => { + // 添加新选项或修改/过滤现有选项 + items.push({ + url: '/extra-page', + changefreq: 'monthly', + priority: 0.8 + }) + return items + } + } +}) +``` diff --git a/docs/zh/guide/ssr-compat.md b/docs/zh/guide/ssr-compat.md new file mode 100644 index 00000000..0e980f4a --- /dev/null +++ b/docs/zh/guide/ssr-compat.md @@ -0,0 +1,136 @@ +--- +outline: deep +--- + +# SSR 兼容性 {#ssr-compatibility} + +通过使用 Vue 的服务器端渲染 (SSR) 功能,VitePress 能够在生产构建期间在 Node.js 中预渲染应用程序。这意味着主题组件中的所有自定义代码都需要考虑 SSR 兼容性。 + +[Vue 官方文档的 SSR 部分](https://cn.vuejs.org/guide/scaling-up/ssr.html)提供了更多有关 SSR 是什么,SSR / SSG 之间的关系以及编写 SSR 友好的代码的常见注意事项等信息。原则上只在 Vue 组件的 `beforeMount` 或 `mounted` 钩子中访问浏览器或 DOM API。 + +## `` + +如果正在使用或演示不支持 SSR 的组件 (例如,包含自定义指令),则可以将它们包装在内置的 `` 组件中: + +```md + + + +``` + +## 在导入时访问浏览器 API 的库 {#libraries-that-access-browser-api-on-import} + +一些组件或库在**导入时**访问浏览器 API。要使用假定在导入时处于浏览器环境的代码,需要动态导入它们。 + +### 在 mounted 钩子中导入 {#importing-in-mounted-hook} + +```vue + +``` + +### 条件导入 {#conditional-import} + +也可以使用 `import.meta.env.SSR` 标志 ([Vite 环境变量](https://cn.vitejs.dev/guide/env-and-mode.html#env-variables)的一部分) 来有条件地导入依赖项: + +```js +if (!import.meta.env.SSR) { + import('./lib-that-access-window-on-import').then((module) => { + // use code + }) +} +``` + +因为 [`Theme.enhanceApp`](/guide/custom-theme#theme-interface) 可以是异步的,所以可以有条件地导入并注册访问浏览器 API 的 Vue 插件: + +```js +// .vitepress/theme/index.js +/** @type {import('vitepress').Theme} */ +export default { + // ... + async enhanceApp({ app }) { + if (!import.meta.env.SSR) { + const plugin = await import('plugin-that-access-window-on-import') + app.use(plugin.default) + } + } +} +``` + +如果使用 TypeScript: +```ts +// .vitepress/theme/index.ts +import type { Theme } from 'vitepress' + +export default { + // ... + async enhanceApp({ app }) { + if (!import.meta.env.SSR) { + const plugin = await import('plugin-that-access-window-on-import') + app.use(plugin.default) + } + } +} satisfies Theme +``` + +### `defineClientComponent` + +VitePress 为导入 Vue 组件提供了一个方便的辅助函数,该组件可以在导入时访问浏览器 API。 + +```vue + + + +``` + +还可以将 props/children/slots 传递给目标组件: + +```vue + + + +``` + +目标组件将仅在 wrapper 组件的 mounted 钩子中导入。 diff --git a/docs/zh/guide/using-vue.md b/docs/zh/guide/using-vue.md new file mode 100644 index 00000000..0dc4648e --- /dev/null +++ b/docs/zh/guide/using-vue.md @@ -0,0 +1,256 @@ +# 在 Markdown 使用 Vue {#using-vue-in-markdown} + +在 VitePress 中,每个 Markdown 文件都被编译成 HTML,而且将其作为 [Vue 单文件组件](https://cn.vuejs.org/guide/scaling-up/sfc.html)处理。这意味着可以在 Markdown 中使用任何 Vue 功能,包括动态模板、使用 Vue 组件或通过添加 ` + +## Markdown Content + +The count is: {{ count }} + + + + +``` + +:::warning 避免在 Markdown 中使用 ` +``` + +## 使用 teleport 传递组件内容 {#using-teleports} + +Vitepress 目前只有使用 teleport 传送到 body 的 SSG 支持。对于其他地方,可以将它们包裹在内置的 `` 组件中,或者通过 [postRender 钩子](../reference/site-config#postrender)将 teleport 标签注入到最终页面 HTML 中的正确位置。 + + + +::: details +<<< @/components/ModalDemo.vue +::: + +```md + + +
+ // ... +
+
+
+``` + + + + diff --git a/docs/zh/guide/what-is-vitepress.md b/docs/zh/guide/what-is-vitepress.md new file mode 100644 index 00000000..cee35162 --- /dev/null +++ b/docs/zh/guide/what-is-vitepress.md @@ -0,0 +1,57 @@ +# VitePress 是什么? {#what-is-vitepress} + +VitePress 是一个[静态站点生成器](https://en.wikipedia.org/wiki/Static_site_generator) (SSG),专为构建快速、以内容为中心的站点而设计。简而言之,VitePress 获取用 Markdown 编写的内容,对其应用主题,并生成可以轻松部署到任何地方的静态 HTML 页面。 + +
+ +只是想尝试一下?跳到[快速开始](./getting-started)。 + +
+ +## 使用场景 {#use-cases} + +- **文档** + + VitePress 附带一个专为技术文档设计的默认主题。你现在正在阅读的这个页面以及 [Vite](https://vitejs.dev/)、[Rollup](https://rollupjs.org/)、[Pinia](https://pinia.vuejs.org/)、[VueUse](https://vueuse.org/)、[Vitest](https://vitest.dev/)、[D3](https://d3js.org/)、[UnoCSS](https://unocss.dev/)、[Iconify](https://iconify.design/) [等](https://www.vuetelescope.com/explore?framework.slug=vitepress)文档都是基于这个主题的。 + + [Vue.js 官方文档](https://cn.vuejs.org/)也是基于 VitePress 的。但是为了可以在不同的翻译文档之间切换,它自定义了自己的主题。 + +- **博客、档案和营销网站** + + VitePress 支持[完全的自定义主题](./custom-theme),具有标准 Vite + Vue 应用程序的开发体验。基于 Vite 构建还意味着可以直接利用其生态系统中丰富的 Vite 插件。此外,VitePress 提供了灵活的 API 来[加载数据](./data-loading) (本地或远程),也可以[动态生成路由](./routing#dynamic-routes)。只要可以在构建时确定数据,就可以使用它来构建几乎任何东西。 + + [Vue.js 官方博客](https://blog.vuejs.org/)是一个简单的博客页面,它根据本地内容生成其索引页面。 + +## 开发体验 {#developer-experience} + +VitePress 旨在使用 Markdown 生成内容时提供出色的开发体验。 + +- **[Vite 驱动](https://cn.vitejs.dev/)**:即时服务器启动,始终立即反映 (<100ms) 编辑变化,无需重新加载页面。 + +- **[内置 Markdown 扩展](./markdown)**:frontmatter、表格、语法高亮……应有尽有。具体来说,VitePress 提供了许多用于处理代码块的高级功能,使其真正成为技术文档的理想选择。 + +- **[Vue 增强的 Markdown](./using-vue)**:每个 Markdown 页面都是 Vue [单文件组件](https://cn.vuejs.org/guide/scaling-up/sfc.html),这要归功于 Vue 模板与 HTML 的 100% 语法兼容性。可以使用 Vue 模板语法或导入的 Vue 组件在静态内容中嵌入交互性。 + +## 性能 {#performance} + +与许多传统的 SSG 不同,每次导航都会导致页面完全重新加载,VitePress 生成的网站在初次访问时提供静态 HTML,但它变成了[单页应用程序](https://en.wikipedia.org/wiki/Single-page_application)(SPA)进行站点内的后续导航。我们认为,这种模式为性能提供了最佳平衡: + +- **快速的初始加载** + + 对任何页面的初次访问都将会是静态的、预呈现的 HTML,以实现极快的加载速度和最佳的 SEO。然后页面加载一个 JavaScript bundle,将页面变成 Vue SPA (这被称为“激活”)。与 SPA 激活缓慢的常见假设不同,由于 Vue 3 良好的原始性能和编译优化,这个过程实际上非常快。在 [PageSpeed Insights](https://pagespeed.web.dev/report?url=https%3A%2F%2Fvitepress.dev%2F) 上,典型的 VitePress 站点即使在网络速度较慢的低端移动设备上也能获得近乎完美的性能分数。 + +- **加载完成后可以快速切换** + + 更重要的是,SPA 模型在首次加载后能够提升用户体验。用户在站点内导航时,不会再触发整个页面的刷新。而是通过获取并动态更新页面的内容来实现切换。VitePress 还会自动预加载视口范围内链接对应的页面片段。这样一来,大部分情况下,用户在加载完成后就能立即浏览新页面。 + +- **高效的交互** + + 为了能够嵌入静态 Markdown 中的动态 Vue 部分,每个 Markdown 页面都被处理为 Vue 组件并编译成 JavaScript。这听起来可能效率低下,但 Vue 编译器足够聪明,可以将静态和动态部分分开,从而最大限度地减少激活成本和有效负载大小。对于初始的页面加载,静态部分会自动从 JavaScript 有效负载中删除,并在激活期间跳过。 + +## VuePress 又是什么? {#what-about-vuepress} + +VitePress 灵感来源于 VuePress。最初的 VuePress 基于 Vue 2 和 webpack。借助 Vue 3 和 Vite,VitePress 提供了更好的开发体验、更好的生产性能、更精美的默认主题和更灵活的自定义 API。 + +VitePress 和 VuePress 之间的 API 区别主要在于主题和自定义。如果使用的是带有默认主题的 VuePress 1,迁移到 VitePress 应该相对简单。 + +VuePress 2 我们也投入了精力,它也支持 Vue 3 和 Vite,与 VuePress 1 的兼容性更好。但是,并行维护两个 SSG 是难以持续的,因此 Vue 团队决定将重点放在 VitePress,作为长期的主要 SSG 选择推荐。 diff --git a/docs/zh/index.md b/docs/zh/index.md new file mode 100644 index 00000000..23299c1f --- /dev/null +++ b/docs/zh/index.md @@ -0,0 +1,59 @@ +--- +layout: home + +title: VitePress +titleTemplate: 由 Vite 和 Vue 驱动的静态站点生成器 + +hero: + name: VitePress + text: 由 Vite 和 Vue 驱动的静态站点生成器 + tagline: 将 Markdown 变成优雅的文档,只需几分钟 + actions: + - theme: brand + text: 什么是 VitePress? + link: /zh/guide/what-is-vitepress + - theme: alt + text: 快速开始 + link: /zh/guide/getting-started + - theme: alt + text: GitHub + link: https://github.com/vuejs/vitepress + image: + src: /vitepress-logo-large.webp + alt: VitePress + +features: + - icon: 📝 + title: 专注内容 + details: 只需 Markdown 即可轻松创建美观的文档站点。 + - icon: + title: 享受 Vite 无可比拟的体验 + details: 服务器即时启动,闪电般的热更新,还可以使用基于 Vite 生态的插件。 + - icon: + title: 使用 Vue 自定义 + details: 直接在 Markdown 中使用 Vue 语法和组件,或者使用 Vue 组件构建自定义主题。 + - icon: 🚀 + title: 速度真的很快! + details: 采用静态 HTML 实现快速的页面初次加载,使用客户端路由实现快速的页面切换导航。 +--- + diff --git a/docs/zh/reference/cli.md b/docs/zh/reference/cli.md new file mode 100644 index 00000000..71d892c6 --- /dev/null +++ b/docs/zh/reference/cli.md @@ -0,0 +1,74 @@ +# 命令行接口 {#command-line-interface} + +## `vitepress dev` + +使用指定目录作为根目录来启动 VitePress 开发服务器。默认为当前目录。在当前目录下运行时也可以省略 `dev` 命令。 + +### 用法 + +```sh +# 从当前目录启动,省略 `dev` +vitepress + +# 从子目录启动 +vitepress dev [root] +``` + +### 选项 {#options} + +| 选项 | 说明 | +| --------------- | ------------------------------------------ | +| `--open [path]` | 启动时打开浏览器 (`boolean \| string`) | +| `--port ` | 指定端口 (`number`) | +| `--base ` | public base URL (默认值: `/`) (`string`) | +| `--cors` | 启用 CORS | +| `--strictPort` | 如果指定的端口已被占用则退出 (`boolean`) | +| `--force` | 强制优化程序忽略缓存并重新绑定 (`boolean`) | + +## `vitepress build` + +构建用于生产环境的 VitePress 站点。 + +### 用法 + +```sh +vitepress build [root] +``` + +### 选项\ + +| 选项 | 说明 | +| ------------------------------ | ------------------------------------------------------------------------------------------------- | +| `--mpa` (experimental) | [MPA 模式](../guide/mpa-mode) 下构建,无需客户端激活 (`boolean`) | +| `--base ` | public base URL (默认值: `/`) (`string`) | +| `--target ` | 转译目标 (默认值:`"modules"`) (`string`) | +| `--outDir ` | 输出目录 (默认值:`.vitepress/dist`) (`string`) | +| `--minify [minifier]` | 启用/禁用压缩,或指定要使用的压缩程序 (默认值:`"esbuild"`) (`boolean \| "terser" \| "esbuild"`) | +| `--assetsInlineLimit ` | 静态资源 base64 内联阈值(以字节为单位)(默认值:`4096`) (`number`) | + +## `vitepress preview` + +在本地预览生产版本。 + +### 用法 + +```sh +vitepress preview [root] +``` + +### 选项 + +| 选项 | 说明 | +| --------------- | -------------------------------------- | +| `--base ` | public base URL (默认值: `/`) (`string`) | +| `--port ` | 指定端口 (`number`) | + +## `vitepress init` + +在当前目录中启动[安装向导](../guide/getting-started#setup-wizard)。 + +### 用法 + +```sh +vitepress init +``` diff --git a/docs/zh/reference/default-theme-badge.md b/docs/zh/reference/default-theme-badge.md new file mode 100644 index 00000000..c19cb129 --- /dev/null +++ b/docs/zh/reference/default-theme-badge.md @@ -0,0 +1,69 @@ +# 徽标 {#badge} + +徽标可让你为标题添加状态。例如,指定部分的类型或支持的版本可能很有用。 + +## 用法 {#usage} + +可以使用全局组件 `Badge` 。 + +```html +### Title +### Title +### Title +### Title +``` + +上面的代码渲染如下: + +### Title +### Title +### Title +### Title + +## 自定义子节点 {#custom-children} + +`` 接受 `children`,这将显示在徽标中。 + +```html +### Title custom element +``` + +### Title custom element + +## 自定义不同类型徽标的背景色 {#customize-type-color} + +可以通过覆盖 css 来自定义不同类型 `` 的样式。以下是默认值。 + +```css +:root { + --vp-badge-info-border: transparent; + --vp-badge-info-text: var(--vp-c-text-2); + --vp-badge-info-bg: var(--vp-c-default-soft); + + --vp-badge-tip-border: transparent; + --vp-badge-tip-text: var(--vp-c-brand-1); + --vp-badge-tip-bg: var(--vp-c-brand-soft); + + --vp-badge-warning-border: transparent; + --vp-badge-warning-text: var(--vp-c-warning-1); + --vp-badge-warning-bg: var(--vp-c-warning-soft); + + --vp-badge-danger-border: transparent; + --vp-badge-danger-text: var(--vp-c-danger-1); + --vp-badge-danger-bg: var(--vp-c-danger-soft); +} +``` + +## `` + +`` 组件接受以下属性: + +```ts +interface Props { + // 当传递 `` 时,该值将被忽略 + text?: string + + // 默认为 `tip`. + type?: 'info' | 'tip' | 'warning' | 'danger' +} +``` diff --git a/docs/zh/reference/default-theme-carbon-ads.md b/docs/zh/reference/default-theme-carbon-ads.md new file mode 100644 index 00000000..1633b281 --- /dev/null +++ b/docs/zh/reference/default-theme-carbon-ads.md @@ -0,0 +1,22 @@ +# Carbon Ads {#carbon-ads} + +VitePress 内置了对 [Carbon Ads](https://www.carbonads.net/) 的原生支持。通过在配置中定义 Carbon Ads 凭据,VitePress 将在页面上显示广告。 + +```js +export default { + themeConfig: { + carbonAds: { + code: 'your-carbon-code', + placement: 'your-carbon-placement' + } + } +} +``` + +这些值用于调用 carbon CDN 脚本,如下所示。 + +```js +`//cdn.carbonads.com/carbon.js?serve=${code}&placement=${placement}` +``` + +要了解有关 Carbon Ads 配置的更多信息,请访问 [Carbon Ads 站点](https://www.carbonads.net/)。 diff --git a/docs/zh/reference/default-theme-config.md b/docs/zh/reference/default-theme-config.md new file mode 100644 index 00000000..a7028f16 --- /dev/null +++ b/docs/zh/reference/default-theme-config.md @@ -0,0 +1,452 @@ +# 默认主题配置 {#default-theme-config} + +主题配置可以让你能够自定义主题。可以通过将 `themeConfig` 添加到配置文件来进行主题配置: + +```ts +export default { + lang: 'en-US', + title: 'VitePress', + description: 'Vite & Vue powered static site generator.', + + // 主题相关配置 + themeConfig: { + logo: '/logo.svg', + nav: [...], + sidebar: { ... } + } +} +``` + +**此页面上记录的选项仅适用于默认主题**。不同的主题需要不同的主题配置。使用自定义主题时,主题配置对象将传递给主题,以便主题可以基于它作出不同表现。 + +## i18nRouting + +- 类型:`boolean` + +将本地语言更改为 `zh` 会将 URL 从 `/foo`(或 `/en/foo/`)更改为 `/zh/foo`。可以通过将 `themeConfig.i18nRouting` 设置为 `false` 来禁用此行为。 + +## logo + +- 类型:`ThemeableImage` + +导航栏上显示的 Logo,位于站点标题前。可以接受一个路径字符串,或者一个对象来设置在浅色/深色模式下不同的 Logo。 + +```ts +export default { + themeConfig: { + logo: '/logo.svg' + } +} +``` + +```ts +type ThemeableImage = + | string + | { src: string; alt?: string } + | { light: string; dark: string; alt?: string } +``` + +## siteTitle + +- 类型:`string | false` + +可以自定义此项以替换导航中的默认站点标题 (应用配置中的 `title`)。当设置为 `false` 时,导航中的标题将被禁用。这在当 `logo` 已经包含站点标题文本时很有用。 + +```ts +export default { + themeConfig: { + siteTitle: 'Hello World' + } +} +``` + +## nav + +- 类型:`NavItem` + +导航菜单项的配置。可以在[默认主题: 导航栏](./default-theme-nav#navigation-links) 了解更多详情。 + +```ts +export default { + themeConfig: { + nav: [ + { text: 'Guide', link: '/guide' }, + { + text: 'Dropdown Menu', + items: [ + { text: 'Item A', link: '/item-1' }, + { text: 'Item B', link: '/item-2' }, + { text: 'Item C', link: '/item-3' } + ] + } + ] + } +} +``` + +```ts +type NavItem = NavItemWithLink | NavItemWithChildren + +interface NavItemWithLink { + text: string + link: string + activeMatch?: string + target?: string + rel?: string + noIcon?: boolean +} + +interface NavItemChildren { + text?: string + items: NavItemWithLink[] +} + +interface NavItemWithChildren { + text?: string + items: (NavItemChildren | NavItemWithLink)[] + activeMatch?: string +} +``` + +## sidebar + +- 类型:`Sidebar` + +侧边栏菜单项的配置。可以在[默认主题: 侧边栏](./default-theme-sidebar)了解更多详情。 + +```ts +export default { + themeConfig: { + sidebar: [ + { + text: 'Guide', + items: [ + { text: 'Introduction', link: '/introduction' }, + { text: 'Getting Started', link: '/getting-started' }, + ... + ] + } + ] + } +} +``` + +```ts +export type Sidebar = SidebarItem[] | SidebarMulti + +export interface SidebarMulti { + [path: string]: SidebarItem[] +} + +export type SidebarItem = { + /** + * 侧边栏项的文本标签 + */ + text?: string + + /** + * 侧边栏项的链接 + */ + link?: string + + /** + * 侧边栏项的子项 + */ + items?: SidebarItem[] + + /** + * 如果未指定,侧边栏组不可折叠 + * + * 如果为 `true`,则侧边栏组可折叠并且默认折叠 + * + * 如果为 `false`,则侧边栏组可折叠但默认展开 + */ + collapsed?: boolean +} +``` + +## aside + +- 类型:`boolean | 'left'` +- 默认值:`true` +- 每个页面可以通过 [frontmatter](./frontmatter-config#aside) 覆盖 + +将此值设置为 `false` 可禁用 aside 容器。\ +将此值设置为 `true` 将在页面右侧渲染。\ +将此值设置为 `left` 将在页面左侧渲染。 + +如果想对所有页面禁用它,应该使用 `outline: false`。 + +## outline + +- 类型:`Outline | Outline['level'] | false` +- 每个页面可以通过 [frontmatter](./frontmatter-config#outline) 覆盖层级 + +将此值设置为 `false` 可禁止渲染大纲容器。更多详情请参考该接口: + +```ts +interface Outline { + /** + * outline 中要显示的标题级别。 + * 单个数字表示只显示该级别的标题。 + * 如果传递的是一个元组,第一个数字是最小级别,第二个数字是最大级别。 + * `'deep'` 与 `[2, 6]` 相同,将显示从 `

` 到 `

` 的所有标题。 + * + * @default 2 + */ + level?: number | [number, number] | 'deep' + + /** + * 显示在 outline 上的标题。 + * + * @default 'On this page' + */ + label?: string +} +``` + +## socialLinks + +- 类型:`SocialLink[]` + +可以定义此选项以在导航栏中展示带有图标的社交帐户链接。 + +```ts +export default { + themeConfig: { + socialLinks: [ + { icon: 'github', link: 'https://github.com/vuejs/vitepress' }, + { icon: 'twitter', link: '...' }, + // 可以通过将 SVG 作为字符串传递来添加自定义图标: + { + icon: { + svg: 'Dribbble' + }, + link: '...', + // 也可以为无障碍添加一个自定义标签 (可选但推荐): + ariaLabel: 'cool link' + } + ] + } +} +``` + +```ts +interface SocialLink { + icon: SocialLinkIcon + link: string + ariaLabel?: string +} + +type SocialLinkIcon = + | 'discord' + | 'facebook' + | 'github' + | 'instagram' + | 'linkedin' + | 'mastodon' + | 'npm' + | 'slack' + | 'twitter' + | 'x' + | 'youtube' + | { svg: string } +``` + +## footer + +- 类型:`Footer` +- 可以通过 [frontmatter](./frontmatter-config#footer) 进行覆盖。 + +页脚配置。可以添加 message 和 copyright。由于设计原因,仅当页面不包含侧边栏时才会显示页脚。 + +```ts +export default { + themeConfig: { + footer: { + message: 'Released under the MIT License.', + copyright: 'Copyright © 2019-present Evan You' + } + } +} +``` + +```ts +export interface Footer { + message?: string + copyright?: string +} +``` + +## editLink + +- 类型:`EditLink` +- 每个页面可以通过 [frontmatter](./frontmatter-config#editlink) 覆盖 + +编辑链接可让显示链接以编辑 Git 管理服务 (例如 GitHub 或 GitLab) 上的页面。有关详细信息,请参阅[默认主题:编辑链接](./default-theme-edit-link)。 + +```ts +export default { + themeConfig: { + editLink: { + pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path', + text: 'Edit this page on GitHub' + } + } +} +``` + +```ts +export interface EditLink { + pattern: string + text?: string +} +``` + +## lastUpdated + +- 类型:`LastUpdatedOptions` + +允许自定义上次更新的文本和日期格式。 + +```ts +export default { + themeConfig: { + lastUpdated: { + text: 'Updated at', + formatOptions: { + dateStyle: 'full', + timeStyle: 'medium' + } + } + } +} +``` + +```ts +export interface LastUpdatedOptions { + /** + * @default 'Last updated' + */ + text?: string + + /** + * @default + * { dateStyle: 'short', timeStyle: 'short' } + */ + formatOptions?: Intl.DateTimeFormatOptions & { forceLocale?: boolean } +} +``` + +## algolia + +- 类型:`AlgoliaSearch` + +支持使用 [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch) 搜索站点文档。在[默认主题:搜索](./default-theme-search) 中了解更多信息。 + +```ts +export interface AlgoliaSearchOptions extends DocSearchProps { + locales?: Record> +} +``` + +在[这里](https://github.com/vuejs/vitepress/blob/main/types/docsearch.d.ts)查看完整配置。 + +## carbonAds {#carbon-ads} + +- 类型:`CarbonAdsOptions` + +一个配置即可展示 [Carbon Ads](https://www.carbonads.net/)。 + +```ts +export default { + themeConfig: { + carbonAds: { + code: 'your-carbon-code', + placement: 'your-carbon-placement' + } + } +} +``` + +```ts +export interface CarbonAdsOptions { + code: string + placement: string +} +``` + +在 [Default Theme: Carbon Ads](./default-theme-carbon-ads) 中了解更多信息。 + +## docFooter + +- 类型:`DocFooter` + +可用于自定义出现在上一页和下一页链接上方的文本。如果不是用英语编写文档,这很有帮助。也可用于全局禁用上一页/下一页链接。如果想有选择地启用/禁用上一个/下一个链接,可以使用 [frontmatter](./default-theme-prev-next-links)。 + +```ts +export default { + themeConfig: { + docFooter: { + prev: 'Pagina prior', + next: 'Proxima pagina' + } + } +} +``` + +```ts +export interface DocFooter { + prev?: string | false + next?: string | false +} +``` + +## darkModeSwitchLabel + +- 类型:`string` +- 默认值:`Appearance` + +用于自定义深色模式开关标签,该标签仅在移动端视图中显示。 + +## lightModeSwitchTitle + +- 类型:`string` +- 默认值:`Switch to light theme` + +用于自定义悬停时显示的浅色模式开关标题。 + +## darkModeSwitchTitle + +- 类型:`string` +- 默认值:`Switch to dark theme` + +用于自定义悬停时显示的深色模式开关标题。 + +## sidebarMenuLabel + +- 类型:`string` +- 默认值:`Menu` + +用于自定义侧边栏菜单标签,该标签仅在移动端视图中显示。 + +## returnToTopLabel + +- 类型:`string` +- 默认值:`Return to top` + +用于自定义返回顶部按钮的标签,该标签仅在移动端视图中显示。 + +## langMenuLabel + +- 类型:`string` +- 默认值:`Change language` + +用于自定义导航栏中语言切换按钮的 aria-label,仅当使用 [i18n](../guide/i18n) 时才使用此选项。 + +## externalLinkIcon + +- 类型:`boolean` +- 默认值:`false` + +是否在 markdown 中的外部链接旁显示外部链接图标。 diff --git a/docs/zh/reference/default-theme-edit-link.md b/docs/zh/reference/default-theme-edit-link.md new file mode 100644 index 00000000..92f3cd25 --- /dev/null +++ b/docs/zh/reference/default-theme-edit-link.md @@ -0,0 +1,60 @@ +# 编辑链接 {#edit-link} + +## 站点级配置 {#site-level-config} + +编辑链接让你可以显示一个链接,以在 GitHub 或 GitLab 等 Git 管理服务上编辑页面。要启用它,请将 `themeConfig.editLink` 选项添加到配置中。 + +```js +export default { + themeConfig: { + editLink: { + pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path' + } + } +} +``` + +`pattern` 选项定义链接的 URL 结构,并且 `:path` 将被替换为页面路径。 + +你还可以放置一个接受 [`PageData`](./runtime-api#usedata) 作为参数并返回 URL 字符串的纯函数。 + +```js +export default { + themeConfig: { + editLink: { + pattern: ({ filePath }) => { + if (filePath.startsWith('packages/')) { + return `https://github.com/acme/monorepo/edit/main/${filePath}` + } else { + return `https://github.com/acme/monorepo/edit/main/docs/${filePath}` + } + } + } + } +} +``` + +它不应该有副作用,也不应该访问其范围之外的任何东西,因为它将在浏览器中被序列化和执行。 + +默认情况下,这将在文档页面底部添加链接文本“Edit this page”。可以通过定义 `text` 选项来自定义此文本。 + +```js +export default { + themeConfig: { + editLink: { + pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path', + text: 'Edit this page on GitHub' + } + } +} +``` + +## frontmatter 配置 {#frontmatter-config} + +可以使用 frontmatter 上的 `editLink` 选项单独禁用某个页面的编辑链接: + +```yaml +--- +editLink: false +--- +``` diff --git a/docs/zh/reference/default-theme-footer.md b/docs/zh/reference/default-theme-footer.md new file mode 100644 index 00000000..7499089f --- /dev/null +++ b/docs/zh/reference/default-theme-footer.md @@ -0,0 +1,53 @@ +# 页脚 {#footer} + +配置好 `themeConfig.footer`,VitePress 将在全局页面底部显示页脚。 + +```ts +export default { + themeConfig: { + footer: { + message: 'Released under the MIT License.', + copyright: 'Copyright © 2019-present Evan You' + } + } +} +``` + +```ts +export interface Footer { + // 版权前显示的信息 + message?: string + + // 实际的版权文本 + copyright?: string +} +``` + +上面的配置也支持 HTML 字符串。所以,例如,如果想配置页脚文本有一些链接,可以调整配置如下: + +```ts +export default { + themeConfig: { + footer: { + message: 'Released under the MIT License.', + copyright: 'Copyright © 2019-present Evan You' + } + } +} +``` + +::: warning +只有内联元素可以在 `message` 和 `copyright` 中使用,因为它们渲染在 `

` 元素中。如果想添加块元素,请考虑使用 [`layout-bottom`](../guide/extending-default-theme#layout-slots) 插槽。 +::: + +请注意,当[侧边栏](./default-theme-sidebar)可见时,不会显示页脚。 + +## frontmatter 配置 {#frontmatter-config} + +可以使用 frontmatter 上的 `footer` 选项在单独页面上禁用此功能: + +```yaml +--- +footer: false +--- +``` diff --git a/docs/zh/reference/default-theme-home-page.md b/docs/zh/reference/default-theme-home-page.md new file mode 100644 index 00000000..b83364f9 --- /dev/null +++ b/docs/zh/reference/default-theme-home-page.md @@ -0,0 +1,195 @@ +# 主页 {#home-page} + +VitePress 默认主题提供了一个首页布局,也可以在[此站点首页](../)看到。可以通过 [frontmatter](./frontmatter-config) 指定 `layout: home` 在任何页面上使用它 + +```yaml +--- +layout: home +--- +``` + +但是,仅做这个配置不会有太大作用。可以通过设置其他选项 (例如 `hero` 和 `features`) 向主页添加几个不同的预设。 + +## Hero 部分 {#hero-section} + +Hero 部分位于主页顶部。以下是配置 Hero 的方法。 + +```yaml +--- +layout: home + +hero: + name: VitePress + text: Vite & Vue powered static site generator. + tagline: Lorem ipsum... + image: + src: /logo.png + alt: VitePress + actions: + - theme: brand + text: Get Started + link: /guide/what-is-vitepress + - theme: alt + text: View on GitHub + link: https://github.com/vuejs/vitepress +--- +``` + +```ts +interface Hero { + // `text` 上方的字符,带有品牌颜色 + // 预计简短,例如产品名称 + name?: string + + // hero 部分的主要文字, + // 被定义为 `h1` 标签 + text: string + + // `text` 下方的标语 + tagline?: string + + // text 和 tagline 区域旁的图片 + image?: ThemeableImage + + // 主页 hero 部分的操作按钮 + actions?: HeroAction[] +} + +type ThemeableImage = + | string + | { src: string; alt?: string } + | { light: string; dark: string; alt?: string } + +interface HeroAction { + // 按钮的颜色主题,默认为 `brand` + theme?: 'brand' | 'alt' + + // 按钮的标签 + text: string + + // 按钮的目标链接 + link: string + + // 链接的 target 属性 + target?: string + + // 链接的 rel 属性 + rel?: string +} +``` + +### 自定义 name 的颜色 {#customizing-the-name-color} + +VitePress 通过 (`--vp-c-brand-1`) 设置 `name` 的颜色 .但是,可以通过覆盖 `--vp-home-hero-name-color` 变量来自定义此颜色。 + +```css +:root { + --vp-home-hero-name-color: blue; +} +``` + +也可以通过组合 `--vp-home-hero-name-background` 来进一步自定义 `name` 为渐变色。 + +```css +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe, #41d1ff); +} +``` + +## Features 部分 {#features-section} + +在 Features 部分,可以在 Hero 部分之后列出任意数量的 Feature。可以在 frontmatter 中配置 `features`。 + +可以为每个 feature 提供一个图标,可以是表情符号或任何类型的图像。当配置的图标是图片(svg, png, jpeg...)时,必须提供合适的宽度和高度的图标;还可以在需要时配置其描述、固有大小以及深色和浅色主题下的不同表现。 + +```yaml +--- +layout: home + +features: + - icon: 🛠️ + title: Simple and minimal, always + details: Lorem ipsum... + - icon: + src: /cool-feature-icon.svg + title: Another cool feature + details: Lorem ipsum... + - icon: + dark: /dark-feature-icon.svg + light: /light-feature-icon.svg + title: Another cool feature + details: Lorem ipsum... +--- +``` + +```ts +interface Feature { + // 在每个 feature 框中显示图标 + icon?: FeatureIcon + + // feature 的标题 + title: string + + // feature 的详情 + details: string + + // 点击 feature 组件时的链接,可以是内部链接,也可以是外部链接。 + // + // + // 例如 `guide/reference/default-theme-home-page` 或 `https://example.com` + link?: string + + // feature 组件内显示的链接文本,最好与 `link` 选项一起使用 + // + // + // 例如 `Learn more`, `Visit page` 等 + linkText?: string + + // `link` 选项的链接 rel 属性 + // + // 例如 `external` + rel?: string + + // `link` 选项的链接 target 属性 + target?: string +} + +type FeatureIcon = + | string + | { src: string; alt?: string; width?: string; height: string } + | { + light: string + dark: string + alt?: string + width?: string + height: string + } +``` + +## Markdown 内容 {#markdown-content} + +可以在 frontmatter 的分隔符 `---` 下方为站点主页添加额外的 Markdown 内容。 + +````md +--- +layout: home + +hero: + name: VitePress + text: Vite & Vue powered static site generator. +--- + +## Getting Started + +You can get started using VitePress right away using `npx`! + +```sh +npm init +npx vitepress init +``` +```` + +::: info +VitePress 并不总是为 `layout: home` 页面里额外的内容自动添加样式。要回到以前的行为,可以在 frontmatter 中添加 `markdownStyles: false`。 +::: diff --git a/docs/zh/reference/default-theme-last-updated.md b/docs/zh/reference/default-theme-last-updated.md new file mode 100644 index 00000000..6c04a2c6 --- /dev/null +++ b/docs/zh/reference/default-theme-last-updated.md @@ -0,0 +1,27 @@ +# 最后更新于 {#last-updated} + +最近一条内容的更新时间会显示在页面右下角。要启用它,请将 `lastUpdated` 选项添加到配置中。 + +::: tip +你必须提交 markdown 文件才能看到最后更新时间。 +::: + +## 全局配置 {#site-level-config} + +```js +export default { + lastUpdated: true +} +``` + +## frontmatter 配置 {#frontmatter-config} + +可以使用 frontmatter 上的 `lastUpdated` 选项单独禁用某个页面的最后更新展示: + +```yaml +--- +lastUpdated: false +--- +``` + +另请参阅[默认主题:最后更新时间](./default-theme-config#lastupdated) 了解更多详细信息。主题级别的任何 [truthy](https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy) 值也将启用该功能,除非在站点或页面级别明确禁用。 diff --git a/docs/zh/reference/default-theme-layout.md b/docs/zh/reference/default-theme-layout.md new file mode 100644 index 00000000..87015218 --- /dev/null +++ b/docs/zh/reference/default-theme-layout.md @@ -0,0 +1,62 @@ +# 布局 {#layout} + +可以通过设置页面 [frontmatter](./frontmatter-config) 选项来选择页面布局。有 3 种布局选项 `doc`、`page` 和 `home`。如果未指定任何内容,则该页面将被视为 `doc` 页面。 + +```yaml +--- +layout: doc +--- +``` + +## doc 布局 {#doc-layout} + +`doc` 是默认布局,它将整个 Markdown 内容设置为“documentation”外观。它的工作原理是将整个内容包装在 css `vp-doc` 类中,并将样式应用于它下面的元素。 + +几乎所有通用元素,例如 `p`, 或 `h2` 都有特殊的样式。因此,请记住,如果在 Markdown 内容中添加任何自定义 HTML,这些内容也会受到这些样式的影响。 + +它还提供下面列出的文档特定功能。这些功能仅在此布局中启用。 + +- [编辑链接](./default-theme-edit-link) +- [上下页链接](./default-theme-prev-next-links) +- [大纲](./default-theme-config#outline) +- [Carbon Ads](./default-theme-carbon-ads) + +## page 布局 {#page-layout} + +`page` 被视为“空白页”。Markdown 仍然会被解析,所有的 [Markdown 扩展](../guide/markdown) 都和 `doc` 布局一样运行,但它没有任何默认样式。 + +`page` 布局将使可以自行设计所有内容,而不会受 VitePress 主题影响。当想要创建自己的自定义页面时,这很有用。 + +请注意,即使在此布局中,如果页面具有匹配的侧边栏配置,侧边栏仍会显示。 + +## home 布局 {#home-layout} + +`home` 将生成模板化的“主页”。在此布局中,可以设置额外的选项,例如 `hero` 和 `features` 以进一步自定义内容。请访问[默认主题: 主页](./default-theme-home-page)了解更多详情。 + +## 无布局 {#no-layout} + +如果不想要任何布局,可以通过 frontmatter 传递 `layout: false`。如果想要一个完全可自定义的登录页面(默认情况下没有任何侧边栏、导航栏或页脚),此选项很有用。 + +## 自定义布局 {#custom-layout} + +也可以使用自定义布局: + +```md +--- +layout: foo +--- +``` + +这将在上下文中查找注册名为 `foo` 的组件。例如,可以在 `.vitepress/theme/index.ts`中全局注册组件: + +```ts +import DefaultTheme from 'vitepress/theme' +import Foo from './Foo.vue' + +export default { + extends: DefaultTheme, + enhanceApp({ app }) { + app.component('foo', Foo) + } +} +``` diff --git a/docs/zh/reference/default-theme-nav.md b/docs/zh/reference/default-theme-nav.md new file mode 100644 index 00000000..be9feaac --- /dev/null +++ b/docs/zh/reference/default-theme-nav.md @@ -0,0 +1,161 @@ +# 导航栏 {#nav} + +Nav 是显示在页面顶部的导航栏。它包含站点标题、全局菜单链接等。 + +## 站点标题和图标 {#site-title-and-logo} + +默认情况下,nav 显示 [`config.title`](./site-config#title) 作为站点的标题。如果想更改导航栏上显示的内容,可以在 `themeConfig.siteTitle` 选项中定义自定义文本。 + +```js +export default { + themeConfig: { + siteTitle: 'My Custom Title' + } +} +``` + +如果站点有图标,则可以通过传递图片路径来显示它。应该将图标直接放在 `public` 中,并赋值该绝对路径。 + +```js +export default { + themeConfig: { + logo: '/my-logo.svg' + } +} +``` + +添加图标时,它会与站点标题一起显示。如果只需要图标并且想要隐藏站点标题文本,请将 `siteTitle` 选项设置为 `false`。 + +```js +export default { + themeConfig: { + logo: '/my-logo.svg', + siteTitle: false + } +} +``` + +如果想添加 `alt` 属性或根据深色/浅色模式自定义,还可以将图标作为对象传递。有关详细信息,请参阅 [`themeConfig.logo`](./default-theme-config#logo)。 + +## 导航链接 {#navigation-links} + +可以定义 `themeConfig.nav` 选项以将链接添加到导航栏。 + +```js +export default { + themeConfig: { + nav: [ + { text: 'Guide', link: '/guide' }, + { text: 'Config', link: '/config' }, + { text: 'Changelog', link: 'https://github.com/...' } + ] + } +} +``` + +`text` 是 nav 中显示的实际文本,而 `link` 是单击文本时将导航到的链接。对于链接,将路径设置为不带 `.md` 后缀的实际文件,并且始终以 `/` 开头。 + +导航链接也可以是下拉菜单。为此,请替换 `link` 选项,设置 `items` 数组。 + +```js +export default { + themeConfig: { + nav: [ + { text: 'Guide', link: '/guide' }, + { + text: 'Dropdown Menu', + items: [ + { text: 'Item A', link: '/item-1' }, + { text: 'Item B', link: '/item-2' }, + { text: 'Item C', link: '/item-3' } + ] + } + ] + } +} +``` + +请注意,下拉菜单标题 (上例中的 `Dropdown Menu`) 不能具有 `link` 属性,因为它是打开下拉对话框的按钮。 + +还可以通过传入更多嵌套项来进一步向下拉菜单项添加“sections”。 + +```js +export default { + themeConfig: { + nav: [ + { text: 'Guide', link: '/guide' }, + { + text: 'Dropdown Menu', + items: [ + { + // 该部分的标题 + text: 'Section A Title', + items: [ + { text: 'Section A Item A', link: '...' }, + { text: 'Section B Item B', link: '...' } + ] + } + ] + }, + { + text: 'Dropdown Menu', + items: [ + { + // 也可以省略标题 + items: [ + { text: 'Section A Item A', link: '...' }, + { text: 'Section B Item B', link: '...' } + ] + } + ] + } + ] + } +} +``` + +### 自定义链接的路由匹配状态 {#customize-link-s-active-state} + +当前页面位于匹配路径下时,导航菜单项将突出显示。如果想自定义要匹配的路径,请将 `activeMatch` 属性和正则表达式定义为字符串值。 + +```js +export default { + themeConfig: { + nav: [ + // 当用户位于 `/config/` 路径时,该链接处于激活状态 + { + text: 'Guide', + link: '/guide', + activeMatch: '/config/' + } + ] + } +} +``` + +::: warning +`activeMatch` 应为正则表达式字符串,但必须将其定义为字符串。我们不能在这里使用实际的 RegExp 对象,因为它在构建期间不可序列化。 +::: + +### 自定义链接的“target”和“rel”属性 {#customize-link-s-target-and-rel-attributes} + +默认情况下,VitePress 会根据链接是否为外部链接自动判断 `target` 和 `rel` 属性。但如果愿意,也可以自定义它们。 + +```js +export default { + themeConfig: { + nav: [ + { + text: 'Merchandise', + link: 'https://www.thegithubshop.com/', + target: '_self', + rel: 'sponsored' + } + ] + } +} +``` + +## 社交链接 {#social-links} + +参考 [`socialLinks`](./default-theme-config#sociallinks)。 diff --git a/docs/zh/reference/default-theme-prev-next-links.md b/docs/zh/reference/default-theme-prev-next-links.md new file mode 100644 index 00000000..cdbe8434 --- /dev/null +++ b/docs/zh/reference/default-theme-prev-next-links.md @@ -0,0 +1,43 @@ +# 上下页链接 {#prev-next-links} + +可以自定义上一页和下一页的文本和链接 (显示在文档页脚处)。如果要使其与侧边栏上的文本不同,这会很有帮助。此外,你可能会发现,要禁用未包含在侧边栏中的页面的页脚或链接时,这很有用。 + +## prev + +- 类型:`string | false | { text?: string; link?: string }` + +- 说明: + + 指定要在指向上一页的链接上显示的文本/链接。如果没有在 frontmatter 中设置它,文本/链接将从侧边栏配置中推断出来。 + +- 示例: + + - 仅自定义文本: + + ```yaml + --- + prev: 'Get Started | Markdown' + --- + ``` + + - 自定义文本和链接: + + ```yaml + --- + prev: + text: 'Markdown' + link: '/guide/markdown' + --- + ``` + + - 隐藏上一页: + + ```yaml + --- + prev: false + --- + ``` + +## next + +与 `prev` 相同,但用于下一页。 diff --git a/docs/zh/reference/default-theme-search.md b/docs/zh/reference/default-theme-search.md new file mode 100644 index 00000000..fdd97200 --- /dev/null +++ b/docs/zh/reference/default-theme-search.md @@ -0,0 +1,379 @@ +--- +outline: deep +--- + +# 搜索 {#search} + +## 本地搜索 {#local-search} + +得益于 [minisearch](https://github.com/lucaong/minisearch/),VitePress 支持使用浏览器内索引进行模糊全文搜索。要启用此功能,只需在 `.vitepress/config.ts` 文件中将 `themeConfig.search.provider` 选项设置为 `'local'` 即可: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local' + } + } +}) +``` + +示例结果: + +![搜索弹窗截图](/search.png) + +或者,你可以使用 [Algolia DocSearch](#algolia-search) 或一些社区插件,例如: 或者 。 + +### i18n {#local-search-i18n} + +你可以使用这样的配置来使用多语言搜索: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + locales: { + zh: { + translations: { + button: { + buttonText: '搜索文档', + buttonAriaLabel: '搜索文档' + }, + modal: { + noResultsText: '无法找到相关结果', + resetButtonTitle: '清除查询条件', + footer: { + selectText: '选择', + navigateText: '切换' + } + } + } + } + } + } + } + } +}) +``` + +### MiniSearch 配置项 {#mini-search-options} + +你可以像这样配置 MiniSearch : + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + miniSearch: { + /** + * @type {Pick} + */ + options: { + /* ... */ + }, + /** + * @type {import('minisearch').SearchOptions} + * @default + * { fuzzy: 0.2, prefix: true, boost: { title: 4, text: 2, titles: 1 } } + */ + searchOptions: { + /* ... */ + } + } + } + } + } +}) +``` + +参阅 [MiniSearch 文档](https://lucaong.github.io/minisearch/classes/MiniSearch.MiniSearch.html)了解更多信息。 + +### 自定义渲染内容 {#custom-content-renderer} + +可以在索引之前自定义用于渲染 Markdown 内容的函数: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + /** + * @param {string} src + * @param {import('vitepress').MarkdownEnv} env + * @param {import('markdown-it')} md + */ + _render(src, env, md) { + // 返回 html 字符串 + } + } + } + } +}) +``` + +该函数将从客户端站点数据中剥离,因此你可以在其中使用 Node.js API。 + +#### 示例:从搜索中排除页面 {#example-excluding-pages-from-search} + +你可以通过将 `search: false` 添加到页面的 `frontmatter` 来从搜索中排除页面。或者: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + _render(src, env, md) { + const html = md.render(src, env) + if (env.frontmatter?.search === false) return '' + if (env.relativePath.startsWith('some/path')) return '' + return html + } + } + } + } +}) +``` + +::: warning 注意 +如果提供了自定义的 `_render` 函数,你需要自己处理 `search: false` 的 frontmatter。此外,在调用 `md.render` 之前,`env` 对象不会完全填充,因此对可选 `env` 属性 (如 `frontmatter`) 的任何检查都应该在此之后完成。 +::: + +#### 示例:转换内容——添加锚点 {#example-transforming-content-adding-anchors} + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'local', + options: { + _render(src, env, md) { + const html = md.render(src, env) + if (env.frontmatter?.title) + return md.render(`# ${env.frontmatter.title}`) + html + return html + } + } + } + } +}) +``` + +## Algolia Search {#algolia-search} + +VitePress 支持使用 [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch) 搜索文档站点。请参阅他们的入门指南。在你的 `.vitepress/config.ts` 中,你至少需要提供以下内容才能使其正常工作: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'algolia', + options: { + appId: '...', + apiKey: '...', + indexName: '...' + } + } + } +}) +``` + +### i18n {#algolia-search-i18n} + +你可以使用这样的配置来使用多语言搜索: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + search: { + provider: 'algolia', + options: { + appId: '...', + apiKey: '...', + indexName: '...', + locales: { + zh: { + placeholder: '搜索文档', + translations: { + button: { + buttonText: '搜索文档', + buttonAriaLabel: '搜索文档' + }, + modal: { + searchBox: { + resetButtonTitle: '清除查询条件', + resetButtonAriaLabel: '清除查询条件', + cancelButtonText: '取消', + cancelButtonAriaLabel: '取消' + }, + startScreen: { + recentSearchesTitle: '搜索历史', + noRecentSearchesText: '没有搜索历史', + saveRecentSearchButtonTitle: '保存至搜索历史', + removeRecentSearchButtonTitle: '从搜索历史中移除', + favoriteSearchesTitle: '收藏', + removeFavoriteSearchButtonTitle: '从收藏中移除' + }, + errorScreen: { + titleText: '无法获取结果', + helpText: '你可能需要检查你的网络连接' + }, + footer: { + selectText: '选择', + navigateText: '切换', + closeText: '关闭', + searchByText: '搜索提供者' + }, + noResultsScreen: { + noResultsText: '无法找到相关结果', + suggestedQueryText: '你可以尝试查询', + reportMissingResultsText: '你认为该查询应该有结果?', + reportMissingResultsLinkText: '点击反馈' + } + } + } + } + } + } + } + } +}) +``` + +[这些选项](https://github.com/vuejs/vitepress/blob/main/types/docsearch.d.ts)可以被覆盖。请参阅 Algolia 官方文档以了解更多信息。 + +### 爬虫配置 {#crawler-config} + +以下是基于此站点使用的示例配置: + +```ts +new Crawler({ + appId: '...', + apiKey: '...', + rateLimit: 8, + startUrls: ['https://vitepress.dev/'], + renderJavaScript: false, + sitemaps: [], + exclusionPatterns: [], + ignoreCanonicalTo: false, + discoveryPatterns: ['https://vitepress.dev/**'], + schedule: 'at 05:10 on Saturday', + actions: [ + { + indexName: 'vitepress', + pathsToMatch: ['https://vitepress.dev/**'], + recordExtractor: ({ $, helpers }) => { + return helpers.docsearch({ + recordProps: { + lvl1: '.content h1', + content: '.content p, .content li', + lvl0: { + selectors: '', + defaultValue: 'Documentation' + }, + lvl2: '.content h2', + lvl3: '.content h3', + lvl4: '.content h4', + lvl5: '.content h5' + }, + indexHeadings: true + }) + } + } + ], + initialIndexSettings: { + vitepress: { + attributesForFaceting: ['type', 'lang'], + attributesToRetrieve: ['hierarchy', 'content', 'anchor', 'url'], + attributesToHighlight: ['hierarchy', 'hierarchy_camel', 'content'], + attributesToSnippet: ['content:10'], + camelCaseAttributes: ['hierarchy', 'hierarchy_radio', 'content'], + searchableAttributes: [ + 'unordered(hierarchy_radio_camel.lvl0)', + 'unordered(hierarchy_radio.lvl0)', + 'unordered(hierarchy_radio_camel.lvl1)', + 'unordered(hierarchy_radio.lvl1)', + 'unordered(hierarchy_radio_camel.lvl2)', + 'unordered(hierarchy_radio.lvl2)', + 'unordered(hierarchy_radio_camel.lvl3)', + 'unordered(hierarchy_radio.lvl3)', + 'unordered(hierarchy_radio_camel.lvl4)', + 'unordered(hierarchy_radio.lvl4)', + 'unordered(hierarchy_radio_camel.lvl5)', + 'unordered(hierarchy_radio.lvl5)', + 'unordered(hierarchy_radio_camel.lvl6)', + 'unordered(hierarchy_radio.lvl6)', + 'unordered(hierarchy_camel.lvl0)', + 'unordered(hierarchy.lvl0)', + 'unordered(hierarchy_camel.lvl1)', + 'unordered(hierarchy.lvl1)', + 'unordered(hierarchy_camel.lvl2)', + 'unordered(hierarchy.lvl2)', + 'unordered(hierarchy_camel.lvl3)', + 'unordered(hierarchy.lvl3)', + 'unordered(hierarchy_camel.lvl4)', + 'unordered(hierarchy.lvl4)', + 'unordered(hierarchy_camel.lvl5)', + 'unordered(hierarchy.lvl5)', + 'unordered(hierarchy_camel.lvl6)', + 'unordered(hierarchy.lvl6)', + 'content' + ], + distinct: true, + attributeForDistinct: 'url', + customRanking: [ + 'desc(weight.pageRank)', + 'desc(weight.level)', + 'asc(weight.position)' + ], + ranking: [ + 'words', + 'filters', + 'typo', + 'attribute', + 'proximity', + 'exact', + 'custom' + ], + highlightPreTag: '', + highlightPostTag: '', + minWordSizefor1Typo: 3, + minWordSizefor2Typos: 7, + allowTyposOnNumericTokens: false, + minProximity: 1, + ignorePlurals: true, + advancedSyntax: true, + attributeCriteriaComputedByMinProximity: true, + removeWordsIfNoResults: 'allOptional' + } + } +}) +``` + + diff --git a/docs/zh/reference/default-theme-sidebar.md b/docs/zh/reference/default-theme-sidebar.md new file mode 100644 index 00000000..ba9a9adc --- /dev/null +++ b/docs/zh/reference/default-theme-sidebar.md @@ -0,0 +1,213 @@ +# 侧边栏 {#sidebar} + +侧边栏是文档的主要导航块。可以在 [`themeConfig.sidebar`](./default-theme-config#sidebar) 中配置侧边栏菜单。 + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Guide', + items: [ + { text: 'Introduction', link: '/introduction' }, + { text: 'Getting Started', link: '/getting-started' }, + ... + ] + } + ] + } +} +``` + +## 基本用法 {#the-basics} + +侧边栏菜单的最简单形式是传入一个链接数组。第一级项目定义侧边栏的“部分”。它应该包含作为小标题的 `text` 和作为实际导航链接的 `items`。 + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Section Title A', + items: [ + { text: 'Item A', link: '/item-a' }, + { text: 'Item B', link: '/item-b' }, + ... + ] + }, + { + text: 'Section Title B', + items: [ + { text: 'Item C', link: '/item-c' }, + { text: 'Item D', link: '/item-d' }, + ... + ] + } + ] + } +} +``` + +每个 `link` 都应指定以 `/` 开头的实际文件的路径。如果在链接末尾添加斜杠,它将显示相应目录的 `index.md`。 + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Guide', + items: [ + // 显示的是 `/guide/index.md` 页面 + { text: 'Introduction', link: '/guide/' } + ] + } + ] + } +} +``` + +可以进一步将侧边栏项目嵌入到 6 级深度,从根级别上计数。请注意,深度超过 6 级将被忽略,并且不会在侧边栏上显示。 + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Level 1', + items: [ + { + text: 'Level 2', + items: [ + { + text: 'Level 3', + items: [ + ... + ] + } + ] + } + ] + } + ] + } +} +``` + +## 多侧边栏 {#multiple-sidebars} + +可能会根据页面路径显示不同的侧边栏。例如,如本站点所示,可能希望在文档中创建单独的侧边栏,例如“指南”页面和“配置参考”页面。 + +为此,首先将你的页面组织到每个所需部分的目录中: + +``` +. +├─ guide/ +│ ├─ index.md +│ ├─ one.md +│ └─ two.md +└─ config/ + ├─ index.md + ├─ three.md + └─ four.md +``` + +然后,更新配置以定义每个部分的侧边栏。这一次,应该传递一个对象而不是数组。 + +```js +export default { + themeConfig: { + sidebar: { + // 当用户位于 `guide` 目录时,会显示此侧边栏 + '/guide/': [ + { + text: 'Guide', + items: [ + { text: 'Index', link: '/guide/' }, + { text: 'One', link: '/guide/one' }, + { text: 'Two', link: '/guide/two' } + ] + } + ], + + // 当用户位于 `config` 目录时,会显示此侧边栏 + '/config/': [ + { + text: 'Config', + items: [ + { text: 'Index', link: '/config/' }, + { text: 'Three', link: '/config/three' }, + { text: 'Four', link: '/config/four' } + ] + } + ] + } + } +} +``` + +## 可折叠的侧边栏组 {#collapsible-sidebar-groups} + +通过向侧边栏组添加 `collapsed` 选项,它会显示一个切换按钮来隐藏/显示每个部分。 + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Section Title A', + collapsed: false, + items: [...] + } + ] + } +} +``` + +默认情况下,所有部分都是“打开”的。如果希望它们在初始页面加载时“关闭”,请将 `collapsed` 选项设置为 `true`。 + +```js +export default { + themeConfig: { + sidebar: [ + { + text: 'Section Title A', + collapsed: true, + items: [...] + } + ] + } +} +``` + +## `useSidebar` + +返回侧边栏相关数据。返回的对象具有以下类型: + +```ts +export interface DocSidebar { + isOpen: Ref + sidebar: ComputedRef + sidebarGroups: ComputedRef + hasSidebar: ComputedRef + hasAside: ComputedRef + leftAside: ComputedRef + isSidebarEnabled: ComputedRef + open: () => void + close: () => void + toggle: () => void +} +``` + +**示例:** + +```vue + + + +``` diff --git a/docs/zh/reference/default-theme-team-page.md b/docs/zh/reference/default-theme-team-page.md new file mode 100644 index 00000000..0341f0f2 --- /dev/null +++ b/docs/zh/reference/default-theme-team-page.md @@ -0,0 +1,257 @@ + + +# 团队页 {#team-page} + +如果你想介绍你的团队,你可以使用 Team components 来构建团队页面。有两种使用这些组件的方法。一种是将其嵌入文档页面,另一种是创建完整的团队页面。 + +## 在页面中显示团队成员 {#show-team-members-in-a-page} + +你可以在任何页面上使用从 `vitepress/theme` 暴露出的公共组件 `` 显示团队成员。 + +```html + + +# Our Team + +Say hello to our awesome team. + + +``` + +以上将在卡片外观元素中显示团队成员。它应该显示类似于下面的内容。 + + + +`` 组件有 2 种不同的尺寸,`small` 和 `medium`。虽然它取决于你的偏好,但通常尺寸在文档页面中使用时 `small` 应该更适合。此外,你可以为每个成员添加更多属性,例如添加“描述”或“赞助”按钮。在 [``](#vpteammembers) 中了解更多信息。 + +在文档页面中嵌入团队成员对于小型团队来说非常有用,某种情况下,完整的贡献团队可能太大了,可以引入部分成员作为文档上下文的参考。 + +如果你有大量成员,或者只是想有更多空间来展示团队成员,请考虑[创建一个完整的团队页面](#create-a-full-team-page)。 + +## 创建一个完整的团队页面 {#create-a-full-team-page} + +除了将团队成员添加到 doc 页面,你还可以创建一个完整的团队页面,类似于创建自定义[默认主题:主页](./default-theme-home-page)的方式。 + +要创建团队页面,首先,创建一个新的 md 文件。文件名无所谓,这里我们就叫它 `team.md` 吧。在这个文件中,在 frontmatter 设置 `layout: page`,然后你可以使用 `TeamPage` 组件来组成页面结构。 + +```html +--- +layout: page +--- + + + + + + + + + +``` + +创建完整的团队页面时,请记住用 `` 组件包装所有团队相关组件,以获得正确的布局结构,如间距。 + +`` 组件添加页面标题部分。标题是 `

` 标题。使用 `#title` 和 `#lead` 插槽来介绍你的团队。 + +`` 和在 doc 页面中使用时一样。它将显示成员列表。 + +### 添加 section 以划分团队成员 {#add-sections-to-divide-team-members} + +你可以将“section”添加到团队页面。例如,你可能有不同类型的团队成员,例如核心团队成员和社区合作伙伴。你可以将这些成员分成几个部分,以更好地解释每组的角色。 + +为此,将 `` 组件添加到我们之前创建的 `team.md` 文件中。 + +```html +--- +layout: page +--- + + + + + + + + + + + + + + +``` + +`` 组件可以有类似于 `VPTeamPageTitle` 组件的 `#title` 和 `#lead` 插槽,还有用于显示团队成员的 `#members` 插槽。 + +请记住将 `` 组件放入 `#members` 插槽中。 + +## `` + +`` 组件显示给定的成员列表。 + +```html + +``` + +```ts +interface Props { + // 每个成员的大小,默认为 `medium` + size?: 'small' | 'medium' + + // 显示的成员列表 + members: TeamMember[] +} + +interface TeamMember { + // 成员的头像图像 + avatar: string + + // 成员的名称 + name: string + + // 成员姓名下方的标题 + // 例如:Developer, Software Engineer, etc. + title?: string + + // 成员所属的组织 + org?: string + + // 组织的 URL + orgLink?: string + + // 成员的描述 + desc?: string + + // 社交媒体链接,例如 GitHub、Twitter 等,可以在此处传入 Social Links 对象 + // 参见: https://vitepress.dev/reference/default-theme-config.html#sociallinks + links?: SocialLink[] + + // 成员 sponsor 页面的 URL + sponsor?: string + + // sponsor 链接的文本,默认为 'Sponsor' + actionText?: string +} +``` + +## `` + +创建完整团队页面时的根组件。它只接受一个插槽。它将设置所有传入的团队相关组件的样式。 + +## `` + +添加页面的标题。最好在一开始就在 `` 下使用。它接受 `#title` 和 `#lead` 插槽。 + +```html + + + + + + +``` + +## `` + +在团队页面中创建一个“section”。它接受 `#title`、`#lead` 和 `#members` 插槽。你可以在 `` 中添加任意数量的section。 + +```html + + ... + + + + + + +``` diff --git a/docs/zh/reference/frontmatter-config.md b/docs/zh/reference/frontmatter-config.md new file mode 100644 index 00000000..2cf0eaaa --- /dev/null +++ b/docs/zh/reference/frontmatter-config.md @@ -0,0 +1,221 @@ +--- +outline: deep +--- + +# frontmatter 配置 {#frontmatter-config} + +frontmatter 支持基于页面的配置。在每个 markdown 文件中,可以使用 frontmatter 配置来覆盖站点级别或主题级别的配置选项。此外,还有一些配置选项只能在 frontmatter 中定义。 + +示例用法: + +```md +--- +title: Docs with VitePress +editLink: true +--- +``` + +可以通过 Vue 表达式中的 `$frontmatter` 全局变量访问 frontmatter 数据: + +```md +{{ $frontmatter.title }} +``` + +## title + +- 类型:`string` + +页面的标题。它与 [config.title](./site-config#title) 相同,并且覆盖站点级配置。 + +```yaml +--- +title: VitePress +--- +``` + +## titleTemplate + +- 类型:`string | boolean` + +标题的后缀。它与 [config.titleTemplate](./site-config#titletemplate) 相同,它会覆盖站点级别的配置。 + +```yaml +--- +title: VitePress +titleTemplate: Vite & Vue powered static site generator +--- +``` + +## description + +- 类型:`string` + +页面的描述。它与 [config.description](./site-config#description) 相同,它会覆盖站点级别的配置。 + +```yaml +--- +description: VitePress +--- +``` + +## head + +- 类型:`HeadConfig[]` + +指定要为当前页面注入的额外 head 标签。将附加在站点级配置注入的头部标签之后。 + +```yaml +--- +head: + - - meta + - name: description + content: hello + - - meta + - name: keywords + content: super duper SEO +--- +``` + +```ts +type HeadConfig = + | [string, Record] + | [string, Record, string] +``` + +## 仅默认主题 {#default-theme-only} + +以下 frontmatter 选项仅在使用默认主题时适用。 + +### layout + +- 类型:`doc | home | page` +- 默认值:`doc` + +指定页面的布局。 + +- `doc`——它将默认文档样式应用于 markdown 内容。 +- `home`——“主页”的特殊布局。可以添加额外的选项,例如 `hero` 和 `features`,以快速创建漂亮的落地页。 +- `page`——表现类似于 `doc`,但它不对内容应用任何样式。当想创建一个完全自定义的页面时很有用。 + +```yaml +--- +layout: doc +--- +``` + +### hero + +当 `layout` 设置为 `home` 时,定义主页 hero 部分的内容。更多详细信息:[默认主题:主页](./default-theme-home-page)。 + +### features + +定义当`layout` 设置为 `home` 时要在 features 部分中显示的项目。更多详细信息:[默认主题:主页](./default-theme-home-page)。 + +### navbar + +- 类型:`boolean` +- 默认值:`true` + +是否显示[导航栏](./default-theme-nav)。 + +```yaml +--- +navbar: false +--- +``` + +### sidebar + +- 类型:`boolean` +- 默认值:`true` + +是否显示 [侧边栏](./default-theme-sidebar). + +```yaml +--- +sidebar: false +--- +``` + +### aside + +- 类型:`boolean | 'left'` +- 默认值:`true` + +定义侧边栏组件在 `doc` 布局中的位置。 + +将此值设置为 `false` 可禁用侧边栏容器。\ +将此值设置为 `true` 会将侧边栏渲染到右侧。\ +将此值设置为 `left` 会将侧边栏渲染到左侧。 + +```yaml +--- +aside: false +--- +``` + +### outline + +- 类型:`number | [number, number] | 'deep' | false` +- 默认值:`2` + +大纲中显示的标题级别。它与 [config.themeConfig.outline.level](./default-theme-config#outline) 相同,它会覆盖站点级的配置。 + +### lastUpdated + +- 类型:`boolean | Date` +- 默认值:`true` + +是否在当前页面的页脚中显示[最后更新时间](./default-theme-last-updated)的文本。如果指定了日期时间,则会显示该日期时间而不是上次 git 修改的时间戳。 + +```yaml +--- +lastUpdated: false +--- +``` + +### editLink + +- 类型:`boolean` +- 默认值:`true` + +是否在当前页的页脚显示[编辑链接](./default-theme-edit-link)。 + +```yaml +--- +editLink: false +--- +``` + +### footer + +- 类型:`boolean` +- 默认值:`true` + +是否显示[页脚](./default-theme-footer)。 + +```yaml +--- +footer: false +--- +``` + +### pageClass + +- 类型:`string` + +将额外的类名称添加到特定页面。 + +```yaml +--- +pageClass: custom-page-class +--- +``` + +然后可以在 `.vitepress/theme/custom.css` 文件中自定义该特定页面的样式: + +```css +.custom-page-class { +  /* 特定页面的样式 */ +} +``` diff --git a/docs/zh/reference/runtime-api.md b/docs/zh/reference/runtime-api.md new file mode 100644 index 00000000..b64d44f5 --- /dev/null +++ b/docs/zh/reference/runtime-api.md @@ -0,0 +1,164 @@ +# 运行时 API {#runtime-api} + +VitePress 提供了几个内置的 API 来让你访问应用程序数据。VitePress 还附带了一些可以在全局范围内使用的内置组件。 + +辅助函数可从 `vitepress` 全局导入,通常用于自定义主题 Vue 组件。但是,它们也可以在 `.md` 页面内使用,因为 markdown 文件被编译成 Vue [单文件组件](https://cn.vuejs.org/guide/scaling-up/sfc.html)。 + +以 `use*` 开头的方法表示它是一个 [Vue 3 组合式 API](https://cn.vuejs.org/guide/introduction.html#composition-api) 函数,只能在 `setup()` 或 ` + + +``` + +## `useRoute` + +返回具有以下类型的当前路由对象: + +```ts +interface Route { + path: string + data: PageData + component: Component | null +} +``` + +## `useRouter` + +返回 VitePress 路由实例,以便可以以编程方式导航到另一个页面。 + +```ts +interface Router { + /** + * 当前路由 + */ + route: Route + /** + * 导航到新的 URL + */ + go: (to?: string) => Promise + /** + * 在路由更改前调用。返回 `false` 表示取消导航 + */ + onBeforeRouteChange?: (to: string) => Awaitable + /** + * 在页面组件加载前(history 状态更新后)调用。返回 `false` 表示取消导航 + */ + onBeforePageLoad?: (to: string) => Awaitable + /** + * 在路由更改后调用 + */ + onAfterRouteChanged?: (to: string) => Awaitable +} +``` + +## `withBase` + +- **Type**: `(path: string) => string` + +将配置的 [`base`](./site-config#base) 追加到给定的 URL 路径。另请参阅 [Base URL](../guide/asset-handling#base-url)。 + +## `` + +`` 组件显示渲染的 markdown 内容。在[创建自己的主题时](../guide/custom-theme)很有用。 + +```vue + +``` + +## `` + +`` 组件仅在客户端渲染其插槽。 + +由于 VitePress 应用程序在生成静态构建时是在 Node.js 中服务器渲染的,因此任何 Vue 使用都必须符合通用代码要求。简而言之,确保仅在 beforeMount 或 mounted 钩子中访问 Browser/DOM API。 + +如果正在使用或演示对 SSR 不友好的组件 (例如,包含自定义指令),可以将它们包装在 `ClientOnly` 组件中。 + +```vue-html + + + +``` + +- 相关文档:[SSR 兼容性](../guide/ssr-compat) + +## `$frontmatter` + +在 Vue 表达式中直接访问当前页面的 [frontmatter](../guide/frontmatter) 数据。 + +```md +--- +title: Hello +--- + +# {{ $frontmatter.title }} +``` + +## `$params` + +在 Vue 表达式中直接访问当前页面的[动态路由参数](../guide/routing#dynamic-routes)。 + +```md +- package name: {{ $params.pkg }} +- version: {{ $params.version }} +``` diff --git a/docs/zh/reference/site-config.md b/docs/zh/reference/site-config.md new file mode 100644 index 00000000..5eb29787 --- /dev/null +++ b/docs/zh/reference/site-config.md @@ -0,0 +1,720 @@ +--- +outline: deep +--- + +# 站点配置 {#site-config} + +站点配置可以定义站点的全局设置。应用配置选项适用于每个 VitePress 站点,无论它使用什么主题。例如根目录或站点的标题。 + +## 概览 {#overview} + +### 配置解析 {#config-resolution} + +配置文件总是从 `/.vitepress/config.[ext]` 解析,其中 `` 是 VitePress [项目根目录](../guide/routing#root-and-source-directory),`[ext]` 是支持的文件扩展名之一。开箱即用地支持 TypeScript。支持的扩展名包括 `.js`、`.ts`、`.mjs` 和 `.mts`。 + +建议在配置文件中使用 ES 模块语法。配置文件应该默认导出一个对象: + +```ts +export default { + // 应用级配置选项 + lang: 'en-US', + title: 'VitePress', + description: 'Vite & Vue powered static site generator.', + ... +} +``` + +:::details 异步的动态配置 + +如果需要动态生成配置,也可以默认导出一个函数,例如: + +```ts +import { defineConfig } from 'vitepress' + +export default async () => { + const posts = await (await fetch('https://my-cms.com/blog-posts')).json() + + return defineConfig({ + // 应用级配置选项 + lang: 'en-US', + title: 'VitePress', + description: 'Vite & Vue powered static site generator.', + + // 主题级配置选项 + themeConfig: { + sidebar: [ + ...posts.map((post) => ({ + text: post.name, + link: `/posts/${post.name}` + })) + ] + } + }) +} +``` + +也可以在最外层使用 `await`。例如: + +```ts +import { defineConfig } from 'vitepress' + +const posts = await (await fetch('https://my-cms.com/blog-posts')).json() + +export default defineConfig({ + // 应用级配置选项 + lang: 'en-US', + title: 'VitePress', + description: 'Vite & Vue powered static site generator.', + + // 主题级别配置选项 + themeConfig: { + sidebar: [ + ...posts.map((post) => ({ + text: post.name, + link: `/posts/${post.name}` + })) + ] + } +}) +``` + +::: + +### 配置智能提示 {#config-intellisense} + +使用 `defineConfig` 辅助函数将为配置选项提供 TypeScript 支持的智能提示。假设 IDE 支持它,那么在 JavaScript 和 TypeScript 中都将触发智能提示。 + +```js +import { defineConfig } from 'vitepress' + +export default defineConfig({ + // ... +}) +``` + +### 主题类型提示 {#typed-theme-config} + +默认情况下,`defineConfig` 辅助函数期望默认主题的主题配置数据类型为: + +```ts +import { defineConfig } from 'vitepress' + +export default defineConfig({ + themeConfig: { + // 类型为 `DefaultTheme.Config` + } +}) +``` + +如果使用自定义主题并希望对主题配置进行类型检查,则需要改用 `defineConfigWithTheme`,并通过通用参数传递自定义主题的配置类型: + +```ts +import { defineConfigWithTheme } from 'vitepress' +import type { ThemeConfig } from 'your-theme' + +export default defineConfigWithTheme({ + themeConfig: { + // 类型为 `ThemeConfig` + } +}) +``` + +### Vite、Vue 和 Markdown 配置 + +- **Vite** + + 可以使用 VitePress 配置中的 [vite](#vite) 选项配置底层 Vite 实例。无需创建单独的 Vite 配置文件。 + +- **Vue** + + VitePress 已经包含 Vite 的官方 Vue 插件 ([@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue)),所以我们可以配置 VitePress 中的 [vue](#vue) 选项。 + +- **Markdown** + + 可以使用 VitePress 配置中的 [markdown](#markdown) 选项配置底层的 [Markdown-It](https://github.com/markdown-it/markdown-it) 实例。 + +## 站点元数据 {#site-metadata} + +### title + +- 类型:`string` +- 默认值: `VitePress` +- 每个页面可以通过 [frontmatter](./frontmatter-config#title) 覆盖 + +站点的标题。使用默认主题时,这将显示在导航栏中。 + +它还将用作所有单独页面标题的默认后缀,除非定义了 [`titleTemplate`](#titletemplate)。单个页面的最终标题将是其第一个 `

` 标题的文本内容加上的全局 `title`。例如使用以下配置和页面内容: + +```ts +export default { + title: 'My Awesome Site' +} +``` + +```md +# Hello +``` + +页面标题就是 `Hello | My Awesome Site`. + +### titleTemplate + +- 类型:`string | boolean` +- 每个页面可以通过 [frontmatter](./frontmatter-config#titletemplate) 覆盖 + +允许自定义每个页面的标题后缀或整个标题。例如: + +```ts +export default { + title: 'My Awesome Site', + titleTemplate: 'Custom Suffix' +} +``` + +```md +# Hello +``` + +页面标题就是 `Hello | Custom Suffix`. + +要完全自定义标题的呈现方式,可以在 `titleTemplate` 中使用 `:title` 标识符: + +```ts +export default { + titleTemplate: ':title - Custom Suffix' +} +``` + +这里的 `:title` 将替换为从页面的第一个 `

` 标题推断出的文本。上一个示例页面的标题将是 `Hello - Custom Suffix`。 + +该选项可以设置为 `false` 以禁用标题后缀。 + +### description + +- 类型:`string` +- 默认值: `A VitePress site` +- 每个页面可以通过 [frontmatter](./frontmatter-config#description) 覆盖 + +站点的描述。这将呈现为页面 HTML 中的 `` 标签。 + +```ts +export default { + description: 'A VitePress site' +} +``` + +### head + +- 类型:`HeadConfig[]` +- 默认值: `[]` +- 可以通过 [frontmatter](./frontmatter-config#head) 为每个页面追加 + +要在页面 HTML 的 `` 标签中呈现的其他元素。用户添加的标签在结束 `head` 标签之前呈现,在 VitePress 标签之后。 + +```ts +type HeadConfig = + | [string, Record] + | [string, Record, string] +``` + +#### 示例:添加一个图标 {#example-adding-a-favicon} + +```ts +export default { + head: [['link', { rel: 'icon', href: '/favicon.ico' }]] +} // 将 favicon.ico 放在公共目录中,如果设置了 base,则使用 /base/favicon.ico + +/* 渲染成: + +*/ +``` + +#### 示例:添加谷歌字体 {#example-adding-google-fonts} + +```ts +export default { + head: [ + [ + 'link', + { rel: 'preconnect', href: 'https://fonts.googleapis.com' } + ], + [ + 'link', + { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' } + ], + [ + 'link', + { href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap', rel: 'stylesheet' } + ] + ] +} + +/* 渲染成: + + + +*/ +``` + +#### 示例:添加一个 serviceWorker {#example-registering-a-service-worker} + +```ts +export default { + head: [ + [ + 'script', + { id: 'register-sw' }, + `;(() => { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.register('/sw.js') + } + })()` + ] + ] +} + +/* 渲染成: + +*/ +``` + +#### 示例:使用谷歌分析 {#example-using-google-analytics} + +```ts +export default { + head: [ + [ + 'script', + { async: '', src: 'https://www.googletagmanager.com/gtag/js?id=TAG_ID' } + ], + [ + 'script', + {}, + `window.dataLayer = window.dataLayer || []; + function gtag(){dataLayer.push(arguments);} + gtag('js', new Date()); + gtag('config', 'TAG_ID');` + ] + ] +} + +/* 渲染成: + + +*/ +``` + +### lang + +- 类型:`string` +- 默认值: `en-US` + +站点的 lang 属性。这将呈现为页面 HTML 中的 `` 标签。 + +```ts +export default { + lang: 'en-US' +} +``` + +### base + +- 类型:`string` +- 默认值: `/` + +站点将部署到的 base URL。如果计划在子路径例如 GitHub 页面)下部署站点,则需要设置此项。如果计划将站点部署到 `https://foo.github.io/bar/`,那么应该将 `base` 设置为 `“/bar/”`。它应该始终以 `/` 开头和结尾。 + +base 会自动添加到其他选项中以 `/` 开头的所有 URL 前面,因此只需指定一次。 + +```ts +export default { + base: '/base/' +} +``` + +## 路由 {#routing} + +### cleanUrls + +- 类型:`boolean` +- 默认值: `false` + +当设置为 `true` 时,VitePress 将从 URL 中删除 `.html` 后缀。另请参阅[生成简洁的 URL](../guide/routing#generating-clean-url)。 + +::: warning 需要服务器支持 +要启用此功能,可能需要在托管平台上进行额外配置。要使其正常工作,服务器必须能够在**不重定向的情况下**访问 `/foo` 时提供 `/foo.html`。 +::: + +### rewrites + +- 类型:`Record` + +自定义目录 <-> URL 映射。详细信息请参阅[路由:路由重写](../guide/routing#route-rewrites)。 + +```ts +export default { + rewrites: { + 'source/:page': 'destination/:page' + } +} +``` + +## 构建 {#build} + +### srcDir + +- 类型:`string` +- 默认值: `.` + +相对于项目根目录的 markdown 文件所在的文件夹。另请参阅[根目录和源目录](../guide/routing#root-and-source-directory)。 + +```ts +export default { + srcDir: './src' +} +``` + +### srcExclude + +- 类型:`string` +- 默认值: `undefined` + +用于匹配应排除作为源内容输出的 markdown 文件,语法详见 [glob pattern](https://github.com/mrmlnc/fast-glob#pattern-syntax)。 + +```ts +export default { + srcExclude: ['**/README.md', '**/TODO.md'] +} +``` + +### outDir + +- 类型:`string` +- 默认值: `./.vitepress/dist` + +项目的构建输出位置,相对于[项目根目录](../guide/routing#root-and-source-directory)。 + +```ts +export default { + outDir: '../public' +} +``` + +### assetsDir + +- 类型:`string` +- 默认值: `assets` + +指定放置生成的静态资源的目录。该路径应位于 [`outDir`](#outdir) 内,并相对于它进行解析。 + +```ts +export default { + assetsDir: 'static' +} +``` + +### cacheDir + +- 类型:`string` +- 默认值: `./.vitepress/cache` + +缓存文件的目录,相对于[项目根目录](../guide/routing#root-and-source-directory)。另请参阅:[cacheDir](https://vitejs.dev/config/shared-options.html#cachedir)。 + +```ts +export default { + cacheDir: './.vitepress/.vite' +} +``` + +### ignoreDeadLinks + +- 类型:`boolean | 'localhostLinks' | (string | RegExp | ((link: string) => boolean))[]` +- 默认值: `false` + +当设置为 `true` 时,VitePress 不会因为死链而导致构建失败。 + +当设置为 `'localhostLinks'` ,出现死链时构建将失败,但不会检查 `localhost` 链接。 + +```ts +export default { + ignoreDeadLinks: true +} +``` + +它也可以是一组精确的 url 字符串、正则表达式模式或自定义过滤函数。 + +```ts +export default { + ignoreDeadLinks: [ + // 忽略精确网址 "/playground" + '/playground', + // 忽略所有 localhost 链接 + /^https?:\/\/localhost/, + // 忽略所有包含 "/repl/" 的链接 + /\/repl\//, + // 自定义函数,忽略所有包含 "ignore "的链接 + (url) => { + return url.toLowerCase().includes('ignore') + } + ] +} +``` + +### metaChunk + +- 类型:`boolean` +- 默认值:`false` + +当设置为 `true` 时,将页面元数据提取到单独的 JavaScript 块中,而不是内联在初始 HTML 中。这使每个页面的 HTML 负载更小,并使页面元数据可缓存,从而当站点中有很多页面时可以减少服务器带宽。 + +### mpa + +- 类型:`boolean` +- 默认值: `false` + +设置为 `true` 时,生产应用程序将在 [MPA 模式](../guide/mpa-mode)下构建。MPA 模式默认提供 零 JavaScript 支持,代价是禁用客户端导航,并且需要明确选择加入才能进行交互。 + +## 主题 {#theming} + +### appearance + +- 类型:`boolean | 'dark' | 'force-dark' | import('@vueuse/core').UseDarkOptions` +- 默认值: `true` + +是否启用深色模式 (通过将 `.dark` 类添加到 `` 元素)。 + +- 如果该选项设置为 `true`,则默认主题将由用户的首选配色方案决定。 +- 如果该选项设置为 `dark`,则默认情况下主题将是深色的,除非用户手动切换它。 +- 如果该选项设置为 `false`,用户将无法切换主题。 + +此选项注入一个内联脚本,使用 `vitepress-theme-appearance` key 从本地存储恢复用户设置。这确保在呈现页面之前应用 `.dark` 类以避免闪烁。 + +`appearance.initialValue` 只能是 `'dark' | undefined`。 不支持 Refs 或 getters。 + +### lastUpdated + +- 类型:`boolean` +- 默认值: `false` + +是否使用 Git 获取每个页面的最后更新时间戳。时间戳将包含在每个页面的页面数据中,可通过 [`useData`](./runtime-api#usedata) 访问。 + +使用默认主题时,启用此选项将显示每个页面的最后更新时间。可以通过 [`themeConfig.lastUpdatedText`](./default-theme-config#lastupdatedtext) 选项自定义文本。 + +## 自定义 {#customization} + +### markdown + +- 类型:`MarkdownOption` + +配置 Markdown 解析器选项。VitePress 使用 [Markdown-it](https://github.com/markdown-it/markdown-it) 作为解析器,使用 [Shiki](https://github.com/shikijs/shiki) 来高亮不同语言语法。在此选项中,可以传递各种 Markdown 相关选项以满足你的需要。 + +```js +export default { + markdown: {...} +} +``` + +查看[类型声明和 jsdocs](https://github.com/vuejs/vitepress/blob/main/src/node/markdown/markdown.ts) 以获得所有可配置的选项。 + +### vite + +- 类型:`import('vite').UserConfig` + +将原始 [Vite 配置](https://vitejs.dev/config/)传递给内部 Vite 开发服务器 / bundler。 + +```js +export default { + vite: { + // Vite 配置选项 + } +} +``` + +### vue + +- 类型:`import('@vitejs/plugin-vue').Options` + +将原始的 [@vitejs/plugin-vue 选项](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue#options)传递给内部插件实例。 + +```js +export default { + vue: { + // @vitejs/plugin-vue 选项 + } +} +``` + +## 构建钩子 {#build-hooks} + +VitePress 构建钩子允许向站点添加新功能和行为: + +- Sitemap +- Search Indexing +- PWA +- Teleport + +### buildEnd + +- 类型:`(siteConfig: SiteConfig) => Awaitable` + +`buildEnd` 是一个构建 CLI 钩子,它将在构建 SSG 完成后但在 VitePress CLI 进程退出之前运行。 + +```ts +export default { + async buildEnd(siteConfig) { + // ... + } +} +``` + +### postRender + +- 类型:`(context: SSGContext) => Awaitable` + + `postRender` 是一个构建钩子,在 SSG 渲染完成时调用。它将允许在 SSG 期间处理传递的内容。 + +```ts +export default { + async postRender(context) { + // ... + } +} +``` + +```ts +interface SSGContext { + content: string + teleports?: Record + [key: string]: any +} +``` + +### transformHead + +- 类型:`(context: TransformContext) => Awaitable` + +`transformHead` 是一个构建钩子,用于在生成每个页面之前转换 head。它将允许添加无法静态添加到 VitePress 配置中的 head entries。只需要返回额外的 entries,它们将自动与现有 entries 合并。 + +::: warning +不要改变 `context` 中的任何东西。 +::: + +```ts +export default { + async transformHead(context) { + // ... + } +} +``` + +```ts +interface TransformContext { + page: string // 例如 index.md (相对于 srcDir) + assets: string[] // 所有非 js/css 资源均作为完全解析的公共 URL + siteConfig: SiteConfig + siteData: SiteData + pageData: PageData + title: string + description: string + head: HeadConfig[] + content: string +} +``` + +请注意,仅在静态生成站点时才会调用此钩子。在开发期间不会调用它。如果需要在开发期间添加动态 head 条目,可以使用 [`transformPageData`](#transformpagedata) 钩子来替代: + +```ts +export default { + transformPageData(pageData) { + pageData.frontmatter.head ??= [] + pageData.frontmatter.head.push([ + 'meta', + { + name: 'og:title', + content: + pageData.frontmatter.layout === 'home' + ? `VitePress` + : `${pageData.title} | VitePress` + } + ]) + } +} +``` + +#### 示例:添加 canonical URL `` {#example-adding-a-canonical-url-link} + +```ts +export default { + transformPageData(pageData) { + const canonicalUrl = `https://example.com/${pageData.relativePath}` + .replace(/index\.md$/, '') + .replace(/\.md$/, '.html') + + pageData.frontmatter.head ??= [] + pageData.frontmatter.head.push([ + 'link', + { rel: 'canonical', href: canonicalUrl } + ]) + } +} +``` + +### transformHtml + +- 类型:`(code: string, id: string, context: TransformContext) => Awaitable` + +`transformHtml` 是一个构建钩子,用于在保存到磁盘之前转换每个页面的内容。 + +::: warning +不要改变 `context` 中的任何东西。另外,修改 html 内容可能会导致运行时出现激活问题。 +::: + +```ts +export default { + async transformHtml(code, id, context) { + // ... + } +} +``` + +### transformPageData + +- 类型:`(pageData: PageData, context: TransformPageContext) => Awaitable | { [key: string]: any } | void>` + +`transformPageData` 是一个钩子,用于转换每个页面的 `pageData`。可以直接改变 `pageData` 或返回将合并到 `PageData` 中的更改值。 + +::: warning +不要改变 `context` 中的任何东西。请注意,这可能会影响开发服务器的性能,特别是当在钩子中有一些网络请求或大量计算 (例如生成图像) 时。可以通过判断 `process.env.NODE_ENV === 'production'` 匹配符合条件的情况。 +::: + +```ts +export default { + async transformPageData(pageData, { siteConfig }) { + pageData.contributors = await getPageContributors(pageData.relativePath) + } + + // 或返回要合并的数据 + async transformPageData(pageData, { siteConfig }) { + return { + contributors: await getPageContributors(pageData.relativePath) + } + } +} +``` + +```ts +interface TransformPageContext { + siteConfig: SiteConfig +} +``` diff --git a/lib/vue-demi.mjs b/lib/vue-demi.mjs new file mode 100644 index 00000000..fd8ead4f --- /dev/null +++ b/lib/vue-demi.mjs @@ -0,0 +1,34 @@ +/** + * vue-demi v0.14.7 + * Copyright (c) 2020-present, Anthony Fu + * @license MIT + */ + +import * as Vue from 'vue' + +var isVue2 = false +var isVue3 = true +var Vue2 = undefined + +function install() {} + +export function set(target, key, val) { + if (Array.isArray(target)) { + target.length = Math.max(target.length, key) + target.splice(key, 1, val) + return val + } + target[key] = val + return val +} + +export function del(target, key) { + if (Array.isArray(target)) { + target.splice(key, 1) + return + } + delete target[key] +} + +export * from 'vue' +export { Vue, Vue2, isVue2, isVue3, install } diff --git a/netlify.toml b/netlify.toml index f4e5c802..801b84fc 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,6 +1,6 @@ [build.environment] - NODE_VERSION = "18" + NODE_VERSION = "20" [build] publish = "docs/.vitepress/dist" - command = "pnpm docs:build" + command = "pnpm docs:build && pnpm docs:lunaria:build" diff --git a/package.json b/package.json index 9b30eb78..26b8675f 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,23 @@ { "name": "vitepress", - "version": "1.0.0-rc.31", + "version": "1.1.3", "description": "Vite & Vue powered static site generator", + "keywords": [ + "vite", + "vue", + "vitepress" + ], + "homepage": "https://github.com/vuejs/vitepress/tree/main/#readme", + "bugs": { + "url": "https://github.com/vuejs/vitepress/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/vuejs/vitepress.git" + }, + "license": "MIT", + "author": "Evan You", "type": "module", - "packageManager": "pnpm@8.11.0", - "main": "dist/node/index.js", - "types": "types/index.d.ts", "exports": { ".": { "types": "./types/index.d.ts", @@ -24,8 +36,13 @@ "./theme-without-fonts": { "types": "./theme-without-fonts.d.ts", "default": "./dist/client/theme-default/without-fonts.js" + }, + "./vue-demi": { + "default": "./lib/vue-demi.mjs" } }, + "main": "dist/node/index.js", + "types": "types/index.d.ts", "bin": { "vitepress": "bin/vitepress.js" }, @@ -36,23 +53,9 @@ "template", "client.d.ts", "theme.d.ts", - "theme-without-fonts.d.ts" + "theme-without-fonts.d.ts", + "lib" ], - "repository": { - "type": "git", - "url": "git+https://github.com/vuejs/vitepress.git" - }, - "keywords": [ - "vite", - "vue", - "vitepress" - ], - "author": "Evan You", - "license": "MIT", - "homepage": "https://github.com/vuejs/vitepress/tree/main/#readme", - "bugs": { - "url": "https://github.com/vuejs/vitepress/issues" - }, "scripts": { "dev": "rimraf dist && run-s dev:shared dev:start", "dev:start": "run-p dev:client dev:node dev:watch", @@ -83,56 +86,53 @@ "docs:build": "run-s build docs:build:only", "docs:build:only": "pnpm -F=docs build", "docs:preview": "pnpm -F=docs preview", + "docs:lunaria:build": "pnpm -F=docs lunaria:build", + "docs:lunaria:open": "pnpm -F=docs lunaria:open", "format": "prettier --check --write .", "format:fail": "prettier --check .", "check": "run-s format:fail build test", "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", "release": "node scripts/release.js" }, + "simple-git-hooks": { + "pre-commit": "pnpm lint-staged" + }, + "lint-staged": { + "*": "prettier --write --ignore-unknown", + "package.json": "sort-package-json" + }, "dependencies": { - "@docsearch/css": "^3.5.2", - "@docsearch/js": "^3.5.2", - "@types/markdown-it": "^13.0.7", - "@vitejs/plugin-vue": "^4.5.0", - "@vue/devtools-api": "^6.5.1", - "@vueuse/core": "^10.6.1", - "@vueuse/integrations": "^10.6.1", + "@docsearch/css": "^3.6.0", + "@docsearch/js": "^3.6.0", + "@shikijs/core": "^1.3.0", + "@shikijs/transformers": "^1.3.0", + "@types/markdown-it": "^14.0.1", + "@vitejs/plugin-vue": "^5.0.4", + "@vue/devtools-api": "^7.0.27", + "@vueuse/core": "^10.9.0", + "@vueuse/integrations": "^10.9.0", "focus-trap": "^7.5.4", "mark.js": "8.11.1", "minisearch": "^6.3.0", - "mrmime": "^1.0.1", - "shikiji": "^0.7.4", - "shikiji-transformers": "^0.7.4", - "vite": "^5.0.2", - "vue": "^3.3.8" - }, - "peerDependencies": { - "markdown-it-mathjax3": "^4.3.2", - "postcss": "^8.4.31" - }, - "peerDependenciesMeta": { - "markdown-it-mathjax3": { - "optional": true - }, - "postcss": { - "optional": true - } + "shiki": "^1.3.0", + "vite": "^5.2.9", + "vue": "^3.4.23" }, "devDependencies": { "@clack/prompts": "^0.7.0", - "@mdit-vue/plugin-component": "^1.0.0", - "@mdit-vue/plugin-frontmatter": "^1.0.0", - "@mdit-vue/plugin-headers": "^1.0.0", - "@mdit-vue/plugin-sfc": "^1.0.0", - "@mdit-vue/plugin-title": "^1.0.0", - "@mdit-vue/plugin-toc": "^1.0.0", - "@mdit-vue/shared": "^1.0.0", - "@rollup/plugin-alias": "^5.0.1", + "@mdit-vue/plugin-component": "^2.1.2", + "@mdit-vue/plugin-frontmatter": "^2.1.2", + "@mdit-vue/plugin-headers": "^2.1.2", + "@mdit-vue/plugin-sfc": "^2.1.2", + "@mdit-vue/plugin-title": "^2.1.2", + "@mdit-vue/plugin-toc": "^2.1.2", + "@mdit-vue/shared": "^2.1.2", + "@polka/compression": "1.0.0-next.25", + "@rollup/plugin-alias": "^5.1.0", "@rollup/plugin-commonjs": "^25.0.7", - "@rollup/plugin-json": "^6.0.1", + "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^5.0.5", - "@types/compression": "^1.7.5", "@types/cross-spawn": "^6.0.6", "@types/debug": "^4.1.12", "@types/escape-html": "^1.0.4", @@ -140,81 +140,91 @@ "@types/lodash.template": "^4.5.3", "@types/mark.js": "^8.11.12", "@types/markdown-it-attrs": "^4.1.3", - "@types/markdown-it-container": "^2.0.9", - "@types/markdown-it-emoji": "^2.0.4", - "@types/micromatch": "^4.0.6", + "@types/markdown-it-container": "^2.0.10", + "@types/markdown-it-emoji": "^2.0.5", + "@types/micromatch": "^4.0.7", "@types/minimist": "^1.2.5", - "@types/node": "^20.10.0", + "@types/node": "^20.12.7", "@types/postcss-prefix-selector": "^1.16.3", "@types/prompts": "^2.4.9", - "@vue/shared": "^3.3.8", - "chokidar": "^3.5.3", - "compression": "^1.7.4", + "@vue/shared": "^3.4.23", + "chokidar": "^3.6.0", "conventional-changelog-cli": "^4.1.0", "cross-spawn": "^7.0.3", "debug": "^4.3.4", - "esbuild": "^0.19.7", + "esbuild": "^0.20.2", "escape-html": "^1.0.3", "execa": "^8.0.1", "fast-glob": "^3.3.2", - "fs-extra": "^11.1.1", - "get-port": "^7.0.0", + "fs-extra": "^11.2.0", + "get-port": "^7.1.0", "gray-matter": "^4.0.3", - "lint-staged": "^15.1.0", + "lint-staged": "^15.2.2", "lodash.template": "^4.5.0", - "lru-cache": "^10.1.0", - "markdown-it": "^13.0.2", + "lru-cache": "^10.2.0", + "markdown-it": "^14.1.0", "markdown-it-anchor": "^8.6.7", "markdown-it-attrs": "^4.1.6", - "markdown-it-container": "^3.0.0", - "markdown-it-emoji": "^2.0.2", + "markdown-it-container": "^4.0.0", + "markdown-it-emoji": "^3.0.0", "markdown-it-mathjax3": "^4.3.2", "micromatch": "^4.0.5", "minimist": "^1.2.8", - "nanoid": "^5.0.3", + "nanoid": "^5.0.7", "npm-run-all": "^4.1.5", - "ora": "^7.0.1", - "path-to-regexp": "^6.2.1", + "ora": "^8.0.1", + "p-map": "^7.0.2", + "path-to-regexp": "^6.2.2", "picocolors": "^1.0.0", "pkg-dir": "^8.0.0", - "playwright-chromium": "^1.40.0", - "polka": "1.0.0-next.23", + "playwright-chromium": "^1.43.1", + "polka": "1.0.0-next.25", "postcss-prefix-selector": "^1.16.0", - "prettier": "^3.1.0", + "prettier": "^3.2.5", "prompts": "^2.4.2", "punycode": "^2.3.1", "rimraf": "^5.0.5", - "rollup": "^4.5.2", + "rollup": "^4.14.3", "rollup-plugin-dts": "^6.1.0", - "rollup-plugin-esbuild": "^6.1.0", - "semver": "^7.5.4", - "simple-git-hooks": "^2.9.0", - "sirv": "^2.0.3", + "rollup-plugin-esbuild": "^6.1.1", + "semver": "^7.6.0", + "simple-git-hooks": "^2.11.1", + "sirv": "^2.0.4", "sitemap": "^7.1.1", + "sort-package-json": "^2.10.0", "supports-color": "^9.4.0", - "typescript": "^5.3.2", - "vitest": "^1.0.0-beta.4", - "vue-tsc": "^1.8.22", + "typescript": "^5.4.5", + "vitest": "^1.5.0", + "vue-tsc": "^2.0.13", "wait-on": "^7.2.0" }, - "simple-git-hooks": { - "pre-commit": "pnpm lint-staged" + "peerDependencies": { + "markdown-it-mathjax3": "^4", + "postcss": "^8" }, - "lint-staged": { - "*": [ - "prettier --write --ignore-unknown" - ] + "peerDependenciesMeta": { + "markdown-it-mathjax3": { + "optional": true + }, + "postcss": { + "optional": true + } }, + "packageManager": "pnpm@9.0.2", "pnpm": { - "overrides": { - "ora>string-width": "^5" - }, "peerDependencyRules": { "ignoreMissing": [ "@algolia/client-search", "search-insights", "postcss" ] + }, + "overrides": { + "ora>string-width": "^5" + }, + "patchedDependencies": { + "@types/markdown-it@14.0.1": "patches/@types__markdown-it@14.0.1.patch", + "markdown-it-anchor@8.6.7": "patches/markdown-it-anchor@8.6.7.patch" } } } diff --git a/patches/@types__markdown-it@14.0.1.patch b/patches/@types__markdown-it@14.0.1.patch new file mode 100644 index 00000000..945e8080 --- /dev/null +++ b/patches/@types__markdown-it@14.0.1.patch @@ -0,0 +1,13 @@ +diff --git a/package.json b/package.json +index 3b3cdfc4427a1a64fdd3b37604a7174e4646e423..afaea16b115554fcf15a905642562e881ece7ca6 100644 +--- a/package.json ++++ b/package.json +@@ -27,7 +27,7 @@ + } + ], + "main": "", +- "types": "index.d.ts", ++ "types": "index.d.mts", + "exports": { + ".": { + "import": "./index.d.mts", diff --git a/patches/markdown-it-anchor@8.6.7.patch b/patches/markdown-it-anchor@8.6.7.patch new file mode 100644 index 00000000..37bfd174 --- /dev/null +++ b/patches/markdown-it-anchor@8.6.7.patch @@ -0,0 +1,29 @@ +diff --git a/types/index.d.ts b/types/index.d.ts +index 7c94aae194faa66ca006ace98cdb0dee82a3e471..0377cace7c4a9653d4ecf963babffd4bd68494b0 100644 +--- a/types/index.d.ts ++++ b/types/index.d.ts +@@ -1,10 +1,10 @@ +-import MarkdownIt = require('markdown-it'); +-import Token = require('markdown-it/lib/token'); +-import State = require('markdown-it/lib/rules_core/state_core'); ++import MarkdownIt from 'markdown-it'; ++import Token from 'markdown-it/lib/token.mjs'; ++import StateCore from 'markdown-it/lib/rules_core/state_core.mjs'; + + declare namespace anchor { +- export type RenderHref = (slug: string, state: State) => string; +- export type RenderAttrs = (slug: string, state: State) => Record; ++ export type RenderHref = (slug: string, state: StateCore) => string; ++ export type RenderAttrs = (slug: string, state: StateCore) => Record; + + export interface PermalinkOptions { + class?: string, +@@ -37,7 +37,7 @@ declare namespace anchor { + placement?: 'before' | 'after' + } + +- export type PermalinkGenerator = (slug: string, opts: PermalinkOptions, state: State, index: number) => void; ++ export type PermalinkGenerator = (slug: string, opts: PermalinkOptions, state: StateCore, index: number) => void; + + export interface AnchorInfo { + slug: string; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 616b81ce..13594ec1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: false @@ -7,31 +7,45 @@ settings: overrides: ora>string-width: ^5 +patchedDependencies: + '@types/markdown-it@14.0.1': + hash: f3sowjfcbslfedfcollco2ioje + path: patches/@types__markdown-it@14.0.1.patch + markdown-it-anchor@8.6.7: + hash: 7jac6clbacexfaqdjyv4p6a5n4 + path: patches/markdown-it-anchor@8.6.7.patch + importers: .: dependencies: '@docsearch/css': - specifier: ^3.5.2 - version: 3.5.2 + specifier: ^3.6.0 + version: 3.6.0 '@docsearch/js': - specifier: ^3.5.2 - version: 3.5.2 + specifier: ^3.6.0 + version: 3.6.0(@algolia/client-search@4.23.3) + '@shikijs/core': + specifier: ^1.3.0 + version: 1.3.0 + '@shikijs/transformers': + specifier: ^1.3.0 + version: 1.3.0 '@types/markdown-it': - specifier: ^13.0.7 - version: 13.0.7 + specifier: ^14.0.1 + version: 14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje) '@vitejs/plugin-vue': - specifier: ^4.5.0 - version: 4.5.0(vite@5.0.5)(vue@3.3.8) + specifier: ^5.0.4 + version: 5.0.4(vite@5.2.9(@types/node@20.12.7))(vue@3.4.23(typescript@5.4.5)) '@vue/devtools-api': - specifier: ^6.5.1 - version: 6.5.1 + specifier: ^7.0.27 + version: 7.0.27(vue@3.4.23(typescript@5.4.5)) '@vueuse/core': - specifier: ^10.6.1 - version: 10.6.1(vue@3.3.8) + specifier: ^10.9.0 + version: 10.9.0(vue@3.4.23(typescript@5.4.5)) '@vueuse/integrations': - specifier: ^10.6.1 - version: 10.6.1(focus-trap@7.5.4)(vue@3.3.8) + specifier: ^10.9.0 + version: 10.9.0(axios@1.6.8(debug@4.3.4(supports-color@9.4.0)))(focus-trap@7.5.4)(vue@3.4.23(typescript@5.4.5)) focus-trap: specifier: ^7.5.4 version: 7.5.4 @@ -41,64 +55,58 @@ importers: minisearch: specifier: ^6.3.0 version: 6.3.0 - mrmime: - specifier: ^1.0.1 - version: 1.0.1 - shikiji: - specifier: ^0.7.4 - version: 0.7.4 - shikiji-transformers: - specifier: ^0.7.4 - version: 0.7.4 + shiki: + specifier: ^1.3.0 + version: 1.3.0 vite: - specifier: ^5.0.2 - version: 5.0.5(@types/node@20.10.0) + specifier: ^5.2.9 + version: 5.2.9(@types/node@20.12.7) vue: - specifier: ^3.3.8 - version: 3.3.8(typescript@5.3.2) + specifier: ^3.4.23 + version: 3.4.23(typescript@5.4.5) devDependencies: '@clack/prompts': specifier: ^0.7.0 version: 0.7.0 '@mdit-vue/plugin-component': - specifier: ^1.0.0 - version: 1.0.0 + specifier: ^2.1.2 + version: 2.1.2 '@mdit-vue/plugin-frontmatter': - specifier: ^1.0.0 - version: 1.0.0 + specifier: ^2.1.2 + version: 2.1.2 '@mdit-vue/plugin-headers': - specifier: ^1.0.0 - version: 1.0.0 + specifier: ^2.1.2 + version: 2.1.2 '@mdit-vue/plugin-sfc': - specifier: ^1.0.0 - version: 1.0.0 + specifier: ^2.1.2 + version: 2.1.2 '@mdit-vue/plugin-title': - specifier: ^1.0.0 - version: 1.0.0 + specifier: ^2.1.2 + version: 2.1.2 '@mdit-vue/plugin-toc': - specifier: ^1.0.0 - version: 1.0.0 + specifier: ^2.1.2 + version: 2.1.2 '@mdit-vue/shared': - specifier: ^1.0.0 - version: 1.0.0 + specifier: ^2.1.2 + version: 2.1.2 + '@polka/compression': + specifier: 1.0.0-next.25 + version: 1.0.0-next.25 '@rollup/plugin-alias': - specifier: ^5.0.1 - version: 5.0.1(rollup@4.5.2) + specifier: ^5.1.0 + version: 5.1.0(rollup@4.14.3) '@rollup/plugin-commonjs': specifier: ^25.0.7 - version: 25.0.7(rollup@4.5.2) + version: 25.0.7(rollup@4.14.3) '@rollup/plugin-json': - specifier: ^6.0.1 - version: 6.0.1(rollup@4.5.2) + specifier: ^6.1.0 + version: 6.1.0(rollup@4.14.3) '@rollup/plugin-node-resolve': specifier: ^15.2.3 - version: 15.2.3(rollup@4.5.2) + version: 15.2.3(rollup@4.14.3) '@rollup/plugin-replace': specifier: ^5.0.5 - version: 5.0.5(rollup@4.5.2) - '@types/compression': - specifier: ^1.7.5 - version: 1.7.5 + version: 5.0.5(rollup@4.14.3) '@types/cross-spawn': specifier: ^6.0.6 version: 6.0.6 @@ -121,20 +129,20 @@ importers: specifier: ^4.1.3 version: 4.1.3 '@types/markdown-it-container': - specifier: ^2.0.9 - version: 2.0.9 + specifier: ^2.0.10 + version: 2.0.10 '@types/markdown-it-emoji': - specifier: ^2.0.4 - version: 2.0.4 + specifier: ^2.0.5 + version: 2.0.5 '@types/micromatch': - specifier: ^4.0.6 - version: 4.0.6 + specifier: ^4.0.7 + version: 4.0.7 '@types/minimist': specifier: ^1.2.5 version: 1.2.5 '@types/node': - specifier: ^20.10.0 - version: 20.10.0 + specifier: ^20.12.7 + version: 20.12.7 '@types/postcss-prefix-selector': specifier: ^1.16.3 version: 1.16.3 @@ -142,14 +150,11 @@ importers: specifier: ^2.4.9 version: 2.4.9 '@vue/shared': - specifier: ^3.3.8 - version: 3.3.8 + specifier: ^3.4.23 + version: 3.4.23 chokidar: - specifier: ^3.5.3 - version: 3.5.3 - compression: - specifier: ^1.7.4 - version: 1.7.4(supports-color@9.4.0) + specifier: ^3.6.0 + version: 3.6.0 conventional-changelog-cli: specifier: ^4.1.0 version: 4.1.0 @@ -160,8 +165,8 @@ importers: specifier: ^4.3.4 version: 4.3.4(supports-color@9.4.0) esbuild: - specifier: ^0.19.7 - version: 0.19.7 + specifier: ^0.20.2 + version: 0.20.2 escape-html: specifier: ^1.0.3 version: 1.0.3 @@ -172,38 +177,38 @@ importers: specifier: ^3.3.2 version: 3.3.2 fs-extra: - specifier: ^11.1.1 - version: 11.1.1 + specifier: ^11.2.0 + version: 11.2.0 get-port: - specifier: ^7.0.0 - version: 7.0.0 + specifier: ^7.1.0 + version: 7.1.0 gray-matter: specifier: ^4.0.3 version: 4.0.3 lint-staged: - specifier: ^15.1.0 - version: 15.1.0(supports-color@9.4.0) + specifier: ^15.2.2 + version: 15.2.2(supports-color@9.4.0) lodash.template: specifier: ^4.5.0 version: 4.5.0 lru-cache: - specifier: ^10.1.0 - version: 10.1.0 + specifier: ^10.2.0 + version: 10.2.0 markdown-it: - specifier: ^13.0.2 - version: 13.0.2 + specifier: ^14.1.0 + version: 14.1.0 markdown-it-anchor: specifier: ^8.6.7 - version: 8.6.7(@types/markdown-it@13.0.7)(markdown-it@13.0.2) + version: 8.6.7(patch_hash=7jac6clbacexfaqdjyv4p6a5n4)(@types/markdown-it@14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje))(markdown-it@14.1.0) markdown-it-attrs: specifier: ^4.1.6 - version: 4.1.6(markdown-it@13.0.2) + version: 4.1.6(markdown-it@14.1.0) markdown-it-container: + specifier: ^4.0.0 + version: 4.0.0 + markdown-it-emoji: specifier: ^3.0.0 version: 3.0.0 - markdown-it-emoji: - specifier: ^2.0.2 - version: 2.0.2 markdown-it-mathjax3: specifier: ^4.3.2 version: 4.3.2 @@ -214,17 +219,20 @@ importers: specifier: ^1.2.8 version: 1.2.8 nanoid: - specifier: ^5.0.3 - version: 5.0.3 + specifier: ^5.0.7 + version: 5.0.7 npm-run-all: specifier: ^4.1.5 version: 4.1.5 ora: - specifier: ^7.0.1 - version: 7.0.1 + specifier: ^8.0.1 + version: 8.0.1 + p-map: + specifier: ^7.0.2 + version: 7.0.2 path-to-regexp: - specifier: ^6.2.1 - version: 6.2.1 + specifier: ^6.2.2 + version: 6.2.2 picocolors: specifier: ^1.0.0 version: 1.0.0 @@ -232,17 +240,17 @@ importers: specifier: ^8.0.0 version: 8.0.0 playwright-chromium: - specifier: ^1.40.0 - version: 1.40.0 + specifier: ^1.43.1 + version: 1.43.1 polka: - specifier: 1.0.0-next.23 - version: 1.0.0-next.23 + specifier: 1.0.0-next.25 + version: 1.0.0-next.25 postcss-prefix-selector: specifier: ^1.16.0 - version: 1.16.0 + version: 1.16.0(postcss@8.4.38) prettier: - specifier: ^3.1.0 - version: 3.1.0 + specifier: ^3.2.5 + version: 3.2.5 prompts: specifier: ^2.4.2 version: 2.4.2 @@ -253,41 +261,44 @@ importers: specifier: ^5.0.5 version: 5.0.5 rollup: - specifier: ^4.5.2 - version: 4.5.2 + specifier: ^4.14.3 + version: 4.14.3 rollup-plugin-dts: specifier: ^6.1.0 - version: 6.1.0(rollup@4.5.2)(typescript@5.3.2) + version: 6.1.0(rollup@4.14.3)(typescript@5.4.5) rollup-plugin-esbuild: - specifier: ^6.1.0 - version: 6.1.0(esbuild@0.19.7)(rollup@4.5.2)(supports-color@9.4.0) + specifier: ^6.1.1 + version: 6.1.1(esbuild@0.20.2)(rollup@4.14.3)(supports-color@9.4.0) semver: - specifier: ^7.5.4 - version: 7.5.4 + specifier: ^7.6.0 + version: 7.6.0 simple-git-hooks: - specifier: ^2.9.0 - version: 2.9.0 + specifier: ^2.11.1 + version: 2.11.1 sirv: - specifier: ^2.0.3 - version: 2.0.3 + specifier: ^2.0.4 + version: 2.0.4 sitemap: specifier: ^7.1.1 version: 7.1.1 + sort-package-json: + specifier: ^2.10.0 + version: 2.10.0 supports-color: specifier: ^9.4.0 version: 9.4.0 typescript: - specifier: ^5.3.2 - version: 5.3.2 + specifier: ^5.4.5 + version: 5.4.5 vitest: - specifier: ^1.0.0-beta.4 - version: 1.0.0-beta.5(@types/node@20.10.0)(supports-color@9.4.0) + specifier: ^1.5.0 + version: 1.5.0(@types/node@20.12.7)(supports-color@9.4.0) vue-tsc: - specifier: ^1.8.22 - version: 1.8.22(typescript@5.3.2) + specifier: ^2.0.13 + version: 2.0.13(typescript@5.4.5) wait-on: specifier: ^7.2.0 - version: 7.2.0(debug@4.3.4) + version: 7.2.0(debug@4.3.4(supports-color@9.4.0)) __tests__/e2e: devDependencies: @@ -303,232 +314,127 @@ importers: docs: devDependencies: + '@lunariajs/core': + specifier: ^0.0.32 + version: 0.0.32(supports-color@9.4.0) markdown-it-mathjax3: specifier: ^4.3.2 version: 4.3.2 + open-cli: + specifier: ^8.0.0 + version: 8.0.0 vitepress: specifier: workspace:* version: link:.. packages: - /@algolia/autocomplete-core@1.9.3(algoliasearch@4.20.0): + '@algolia/autocomplete-core@1.9.3': resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} - dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(algoliasearch@4.20.0) - '@algolia/autocomplete-shared': 1.9.3(algoliasearch@4.20.0) - transitivePeerDependencies: - - '@algolia/client-search' - - algoliasearch - - search-insights - dev: false - /@algolia/autocomplete-plugin-algolia-insights@1.9.3(algoliasearch@4.20.0): + '@algolia/autocomplete-plugin-algolia-insights@1.9.3': resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==} peerDependencies: search-insights: '>= 1 < 3' - peerDependenciesMeta: - search-insights: - optional: true - dependencies: - '@algolia/autocomplete-shared': 1.9.3(algoliasearch@4.20.0) - transitivePeerDependencies: - - '@algolia/client-search' - - algoliasearch - dev: false - /@algolia/autocomplete-preset-algolia@1.9.3(algoliasearch@4.20.0): + '@algolia/autocomplete-preset-algolia@1.9.3': resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==} peerDependencies: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - peerDependenciesMeta: - '@algolia/client-search': - optional: true - dependencies: - '@algolia/autocomplete-shared': 1.9.3(algoliasearch@4.20.0) - algoliasearch: 4.20.0 - dev: false - /@algolia/autocomplete-shared@1.9.3(algoliasearch@4.20.0): + '@algolia/autocomplete-shared@1.9.3': resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} peerDependencies: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - peerDependenciesMeta: - '@algolia/client-search': - optional: true - dependencies: - algoliasearch: 4.20.0 - dev: false - /@algolia/cache-browser-local-storage@4.20.0: - resolution: {integrity: sha512-uujahcBt4DxduBTvYdwO3sBfHuJvJokiC3BP1+O70fglmE1ShkH8lpXqZBac1rrU3FnNYSUs4pL9lBdTKeRPOQ==} - dependencies: - '@algolia/cache-common': 4.20.0 - dev: false + '@algolia/cache-browser-local-storage@4.23.3': + resolution: {integrity: sha512-vRHXYCpPlTDE7i6UOy2xE03zHF2C8MEFjPN2v7fRbqVpcOvAUQK81x3Kc21xyb5aSIpYCjWCZbYZuz8Glyzyyg==} - /@algolia/cache-common@4.20.0: - resolution: {integrity: sha512-vCfxauaZutL3NImzB2G9LjLt36vKAckc6DhMp05An14kVo8F1Yofb6SIl6U3SaEz8pG2QOB9ptwM5c+zGevwIQ==} - dev: false + '@algolia/cache-common@4.23.3': + resolution: {integrity: sha512-h9XcNI6lxYStaw32pHpB1TMm0RuxphF+Ik4o7tcQiodEdpKK+wKufY6QXtba7t3k8eseirEMVB83uFFF3Nu54A==} - /@algolia/cache-in-memory@4.20.0: - resolution: {integrity: sha512-Wm9ak/IaacAZXS4mB3+qF/KCoVSBV6aLgIGFEtQtJwjv64g4ePMapORGmCyulCFwfePaRAtcaTbMcJF+voc/bg==} - dependencies: - '@algolia/cache-common': 4.20.0 - dev: false + '@algolia/cache-in-memory@4.23.3': + resolution: {integrity: sha512-yvpbuUXg/+0rbcagxNT7un0eo3czx2Uf0y4eiR4z4SD7SiptwYTpbuS0IHxcLHG3lq22ukx1T6Kjtk/rT+mqNg==} - /@algolia/client-account@4.20.0: - resolution: {integrity: sha512-GGToLQvrwo7am4zVkZTnKa72pheQeez/16sURDWm7Seyz+HUxKi3BM6fthVVPUEBhtJ0reyVtuK9ArmnaKl10Q==} - dependencies: - '@algolia/client-common': 4.20.0 - '@algolia/client-search': 4.20.0 - '@algolia/transporter': 4.20.0 - dev: false + '@algolia/client-account@4.23.3': + resolution: {integrity: sha512-hpa6S5d7iQmretHHF40QGq6hz0anWEHGlULcTIT9tbUssWUriN9AUXIFQ8Ei4w9azD0hc1rUok9/DeQQobhQMA==} - /@algolia/client-analytics@4.20.0: - resolution: {integrity: sha512-EIr+PdFMOallRdBTHHdKI3CstslgLORQG7844Mq84ib5oVFRVASuuPmG4bXBgiDbcsMLUeOC6zRVJhv1KWI0ug==} - dependencies: - '@algolia/client-common': 4.20.0 - '@algolia/client-search': 4.20.0 - '@algolia/requester-common': 4.20.0 - '@algolia/transporter': 4.20.0 - dev: false + '@algolia/client-analytics@4.23.3': + resolution: {integrity: sha512-LBsEARGS9cj8VkTAVEZphjxTjMVCci+zIIiRhpFun9jGDUlS1XmhCW7CTrnaWeIuCQS/2iPyRqSy1nXPjcBLRA==} - /@algolia/client-common@4.20.0: - resolution: {integrity: sha512-P3WgMdEss915p+knMMSd/fwiHRHKvDu4DYRrCRaBrsfFw7EQHon+EbRSm4QisS9NYdxbS04kcvNoavVGthyfqQ==} - dependencies: - '@algolia/requester-common': 4.20.0 - '@algolia/transporter': 4.20.0 - dev: false + '@algolia/client-common@4.23.3': + resolution: {integrity: sha512-l6EiPxdAlg8CYhroqS5ybfIczsGUIAC47slLPOMDeKSVXYG1n0qGiz4RjAHLw2aD0xzh2EXZ7aRguPfz7UKDKw==} - /@algolia/client-personalization@4.20.0: - resolution: {integrity: sha512-N9+zx0tWOQsLc3K4PVRDV8GUeOLAY0i445En79Pr3zWB+m67V+n/8w4Kw1C5LlbHDDJcyhMMIlqezh6BEk7xAQ==} - dependencies: - '@algolia/client-common': 4.20.0 - '@algolia/requester-common': 4.20.0 - '@algolia/transporter': 4.20.0 - dev: false + '@algolia/client-personalization@4.23.3': + resolution: {integrity: sha512-3E3yF3Ocr1tB/xOZiuC3doHQBQ2zu2MPTYZ0d4lpfWads2WTKG7ZzmGnsHmm63RflvDeLK/UVx7j2b3QuwKQ2g==} - /@algolia/client-search@4.20.0: - resolution: {integrity: sha512-zgwqnMvhWLdpzKTpd3sGmMlr4c+iS7eyyLGiaO51zDZWGMkpgoNVmltkzdBwxOVXz0RsFMznIxB9zuarUv4TZg==} - dependencies: - '@algolia/client-common': 4.20.0 - '@algolia/requester-common': 4.20.0 - '@algolia/transporter': 4.20.0 - dev: false + '@algolia/client-search@4.23.3': + resolution: {integrity: sha512-P4VAKFHqU0wx9O+q29Q8YVuaowaZ5EM77rxfmGnkHUJggh28useXQdopokgwMeYw2XUht49WX5RcTQ40rZIabw==} - /@algolia/logger-common@4.20.0: - resolution: {integrity: sha512-xouigCMB5WJYEwvoWW5XDv7Z9f0A8VoXJc3VKwlHJw/je+3p2RcDXfksLI4G4lIVncFUYMZx30tP/rsdlvvzHQ==} - dev: false + '@algolia/logger-common@4.23.3': + resolution: {integrity: sha512-y9kBtmJwiZ9ZZ+1Ek66P0M68mHQzKRxkW5kAAXYN/rdzgDN0d2COsViEFufxJ0pb45K4FRcfC7+33YB4BLrZ+g==} - /@algolia/logger-console@4.20.0: - resolution: {integrity: sha512-THlIGG1g/FS63z0StQqDhT6bprUczBI8wnLT3JWvfAQDZX5P6fCg7dG+pIrUBpDIHGszgkqYEqECaKKsdNKOUA==} - dependencies: - '@algolia/logger-common': 4.20.0 - dev: false + '@algolia/logger-console@4.23.3': + resolution: {integrity: sha512-8xoiseoWDKuCVnWP8jHthgaeobDLolh00KJAdMe9XPrWPuf1by732jSpgy2BlsLTaT9m32pHI8CRfrOqQzHv3A==} - /@algolia/requester-browser-xhr@4.20.0: - resolution: {integrity: sha512-HbzoSjcjuUmYOkcHECkVTwAelmvTlgs48N6Owt4FnTOQdwn0b8pdht9eMgishvk8+F8bal354nhx/xOoTfwiAw==} - dependencies: - '@algolia/requester-common': 4.20.0 - dev: false + '@algolia/recommend@4.23.3': + resolution: {integrity: sha512-9fK4nXZF0bFkdcLBRDexsnGzVmu4TSYZqxdpgBW2tEyfuSSY54D4qSRkLmNkrrz4YFvdh2GM1gA8vSsnZPR73w==} - /@algolia/requester-common@4.20.0: - resolution: {integrity: sha512-9h6ye6RY/BkfmeJp7Z8gyyeMrmmWsMOCRBXQDs4mZKKsyVlfIVICpcSibbeYcuUdurLhIlrOUkH3rQEgZzonng==} - dev: false + '@algolia/requester-browser-xhr@4.23.3': + resolution: {integrity: sha512-jDWGIQ96BhXbmONAQsasIpTYWslyjkiGu0Quydjlowe+ciqySpiDUrJHERIRfELE5+wFc7hc1Q5hqjGoV7yghw==} - /@algolia/requester-node-http@4.20.0: - resolution: {integrity: sha512-ocJ66L60ABSSTRFnCHIEZpNHv6qTxsBwJEPfYaSBsLQodm0F9ptvalFkHMpvj5DfE22oZrcrLbOYM2bdPJRHng==} - dependencies: - '@algolia/requester-common': 4.20.0 - dev: false + '@algolia/requester-common@4.23.3': + resolution: {integrity: sha512-xloIdr/bedtYEGcXCiF2muajyvRhwop4cMZo+K2qzNht0CMzlRkm8YsDdj5IaBhshqfgmBb3rTg4sL4/PpvLYw==} - /@algolia/transporter@4.20.0: - resolution: {integrity: sha512-Lsii1pGWOAISbzeyuf+r/GPhvHMPHSPrTDWNcIzOE1SG1inlJHICaVe2ikuoRjcpgxZNU54Jl+if15SUCsaTUg==} - dependencies: - '@algolia/cache-common': 4.20.0 - '@algolia/logger-common': 4.20.0 - '@algolia/requester-common': 4.20.0 - dev: false + '@algolia/requester-node-http@4.23.3': + resolution: {integrity: sha512-zgu++8Uj03IWDEJM3fuNl34s746JnZOWn1Uz5taV1dFyJhVM/kTNw9Ik7YJWiUNHJQXcaD8IXD1eCb0nq/aByA==} + + '@algolia/transporter@4.23.3': + resolution: {integrity: sha512-Wjl5gttqnf/gQKJA+dafnD0Y6Yw97yvfY8R9h0dQltX1GXTgNs1zWgvtWW0tHl1EgMdhAyw189uWiZMnL3QebQ==} - /@babel/code-frame@7.23.4: - resolution: {integrity: sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==} + '@babel/code-frame@7.24.2': + resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.23.4 - chalk: 2.4.2 - dev: true - /@babel/helper-string-parser@7.23.4: - resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + '@babel/helper-string-parser@7.24.1': + resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} engines: {node: '>=6.9.0'} - /@babel/helper-validator-identifier@7.22.20: + '@babel/helper-validator-identifier@7.22.20': resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} - /@babel/highlight@7.23.4: - resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + '@babel/highlight@7.24.2': + resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==} engines: {node: '>=6.9.0'} - requiresBuild: true - dependencies: - '@babel/helper-validator-identifier': 7.22.20 - chalk: 2.4.2 - js-tokens: 4.0.0 - dev: true - /@babel/parser@7.23.4: - resolution: {integrity: sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==} + '@babel/parser@7.24.4': + resolution: {integrity: sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==} engines: {node: '>=6.0.0'} hasBin: true - dependencies: - '@babel/types': 7.23.4 - /@babel/types@7.23.4: - resolution: {integrity: sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==} + '@babel/types@7.24.0': + resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.23.4 - '@babel/helper-validator-identifier': 7.22.20 - to-fast-properties: 2.0.0 - /@clack/core@0.3.3: - resolution: {integrity: sha512-5ZGyb75BUBjlll6eOa1m/IZBxwk91dooBWhPSL67sWcLS0zt9SnswRL0l26TVdBhb0wnWORRxUn//uH6n4z7+A==} - dependencies: - picocolors: 1.0.0 - sisteransi: 1.0.5 - dev: true + '@clack/core@0.3.4': + resolution: {integrity: sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==} - /@clack/prompts@0.7.0: + '@clack/prompts@0.7.0': resolution: {integrity: sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==} - dependencies: - '@clack/core': 0.3.3 - picocolors: 1.0.0 - sisteransi: 1.0.5 - dev: true bundledDependencies: - is-unicode-supported - /@docsearch/css@3.5.2: - resolution: {integrity: sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==} - dev: false + '@docsearch/css@3.6.0': + resolution: {integrity: sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ==} - /@docsearch/js@3.5.2: - resolution: {integrity: sha512-p1YFTCDflk8ieHgFJYfmyHBki1D61+U9idwrLh+GQQMrBSP3DLGKpy0XUJtPjAOPltcVbqsTjiPFfH7JImjUNg==} - dependencies: - '@docsearch/react': 3.5.2 - preact: 10.19.2 - transitivePeerDependencies: - - '@algolia/client-search' - - '@types/react' - - react - - react-dom - - search-insights - dev: false + '@docsearch/js@3.6.0': + resolution: {integrity: sha512-QujhqINEElrkIfKwyyyTfbsfMAYCkylInLYMRqHy7PHc8xTBQCow73tlo/Kc7oIwBrCLf0P3YhjlOeV4v8hevQ==} - /@docsearch/react@3.5.2: - resolution: {integrity: sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==} + '@docsearch/react@3.6.0': + resolution: {integrity: sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w==} peerDependencies: '@types/react': '>= 16.8.0 < 19.0.0' react: '>= 16.8.0 < 19.0.0' @@ -543,337 +449,234 @@ packages: optional: true search-insights: optional: true - dependencies: - '@algolia/autocomplete-core': 1.9.3(algoliasearch@4.20.0) - '@algolia/autocomplete-preset-algolia': 1.9.3(algoliasearch@4.20.0) - '@docsearch/css': 3.5.2 - algoliasearch: 4.20.0 - transitivePeerDependencies: - - '@algolia/client-search' - dev: false - /@esbuild/android-arm64@0.19.7: - resolution: {integrity: sha512-YEDcw5IT7hW3sFKZBkCAQaOCJQLONVcD4bOyTXMZz5fr66pTHnAet46XAtbXAkJRfIn2YVhdC6R9g4xa27jQ1w==} + '@esbuild/aix-ppc64@0.20.2': + resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.20.2': + resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} engines: {node: '>=12'} cpu: [arm64] os: [android] - requiresBuild: true - optional: true - /@esbuild/android-arm@0.19.7: - resolution: {integrity: sha512-YGSPnndkcLo4PmVl2tKatEn+0mlVMr3yEpOOT0BeMria87PhvoJb5dg5f5Ft9fbCVgtAz4pWMzZVgSEGpDAlww==} + '@esbuild/android-arm@0.20.2': + resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} engines: {node: '>=12'} cpu: [arm] os: [android] - requiresBuild: true - optional: true - /@esbuild/android-x64@0.19.7: - resolution: {integrity: sha512-jhINx8DEjz68cChFvM72YzrqfwJuFbfvSxZAk4bebpngGfNNRm+zRl4rtT9oAX6N9b6gBcFaJHFew5Blf6CvUw==} + '@esbuild/android-x64@0.20.2': + resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} engines: {node: '>=12'} cpu: [x64] os: [android] - requiresBuild: true - optional: true - /@esbuild/darwin-arm64@0.19.7: - resolution: {integrity: sha512-dr81gbmWN//3ZnBIm6YNCl4p3pjnabg1/ZVOgz2fJoUO1a3mq9WQ/1iuEluMs7mCL+Zwv7AY5e3g1hjXqQZ9Iw==} + '@esbuild/darwin-arm64@0.20.2': + resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] - requiresBuild: true - optional: true - /@esbuild/darwin-x64@0.19.7: - resolution: {integrity: sha512-Lc0q5HouGlzQEwLkgEKnWcSazqr9l9OdV2HhVasWJzLKeOt0PLhHaUHuzb8s/UIya38DJDoUm74GToZ6Wc7NGQ==} + '@esbuild/darwin-x64@0.20.2': + resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} engines: {node: '>=12'} cpu: [x64] os: [darwin] - requiresBuild: true - optional: true - /@esbuild/freebsd-arm64@0.19.7: - resolution: {integrity: sha512-+y2YsUr0CxDFF7GWiegWjGtTUF6gac2zFasfFkRJPkMAuMy9O7+2EH550VlqVdpEEchWMynkdhC9ZjtnMiHImQ==} + '@esbuild/freebsd-arm64@0.20.2': + resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] - requiresBuild: true - optional: true - /@esbuild/freebsd-x64@0.19.7: - resolution: {integrity: sha512-CdXOxIbIzPJmJhrpmJTLx+o35NoiKBIgOvmvT+jeSadYiWJn0vFKsl+0bSG/5lwjNHoIDEyMYc/GAPR9jxusTA==} + '@esbuild/freebsd-x64@0.20.2': + resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] - requiresBuild: true - optional: true - /@esbuild/linux-arm64@0.19.7: - resolution: {integrity: sha512-inHqdOVCkUhHNvuQPT1oCB7cWz9qQ/Cz46xmVe0b7UXcuIJU3166aqSunsqkgSGMtUCWOZw3+KMwI6otINuC9g==} + '@esbuild/linux-arm64@0.20.2': + resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} engines: {node: '>=12'} cpu: [arm64] os: [linux] - requiresBuild: true - optional: true - /@esbuild/linux-arm@0.19.7: - resolution: {integrity: sha512-Y+SCmWxsJOdQtjcBxoacn/pGW9HDZpwsoof0ttL+2vGcHokFlfqV666JpfLCSP2xLxFpF1lj7T3Ox3sr95YXww==} + '@esbuild/linux-arm@0.20.2': + resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} engines: {node: '>=12'} cpu: [arm] os: [linux] - requiresBuild: true - optional: true - /@esbuild/linux-ia32@0.19.7: - resolution: {integrity: sha512-2BbiL7nLS5ZO96bxTQkdO0euGZIUQEUXMTrqLxKUmk/Y5pmrWU84f+CMJpM8+EHaBPfFSPnomEaQiG/+Gmh61g==} + '@esbuild/linux-ia32@0.20.2': + resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} engines: {node: '>=12'} cpu: [ia32] os: [linux] - requiresBuild: true - optional: true - /@esbuild/linux-loong64@0.19.7: - resolution: {integrity: sha512-BVFQla72KXv3yyTFCQXF7MORvpTo4uTA8FVFgmwVrqbB/4DsBFWilUm1i2Oq6zN36DOZKSVUTb16jbjedhfSHw==} + '@esbuild/linux-loong64@0.20.2': + resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} engines: {node: '>=12'} cpu: [loong64] os: [linux] - requiresBuild: true - optional: true - /@esbuild/linux-mips64el@0.19.7: - resolution: {integrity: sha512-DzAYckIaK+pS31Q/rGpvUKu7M+5/t+jI+cdleDgUwbU7KdG2eC3SUbZHlo6Q4P1CfVKZ1lUERRFP8+q0ob9i2w==} + '@esbuild/linux-mips64el@0.20.2': + resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] - requiresBuild: true - optional: true - /@esbuild/linux-ppc64@0.19.7: - resolution: {integrity: sha512-JQ1p0SmUteNdUaaiRtyS59GkkfTW0Edo+e0O2sihnY4FoZLz5glpWUQEKMSzMhA430ctkylkS7+vn8ziuhUugQ==} + '@esbuild/linux-ppc64@0.20.2': + resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] - requiresBuild: true - optional: true - /@esbuild/linux-riscv64@0.19.7: - resolution: {integrity: sha512-xGwVJ7eGhkprY/nB7L7MXysHduqjpzUl40+XoYDGC4UPLbnG+gsyS1wQPJ9lFPcxYAaDXbdRXd1ACs9AE9lxuw==} + '@esbuild/linux-riscv64@0.20.2': + resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] - requiresBuild: true - optional: true - /@esbuild/linux-s390x@0.19.7: - resolution: {integrity: sha512-U8Rhki5PVU0L0nvk+E8FjkV8r4Lh4hVEb9duR6Zl21eIEYEwXz8RScj4LZWA2i3V70V4UHVgiqMpszXvG0Yqhg==} + '@esbuild/linux-s390x@0.20.2': + resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} engines: {node: '>=12'} cpu: [s390x] os: [linux] - requiresBuild: true - optional: true - /@esbuild/linux-x64@0.19.7: - resolution: {integrity: sha512-ZYZopyLhm4mcoZXjFt25itRlocKlcazDVkB4AhioiL9hOWhDldU9n38g62fhOI4Pth6vp+Mrd5rFKxD0/S+7aQ==} + '@esbuild/linux-x64@0.20.2': + resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} engines: {node: '>=12'} cpu: [x64] os: [linux] - requiresBuild: true - optional: true - /@esbuild/netbsd-x64@0.19.7: - resolution: {integrity: sha512-/yfjlsYmT1O3cum3J6cmGG16Fd5tqKMcg5D+sBYLaOQExheAJhqr8xOAEIuLo8JYkevmjM5zFD9rVs3VBcsjtQ==} + '@esbuild/netbsd-x64@0.20.2': + resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] - requiresBuild: true - optional: true - /@esbuild/openbsd-x64@0.19.7: - resolution: {integrity: sha512-MYDFyV0EW1cTP46IgUJ38OnEY5TaXxjoDmwiTXPjezahQgZd+j3T55Ht8/Q9YXBM0+T9HJygrSRGV5QNF/YVDQ==} + '@esbuild/openbsd-x64@0.20.2': + resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] - requiresBuild: true - optional: true - /@esbuild/sunos-x64@0.19.7: - resolution: {integrity: sha512-JcPvgzf2NN/y6X3UUSqP6jSS06V0DZAV/8q0PjsZyGSXsIGcG110XsdmuWiHM+pno7/mJF6fjH5/vhUz/vA9fw==} + '@esbuild/sunos-x64@0.20.2': + resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} engines: {node: '>=12'} cpu: [x64] os: [sunos] - requiresBuild: true - optional: true - /@esbuild/win32-arm64@0.19.7: - resolution: {integrity: sha512-ZA0KSYti5w5toax5FpmfcAgu3ZNJxYSRm0AW/Dao5up0YV1hDVof1NvwLomjEN+3/GMtaWDI+CIyJOMTRSTdMw==} + '@esbuild/win32-arm64@0.20.2': + resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} engines: {node: '>=12'} cpu: [arm64] os: [win32] - requiresBuild: true - optional: true - /@esbuild/win32-ia32@0.19.7: - resolution: {integrity: sha512-CTOnijBKc5Jpk6/W9hQMMvJnsSYRYgveN6O75DTACCY18RA2nqka8dTZR+x/JqXCRiKk84+5+bRKXUSbbwsS0A==} + '@esbuild/win32-ia32@0.20.2': + resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} engines: {node: '>=12'} cpu: [ia32] os: [win32] - requiresBuild: true - optional: true - /@esbuild/win32-x64@0.19.7: - resolution: {integrity: sha512-gRaP2sk6hc98N734luX4VpF318l3w+ofrtTu9j5L8EQXF+FzQKV6alCOHMVoJJHvVK/mGbwBXfOL1HETQu9IGQ==} + '@esbuild/win32-x64@0.20.2': + resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} engines: {node: '>=12'} cpu: [x64] os: [win32] - requiresBuild: true - optional: true - /@hapi/hoek@9.3.0: + '@hapi/hoek@9.3.0': resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} - dev: true - /@hapi/topo@5.1.0: + '@hapi/topo@5.1.0': resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} - dependencies: - '@hapi/hoek': 9.3.0 - dev: true - /@hutson/parse-repository-url@5.0.0: + '@hutson/parse-repository-url@5.0.0': resolution: {integrity: sha512-e5+YUKENATs1JgYHMzTr2MW/NDcXGfYFAuOQU8gJgF/kEh4EqKgfGrfLI67bMD4tbhZVlkigz/9YYwWcbOFthg==} engines: {node: '>=10.13.0'} - dev: true - /@isaacs/cliui@8.0.2: + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} - dependencies: - string-width: 5.1.2 - string-width-cjs: /string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: /strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: /wrap-ansi@7.0.0 - dev: true - /@jest/schemas@29.6.3: + '@jest/schemas@29.6.3': resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@sinclair/typebox': 0.27.8 - dev: true - /@jridgewell/sourcemap-codec@1.4.15: + '@jridgewell/sourcemap-codec@1.4.15': resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - /@mdit-vue/plugin-component@1.0.0: - resolution: {integrity: sha512-ZXsJwxkG5yyTHARIYbR74cT4AZ0SfMokFFjiHYCbypHIeYWgJhso4+CZ8+3V9EWFG3EHlGoKNGqKp9chHnqntQ==} - dependencies: - '@types/markdown-it': 13.0.7 - markdown-it: 13.0.2 - dev: true + '@kwsites/file-exists@1.1.1': + resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} - /@mdit-vue/plugin-frontmatter@1.0.0: - resolution: {integrity: sha512-MMA7Ny+YPZA7eDOY1t4E+rKuEWO39mzDdP/M68fKdXJU6VfcGkPr7gnpnJfW2QBJ5qIvMrK/3lDAA2JBy5TfpA==} - dependencies: - '@mdit-vue/types': 1.0.0 - '@types/markdown-it': 13.0.7 - gray-matter: 4.0.3 - markdown-it: 13.0.2 - dev: true + '@kwsites/promise-deferred@1.1.1': + resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} - /@mdit-vue/plugin-headers@1.0.0: - resolution: {integrity: sha512-0rK/iKy6x13d/Pp5XxdLBshTD0+YjZvtHIaIV+JO+/H2WnOv7oaRgs48G5d44z3XJVUE2u6fNnTlI169fef0/A==} - dependencies: - '@mdit-vue/shared': 1.0.0 - '@mdit-vue/types': 1.0.0 - '@types/markdown-it': 13.0.7 - markdown-it: 13.0.2 - dev: true + '@lunariajs/core@0.0.32': + resolution: {integrity: sha512-l4JbgtatUlh64FJIyjPPPiLTEu26TTOKVa8GUBF32aGmzXb1ScdKwYQuN1c7Hf1sjW5VAc9Z+wthhx4/GU0jGA==} + engines: {node: '>=18.17.0'} + hasBin: true - /@mdit-vue/plugin-sfc@1.0.0: - resolution: {integrity: sha512-agMUe0fY4YHxsZivSvplBwRwrFvsIf/JNUJCAYq1+2Sg9+2hviTBZwjZDxYqHDHOVLtiNr+wuo68tE24mAx3AQ==} - dependencies: - '@mdit-vue/types': 1.0.0 - '@types/markdown-it': 13.0.7 - markdown-it: 13.0.2 - dev: true + '@mdit-vue/plugin-component@2.1.2': + resolution: {integrity: sha512-n1HcAC82l912HhtiMSxl5pQLKBYbPok/IcdGRD49rTt53NXBqct68qo58+7jvsj+f8Lmo7kjD+em3tP4BSgl0A==} - /@mdit-vue/plugin-title@1.0.0: - resolution: {integrity: sha512-8yC60fCZ95xcJ/cvJH4Lv43Rs4k+33UGyKrRWj5J8TNyMwUyGcwur0XyPM+ffJH4/Bzq4myZLsj/TTFSkXRxvw==} - dependencies: - '@mdit-vue/shared': 1.0.0 - '@mdit-vue/types': 1.0.0 - '@types/markdown-it': 13.0.7 - markdown-it: 13.0.2 - dev: true + '@mdit-vue/plugin-frontmatter@2.1.2': + resolution: {integrity: sha512-2YOVOsMRtf11bZ6mEB4xoWD6RG5X0Ex+g/1c1iXoYUMUahlZnz9flXUM6WAE++HsLR3Wkvd5FNhGUArrcxn0dA==} - /@mdit-vue/plugin-toc@1.0.0: - resolution: {integrity: sha512-WN8blfX0X/5Nolic0ClDWP7eVo9IB+U4g0jbycX3lolIZX5Bai1UpsD3QYZr5VVsPbQJMKMGvTrCEtCNTGvyWQ==} - dependencies: - '@mdit-vue/shared': 1.0.0 - '@mdit-vue/types': 1.0.0 - '@types/markdown-it': 13.0.7 - markdown-it: 13.0.2 - dev: true + '@mdit-vue/plugin-headers@2.1.2': + resolution: {integrity: sha512-YkBTlHeG4seTcXqrVPvPY6utvkHd2qs7QGU5aM3S5CxUH5l0/SzIRv+irhFMfIRsXQ7zwx2vJVSwJz+n2TFhSA==} - /@mdit-vue/shared@1.0.0: - resolution: {integrity: sha512-nbYBfmEi+pR2Lm0Z6TMVX2/iBjfr/kGEsHW8CC0rQw+3+sG5dY6VG094HuFAkiAmmvZx9DZZb+7ZMWp9vkwCRw==} - dependencies: - '@mdit-vue/types': 1.0.0 - '@types/markdown-it': 13.0.7 - markdown-it: 13.0.2 - dev: true + '@mdit-vue/plugin-sfc@2.1.2': + resolution: {integrity: sha512-wjbFvkUcCcfxc1x33SwqbWSM3WYPJOdlmX9IJQd9y6C7ALujy6Orx1gWn5j0hfke1kIuohvjeJ/K0LqF4oYO4g==} - /@mdit-vue/types@1.0.0: - resolution: {integrity: sha512-xeF5+sHLzRNF7plbksywKCph4qli20l72of2fMlZQQ7RECvXYrRkE9+bjRFQCyULC7B8ydUYbpbkux5xJlVWyw==} - dev: true + '@mdit-vue/plugin-title@2.1.2': + resolution: {integrity: sha512-BXgrpuRp6aI/CV/V3jH3zailG9rZH8f094RSky7PE2wTx3c2hnavz3SB3y3TVDv5UC7BGk/uPfBjdYh8/ejsSg==} - /@nodelib/fs.scandir@2.1.5: + '@mdit-vue/plugin-toc@2.1.2': + resolution: {integrity: sha512-G3t9NjhTvl5cYZ9VSsMzVkYjdUrC9nOZE+oxIzpUTtHRH8NtRvoynUDzEDzRnoRDe29cdWDKTAYaeiHUF+TAvQ==} + + '@mdit-vue/shared@2.1.2': + resolution: {integrity: sha512-5+YHKRyULDqMZsYq+8Ttev0P/osgAoNm2OPYrJtvxLfc1jyrZNiDUCjO2jec7Nk3qyGVZe6FKtXTNLVE+ZRhZw==} + + '@mdit-vue/types@2.1.0': + resolution: {integrity: sha512-TMBB/BQWVvwtpBdWD75rkZx4ZphQ6MN0O4QB2Bc0oI5PC2uE57QerhNxdRZ7cvBHE2iY2C+BUNUziCfJbjIRRA==} + + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - dev: true - /@nodelib/fs.stat@2.0.5: + '@nodelib/fs.stat@2.0.5': resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} - dev: true - /@nodelib/fs.walk@1.2.8: + '@nodelib/fs.walk@1.2.8': resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 - dev: true - /@pkgjs/parseargs@0.11.0: + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - requiresBuild: true - dev: true - optional: true - /@polka/url@1.0.0-next.23: - resolution: {integrity: sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==} - dev: true + '@polka/compression@1.0.0-next.25': + resolution: {integrity: sha512-UlVkoSGRig87riHSn8QOxd2DzGhadRpNSj5Ukqj+Bt7WTE4Es+sE3ju3OYbe8SiV2OwA+8tDcSuHWUh5S3jCBQ==} + engines: {node: '>=6'} + + '@polka/url@1.0.0-next.25': + resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} - /@rollup/plugin-alias@5.0.1(rollup@4.5.2): - resolution: {integrity: sha512-JObvbWdOHoMy9W7SU0lvGhDtWq9PllP5mjpAy+TUslZG/WzOId9u80Hsqq1vCUn9pFJ0cxpdcnAv+QzU2zFH3Q==} + '@rollup/plugin-alias@5.1.0': + resolution: {integrity: sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true - dependencies: - rollup: 4.5.2 - slash: 4.0.0 - dev: true - /@rollup/plugin-commonjs@25.0.7(rollup@4.5.2): + '@rollup/plugin-commonjs@25.0.7': resolution: {integrity: sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==} engines: {node: '>=14.0.0'} peerDependencies: @@ -881,30 +684,17 @@ packages: peerDependenciesMeta: rollup: optional: true - dependencies: - '@rollup/pluginutils': 5.0.5(rollup@4.5.2) - commondir: 1.0.1 - estree-walker: 2.0.2 - glob: 8.1.0 - is-reference: 1.2.1 - magic-string: 0.30.5 - rollup: 4.5.2 - dev: true - /@rollup/plugin-json@6.0.1(rollup@4.5.2): - resolution: {integrity: sha512-RgVfl5hWMkxN1h/uZj8FVESvPuBJ/uf6ly6GTj0GONnkfoBN5KC0MSz+PN2OLDgYXMhtG0mWpTrkiOjoxAIevw==} + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true - dependencies: - '@rollup/pluginutils': 5.0.5(rollup@4.5.2) - rollup: 4.5.2 - dev: true - /@rollup/plugin-node-resolve@15.2.3(rollup@4.5.2): + '@rollup/plugin-node-resolve@15.2.3': resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} engines: {node: '>=14.0.0'} peerDependencies: @@ -912,17 +702,8 @@ packages: peerDependenciesMeta: rollup: optional: true - dependencies: - '@rollup/pluginutils': 5.0.5(rollup@4.5.2) - '@types/resolve': 1.20.2 - deepmerge: 4.3.1 - is-builtin-module: 3.2.1 - is-module: 1.0.0 - resolve: 1.22.8 - rollup: 4.5.2 - dev: true - /@rollup/plugin-replace@5.0.5(rollup@4.5.2): + '@rollup/plugin-replace@5.0.5': resolution: {integrity: sha512-rYO4fOi8lMaTg/z5Jb+hKnrHHVn8j2lwkqwyS4kTRhKyWOLf2wST2sWXr4WzWiTcoHTp2sTjqUbqIj2E39slKQ==} engines: {node: '>=14.0.0'} peerDependencies: @@ -930,553 +711,288 @@ packages: peerDependenciesMeta: rollup: optional: true - dependencies: - '@rollup/pluginutils': 5.0.5(rollup@4.5.2) - magic-string: 0.30.5 - rollup: 4.5.2 - dev: true - /@rollup/pluginutils@5.0.5(rollup@4.5.2): - resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==} + '@rollup/pluginutils@5.1.0': + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true - dependencies: - '@types/estree': 1.0.5 - estree-walker: 2.0.2 - picomatch: 2.3.1 - rollup: 4.5.2 - dev: true - /@rollup/rollup-android-arm-eabi@4.5.2: - resolution: {integrity: sha512-ee7BudTwwrglFYSc3UnqInDDjCLWHKrFmGNi4aK7jlEyg4CyPa1DCMrZfsN1O13YT76UFEqXz2CoN7BCGpUlJw==} + '@rollup/rollup-android-arm-eabi@4.14.3': + resolution: {integrity: sha512-X9alQ3XM6I9IlSlmC8ddAvMSyG1WuHk5oUnXGw+yUBs3BFoTizmG1La/Gr8fVJvDWAq+zlYTZ9DBgrlKRVY06g==} cpu: [arm] os: [android] - requiresBuild: true - optional: true - /@rollup/rollup-android-arm64@4.5.2: - resolution: {integrity: sha512-xOuhj9HHtn8128ir8veoQsBbAUBasDbHIBniYTEx02pAmu9EXL+ZjJqngnNEy6ZgZ4h1JwL33GMNu3yJL5Mzow==} + '@rollup/rollup-android-arm64@4.14.3': + resolution: {integrity: sha512-eQK5JIi+POhFpzk+LnjKIy4Ks+pwJ+NXmPxOCSvOKSNRPONzKuUvWE+P9JxGZVxrtzm6BAYMaL50FFuPe0oWMQ==} cpu: [arm64] os: [android] - requiresBuild: true - optional: true - /@rollup/rollup-darwin-arm64@4.5.2: - resolution: {integrity: sha512-NTGJWoL8bKyqyWFn9/RzSv4hQ4wTbaAv0lHHRwf4OnpiiP4P8W0jiXbm8Nc5BCXKmWAwuvJY82mcIU2TayC20g==} + '@rollup/rollup-darwin-arm64@4.14.3': + resolution: {integrity: sha512-Od4vE6f6CTT53yM1jgcLqNfItTsLt5zE46fdPaEmeFHvPs5SjZYlLpHrSiHEKR1+HdRfxuzXHjDOIxQyC3ptBA==} cpu: [arm64] os: [darwin] - requiresBuild: true - optional: true - /@rollup/rollup-darwin-x64@4.5.2: - resolution: {integrity: sha512-hlKqj7bpPvU15sZo4za14u185lpMzdwWLMc9raMqPK4wywt0wR23y1CaVQ4oAFXat3b5/gmRntyfpwWTKl+vvA==} + '@rollup/rollup-darwin-x64@4.14.3': + resolution: {integrity: sha512-0IMAO21axJeNIrvS9lSe/PGthc8ZUS+zC53O0VhF5gMxfmcKAP4ESkKOCwEi6u2asUrt4mQv2rjY8QseIEb1aw==} cpu: [x64] os: [darwin] - requiresBuild: true - optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.5.2: - resolution: {integrity: sha512-7ZIZx8c3u+pfI0ohQsft/GywrXez0uR6dUP0JhBuCK3sFO5TfdLn/YApnVkvPxuTv3+YKPIZend9Mt7Cz6sS3Q==} + '@rollup/rollup-linux-arm-gnueabihf@4.14.3': + resolution: {integrity: sha512-ge2DC7tHRHa3caVEoSbPRJpq7azhG+xYsd6u2MEnJ6XzPSzQsTKyXvh6iWjXRf7Rt9ykIUWHtl0Uz3T6yXPpKw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.14.3': + resolution: {integrity: sha512-ljcuiDI4V3ySuc7eSk4lQ9wU8J8r8KrOUvB2U+TtK0TiW6OFDmJ+DdIjjwZHIw9CNxzbmXY39wwpzYuFDwNXuw==} cpu: [arm] os: [linux] - requiresBuild: true - optional: true - /@rollup/rollup-linux-arm64-gnu@4.5.2: - resolution: {integrity: sha512-7Pk/5mO11JW/cH+a8lL/i0ZxmRGrbpYqN0VwO2DHhU+SJWWOH2zE1RAcPaj8KqiwC8DCDIJOSxjV9+9lLb6aeA==} + '@rollup/rollup-linux-arm64-gnu@4.14.3': + resolution: {integrity: sha512-Eci2us9VTHm1eSyn5/eEpaC7eP/mp5n46gTRB3Aar3BgSvDQGJZuicyq6TsH4HngNBgVqC5sDYxOzTExSU+NjA==} cpu: [arm64] os: [linux] - requiresBuild: true - optional: true - /@rollup/rollup-linux-arm64-musl@4.5.2: - resolution: {integrity: sha512-KrRnuG5phJx756e62wxvWH2e+TK84MP2IVuPwfge+GBvWqIUfVzFRn09TKruuQBXzZp52Vyma7FjMDkwlA9xpg==} + '@rollup/rollup-linux-arm64-musl@4.14.3': + resolution: {integrity: sha512-UrBoMLCq4E92/LCqlh+blpqMz5h1tJttPIniwUgOFJyjWI1qrtrDhhpHPuFxULlUmjFHfloWdixtDhSxJt5iKw==} cpu: [arm64] os: [linux] - requiresBuild: true - optional: true - /@rollup/rollup-linux-x64-gnu@4.5.2: - resolution: {integrity: sha512-My+53GasPa2D2tU5dXiyHYwrELAUouSfkNlZ3bUKpI7btaztO5vpALEs3mvFjM7aKTvEbc7GQckuXeXIDKQ0fg==} + '@rollup/rollup-linux-powerpc64le-gnu@4.14.3': + resolution: {integrity: sha512-5aRjvsS8q1nWN8AoRfrq5+9IflC3P1leMoy4r2WjXyFqf3qcqsxRCfxtZIV58tCxd+Yv7WELPcO9mY9aeQyAmw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.14.3': + resolution: {integrity: sha512-sk/Qh1j2/RJSX7FhEpJn8n0ndxy/uf0kI/9Zc4b1ELhqULVdTfN6HL31CDaTChiBAOgLcsJ1sgVZjWv8XNEsAQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.14.3': + resolution: {integrity: sha512-jOO/PEaDitOmY9TgkxF/TQIjXySQe5KVYB57H/8LRP/ux0ZoO8cSHCX17asMSv3ruwslXW/TLBcxyaUzGRHcqg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.14.3': + resolution: {integrity: sha512-8ybV4Xjy59xLMyWo3GCfEGqtKV5M5gCSrZlxkPGvEPCGDLNla7v48S662HSGwRd6/2cSneMQWiv+QzcttLrrOA==} cpu: [x64] os: [linux] - requiresBuild: true - optional: true - /@rollup/rollup-linux-x64-musl@4.5.2: - resolution: {integrity: sha512-/f0Q6Sc+Vw54Ws6N8fxaEe4R7at3b8pFyv+O/F2VaQ4hODUJcRUcCBJh6zuqtgQQt7w845VTkGLFgWZkP3tUoQ==} + '@rollup/rollup-linux-x64-musl@4.14.3': + resolution: {integrity: sha512-s+xf1I46trOY10OqAtZ5Rm6lzHre/UiLA1J2uOhCFXWkbZrJRkYBPO6FhvGfHmdtQ3Bx793MNa7LvoWFAm93bg==} cpu: [x64] os: [linux] - requiresBuild: true - optional: true - /@rollup/rollup-win32-arm64-msvc@4.5.2: - resolution: {integrity: sha512-NCKuuZWLht6zj7s6EIFef4BxCRX1GMr83S2W4HPCA0RnJ4iHE4FS1695q6Ewoa6A9nFjJe1//yUu0kgBU07Edw==} + '@rollup/rollup-win32-arm64-msvc@4.14.3': + resolution: {integrity: sha512-+4h2WrGOYsOumDQ5S2sYNyhVfrue+9tc9XcLWLh+Kw3UOxAvrfOrSMFon60KspcDdytkNDh7K2Vs6eMaYImAZg==} cpu: [arm64] os: [win32] - requiresBuild: true - optional: true - /@rollup/rollup-win32-ia32-msvc@4.5.2: - resolution: {integrity: sha512-J5zL3riR4AOyU/J3M/i4k/zZ8eP1yT+nTmAKztCXJtnI36jYH0eepvob22mAQ/kLwfsK2TB6dbyVY1F8c/0H5A==} + '@rollup/rollup-win32-ia32-msvc@4.14.3': + resolution: {integrity: sha512-T1l7y/bCeL/kUwh9OD4PQT4aM7Bq43vX05htPJJ46RTI4r5KNt6qJRzAfNfM+OYMNEVBWQzR2Gyk+FXLZfogGw==} cpu: [ia32] os: [win32] - requiresBuild: true - optional: true - /@rollup/rollup-win32-x64-msvc@4.5.2: - resolution: {integrity: sha512-pL0RXRHuuGLhvs7ayX/SAHph1hrDPXOM5anyYUQXWJEENxw3nfHkzv8FfVlEVcLyKPAEgDRkd6RKZq2SMqS/yg==} + '@rollup/rollup-win32-x64-msvc@4.14.3': + resolution: {integrity: sha512-/BypzV0H1y1HzgYpxqRaXGBRqfodgoBBCcsrujT6QRcakDQdfU+Lq9PENPh5jB4I44YWq+0C2eHsHya+nZY1sA==} cpu: [x64] os: [win32] - requiresBuild: true - optional: true - /@sideway/address@4.1.4: - resolution: {integrity: sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==} - dependencies: - '@hapi/hoek': 9.3.0 - dev: true + '@shikijs/core@1.3.0': + resolution: {integrity: sha512-7fedsBfuILDTBmrYZNFI8B6ATTxhQAasUHllHmjvSZPnoq4bULWoTpHwmuQvZ8Aq03/tAa2IGo6RXqWtHdWaCA==} - /@sideway/formula@3.0.1: + '@shikijs/transformers@1.3.0': + resolution: {integrity: sha512-3mlpg2I9CjhjE96dEWQOGeCWoPcyTov3s4aAsHmgvnTHa8MBknEnCQy8/xivJPSpD+olqOqIEoHnLfbNJK29AA==} + + '@sideway/address@4.1.5': + resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + + '@sideway/formula@3.0.1': resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} - dev: true - /@sideway/pinpoint@2.0.0: + '@sideway/pinpoint@2.0.0': resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} - dev: true - /@sinclair/typebox@0.27.8: + '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - dev: true - /@types/body-parser@1.19.5: - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} - dependencies: - '@types/connect': 3.4.38 - '@types/node': 20.10.0 - dev: true + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - /@types/braces@3.0.4: + '@types/braces@3.0.4': resolution: {integrity: sha512-0WR3b8eaISjEW7RpZnclONaLFDf7buaowRHdqLp4vLj54AsSAYWfh3DRbfiYJY9XDxMgx1B4sE1Afw2PGpuHOA==} - dev: true - - /@types/compression@1.7.5: - resolution: {integrity: sha512-AAQvK5pxMpaT+nDvhHrsBhLSYG5yQdtkaJE1WYieSNY2mVFKAgmU4ks65rkZD5oqnGCFLyQpUr1CqI4DmUMyDg==} - dependencies: - '@types/express': 4.17.21 - dev: true - - /@types/connect@3.4.38: - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - dependencies: - '@types/node': 20.10.0 - dev: true - /@types/cross-spawn@6.0.6: + '@types/cross-spawn@6.0.6': resolution: {integrity: sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==} - dependencies: - '@types/node': 20.10.0 - dev: true - /@types/debug@4.1.12: + '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} - dependencies: - '@types/ms': 0.7.34 - dev: true - /@types/escape-html@1.0.4: + '@types/escape-html@1.0.4': resolution: {integrity: sha512-qZ72SFTgUAZ5a7Tj6kf2SHLetiH5S6f8G5frB2SPQ3EyF02kxdyBFf4Tz4banE3xCgGnKgWLt//a6VuYHKYJTg==} - dev: true - /@types/estree@1.0.5: + '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - dev: true - - /@types/express-serve-static-core@4.17.41: - resolution: {integrity: sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==} - dependencies: - '@types/node': 20.10.0 - '@types/qs': 6.9.10 - '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 - dev: true - /@types/express@4.17.21: - resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} - dependencies: - '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.17.41 - '@types/qs': 6.9.10 - '@types/serve-static': 1.15.5 - dev: true - - /@types/fs-extra@11.0.4: + '@types/fs-extra@11.0.4': resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} - dependencies: - '@types/jsonfile': 6.1.4 - '@types/node': 20.10.0 - dev: true - /@types/hast@3.0.3: - resolution: {integrity: sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==} - dependencies: - '@types/unist': 3.0.2 - dev: false - - /@types/http-errors@2.0.4: - resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} - dev: true - - /@types/jquery@3.5.29: + '@types/jquery@3.5.29': resolution: {integrity: sha512-oXQQC9X9MOPRrMhPHHOsXqeQDnWeCDT3PelUIg/Oy8FAbzSZtFHRjc7IpbfFVmpLtJ+UOoywpRsuO5Jxjybyeg==} - dependencies: - '@types/sizzle': 2.3.8 - dev: true - /@types/jsonfile@6.1.4: + '@types/jsonfile@6.1.4': resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - dependencies: - '@types/node': 20.10.0 - dev: true - /@types/linkify-it@3.0.5: + '@types/linkify-it@3.0.5': resolution: {integrity: sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==} - /@types/lodash.template@4.5.3: + '@types/lodash.template@4.5.3': resolution: {integrity: sha512-Mo0UYKLu1oXgkV9TVoXZLlXXjyIXlW7ZQRxi/4gQJmzJr63dmicE8gG0OkPjYTKBrBic852q0JzqrtNUWLBIyA==} - dependencies: - '@types/lodash': 4.14.202 - dev: true - /@types/lodash@4.14.202: - resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} - dev: true + '@types/lodash@4.17.0': + resolution: {integrity: sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==} - /@types/mark.js@8.11.12: + '@types/mark.js@8.11.12': resolution: {integrity: sha512-244ZnaIBpz4c6xutliAnYVZp6xJlmC569jZqnR3ElO1Y01ooYASSVQEqpd2x0A2UfrgVMs5V9/9tUAdZaDMytQ==} - dependencies: - '@types/jquery': 3.5.29 - dev: true - /@types/markdown-it-attrs@4.1.3: + '@types/markdown-it-attrs@4.1.3': resolution: {integrity: sha512-1JsseFdHD6rQHsPcy4W3xx/whxvZ09Z+CqPpnOtrGtpmkFW07N11q7oM383//LtoKv54yn+HGnk6r4ZHUTHJVg==} - dependencies: - '@types/markdown-it': 13.0.7 - dev: true - - /@types/markdown-it-container@2.0.9: - resolution: {integrity: sha512-pW2W5ibThEXN/wKXTCsORMRJ0zKdFae/v+/n2YV8p6L/1gWQKIaW9KovmckuNV+v9u6yInMV1cXtfmDj+Q52NA==} - dependencies: - '@types/markdown-it': 13.0.7 - dev: true - /@types/markdown-it-emoji@2.0.4: - resolution: {integrity: sha512-H6ulk/ZmbDxOayPwI/leJzrmoW1YKX1Z+MVSCHXuYhvqckV4I/c+hPTf6UiqJyn2avWugfj30XroheEb6/Ekqg==} - dependencies: - '@types/markdown-it': 13.0.7 - dev: true + '@types/markdown-it-container@2.0.10': + resolution: {integrity: sha512-zv+YxrlSYRq51e9kzm3orv4OvF4U79Ll1OyplNXr00o4ZC/8PukJk/jEWH7CnsMtrSWZlyv0czhz42jm9J4uLw==} - /@types/markdown-it@13.0.7: - resolution: {integrity: sha512-U/CBi2YUUcTHBt5tjO2r5QV/x0Po6nsYwQU4Y04fBS6vfoImaiZ6f8bi3CjTCxBPQSO1LMyUqkByzi8AidyxfA==} - dependencies: - '@types/linkify-it': 3.0.5 - '@types/mdurl': 1.0.5 + '@types/markdown-it-emoji@2.0.5': + resolution: {integrity: sha512-iJLsmCNpSWKtV6Ia3mLSjcXJPEt7ubGG342z+hGvYx++TpM19oTUrJcI7XjbOqRQ+W2UQ323E7B0eCLwlgT/9g==} - /@types/mdast@4.0.3: - resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} - dependencies: - '@types/unist': 3.0.2 - dev: false + '@types/markdown-it@14.0.1': + resolution: {integrity: sha512-6WfOG3jXR78DW8L5cTYCVVGAsIFZskRHCDo5tbqa+qtKVt4oDRVH7hyIWu1SpDQJlmIoEivNQZ5h+AGAOrgOtQ==} - /@types/mdurl@1.0.5: + '@types/mdurl@1.0.5': resolution: {integrity: sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==} - /@types/micromatch@4.0.6: - resolution: {integrity: sha512-2eulCHWqjEpk9/vyic4tBhI8a9qQEl6DaK2n/sF7TweX9YESlypgKyhXMDGt4DAOy/jhLPvVrZc8pTDAMsplJA==} - dependencies: - '@types/braces': 3.0.4 - dev: true - - /@types/mime@1.3.5: - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - dev: true + '@types/micromatch@4.0.7': + resolution: {integrity: sha512-C/FMQ8HJAZhTsDpl4wDKZdMeeW5USjgzOczUwTGbRc1ZopPgOhIEnxY2ZgUrsuyy4DwK1JVOJZKFakv3TbCKiA==} - /@types/mime@3.0.4: - resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} - dev: true - - /@types/minimist@1.2.5: + '@types/minimist@1.2.5': resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - dev: true - /@types/ms@0.7.34: + '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} - dev: true - /@types/node@17.0.45: + '@types/node@17.0.45': resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} - dev: true - /@types/node@20.10.0: - resolution: {integrity: sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==} - dependencies: - undici-types: 5.26.5 + '@types/node@20.12.7': + resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} - /@types/normalize-package-data@2.4.4: + '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} - dev: true - /@types/postcss-prefix-selector@1.16.3: + '@types/postcss-prefix-selector@1.16.3': resolution: {integrity: sha512-YZLPWRkJIrYjwaqojVDXzaRCAEYslRAm8Shznwwn+ZFA4iKQR4LZlS3d+ZMVteFz4iyQnngZZG7k/GIzV1f3mQ==} - dependencies: - postcss: 8.4.31 - dev: true - /@types/prompts@2.4.9: + '@types/prompts@2.4.9': resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} - dependencies: - '@types/node': 20.10.0 - kleur: 3.0.3 - dev: true - - /@types/qs@6.9.10: - resolution: {integrity: sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==} - dev: true - - /@types/range-parser@1.2.7: - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - dev: true - /@types/resolve@1.20.2: + '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - dev: true - /@types/sax@1.2.7: + '@types/sax@1.2.7': resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} - dependencies: - '@types/node': 20.10.0 - dev: true - - /@types/send@0.17.4: - resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} - dependencies: - '@types/mime': 1.3.5 - '@types/node': 20.10.0 - dev: true - - /@types/serve-static@1.15.5: - resolution: {integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==} - dependencies: - '@types/http-errors': 2.0.4 - '@types/mime': 3.0.4 - '@types/node': 20.10.0 - dev: true - /@types/sizzle@2.3.8: + '@types/sizzle@2.3.8': resolution: {integrity: sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==} - dev: true - - /@types/unist@3.0.2: - resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} - dev: false - /@types/web-bluetooth@0.0.20: + '@types/web-bluetooth@0.0.20': resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} - dev: false - /@ungap/structured-clone@1.2.0: - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - dev: false - - /@vitejs/plugin-vue@4.5.0(vite@5.0.5)(vue@3.3.8): - resolution: {integrity: sha512-a2WSpP8X8HTEww/U00bU4mX1QpLINNuz/2KMNpLsdu3BzOpak3AGI1CJYBTXcc4SPhaD0eNRUp7IyQK405L5dQ==} - engines: {node: ^14.18.0 || >=16.0.0} + '@vitejs/plugin-vue@5.0.4': + resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==} + engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: - vite: ^4.0.0 || ^5.0.0 + vite: ^5.0.0 vue: ^3.2.25 - dependencies: - vite: 5.0.5(@types/node@20.10.0) - vue: 3.3.8(typescript@5.3.2) - dev: false - /@vitest/expect@1.0.0-beta.5: - resolution: {integrity: sha512-q/TPdbXuEZZNFKILEVicojSWEq1y8qPLcAiZRQD8DsYUAV2cIjsD5lJWYaAjjUAV4lzovSci3KeISQdjUdfxQQ==} - dependencies: - '@vitest/spy': 1.0.0-beta.5 - '@vitest/utils': 1.0.0-beta.5 - chai: 4.3.10 - dev: true + '@vitest/expect@1.5.0': + resolution: {integrity: sha512-0pzuCI6KYi2SIC3LQezmxujU9RK/vwC1U9R0rLuGlNGcOuDWxqWKu6nUdFsX9tH1WU0SXtAxToOsEjeUn1s3hA==} - /@vitest/runner@1.0.0-beta.5: - resolution: {integrity: sha512-o/6ZqQoKCIdI4dmdc4Yb1u3n56dU69SABXyO5yhFZTDjEMJs1DdCQ68JK+UcrpJMQndr6q5lTFrfHEhj4XJy6w==} - dependencies: - '@vitest/utils': 1.0.0-beta.5 - p-limit: 5.0.0 - pathe: 1.1.1 - dev: true + '@vitest/runner@1.5.0': + resolution: {integrity: sha512-7HWwdxXP5yDoe7DTpbif9l6ZmDwCzcSIK38kTSIt6CFEpMjX4EpCgT6wUmS0xTXqMI6E/ONmfgRKmaujpabjZQ==} - /@vitest/snapshot@1.0.0-beta.5: - resolution: {integrity: sha512-fsWoc/mokLawqrLFqK9MHEyzJaGeDzU5gAgky2yZJR58VSsSvW+cesvmdv9ch39xHlTzFTRPgrWkNsmbdm2gbg==} - dependencies: - magic-string: 0.30.5 - pathe: 1.1.1 - pretty-format: 29.7.0 - dev: true + '@vitest/snapshot@1.5.0': + resolution: {integrity: sha512-qpv3fSEuNrhAO3FpH6YYRdaECnnRjg9VxbhdtPwPRnzSfHVXnNzzrpX4cJxqiwgRMo7uRMWDFBlsBq4Cr+rO3A==} - /@vitest/spy@1.0.0-beta.5: - resolution: {integrity: sha512-B5dx87eCiJidWGdURMS/etHE9P3JRdFEQj8HQRGI3OhMy5XcSrdAwg5oEADoqXm32GUGc7bC8Dw/q9PiCJSBIQ==} - dependencies: - tinyspy: 2.2.0 - dev: true + '@vitest/spy@1.5.0': + resolution: {integrity: sha512-vu6vi6ew5N5MMHJjD5PoakMRKYdmIrNJmyfkhRpQt5d9Ewhw9nZ5Aqynbi3N61bvk9UvZ5UysMT6ayIrZ8GA9w==} - /@vitest/utils@1.0.0-beta.5: - resolution: {integrity: sha512-5ippiVcc6KjnAZiMc5Gz5g1tWTG+21g5scr+cedYC+YxAjqZzOG/ncJuM/Eqq9a+/MAJJc5zOGBcDYl27x62jg==} - dependencies: - diff-sequences: 29.6.3 - loupe: 2.3.7 - pretty-format: 29.7.0 - dev: true + '@vitest/utils@1.5.0': + resolution: {integrity: sha512-BDU0GNL8MWkRkSRdNFvCUCAVOeHaUlVJ9Tx0TYBZyXaaOTmGtUFObzchCivIBrIwKzvZA7A9sCejVhXM2aY98A==} - /@volar/language-core@1.10.10: - resolution: {integrity: sha512-nsV1o3AZ5n5jaEAObrS3MWLBWaGwUj/vAsc15FVNIv+DbpizQRISg9wzygsHBr56ELRH8r4K75vkYNMtsSNNWw==} - dependencies: - '@volar/source-map': 1.10.10 - dev: true + '@volar/language-core@2.2.0-alpha.8': + resolution: {integrity: sha512-Ew1Iw7/RIRNuDLn60fWJdOLApAlfTVPxbPiSLzc434PReC9kleYtaa//Wo2WlN1oiRqneW0pWQQV0CwYqaimLQ==} - /@volar/source-map@1.10.10: - resolution: {integrity: sha512-GVKjLnifV4voJ9F0vhP56p4+F3WGf+gXlRtjFZsv6v3WxBTWU3ZVeaRaEHJmWrcv5LXmoYYpk/SC25BKemPRkg==} - dependencies: - muggle-string: 0.3.1 - dev: true + '@volar/source-map@2.2.0-alpha.8': + resolution: {integrity: sha512-E1ZVmXFJ5DU4fWDcWHzi8OLqqReqIDwhXvIMhVdk6+VipfMVv4SkryXu7/rs4GA/GsebcRyJdaSkKBB3OAkIcA==} - /@volar/typescript@1.10.10: - resolution: {integrity: sha512-4a2r5bdUub2m+mYVnLu2wt59fuoYWe7nf0uXtGHU8QQ5LDNfzAR0wK7NgDiQ9rcl2WT3fxT2AA9AylAwFtj50A==} - dependencies: - '@volar/language-core': 1.10.10 - path-browserify: 1.0.1 - dev: true + '@volar/typescript@2.2.0-alpha.8': + resolution: {integrity: sha512-RLbRDI+17CiayHZs9HhSzlH0FhLl/+XK6o2qoiw2o2GGKcyD1aDoY6AcMd44acYncTOrqoTNoY6LuCiRyiJiGg==} - /@vue/compiler-core@3.3.8: - resolution: {integrity: sha512-hN/NNBUECw8SusQvDSqqcVv6gWq8L6iAktUR0UF3vGu2OhzRqcOiAno0FmBJWwxhYEXRlQJT5XnoKsVq1WZx4g==} - dependencies: - '@babel/parser': 7.23.4 - '@vue/shared': 3.3.8 - estree-walker: 2.0.2 - source-map-js: 1.0.2 + '@vue/compiler-core@3.4.23': + resolution: {integrity: sha512-HAFmuVEwNqNdmk+w4VCQ2pkLk1Vw4XYiiyxEp3z/xvl14aLTUBw2OfVH3vBcx+FtGsynQLkkhK410Nah1N2yyQ==} - /@vue/compiler-dom@3.3.8: - resolution: {integrity: sha512-+PPtv+p/nWDd0AvJu3w8HS0RIm/C6VGBIRe24b9hSyNWOAPEUosFZ5diwawwP8ip5sJ8n0Pe87TNNNHnvjs0FQ==} - dependencies: - '@vue/compiler-core': 3.3.8 - '@vue/shared': 3.3.8 + '@vue/compiler-dom@3.4.23': + resolution: {integrity: sha512-t0b9WSTnCRrzsBGrDd1LNR5HGzYTr7LX3z6nNBG+KGvZLqrT0mY6NsMzOqlVMBKKXKVuusbbB5aOOFgTY+senw==} - /@vue/compiler-sfc@3.3.8: - resolution: {integrity: sha512-WMzbUrlTjfYF8joyT84HfwwXo+8WPALuPxhy+BZ6R4Aafls+jDBnSz8PDz60uFhuqFbl3HxRfxvDzrUf3THwpA==} - dependencies: - '@babel/parser': 7.23.4 - '@vue/compiler-core': 3.3.8 - '@vue/compiler-dom': 3.3.8 - '@vue/compiler-ssr': 3.3.8 - '@vue/reactivity-transform': 3.3.8 - '@vue/shared': 3.3.8 - estree-walker: 2.0.2 - magic-string: 0.30.5 - postcss: 8.4.32 - source-map-js: 1.0.2 - dev: false + '@vue/compiler-sfc@3.4.23': + resolution: {integrity: sha512-fSDTKTfzaRX1kNAUiaj8JB4AokikzStWgHooMhaxyjZerw624L+IAP/fvI4ZwMpwIh8f08PVzEnu4rg8/Npssw==} - /@vue/compiler-ssr@3.3.8: - resolution: {integrity: sha512-hXCqQL/15kMVDBuoBYpUnSYT8doDNwsjvm3jTefnXr+ytn294ySnT8NlsFHmTgKNjwpuFy7XVV8yTeLtNl/P6w==} - dependencies: - '@vue/compiler-dom': 3.3.8 - '@vue/shared': 3.3.8 - dev: false + '@vue/compiler-ssr@3.4.23': + resolution: {integrity: sha512-hb6Uj2cYs+tfqz71Wj6h3E5t6OKvb4MVcM2Nl5i/z1nv1gjEhw+zYaNOV+Xwn+SSN/VZM0DgANw5TuJfxfezPg==} + + '@vue/devtools-api@7.0.27': + resolution: {integrity: sha512-BFCFCusSDcw2UcOFD/QeK7OxD1x2C/m+uAN30Q7jLKECSW53hmz0urzJmX834GuWDZX/hIxkyUKnLLfEIP1c/w==} + + '@vue/devtools-kit@7.0.27': + resolution: {integrity: sha512-/A5xM38pPCFX5Yhl/lRFAzjyK6VNsH670nww2WbjFKWqlu3I+lMxWKzQkCW6A1V8bduITgl2kHORfg2gTw6QaA==} + peerDependencies: + vue: ^3.0.0 - /@vue/devtools-api@6.5.1: - resolution: {integrity: sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==} - dev: false + '@vue/devtools-shared@7.0.27': + resolution: {integrity: sha512-4VxtmZ6yjhiSloqZZq2UYU0TBGxOJ8GxWvp5OlAH70zYqi0FIAyWGPkOhvfoZ7DKQyv2UU0mmKzFHjsEkelGyQ==} - /@vue/language-core@1.8.22(typescript@5.3.2): - resolution: {integrity: sha512-bsMoJzCrXZqGsxawtUea1cLjUT9dZnDsy5TuZ+l1fxRMzUGQUG9+Ypq4w//CqpWmrx7nIAJpw2JVF/t258miRw==} + '@vue/language-core@2.0.13': + resolution: {integrity: sha512-oQgM+BM66SU5GKtUMLQSQN0bxHFkFpLSSAiY87wVziPaiNQZuKVDt/3yA7GB9PiQw0y/bTNL0bOc0jM/siYjKg==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - dependencies: - '@volar/language-core': 1.10.10 - '@volar/source-map': 1.10.10 - '@vue/compiler-dom': 3.3.8 - '@vue/shared': 3.3.8 - computeds: 0.0.1 - minimatch: 9.0.3 - muggle-string: 0.3.1 - typescript: 5.3.2 - vue-template-compiler: 2.7.15 - dev: true - - /@vue/reactivity-transform@3.3.8: - resolution: {integrity: sha512-49CvBzmZNtcHua0XJ7GdGifM8GOXoUMOX4dD40Y5DxI3R8OUhMlvf2nvgUAcPxaXiV5MQQ1Nwy09ADpnLQUqRw==} - dependencies: - '@babel/parser': 7.23.4 - '@vue/compiler-core': 3.3.8 - '@vue/shared': 3.3.8 - estree-walker: 2.0.2 - magic-string: 0.30.5 - dev: false - /@vue/reactivity@3.3.8: - resolution: {integrity: sha512-ctLWitmFBu6mtddPyOKpHg8+5ahouoTCRtmAHZAXmolDtuZXfjL2T3OJ6DL6ezBPQB1SmMnpzjiWjCiMYmpIuw==} - dependencies: - '@vue/shared': 3.3.8 - dev: false + '@vue/reactivity@3.4.23': + resolution: {integrity: sha512-GlXR9PL+23fQ3IqnbSQ8OQKLodjqCyoCrmdLKZk3BP7jN6prWheAfU7a3mrltewTkoBm+N7qMEb372VHIkQRMQ==} - /@vue/runtime-core@3.3.8: - resolution: {integrity: sha512-qurzOlb6q26KWQ/8IShHkMDOuJkQnQcTIp1sdP4I9MbCf9FJeGVRXJFr2mF+6bXh/3Zjr9TDgURXrsCr9bfjUw==} - dependencies: - '@vue/reactivity': 3.3.8 - '@vue/shared': 3.3.8 - dev: false + '@vue/runtime-core@3.4.23': + resolution: {integrity: sha512-FeQ9MZEXoFzFkFiw9MQQ/FWs3srvrP+SjDKSeRIiQHIhtkzoj0X4rWQlRNHbGuSwLra6pMyjAttwixNMjc/xLw==} - /@vue/runtime-dom@3.3.8: - resolution: {integrity: sha512-Noy5yM5UIf9UeFoowBVgghyGGPIDPy1Qlqt0yVsUdAVbqI8eeMSsTqBtauaEoT2UFXUk5S64aWVNJN4MJ2vRdA==} - dependencies: - '@vue/runtime-core': 3.3.8 - '@vue/shared': 3.3.8 - csstype: 3.1.2 - dev: false + '@vue/runtime-dom@3.4.23': + resolution: {integrity: sha512-RXJFwwykZWBkMiTPSLEWU3kgVLNAfActBfWFlZd0y79FTUxexogd0PLG4HH2LfOktjRxV47Nulygh0JFXe5f9A==} - /@vue/server-renderer@3.3.8(vue@3.3.8): - resolution: {integrity: sha512-zVCUw7RFskvPuNlPn/8xISbrf0zTWsTSdYTsUTN1ERGGZGVnRxM2QZ3x1OR32+vwkkCm0IW6HmJ49IsPm7ilLg==} + '@vue/server-renderer@3.4.23': + resolution: {integrity: sha512-LDwGHtnIzvKFNS8dPJ1SSU5Gvm36p2ck8wCZc52fc3k/IfjKcwCyrWEf0Yag/2wTFUBXrqizfhK9c/mC367dXQ==} peerDependencies: - vue: 3.3.8 - dependencies: - '@vue/compiler-ssr': 3.3.8 - '@vue/shared': 3.3.8 - vue: 3.3.8(typescript@5.3.2) - dev: false + vue: 3.4.23 - /@vue/shared@3.3.8: - resolution: {integrity: sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==} + '@vue/shared@3.4.23': + resolution: {integrity: sha512-wBQ0gvf+SMwsCQOyusNw/GoXPV47WGd1xB5A1Pgzy0sQ3Bi5r5xm3n+92y3gCnB3MWqnRDdvfkRGxhKtbBRNgg==} - /@vueuse/core@10.6.1(vue@3.3.8): - resolution: {integrity: sha512-Pc26IJbqgC9VG1u6VY/xrXXfxD33hnvxBnKrLlA2LJlyHII+BSrRoTPJgGYq7qZOu61itITFUnm6QbacwZ4H8Q==} - dependencies: - '@types/web-bluetooth': 0.0.20 - '@vueuse/metadata': 10.6.1 - '@vueuse/shared': 10.6.1(vue@3.3.8) - vue-demi: 0.14.6(vue@3.3.8) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - dev: false + '@vueuse/core@10.9.0': + resolution: {integrity: sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==} - /@vueuse/integrations@10.6.1(focus-trap@7.5.4)(vue@3.3.8): - resolution: {integrity: sha512-mPDupuofMJ4DPmtX/FfP1MajmWRzYDv8WSaTCo8LQ5kFznjWgmUQ16ApjYqgMquqffNY6+IRMdMgosLDRZOSZA==} + '@vueuse/integrations@10.9.0': + resolution: {integrity: sha512-acK+A01AYdWSvL4BZmCoJAcyHJ6EqhmkQEXbQLwev1MY7NBnS+hcEMx/BzVoR9zKI+UqEPMD9u6PsyAuiTRT4Q==} peerDependencies: async-validator: '*' axios: '*' @@ -1515,654 +1031,328 @@ packages: optional: true universal-cookie: optional: true - dependencies: - '@vueuse/core': 10.6.1(vue@3.3.8) - '@vueuse/shared': 10.6.1(vue@3.3.8) - focus-trap: 7.5.4 - vue-demi: 0.14.6(vue@3.3.8) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - dev: false - /@vueuse/metadata@10.6.1: - resolution: {integrity: sha512-qhdwPI65Bgcj23e5lpGfQsxcy0bMjCAsUGoXkJ7DsoeDUdasbZ2DBa4dinFCOER3lF4gwUv+UD2AlA11zdzMFw==} - dev: false + '@vueuse/metadata@10.9.0': + resolution: {integrity: sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==} - /@vueuse/shared@10.6.1(vue@3.3.8): - resolution: {integrity: sha512-TECVDTIedFlL0NUfHWncf3zF9Gc4VfdxfQc8JFwoVZQmxpONhLxFrlm0eHQeidHj4rdTPL3KXJa0TZCk1wnc5Q==} - dependencies: - vue-demi: 0.14.6(vue@3.3.8) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - dev: false + '@vueuse/shared@10.9.0': + resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==} - /JSONStream@1.3.5: + JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true - dependencies: - jsonparse: 1.3.1 - through: 2.3.8 - dev: true - - /accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - dev: true - /acorn-walk@8.3.0: - resolution: {integrity: sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==} + acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} engines: {node: '>=0.4.0'} - dev: true - /acorn@8.11.2: - resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} + acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} engines: {node: '>=0.4.0'} hasBin: true - dev: true - /add-stream@1.0.0: + add-stream@1.0.0: resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==} - dev: true - - /algoliasearch@4.20.0: - resolution: {integrity: sha512-y+UHEjnOItoNy0bYO+WWmLWBlPwDjKHW6mNHrPi0NkuhpQOOEbrkwQH/wgKFDLh7qlKjzoKeiRtlpewDPDG23g==} - dependencies: - '@algolia/cache-browser-local-storage': 4.20.0 - '@algolia/cache-common': 4.20.0 - '@algolia/cache-in-memory': 4.20.0 - '@algolia/client-account': 4.20.0 - '@algolia/client-analytics': 4.20.0 - '@algolia/client-common': 4.20.0 - '@algolia/client-personalization': 4.20.0 - '@algolia/client-search': 4.20.0 - '@algolia/logger-common': 4.20.0 - '@algolia/logger-console': 4.20.0 - '@algolia/requester-browser-xhr': 4.20.0 - '@algolia/requester-common': 4.20.0 - '@algolia/requester-node-http': 4.20.0 - '@algolia/transporter': 4.20.0 - dev: false - - /ansi-colors@4.1.3: + + algoliasearch@4.23.3: + resolution: {integrity: sha512-Le/3YgNvjW9zxIQMRhUHuhiUjAlKY/zsdZpfq4dlLqg6mEm0nL6yk+7f2hDOtLpxsgE4jSzDmvHL7nXdBp5feg==} + + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} - dev: true - /ansi-escapes@5.0.0: - resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} - engines: {node: '>=12'} - dependencies: - type-fest: 1.4.0 - dev: true + ansi-escapes@6.2.1: + resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} + engines: {node: '>=14.16'} - /ansi-regex@5.0.1: + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - dev: true - /ansi-regex@6.0.1: + ansi-regex@6.0.1: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} - dev: true - /ansi-styles@3.2.1: + ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} - dependencies: - color-convert: 1.9.3 - dev: true - /ansi-styles@4.3.0: + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - dev: true - /ansi-styles@5.2.0: + ansi-styles@5.2.0: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - dev: true - /ansi-styles@6.2.1: + ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - dev: true - /anymatch@3.1.3: + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - dev: true - /arg@5.0.2: + arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - dev: true - /argparse@1.0.10: + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - dev: true - /argparse@2.0.1: + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true - /array-buffer-byte-length@1.0.0: - resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} - dependencies: - call-bind: 1.0.5 - is-array-buffer: 3.0.2 - dev: true + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} - /array-ify@1.0.0: + array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - dev: true - /arraybuffer.prototype.slice@1.0.2: - resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} - dependencies: - array-buffer-byte-length: 1.0.0 - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 - is-array-buffer: 3.0.2 - is-shared-array-buffer: 1.0.2 - dev: true - /assertion-error@1.1.0: + assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - dev: true - /asynckit@0.4.0: + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: true - /available-typed-arrays@1.0.5: - resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - dev: true - /axios@1.6.2(debug@4.3.4): - resolution: {integrity: sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==} - dependencies: - follow-redirects: 1.15.3(debug@4.3.4) - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - dev: true + axios@1.6.8: + resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==} - /balanced-match@1.0.2: + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - /base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: true - - /binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - dev: true - - /bl@5.1.0: - resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} - dependencies: - buffer: 6.0.3 - inherits: 2.0.4 - readable-stream: 3.6.2 - dev: true - /boolbase@1.0.0: + boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - dev: true - /brace-expansion@1.1.11: + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: true - /brace-expansion@2.0.1: + brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - dependencies: - balanced-match: 1.0.2 - dev: true - /braces@3.0.2: + braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} - dependencies: - fill-range: 7.0.1 - dev: true - /buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - dev: true - - /builtin-modules@3.3.0: + builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} - dev: true - /bytes@3.0.0: - resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} - engines: {node: '>= 0.8'} - dev: true + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} - /cac@6.7.14: + cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} - dev: true - - /call-bind@1.0.5: - resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} - dependencies: - function-bind: 1.1.2 - get-intrinsic: 1.2.2 - set-function-length: 1.1.1 - dev: true - /ccount@2.0.1: - resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - dev: false + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} - /chai@4.3.10: - resolution: {integrity: sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==} + chai@4.4.1: + resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} engines: {node: '>=4'} - dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.3 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.0.8 - dev: true - /chalk@2.4.2: + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - dev: true - /chalk@5.3.0: + chalk@5.3.0: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: true - - /character-entities-html4@2.1.0: - resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} - dev: false - /character-entities-legacy@3.0.0: - resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} - dev: false - - /check-error@1.0.3: + check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} - dependencies: - get-func-name: 2.0.2 - dev: true - /cheerio-select@1.6.0: + cheerio-select@1.6.0: resolution: {integrity: sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==} - dependencies: - css-select: 4.3.0 - css-what: 6.1.0 - domelementtype: 2.3.0 - domhandler: 4.3.1 - domutils: 2.8.0 - dev: true - /cheerio@1.0.0-rc.10: + cheerio@1.0.0-rc.10: resolution: {integrity: sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==} engines: {node: '>= 6'} - dependencies: - cheerio-select: 1.6.0 - dom-serializer: 1.4.1 - domhandler: 4.3.1 - htmlparser2: 6.1.0 - parse5: 6.0.1 - parse5-htmlparser2-tree-adapter: 6.0.1 - tslib: 2.6.2 - dev: true - /chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} - dependencies: - anymatch: 3.1.3 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - dev: true - /cli-cursor@4.0.0: + cli-cursor@4.0.0: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - restore-cursor: 4.0.0 - dev: true - /cli-spinners@2.9.2: + cli-spinners@2.9.2: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} - dev: true - /cli-truncate@3.1.0: - resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - slice-ansi: 5.0.0 - string-width: 5.1.2 - dev: true + cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} - /color-convert@1.9.3: + color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - dependencies: - color-name: 1.1.3 - dev: true - /color-convert@2.0.1: + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - dev: true - /color-name@1.1.3: + color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: true - /color-name@1.1.4: + color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true - /colorette@2.0.20: + colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - dev: true - /combined-stream@1.0.8: + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: true - /comma-separated-tokens@2.0.3: - resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - dev: false - - /commander@11.1.0: + commander@11.1.0: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} - dev: true - /commander@6.2.1: + commander@6.2.1: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} - dev: true - /commander@9.2.0: + commander@9.2.0: resolution: {integrity: sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==} engines: {node: ^12.20.0 || >=14} - dev: true - /commondir@1.0.1: + commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - dev: true - /compare-func@2.0.0: + compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} - dependencies: - array-ify: 1.0.0 - dot-prop: 5.3.0 - dev: true - - /compressible@2.0.18: - resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: true - - /compression@1.7.4(supports-color@9.4.0): - resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} - engines: {node: '>= 0.8.0'} - dependencies: - accepts: 1.3.8 - bytes: 3.0.0 - compressible: 2.0.18 - debug: 2.6.9(supports-color@9.4.0) - on-headers: 1.0.2 - safe-buffer: 5.1.2 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - dev: true - /computeds@0.0.1: + computeds@0.0.1: resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} - dev: true - /concat-map@0.0.1: + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true - /conventional-changelog-angular@7.0.0: + conventional-changelog-angular@7.0.0: resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} engines: {node: '>=16'} - dependencies: - compare-func: 2.0.0 - dev: true - /conventional-changelog-atom@4.0.0: + conventional-changelog-atom@4.0.0: resolution: {integrity: sha512-q2YtiN7rnT1TGwPTwjjBSIPIzDJCRE+XAUahWxnh+buKK99Kks4WLMHoexw38GXx9OUxAsrp44f9qXe5VEMYhw==} engines: {node: '>=16'} - dev: true - /conventional-changelog-cli@4.1.0: + conventional-changelog-cli@4.1.0: resolution: {integrity: sha512-MscvILWZ6nWOoC+p/3Nn3D2cVLkjeQjyZPUr0bQ+vUORE/SPrkClJh8BOoMNpS4yk+zFJ5LlgXACxH6XGQoRXA==} engines: {node: '>=16'} hasBin: true - dependencies: - add-stream: 1.0.0 - conventional-changelog: 5.1.0 - meow: 12.1.1 - tempfile: 5.0.0 - dev: true - /conventional-changelog-codemirror@4.0.0: + conventional-changelog-codemirror@4.0.0: resolution: {integrity: sha512-hQSojc/5imn1GJK3A75m9hEZZhc3urojA5gMpnar4JHmgLnuM3CUIARPpEk86glEKr3c54Po3WV/vCaO/U8g3Q==} engines: {node: '>=16'} - dev: true - /conventional-changelog-conventionalcommits@7.0.2: + conventional-changelog-conventionalcommits@7.0.2: resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} engines: {node: '>=16'} - dependencies: - compare-func: 2.0.0 - dev: true - /conventional-changelog-core@7.0.0: + conventional-changelog-core@7.0.0: resolution: {integrity: sha512-UYgaB1F/COt7VFjlYKVE/9tTzfU3VUq47r6iWf6lM5T7TlOxr0thI63ojQueRLIpVbrtHK4Ffw+yQGduw2Bhdg==} engines: {node: '>=16'} - dependencies: - '@hutson/parse-repository-url': 5.0.0 - add-stream: 1.0.0 - conventional-changelog-writer: 7.0.1 - conventional-commits-parser: 5.0.0 - git-raw-commits: 4.0.0 - git-semver-tags: 7.0.1 - hosted-git-info: 7.0.1 - normalize-package-data: 6.0.0 - read-pkg: 8.1.0 - read-pkg-up: 10.1.0 - dev: true - /conventional-changelog-ember@4.0.0: + conventional-changelog-ember@4.0.0: resolution: {integrity: sha512-D0IMhwcJUg1Y8FSry6XAplEJcljkHVlvAZddhhsdbL1rbsqRsMfGx/PIkPYq0ru5aDgn+OxhQ5N5yR7P9mfsvA==} engines: {node: '>=16'} - dev: true - /conventional-changelog-eslint@5.0.0: + conventional-changelog-eslint@5.0.0: resolution: {integrity: sha512-6JtLWqAQIeJLn/OzUlYmzd9fKeNSWmQVim9kql+v4GrZwLx807kAJl3IJVc3jTYfVKWLxhC3BGUxYiuVEcVjgA==} engines: {node: '>=16'} - dev: true - /conventional-changelog-express@4.0.0: + conventional-changelog-express@4.0.0: resolution: {integrity: sha512-yWyy5c7raP9v7aTvPAWzqrztACNO9+FEI1FSYh7UP7YT1AkWgv5UspUeB5v3Ibv4/o60zj2o9GF2tqKQ99lIsw==} engines: {node: '>=16'} - dev: true - /conventional-changelog-jquery@5.0.0: + conventional-changelog-jquery@5.0.0: resolution: {integrity: sha512-slLjlXLRNa/icMI3+uGLQbtrgEny3RgITeCxevJB+p05ExiTgHACP5p3XiMKzjBn80n+Rzr83XMYfRInEtCPPw==} engines: {node: '>=16'} - dev: true - /conventional-changelog-jshint@4.0.0: + conventional-changelog-jshint@4.0.0: resolution: {integrity: sha512-LyXq1bbl0yG0Ai1SbLxIk8ZxUOe3AjnlwE6sVRQmMgetBk+4gY9EO3d00zlEt8Y8gwsITytDnPORl8al7InTjg==} engines: {node: '>=16'} - dependencies: - compare-func: 2.0.0 - dev: true - /conventional-changelog-preset-loader@4.1.0: + conventional-changelog-preset-loader@4.1.0: resolution: {integrity: sha512-HozQjJicZTuRhCRTq4rZbefaiCzRM2pr6u2NL3XhrmQm4RMnDXfESU6JKu/pnKwx5xtdkYfNCsbhN5exhiKGJA==} engines: {node: '>=16'} - dev: true - /conventional-changelog-writer@7.0.1: + conventional-changelog-writer@7.0.1: resolution: {integrity: sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==} engines: {node: '>=16'} hasBin: true - dependencies: - conventional-commits-filter: 4.0.0 - handlebars: 4.7.8 - json-stringify-safe: 5.0.1 - meow: 12.1.1 - semver: 7.5.4 - split2: 4.2.0 - dev: true - /conventional-changelog@5.1.0: + conventional-changelog@5.1.0: resolution: {integrity: sha512-aWyE/P39wGYRPllcCEZDxTVEmhyLzTc9XA6z6rVfkuCD2UBnhV/sgSOKbQrEG5z9mEZJjnopjgQooTKxEg8mAg==} engines: {node: '>=16'} - dependencies: - conventional-changelog-angular: 7.0.0 - conventional-changelog-atom: 4.0.0 - conventional-changelog-codemirror: 4.0.0 - conventional-changelog-conventionalcommits: 7.0.2 - conventional-changelog-core: 7.0.0 - conventional-changelog-ember: 4.0.0 - conventional-changelog-eslint: 5.0.0 - conventional-changelog-express: 4.0.0 - conventional-changelog-jquery: 5.0.0 - conventional-changelog-jshint: 4.0.0 - conventional-changelog-preset-loader: 4.1.0 - dev: true - /conventional-commits-filter@4.0.0: + conventional-commits-filter@4.0.0: resolution: {integrity: sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==} engines: {node: '>=16'} - dev: true - /conventional-commits-parser@5.0.0: + conventional-commits-parser@5.0.0: resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} engines: {node: '>=16'} hasBin: true - dependencies: - JSONStream: 1.3.5 - is-text-path: 2.0.0 - meow: 12.1.1 - split2: 4.2.0 - dev: true - /cross-spawn@6.0.5: + cross-spawn@6.0.5: resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} engines: {node: '>=4.8'} - dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.2 - shebang-command: 1.2.0 - which: 1.3.1 - dev: true - /cross-spawn@7.0.3: + cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - dev: true - /css-select@4.3.0: + crypto-random-string@4.0.0: + resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} + engines: {node: '>=12'} + + css-select@4.3.0: resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} - dependencies: - boolbase: 1.0.0 - css-what: 6.1.0 - domhandler: 4.3.1 - domutils: 2.8.0 - nth-check: 2.1.1 - dev: true - /css-what@6.1.0: + css-what@6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} - dev: true - /csstype@3.1.2: - resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} - dev: false + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - /dargs@8.1.0: + dargs@8.1.0: resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} engines: {node: '>=12'} - dev: true - /de-indent@1.0.2: - resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} - dev: true + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} - /debug@2.6.9(supports-color@9.4.0): - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - supports-color: 9.4.0 - dev: true + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} - /debug@4.3.4(supports-color@9.4.0): + debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} peerDependencies: @@ -2170,1379 +1360,788 @@ packages: peerDependenciesMeta: supports-color: optional: true - dependencies: - ms: 2.1.2 - supports-color: 9.4.0 - dev: true - /deep-eql@4.1.3: + deep-eql@4.1.3: resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} engines: {node: '>=6'} - dependencies: - type-detect: 4.0.8 - dev: true - /deepmerge@4.3.1: + deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} - dev: true - /define-data-property@1.1.1: - resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.2 - gopd: 1.0.1 - has-property-descriptors: 1.0.1 - dev: true - /define-properties@1.2.1: + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} - dependencies: - define-data-property: 1.1.1 - has-property-descriptors: 1.0.1 - object-keys: 1.1.1 - dev: true - /delayed-stream@1.0.0: + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - dev: true - /dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - dev: false + detect-indent@7.0.1: + resolution: {integrity: sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==} + engines: {node: '>=12.20'} - /devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - dependencies: - dequal: 2.0.3 - dev: false + detect-newline@4.0.1: + resolution: {integrity: sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - /diff-sequences@29.6.3: + diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true - /dom-serializer@1.4.1: + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dom-serializer@1.4.1: resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} - dependencies: - domelementtype: 2.3.0 - domhandler: 4.3.1 - entities: 2.2.0 - dev: true - /domelementtype@2.3.0: + domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - dev: true - /domhandler@3.3.0: + domhandler@3.3.0: resolution: {integrity: sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==} engines: {node: '>= 4'} - dependencies: - domelementtype: 2.3.0 - dev: true - /domhandler@4.3.1: + domhandler@4.3.1: resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} engines: {node: '>= 4'} - dependencies: - domelementtype: 2.3.0 - dev: true - /domutils@2.8.0: + domutils@2.8.0: resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} - dependencies: - dom-serializer: 1.4.1 - domelementtype: 2.3.0 - domhandler: 4.3.1 - dev: true - /dot-prop@5.3.0: + dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} - dependencies: - is-obj: 2.0.0 - dev: true - /eastasianwidth@0.2.0: + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - dev: true - /emoji-regex@8.0.0: + emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true - /emoji-regex@9.2.2: + emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - dev: true - /entities@2.2.0: + entities@2.2.0: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} - dev: true - - /entities@3.0.1: - resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==} - engines: {node: '>=0.12'} - dev: true - /entities@4.5.0: + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - dev: false - /error-ex@1.3.2: + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - dependencies: - is-arrayish: 0.2.1 - dev: true - /es-abstract@1.22.3: - resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} engines: {node: '>= 0.4'} - dependencies: - array-buffer-byte-length: 1.0.0 - arraybuffer.prototype.slice: 1.0.2 - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 - es-set-tostringtag: 2.0.2 - es-to-primitive: 1.2.1 - function.prototype.name: 1.1.6 - get-intrinsic: 1.2.2 - get-symbol-description: 1.0.0 - globalthis: 1.0.3 - gopd: 1.0.1 - has-property-descriptors: 1.0.1 - has-proto: 1.0.1 - has-symbols: 1.0.3 - hasown: 2.0.0 - internal-slot: 1.0.6 - is-array-buffer: 3.0.2 - is-callable: 1.2.7 - is-negative-zero: 2.0.2 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 - is-string: 1.0.7 - is-typed-array: 1.1.12 - is-weakref: 1.0.2 - object-inspect: 1.13.1 - object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.5.1 - safe-array-concat: 1.0.1 - safe-regex-test: 1.0.0 - string.prototype.trim: 1.2.8 - string.prototype.trimend: 1.0.7 - string.prototype.trimstart: 1.0.7 - typed-array-buffer: 1.0.0 - typed-array-byte-length: 1.0.0 - typed-array-byte-offset: 1.0.0 - typed-array-length: 1.0.4 - unbox-primitive: 1.0.2 - which-typed-array: 1.1.13 - dev: true - /es-module-lexer@1.4.1: - resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} - dev: true + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} - /es-set-tostringtag@2.0.2: - resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.2 - has-tostringtag: 1.0.0 - hasown: 2.0.0 - dev: true - /es-to-primitive@1.2.1: + es-module-lexer@1.5.0: + resolution: {integrity: sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.2.1: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} - dependencies: - is-callable: 1.2.7 - is-date-object: 1.0.5 - is-symbol: 1.0.4 - dev: true - /esbuild@0.19.7: - resolution: {integrity: sha512-6brbTZVqxhqgbpqBR5MzErImcpA0SQdoKOkcWK/U30HtQxnokIpG3TX2r0IJqbFUzqLjhU/zC1S5ndgakObVCQ==} + esbuild@0.20.2: + resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} engines: {node: '>=12'} hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/android-arm': 0.19.7 - '@esbuild/android-arm64': 0.19.7 - '@esbuild/android-x64': 0.19.7 - '@esbuild/darwin-arm64': 0.19.7 - '@esbuild/darwin-x64': 0.19.7 - '@esbuild/freebsd-arm64': 0.19.7 - '@esbuild/freebsd-x64': 0.19.7 - '@esbuild/linux-arm': 0.19.7 - '@esbuild/linux-arm64': 0.19.7 - '@esbuild/linux-ia32': 0.19.7 - '@esbuild/linux-loong64': 0.19.7 - '@esbuild/linux-mips64el': 0.19.7 - '@esbuild/linux-ppc64': 0.19.7 - '@esbuild/linux-riscv64': 0.19.7 - '@esbuild/linux-s390x': 0.19.7 - '@esbuild/linux-x64': 0.19.7 - '@esbuild/netbsd-x64': 0.19.7 - '@esbuild/openbsd-x64': 0.19.7 - '@esbuild/sunos-x64': 0.19.7 - '@esbuild/win32-arm64': 0.19.7 - '@esbuild/win32-ia32': 0.19.7 - '@esbuild/win32-x64': 0.19.7 - - /escape-goat@3.0.0: + + escape-goat@3.0.0: resolution: {integrity: sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==} engines: {node: '>=10'} - dev: true - /escape-html@1.0.3: + escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - dev: true - /escape-string-regexp@1.0.5: + escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} - dev: true - /esm@3.2.25: + esm@3.2.25: resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==} engines: {node: '>=6'} - dev: true - /esprima@4.0.1: + esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true - dev: true - /estree-walker@2.0.2: + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - /eventemitter3@5.0.1: + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} - dev: true - /execa@8.0.1: + execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.1.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 - dev: true - /extend-shallow@2.0.1: + extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} - dependencies: - is-extendable: 0.1.1 - dev: true - /fast-glob@3.3.2: + fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - /fastq@1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} - dependencies: - reusify: 1.0.4 - dev: true + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + file-type@18.7.0: + resolution: {integrity: sha512-ihHtXRzXEziMrQ56VSgU7wkxh55iNchFkosu7Y9/S+tXHdKyrGjVK0ujbqNnsxzea+78MaLhN6PGmfYSAv1ACw==} + engines: {node: '>=14.16'} - /fill-range@7.0.1: + fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - dev: true - /find-up-simple@1.0.0: + find-up-simple@1.0.0: resolution: {integrity: sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==} engines: {node: '>=18'} - dev: true - /find-up@6.3.0: + find-up@6.3.0: resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - locate-path: 7.2.0 - path-exists: 5.0.0 - dev: true - /focus-trap@7.5.4: + focus-trap@7.5.4: resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==} - dependencies: - tabbable: 6.2.0 - dev: false - /follow-redirects@1.15.3(debug@4.3.4): - resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} + follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} engines: {node: '>=4.0'} peerDependencies: debug: '*' peerDependenciesMeta: debug: optional: true - dependencies: - debug: 4.3.4(supports-color@9.4.0) - dev: true - /for-each@0.3.3: + for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - dependencies: - is-callable: 1.2.7 - dev: true - /foreground-child@3.1.1: + foreground-child@3.1.1: resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} engines: {node: '>=14'} - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - dev: true - /form-data@4.0.0: + form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: true - /fs-extra@11.1.1: - resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} engines: {node: '>=14.14'} - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - dev: true - /fs.realpath@1.0.0: + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true - /fsevents@2.3.3: + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - requiresBuild: true - optional: true - /function-bind@1.1.2: + function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - dev: true - /function.prototype.name@1.1.6: + function.prototype.name@1.1.6: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - functions-have-names: 1.2.3 - dev: true - /functions-have-names@1.2.3: + functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - dev: true - /get-func-name@2.0.2: + get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + + get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - dev: true - /get-intrinsic@1.2.2: - resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} - dependencies: - function-bind: 1.1.2 - has-proto: 1.0.1 - has-symbols: 1.0.3 - hasown: 2.0.0 - dev: true + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} - /get-port@7.0.0: - resolution: {integrity: sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw==} + get-port@7.1.0: + resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==} engines: {node: '>=16'} - dev: true - /get-stream@8.0.1: + get-stdin@9.0.0: + resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==} + engines: {node: '>=12'} + + get-stream@8.0.1: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} - dev: true - /get-symbol-description@1.0.0: - resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - dev: true - /get-tsconfig@4.7.2: - resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} - dependencies: - resolve-pkg-maps: 1.0.0 - dev: true + get-tsconfig@4.7.3: + resolution: {integrity: sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==} - /git-raw-commits@4.0.0: + git-hooks-list@3.1.0: + resolution: {integrity: sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA==} + + git-raw-commits@4.0.0: resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} engines: {node: '>=16'} hasBin: true - dependencies: - dargs: 8.1.0 - meow: 12.1.1 - split2: 4.2.0 - dev: true - /git-semver-tags@7.0.1: + git-semver-tags@7.0.1: resolution: {integrity: sha512-NY0ZHjJzyyNXHTDZmj+GG7PyuAKtMsyWSwh07CR2hOZFa+/yoTsXci/nF2obzL8UDhakFNkD9gNdt/Ed+cxh2Q==} engines: {node: '>=16'} hasBin: true - dependencies: - meow: 12.1.1 - semver: 7.5.4 - dev: true - /glob-parent@5.1.2: + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} - dependencies: - is-glob: 4.0.3 - dev: true - /glob@10.3.10: - resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + glob@10.3.12: + resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true - dependencies: - foreground-child: 3.1.1 - jackspeak: 2.3.6 - minimatch: 9.0.3 - minipass: 7.0.4 - path-scurry: 1.10.1 - dev: true - /glob@8.1.0: + glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 5.1.6 - once: 1.4.0 - dev: true - /globalthis@1.0.3: + globalthis@1.0.3: resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} engines: {node: '>= 0.4'} - dependencies: - define-properties: 1.2.1 - dev: true - /gopd@1.0.1: + globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} - dependencies: - get-intrinsic: 1.2.2 - dev: true - /graceful-fs@4.2.11: + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true - /gray-matter@4.0.3: + gray-matter@4.0.3: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} - dependencies: - js-yaml: 3.14.1 - kind-of: 6.0.3 - section-matter: 1.0.0 - strip-bom-string: 1.0.0 - dev: true - /handlebars@4.7.8: + handlebars@4.7.8: resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} engines: {node: '>=0.4.7'} hasBin: true - dependencies: - minimist: 1.2.8 - neo-async: 2.6.2 - source-map: 0.6.1 - wordwrap: 1.0.0 - optionalDependencies: - uglify-js: 3.17.4 - dev: true - /has-bigints@1.0.2: + has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} - dev: true - /has-flag@3.0.0: + has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} - dev: true - /has-property-descriptors@1.0.1: - resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} - dependencies: - get-intrinsic: 1.2.2 - dev: true + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - /has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} engines: {node: '>= 0.4'} - dev: true - /has-symbols@1.0.3: + has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} - dev: true - /has-tostringtag@1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: true - /hasown@2.0.0: - resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} - dependencies: - function-bind: 1.1.2 - dev: true - - /hast-util-from-parse5@8.0.1: - resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==} - dependencies: - '@types/hast': 3.0.3 - '@types/unist': 3.0.2 - devlop: 1.1.0 - hastscript: 8.0.0 - property-information: 6.4.0 - vfile: 6.0.1 - vfile-location: 5.0.2 - web-namespaces: 2.0.1 - dev: false - - /hast-util-parse-selector@4.0.0: - resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} - dependencies: - '@types/hast': 3.0.3 - dev: false - - /hast-util-raw@9.0.1: - resolution: {integrity: sha512-5m1gmba658Q+lO5uqL5YNGQWeh1MYWZbZmWrM5lncdcuiXuo5E2HT/CIOp0rLF8ksfSwiCVJ3twlgVRyTGThGA==} - dependencies: - '@types/hast': 3.0.3 - '@types/unist': 3.0.2 - '@ungap/structured-clone': 1.2.0 - hast-util-from-parse5: 8.0.1 - hast-util-to-parse5: 8.0.0 - html-void-elements: 3.0.0 - mdast-util-to-hast: 13.0.2 - parse5: 7.1.2 - unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 - vfile: 6.0.1 - web-namespaces: 2.0.1 - zwitch: 2.0.4 - dev: false - - /hast-util-to-html@9.0.0: - resolution: {integrity: sha512-IVGhNgg7vANuUA2XKrT6sOIIPgaYZnmLx3l/CCOAK0PtgfoHrZwX7jCSYyFxHTrGmC6S9q8aQQekjp4JPZF+cw==} - dependencies: - '@types/hast': 3.0.3 - '@types/unist': 3.0.2 - ccount: 2.0.1 - comma-separated-tokens: 2.0.3 - hast-util-raw: 9.0.1 - hast-util-whitespace: 3.0.0 - html-void-elements: 3.0.0 - mdast-util-to-hast: 13.0.2 - property-information: 6.4.0 - space-separated-tokens: 2.0.2 - stringify-entities: 4.0.3 - zwitch: 2.0.4 - dev: false - - /hast-util-to-parse5@8.0.0: - resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} - dependencies: - '@types/hast': 3.0.3 - comma-separated-tokens: 2.0.3 - devlop: 1.1.0 - property-information: 6.4.0 - space-separated-tokens: 2.0.2 - web-namespaces: 2.0.1 - zwitch: 2.0.4 - dev: false - - /hast-util-whitespace@3.0.0: - resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - dependencies: - '@types/hast': 3.0.3 - dev: false - - /hastscript@8.0.0: - resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==} - dependencies: - '@types/hast': 3.0.3 - comma-separated-tokens: 2.0.3 - hast-util-parse-selector: 4.0.0 - property-information: 6.4.0 - space-separated-tokens: 2.0.2 - dev: false - - /he@1.2.0: + + he@1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true - dev: true - /hosted-git-info@2.8.9: + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - dev: true - /hosted-git-info@7.0.1: + hosted-git-info@7.0.1: resolution: {integrity: sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==} engines: {node: ^16.14.0 || >=18.0.0} - dependencies: - lru-cache: 10.1.0 - dev: true - /html-void-elements@3.0.0: - resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} - dev: false - - /htmlparser2@5.0.1: + htmlparser2@5.0.1: resolution: {integrity: sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==} - dependencies: - domelementtype: 2.3.0 - domhandler: 3.3.0 - domutils: 2.8.0 - entities: 2.2.0 - dev: true - /htmlparser2@6.1.0: + htmlparser2@6.1.0: resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} - dependencies: - domelementtype: 2.3.0 - domhandler: 4.3.1 - domutils: 2.8.0 - entities: 2.2.0 - dev: true - /human-signals@5.0.0: + human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} - dev: true - /ieee754@1.2.1: + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: true - /inflight@1.0.6: + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - dev: true - /inherits@2.0.4: + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true - /internal-slot@1.0.6: - resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.2 - hasown: 2.0.0 - side-channel: 1.0.4 - dev: true - /is-array-buffer@3.0.2: - resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} - dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - is-typed-array: 1.1.12 - dev: true + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} - /is-arrayish@0.2.1: + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true - /is-bigint@1.0.4: + is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} - dependencies: - has-bigints: 1.0.2 - dev: true - /is-binary-path@2.1.0: + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} - dependencies: - binary-extensions: 2.2.0 - dev: true - /is-boolean-object@1.1.2: + is-boolean-object@1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 - dev: true - /is-builtin-module@3.2.1: + is-builtin-module@3.2.1: resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} engines: {node: '>=6'} - dependencies: - builtin-modules: 3.3.0 - dev: true - /is-callable@1.2.7: + is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - dev: true - /is-core-module@2.13.1: + is-core-module@2.13.1: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} - dependencies: - hasown: 2.0.0 - dev: true - /is-date-object@1.0.5: + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - /is-extendable@0.1.1: + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extendable@0.1.1: resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} engines: {node: '>=0.10.0'} - dev: true - /is-extglob@2.1.1: + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - dev: true - /is-fullwidth-code-point@3.0.0: + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - dev: true - /is-fullwidth-code-point@4.0.0: + is-fullwidth-code-point@4.0.0: resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} engines: {node: '>=12'} - dev: true - /is-glob@4.0.3: + is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - /is-interactive@2.0.0: + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-interactive@2.0.0: resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} engines: {node: '>=12'} - dev: true - /is-module@1.0.0: + is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - dev: true - /is-negative-zero@2.0.2: - resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} - dev: true - /is-number-object@1.0.7: + is-number-object@1.0.7: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - /is-number@7.0.0: + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - dev: true - /is-obj@2.0.0: + is-obj@2.0.0: resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} engines: {node: '>=8'} - dev: true - /is-reference@1.2.1: + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-reference@1.2.1: resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} - dependencies: - '@types/estree': 1.0.5 - dev: true - /is-regex@1.1.4: + is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 - dev: true - /is-shared-array-buffer@1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} - dependencies: - call-bind: 1.0.5 - dev: true + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} - /is-stream@3.0.0: + is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - /is-string@1.0.7: + is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - /is-symbol@1.0.4: + is-symbol@1.0.4: resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: true - /is-text-path@2.0.0: + is-text-path@2.0.0: resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} engines: {node: '>=8'} - dependencies: - text-extensions: 2.4.0 - dev: true - /is-typed-array@1.1.12: - resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} engines: {node: '>= 0.4'} - dependencies: - which-typed-array: 1.1.13 - dev: true - /is-unicode-supported@1.3.0: + is-unicode-supported@1.3.0: resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} engines: {node: '>=12'} - dev: true - /is-weakref@1.0.2: + is-unicode-supported@2.0.0: + resolution: {integrity: sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==} + engines: {node: '>=18'} + + is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} - dependencies: - call-bind: 1.0.5 - dev: true - /isarray@2.0.5: + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - dev: true - /isexe@2.0.0: + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true - /jackspeak@2.3.6: + jackspeak@2.3.6: resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} engines: {node: '>=14'} - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - dev: true - /joi@17.11.0: - resolution: {integrity: sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==} - dependencies: - '@hapi/hoek': 9.3.0 - '@hapi/topo': 5.1.0 - '@sideway/address': 4.1.4 - '@sideway/formula': 3.0.1 - '@sideway/pinpoint': 2.0.0 - dev: true + jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + hasBin: true - /js-tokens@4.0.0: + joi@17.12.3: + resolution: {integrity: sha512-2RRziagf555owrm9IRVtdKynOBeITiDpuZqIpgwqXShPncPKNiRQoiGsl/T8SQdq+8ugRzH2LqY67irr2y/d+g==} + + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - requiresBuild: true - dev: true - /js-yaml@3.14.1: + js-tokens@9.0.0: + resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} + + js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - dev: true - /json-parse-better-errors@1.0.2: + json-parse-better-errors@1.0.2: resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} - dev: true - /json-parse-even-better-errors@3.0.0: - resolution: {integrity: sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==} + json-parse-even-better-errors@3.0.1: + resolution: {integrity: sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dev: true - /json-stringify-safe@5.0.1: + json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - dev: true - /jsonc-parser@3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - dev: true + jsonc-parser@3.2.1: + resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} - /jsonfile@6.1.0: + jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - dev: true - /jsonparse@1.3.1: + jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} - dev: true - /juice@8.1.0: + juice@8.1.0: resolution: {integrity: sha512-FLzurJrx5Iv1e7CfBSZH68dC04EEvXvvVvPYB7Vx1WAuhCp1ZPIMtqxc+WTWxVkpTIC2Ach/GAv0rQbtGf6YMA==} engines: {node: '>=10.0.0'} hasBin: true - dependencies: - cheerio: 1.0.0-rc.10 - commander: 6.2.1 - mensch: 0.3.4 - slick: 1.12.2 - web-resource-inliner: 6.0.1 - transitivePeerDependencies: - - encoding - dev: true - /kind-of@6.0.3: + kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - dev: true - /kleur@3.0.3: + kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} - dev: true - /lilconfig@2.1.0: - resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} - engines: {node: '>=10'} - dev: true + lilconfig@3.0.0: + resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} + engines: {node: '>=14'} - /lines-and-columns@2.0.4: + lines-and-columns@2.0.4: resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - /linkify-it@4.0.1: - resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} - dependencies: - uc.micro: 1.0.6 - dev: true + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - /lint-staged@15.1.0(supports-color@9.4.0): - resolution: {integrity: sha512-ZPKXWHVlL7uwVpy8OZ7YQjYDAuO5X4kMh0XgZvPNxLcCCngd0PO5jKQyy3+s4TL2EnHoIXIzP1422f/l3nZKMw==} + lint-staged@15.2.2: + resolution: {integrity: sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==} engines: {node: '>=18.12.0'} hasBin: true - dependencies: - chalk: 5.3.0 - commander: 11.1.0 - debug: 4.3.4(supports-color@9.4.0) - execa: 8.0.1 - lilconfig: 2.1.0 - listr2: 7.0.2 - micromatch: 4.0.5 - pidtree: 0.6.0 - string-argv: 0.3.2 - yaml: 2.3.4 - transitivePeerDependencies: - - supports-color - dev: true - /listr2@7.0.2: - resolution: {integrity: sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==} - engines: {node: '>=16.0.0'} - dependencies: - cli-truncate: 3.1.0 - colorette: 2.0.20 - eventemitter3: 5.0.1 - log-update: 5.0.1 - rfdc: 1.3.0 - wrap-ansi: 8.1.0 - dev: true + listr2@8.0.1: + resolution: {integrity: sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==} + engines: {node: '>=18.0.0'} - /load-json-file@4.0.0: + load-json-file@4.0.0: resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} engines: {node: '>=4'} - dependencies: - graceful-fs: 4.2.11 - parse-json: 4.0.0 - pify: 3.0.0 - strip-bom: 3.0.0 - dev: true - /local-pkg@0.5.0: + local-pkg@0.5.0: resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} - dependencies: - mlly: 1.4.2 - pkg-types: 1.0.3 - dev: true - /locate-path@7.2.0: + locate-path@7.2.0: resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - p-locate: 6.0.0 - dev: true - /lodash._reinterpolate@3.0.0: + lodash._reinterpolate@3.0.0: resolution: {integrity: sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==} - dev: true - /lodash.template@4.5.0: + lodash.template@4.5.0: resolution: {integrity: sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==} - dependencies: - lodash._reinterpolate: 3.0.0 - lodash.templatesettings: 4.2.0 - dev: true - /lodash.templatesettings@4.2.0: + lodash.templatesettings@4.2.0: resolution: {integrity: sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==} - dependencies: - lodash._reinterpolate: 3.0.0 - dev: true - /lodash@4.17.21: + lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true - /log-symbols@5.1.0: - resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} - engines: {node: '>=12'} - dependencies: - chalk: 5.3.0 - is-unicode-supported: 1.3.0 - dev: true + log-symbols@6.0.0: + resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + engines: {node: '>=18'} - /log-update@5.0.1: - resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - ansi-escapes: 5.0.0 - cli-cursor: 4.0.0 - slice-ansi: 5.0.0 - strip-ansi: 7.1.0 - wrap-ansi: 8.1.0 - dev: true + log-update@6.0.0: + resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} + engines: {node: '>=18'} - /loupe@2.3.7: + loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} - dependencies: - get-func-name: 2.0.2 - dev: true - /lru-cache@10.1.0: - resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==} + lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} engines: {node: 14 || >=16.14} - dev: true - /lru-cache@6.0.0: + lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} - dependencies: - yallist: 4.0.0 - dev: true - /magic-string@0.30.5: - resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} - /mark.js@8.11.1: + mark.js@8.11.1: resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} - dev: false - /markdown-it-anchor@8.6.7(@types/markdown-it@13.0.7)(markdown-it@13.0.2): + markdown-it-anchor@8.6.7: resolution: {integrity: sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==} peerDependencies: '@types/markdown-it': '*' markdown-it: '*' - dependencies: - '@types/markdown-it': 13.0.7 - markdown-it: 13.0.2 - dev: true - /markdown-it-attrs@4.1.6(markdown-it@13.0.2): + markdown-it-attrs@4.1.6: resolution: {integrity: sha512-O7PDKZlN8RFMyDX13JnctQompwrrILuz2y43pW2GagcwpIIElkAdfeek+erHfxUOlXWPsjFeWmZ8ch1xtRLWpA==} engines: {node: '>=6'} peerDependencies: markdown-it: '>= 9.0.0' - dependencies: - markdown-it: 13.0.2 - dev: true - /markdown-it-container@3.0.0: - resolution: {integrity: sha512-y6oKTq4BB9OQuY/KLfk/O3ysFhB3IMYoIWhGJEidXt1NQFocFK2sA2t0NYZAMyMShAGL6x5OPIbrmXPIqaN9rw==} - dev: true + markdown-it-container@4.0.0: + resolution: {integrity: sha512-HaNccxUH0l7BNGYbFbjmGpf5aLHAMTinqRZQAEQbMr2cdD3z91Q6kIo1oUn1CQndkT03jat6ckrdRYuwwqLlQw==} - /markdown-it-emoji@2.0.2: - resolution: {integrity: sha512-zLftSaNrKuYl0kR5zm4gxXjHaOI3FAOEaloKmRA5hijmJZvSjmxcokOLlzycb/HXlUFWzXqpIEoyEMCE4i9MvQ==} - dev: true + markdown-it-emoji@3.0.0: + resolution: {integrity: sha512-+rUD93bXHubA4arpEZO3q80so0qgoFJEKRkRbjKX8RTdca89v2kfyF+xR3i2sQTwql9tpPZPOQN5B+PunspXRg==} - /markdown-it-mathjax3@4.3.2: + markdown-it-mathjax3@4.3.2: resolution: {integrity: sha512-TX3GW5NjmupgFtMJGRauioMbbkGsOXAAt1DZ/rzzYmTHqzkO1rNAdiMD4NiruurToPApn2kYy76x02QN26qr2w==} - dependencies: - juice: 8.1.0 - mathjax-full: 3.2.2 - transitivePeerDependencies: - - encoding - dev: true - /markdown-it@13.0.2: - resolution: {integrity: sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==} + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} hasBin: true - dependencies: - argparse: 2.0.1 - entities: 3.0.1 - linkify-it: 4.0.1 - mdurl: 1.0.1 - uc.micro: 1.0.6 - dev: true - /mathjax-full@3.2.2: + mathjax-full@3.2.2: resolution: {integrity: sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==} - dependencies: - esm: 3.2.25 - mhchemparser: 4.2.1 - mj-context-menu: 0.6.1 - speech-rule-engine: 4.0.7 - dev: true - - /mdast-util-to-hast@13.0.2: - resolution: {integrity: sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==} - dependencies: - '@types/hast': 3.0.3 - '@types/mdast': 4.0.3 - '@ungap/structured-clone': 1.2.0 - devlop: 1.1.0 - micromark-util-sanitize-uri: 2.0.0 - trim-lines: 3.0.1 - unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 - dev: false - - /mdurl@1.0.1: - resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} - dev: true - - /memorystream@0.3.1: + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + memorystream@0.3.1: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} - dev: true - /mensch@0.3.4: + mensch@0.3.4: resolution: {integrity: sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==} - dev: true - /meow@12.1.1: + meow@12.1.1: resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} engines: {node: '>=16.10'} - dev: true - /merge-stream@2.0.0: + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true - /merge2@1.4.1: + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - dev: true - /mhchemparser@4.2.1: + mhchemparser@4.2.1: resolution: {integrity: sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==} - dev: true - - /micromark-util-character@2.0.1: - resolution: {integrity: sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==} - dependencies: - micromark-util-symbol: 2.0.0 - micromark-util-types: 2.0.0 - dev: false - - /micromark-util-encode@2.0.0: - resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} - dev: false - - /micromark-util-sanitize-uri@2.0.0: - resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} - dependencies: - micromark-util-character: 2.0.1 - micromark-util-encode: 2.0.0 - micromark-util-symbol: 2.0.0 - dev: false - - /micromark-util-symbol@2.0.0: - resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} - dev: false - /micromark-util-types@2.0.0: - resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} - dev: false - - /micromatch@4.0.5: + micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - dev: true - /mime-db@1.52.0: + mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} - dev: true - /mime-types@2.1.35: + mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: true - /mime@2.6.0: + mime@2.6.0: resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} engines: {node: '>=4.0.0'} hasBin: true - dev: true - /mimic-fn@2.1.0: + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - dev: true - /mimic-fn@4.0.0: + mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} - dev: true - /minimatch@3.1.2: + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - dev: true - /minimatch@5.1.6: + minimatch@5.1.6: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} - dependencies: - brace-expansion: 2.0.1 - dev: true - /minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} engines: {node: '>=16 || 14 >=14.17'} - dependencies: - brace-expansion: 2.0.1 - dev: true - /minimist@1.2.8: + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: true - /minipass@7.0.4: + minipass@7.0.4: resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} engines: {node: '>=16 || 14 >=14.17'} - dev: true - /minisearch@6.3.0: + minisearch@6.3.0: resolution: {integrity: sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ==} - dev: false - /mj-context-menu@0.6.1: + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + mj-context-menu@0.6.1: resolution: {integrity: sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==} - dev: true - /mlly@1.4.2: - resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==} - dependencies: - acorn: 8.11.2 - pathe: 1.1.1 - pkg-types: 1.0.3 - ufo: 1.3.2 - dev: true + mlly@1.6.1: + resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} - /mrmime@1.0.1: - resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} + mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} engines: {node: '>=10'} - /ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - dev: true - - /ms@2.1.2: + ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true - /muggle-string@0.3.1: - resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} - dev: true + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - /nanoid@3.3.7: + nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - /nanoid@5.0.3: - resolution: {integrity: sha512-I7X2b22cxA4LIHXPSqbBCEQSL+1wv8TuoefejsX4HFWyC6jc5JG7CEaxOltiKjc1M+YCS2YkrZZcj4+dytw9GA==} + nanoid@5.0.7: + resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==} engines: {node: ^18 || >=20} hasBin: true - dev: true - /negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - dev: true - - /neo-async@2.6.2: + neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - dev: true - /nice-try@1.0.5: + nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - dev: true - /node-fetch@2.7.0: + node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} peerDependencies: @@ -3550,1165 +2149,692 @@ packages: peerDependenciesMeta: encoding: optional: true - dependencies: - whatwg-url: 5.0.0 - dev: true - /normalize-package-data@2.5.0: + normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} - dependencies: - hosted-git-info: 2.8.9 - resolve: 1.22.8 - semver: 5.7.2 - validate-npm-package-license: 3.0.4 - dev: true - /normalize-package-data@6.0.0: + normalize-package-data@6.0.0: resolution: {integrity: sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==} engines: {node: ^16.14.0 || >=18.0.0} - dependencies: - hosted-git-info: 7.0.1 - is-core-module: 2.13.1 - semver: 7.5.4 - validate-npm-package-license: 3.0.4 - dev: true - /normalize-path@3.0.0: + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - dev: true - /npm-run-all@4.1.5: + npm-run-all@4.1.5: resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} engines: {node: '>= 4'} hasBin: true - dependencies: - ansi-styles: 3.2.1 - chalk: 2.4.2 - cross-spawn: 6.0.5 - memorystream: 0.3.1 - minimatch: 3.1.2 - pidtree: 0.3.1 - read-pkg: 3.0.0 - shell-quote: 1.8.1 - string.prototype.padend: 3.1.5 - dev: true - /npm-run-path@5.1.0: - resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - path-key: 4.0.0 - dev: true - /nth-check@2.1.1: + nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - dependencies: - boolbase: 1.0.0 - dev: true - /object-inspect@1.13.1: + object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} - dev: true - /object-keys@1.1.1: + object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} - dev: true - /object.assign@4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - has-symbols: 1.0.3 - object-keys: 1.1.1 - dev: true - - /on-headers@1.0.2: - resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} - engines: {node: '>= 0.8'} - dev: true - /once@1.4.0: + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - dev: true - /onetime@5.1.2: + onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} - dependencies: - mimic-fn: 2.1.0 - dev: true - /onetime@6.0.0: + onetime@6.0.0: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} - dependencies: - mimic-fn: 4.0.0 - dev: true - /ora@7.0.1: - resolution: {integrity: sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==} - engines: {node: '>=16'} - dependencies: - chalk: 5.3.0 - cli-cursor: 4.0.0 - cli-spinners: 2.9.2 - is-interactive: 2.0.0 - is-unicode-supported: 1.3.0 - log-symbols: 5.1.0 - stdin-discarder: 0.1.0 - string-width: 5.1.2 - strip-ansi: 7.1.0 - dev: true + open-cli@8.0.0: + resolution: {integrity: sha512-3muD3BbfLyzl+aMVSEfn2FfOqGdPYR0O4KNnxXsLEPE2q9OSjBfJAaB6XKbrUzLgymoSMejvb5jpXJfru/Ko2A==} + engines: {node: '>=18'} + hasBin: true + + open@10.1.0: + resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==} + engines: {node: '>=18'} + + ora@8.0.1: + resolution: {integrity: sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==} + engines: {node: '>=18'} - /p-limit@4.0.0: + p-limit@4.0.0: resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - yocto-queue: 1.0.0 - dev: true - /p-limit@5.0.0: + p-limit@5.0.0: resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} engines: {node: '>=18'} - dependencies: - yocto-queue: 1.0.0 - dev: true - /p-locate@6.0.0: + p-locate@6.0.0: resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - p-limit: 4.0.0 - dev: true - /parse-json@4.0.0: + p-map@7.0.2: + resolution: {integrity: sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==} + engines: {node: '>=18'} + + parse-json@4.0.0: resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} engines: {node: '>=4'} - dependencies: - error-ex: 1.3.2 - json-parse-better-errors: 1.0.2 - dev: true - /parse-json@7.1.1: + parse-json@7.1.1: resolution: {integrity: sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==} engines: {node: '>=16'} - dependencies: - '@babel/code-frame': 7.23.4 - error-ex: 1.3.2 - json-parse-even-better-errors: 3.0.0 - lines-and-columns: 2.0.4 - type-fest: 3.13.1 - dev: true - /parse5-htmlparser2-tree-adapter@6.0.1: + parse5-htmlparser2-tree-adapter@6.0.1: resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} - dependencies: - parse5: 6.0.1 - dev: true - /parse5@6.0.1: + parse5@6.0.1: resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} - dev: true - - /parse5@7.1.2: - resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} - dependencies: - entities: 4.5.0 - dev: false - /path-browserify@1.0.1: + path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - dev: true - /path-exists@5.0.0: + path-exists@5.0.0: resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - /path-key@2.0.1: + path-key@2.0.1: resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} engines: {node: '>=4'} - dev: true - /path-key@3.1.1: + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - dev: true - /path-key@4.0.0: + path-key@4.0.0: resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} engines: {node: '>=12'} - dev: true - /path-parse@1.0.7: + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true - /path-scurry@1.10.1: - resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} + path-scurry@1.10.2: + resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} engines: {node: '>=16 || 14 >=14.17'} - dependencies: - lru-cache: 10.1.0 - minipass: 7.0.4 - dev: true - /path-to-regexp@6.2.1: - resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} - dev: true + path-to-regexp@6.2.2: + resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} - /path-type@3.0.0: + path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} engines: {node: '>=4'} - dependencies: - pify: 3.0.0 - dev: true - /pathe@1.1.1: - resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} - dev: true + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - /pathval@1.1.1: + pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} - dev: true - /picocolors@1.0.0: + peek-readable@5.0.0: + resolution: {integrity: sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==} + engines: {node: '>=14.16'} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - /picomatch@2.3.1: + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - dev: true - /pidtree@0.3.1: + pidtree@0.3.1: resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} engines: {node: '>=0.10'} hasBin: true - dev: true - /pidtree@0.6.0: + pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} engines: {node: '>=0.10'} hasBin: true - dev: true - /pify@3.0.0: + pify@3.0.0: resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} engines: {node: '>=4'} - dev: true - /pkg-dir@8.0.0: + pkg-dir@8.0.0: resolution: {integrity: sha512-4peoBq4Wks0riS0z8741NVv+/8IiTvqnZAr8QGgtdifrtpdXbNw/FxRS1l6NFqm4EMzuS0EDqNNx4XGaz8cuyQ==} engines: {node: '>=18'} - dependencies: - find-up-simple: 1.0.0 - dev: true - /pkg-types@1.0.3: + pkg-types@1.0.3: resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} - dependencies: - jsonc-parser: 3.2.0 - mlly: 1.4.2 - pathe: 1.1.1 - dev: true - /playwright-chromium@1.40.0: - resolution: {integrity: sha512-LEObqtviC8ik5QM9dHcx3YYGxTl2bBrUnePHibHX/a7KVbkvt1P13b9oYHylytKBh8C84pg+D3yfs/t5MgGDpg==} + playwright-chromium@1.43.1: + resolution: {integrity: sha512-HL/11hcpIYVt/Rw7wTf5xwm+W0R76JGDDjRxGtBkgMuUqi0Q4UYmx+F/QxW/Z+aApSbDtHd3naRFcL/Jt7Aidg==} engines: {node: '>=16'} hasBin: true - requiresBuild: true - dependencies: - playwright-core: 1.40.0 - dev: true - /playwright-core@1.40.0: - resolution: {integrity: sha512-fvKewVJpGeca8t0ipM56jkVSU6Eo0RmFvQ/MaCQNDYm+sdvKkMBBWTE1FdeMqIdumRaXXjZChWHvIzCGM/tA/Q==} + playwright-core@1.43.1: + resolution: {integrity: sha512-EI36Mto2Vrx6VF7rm708qSnesVQKbxEWvPrfA1IPY6HgczBplDx7ENtx+K2n4kJ41sLLkuGfmb0ZLSSXlDhqPg==} engines: {node: '>=16'} hasBin: true - dev: true - /polka@1.0.0-next.23: - resolution: {integrity: sha512-19z2ny2aGdx+dns3icsQy6G7sWe0Dg7QTqSGE4B010EFbxvGzjjn37gBBjM8T0K2p6rthZ6+oXoBF3DcFceOPA==} + polka@1.0.0-next.25: + resolution: {integrity: sha512-LBgDEGL73aeb/5yAwO9JWsqCuqPdvEdwA/n25Y38F4kv6jqFaLbgIWVuZfsv9Sc9O052eoWWrAjGB75oCQvELw==} engines: {node: '>=8'} - dependencies: - '@polka/url': 1.0.0-next.23 - trouter: 3.2.1 - dev: true - /postcss-prefix-selector@1.16.0: + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postcss-prefix-selector@1.16.0: resolution: {integrity: sha512-rdVMIi7Q4B0XbXqNUEI+Z4E+pueiu/CS5E6vRCQommzdQ/sgsS4dK42U7GX8oJR+TJOtT+Qv3GkNo6iijUMp3Q==} peerDependencies: postcss: '>4 <9' - peerDependenciesMeta: - postcss: - optional: true - dev: true - - /postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} - engines: {node: ^10 || ^12 || >=14} - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.0 - source-map-js: 1.0.2 - dev: true - /postcss@8.4.32: - resolution: {integrity: sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==} + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} engines: {node: ^10 || ^12 || >=14} - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.0 - source-map-js: 1.0.2 - /preact@10.19.2: - resolution: {integrity: sha512-UA9DX/OJwv6YwP9Vn7Ti/vF80XL+YA5H2l7BpCtUr3ya8LWHFzpiO5R+N7dN16ujpIxhekRFuOOF82bXX7K/lg==} - dev: false + preact@10.20.2: + resolution: {integrity: sha512-S1d1ernz3KQ+Y2awUxKakpfOg2CEmJmwOP+6igPx6dgr6pgDvenqYviyokWso2rhHvGtTlWWnJDa7RaPbQerTg==} - /prettier@3.1.0: - resolution: {integrity: sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==} + prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} engines: {node: '>=14'} hasBin: true - dev: true - /pretty-format@29.7.0: + pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.2.0 - dev: true - /prompts@2.4.2: + prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - dev: true - /property-information@6.4.0: - resolution: {integrity: sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==} - dev: false - - /proxy-from-env@1.1.0: + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: true - /punycode@2.3.1: + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - dev: true - /queue-microtask@1.2.3: + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true - /react-is@18.2.0: + react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - dev: true - /read-pkg-up@10.1.0: + read-pkg-up@10.1.0: resolution: {integrity: sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==} engines: {node: '>=16'} - dependencies: - find-up: 6.3.0 - read-pkg: 8.1.0 - type-fest: 4.8.2 - dev: true - /read-pkg@3.0.0: + read-pkg@3.0.0: resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} engines: {node: '>=4'} - dependencies: - load-json-file: 4.0.0 - normalize-package-data: 2.5.0 - path-type: 3.0.0 - dev: true - /read-pkg@8.1.0: + read-pkg@8.1.0: resolution: {integrity: sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==} engines: {node: '>=16'} - dependencies: - '@types/normalize-package-data': 2.4.4 - normalize-package-data: 6.0.0 - parse-json: 7.1.1 - type-fest: 4.8.2 - dev: true - /readable-stream@3.6.2: + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - dev: true - /readdirp@3.6.0: + readable-web-to-node-stream@3.0.2: + resolution: {integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==} + engines: {node: '>=8'} + + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} - dependencies: - picomatch: 2.3.1 - dev: true - /regexp.prototype.flags@1.5.1: - resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} + regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - set-function-name: 2.0.1 - dev: true - /regexparam@1.3.0: - resolution: {integrity: sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==} - engines: {node: '>=6'} - dev: true + regexparam@3.0.0: + resolution: {integrity: sha512-RSYAtP31mvYLkAHrOlh25pCNQ5hWnT106VukGaaFfuJrZFkGRX5GhUAdPqpSDXxOhA2c4akmRuplv1mRqnBn6Q==} + engines: {node: '>=8'} - /resolve-pkg-maps@1.0.0: + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - dev: true - /resolve@1.22.8: + resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true - dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true - /restore-cursor@4.0.0: + restore-cursor@4.0.0: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - dev: true - /reusify@1.0.4: + reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true - /rfdc@1.3.0: - resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} - dev: true + rfdc@1.3.1: + resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} - /rimraf@5.0.5: + rimraf@5.0.5: resolution: {integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==} engines: {node: '>=14'} hasBin: true - dependencies: - glob: 10.3.10 - dev: true - /rollup-plugin-dts@6.1.0(rollup@4.5.2)(typescript@5.3.2): + rollup-plugin-dts@6.1.0: resolution: {integrity: sha512-ijSCPICkRMDKDLBK9torss07+8dl9UpY9z1N/zTeA1cIqdzMlpkV3MOOC7zukyvQfDyxa1s3Dl2+DeiP/G6DOw==} engines: {node: '>=16'} peerDependencies: rollup: ^3.29.4 || ^4 typescript: ^4.5 || ^5.0 - dependencies: - magic-string: 0.30.5 - rollup: 4.5.2 - typescript: 5.3.2 - optionalDependencies: - '@babel/code-frame': 7.23.4 - dev: true - /rollup-plugin-esbuild@6.1.0(esbuild@0.19.7)(rollup@4.5.2)(supports-color@9.4.0): - resolution: {integrity: sha512-HPpXU65V8bSpW8eSYPahtUJaJHmbxJGybuf/M8B3bz/6i11YaYHlNNJIQ38gSEV0FyohQOgVxJ2YMEEZtEmwvA==} + rollup-plugin-esbuild@6.1.1: + resolution: {integrity: sha512-CehMY9FAqJD5OUaE/Mi1r5z0kNeYxItmRO2zG4Qnv2qWKF09J2lTy5GUzjJR354ZPrLkCj4fiBN41lo8PzBUhw==} engines: {node: '>=14.18.0'} peerDependencies: esbuild: '>=0.18.0' rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 - dependencies: - '@rollup/pluginutils': 5.0.5(rollup@4.5.2) - debug: 4.3.4(supports-color@9.4.0) - es-module-lexer: 1.4.1 - esbuild: 0.19.7 - get-tsconfig: 4.7.2 - rollup: 4.5.2 - transitivePeerDependencies: - - supports-color - dev: true - /rollup@4.5.2: - resolution: {integrity: sha512-CRK1uoROBfkcqrZKyaFcqCcZWNsvJ6yVYZkqTlRocZhO2s5yER6Z3f/QaYtO8RGyloPnmhwgzuPQpNGeK210xQ==} + rollup@4.14.3: + resolution: {integrity: sha512-ag5tTQKYsj1bhrFC9+OEWqb5O6VYgtQDO9hPDBMmIbePwhfSr+ExlcU741t8Dhw5DkPCQf6noz0jb36D6W9/hw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.5.2 - '@rollup/rollup-android-arm64': 4.5.2 - '@rollup/rollup-darwin-arm64': 4.5.2 - '@rollup/rollup-darwin-x64': 4.5.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.5.2 - '@rollup/rollup-linux-arm64-gnu': 4.5.2 - '@rollup/rollup-linux-arm64-musl': 4.5.2 - '@rollup/rollup-linux-x64-gnu': 4.5.2 - '@rollup/rollup-linux-x64-musl': 4.5.2 - '@rollup/rollup-win32-arm64-msvc': 4.5.2 - '@rollup/rollup-win32-ia32-msvc': 4.5.2 - '@rollup/rollup-win32-x64-msvc': 4.5.2 - fsevents: 2.3.3 - /run-parallel@1.2.0: + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + engines: {node: '>=18'} + + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - dependencies: - queue-microtask: 1.2.3 - dev: true - /rxjs@7.8.1: + rxjs@7.8.1: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} - dependencies: - tslib: 2.6.2 - dev: true - /safe-array-concat@1.0.1: - resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} engines: {node: '>=0.4'} - dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - has-symbols: 1.0.3 - isarray: 2.0.5 - dev: true - - /safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - dev: true - /safe-buffer@5.2.1: + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true - /safe-regex-test@1.0.0: - resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} - dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - is-regex: 1.1.4 - dev: true + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} - /sax@1.3.0: + sax@1.3.0: resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==} - dev: true - /section-matter@1.0.0: + section-matter@1.0.0: resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} engines: {node: '>=4'} - dependencies: - extend-shallow: 2.0.1 - kind-of: 6.0.3 - dev: true - /semver@5.7.2: + semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true - dev: true - /semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} engines: {node: '>=10'} hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: true - /set-function-length@1.1.1: - resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} - dependencies: - define-data-property: 1.1.1 - get-intrinsic: 1.2.2 - gopd: 1.0.1 - has-property-descriptors: 1.0.1 - dev: true - /set-function-name@2.0.1: - resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} - dependencies: - define-data-property: 1.1.1 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.1 - dev: true - /shebang-command@1.2.0: + shebang-command@1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} - dependencies: - shebang-regex: 1.0.0 - dev: true - /shebang-command@2.0.0: + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - dev: true - /shebang-regex@1.0.0: + shebang-regex@1.0.0: resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} engines: {node: '>=0.10.0'} - dev: true - /shebang-regex@3.0.0: + shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - dev: true - /shell-quote@1.8.1: + shell-quote@1.8.1: resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} - dev: true - - /shikiji-transformers@0.7.4: - resolution: {integrity: sha512-oykilNekcW2FnRGbvZm+RNWHYroSeCVMOaMMwAbxozZgpTdcJtHoA+1+MDFw6/o2hCkX88kKbxG6FwAZoUZ6WQ==} - dependencies: - shikiji: 0.7.4 - dev: false - /shikiji@0.7.4: - resolution: {integrity: sha512-N5dmPvyhH/zfcsuWysUEAMwRJDMz26LUns2VEUs5y4Ozbf5jkAODU0Yswjcf/tZAwpFnk5x3y34dupFMnF2+NA==} - dependencies: - hast-util-to-html: 9.0.0 - dev: false + shiki@1.3.0: + resolution: {integrity: sha512-9aNdQy/etMXctnPzsje1h1XIGm9YfRcSksKOGqZWXA/qP9G18/8fpz5Bjpma8bOgz3tqIpjERAd6/lLjFyzoww==} - /side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - object-inspect: 1.13.1 - dev: true + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} - /siginfo@2.0.0: + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - dev: true - /signal-exit@3.0.7: + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: true - /signal-exit@4.1.0: + signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - dev: true - /simple-git-hooks@2.9.0: - resolution: {integrity: sha512-waSQ5paUQtyGC0ZxlHmcMmD9I1rRXauikBwX31bX58l5vTOhCEcBC5Bi+ZDkPXTjDnZAF8TbCqKBY+9+sVPScw==} + simple-git-hooks@2.11.1: + resolution: {integrity: sha512-tgqwPUMDcNDhuf1Xf6KTUsyeqGdgKMhzaH4PAZZuzguOgTl5uuyeYe/8mWgAr6IBxB5V06uqEf6Dy37gIWDtDg==} hasBin: true - requiresBuild: true - dev: true - /sirv@2.0.3: - resolution: {integrity: sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==} + simple-git@3.24.0: + resolution: {integrity: sha512-QqAKee9Twv+3k8IFOFfPB2hnk6as6Y6ACUpwCtQvRYBAes23Wv3SZlHVobAzqcE8gfsisCvPw3HGW3HYM+VYYw==} + + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} engines: {node: '>= 10'} - dependencies: - '@polka/url': 1.0.0-next.23 - mrmime: 1.0.1 - totalist: 3.0.1 - dev: true - /sisteransi@1.0.5: + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: true - /sitemap@7.1.1: + sitemap@7.1.1: resolution: {integrity: sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==} engines: {node: '>=12.0.0', npm: '>=5.6.0'} hasBin: true - dependencies: - '@types/node': 17.0.45 - '@types/sax': 1.2.7 - arg: 5.0.2 - sax: 1.3.0 - dev: true - /slash@4.0.0: + slash@4.0.0: resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} engines: {node: '>=12'} - dev: true - /slice-ansi@5.0.0: + slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} - dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 4.0.0 - dev: true - /slick@1.12.2: + slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + + slick@1.12.2: resolution: {integrity: sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==} - dev: true - /source-map-js@1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + sort-object-keys@1.1.3: + resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==} + + sort-package-json@2.10.0: + resolution: {integrity: sha512-MYecfvObMwJjjJskhxYfuOADkXp1ZMMnCFC8yhp+9HDsk7HhR336hd7eiBs96lTXfiqmUNI+WQCeCMRBhl251g==} + hasBin: true + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} - /source-map@0.6.1: + source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - dev: true - /space-separated-tokens@2.0.2: - resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - dev: false - - /spdx-correct@3.2.0: + spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} - dependencies: - spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.16 - dev: true - /spdx-exceptions@2.3.0: - resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} - dev: true + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} - /spdx-expression-parse@3.0.1: + spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - dependencies: - spdx-exceptions: 2.3.0 - spdx-license-ids: 3.0.16 - dev: true - /spdx-license-ids@3.0.16: - resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==} - dev: true + spdx-license-ids@3.0.17: + resolution: {integrity: sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==} - /speech-rule-engine@4.0.7: + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + + speech-rule-engine@4.0.7: resolution: {integrity: sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==} hasBin: true - dependencies: - commander: 9.2.0 - wicked-good-xpath: 1.3.0 - xmldom-sre: 0.1.31 - dev: true - /split2@4.2.0: + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} - dev: true - /sprintf-js@1.0.3: + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: true - /stackback@0.0.2: + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - dev: true - /std-env@3.5.0: - resolution: {integrity: sha512-JGUEaALvL0Mf6JCfYnJOTcobY+Nc7sG/TemDRBqCA0wEr4DER7zDchaaixTlmOxAjG1uRJmX82EQcxwTQTkqVA==} - dev: true + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} - /stdin-discarder@0.1.0: - resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - bl: 5.1.0 - dev: true + stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} - /string-argv@0.3.2: + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} - dev: true - /string-width@4.2.3: + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - dev: true - /string-width@5.1.2: + string-width@5.1.2: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - dev: true - /string.prototype.padend@3.1.5: - resolution: {integrity: sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==} + string-width@7.1.0: + resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} + engines: {node: '>=18'} + + string.prototype.padend@3.1.6: + resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - dev: true - /string.prototype.trim@1.2.8: - resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - dev: true - /string.prototype.trimend@1.0.7: - resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} - dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - dev: true + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} - /string.prototype.trimstart@1.0.7: - resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} - dependencies: - call-bind: 1.0.5 - define-properties: 1.2.1 - es-abstract: 1.22.3 - dev: true + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} - /string_decoder@1.3.0: + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - dependencies: - safe-buffer: 5.2.1 - dev: true - - /stringify-entities@4.0.3: - resolution: {integrity: sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==} - dependencies: - character-entities-html4: 2.1.0 - character-entities-legacy: 3.0.0 - dev: false - /strip-ansi@6.0.1: + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - dev: true - /strip-ansi@7.1.0: + strip-ansi@7.1.0: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} - dependencies: - ansi-regex: 6.0.1 - dev: true - /strip-bom-string@1.0.0: + strip-bom-string@1.0.0: resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} engines: {node: '>=0.10.0'} - dev: true - /strip-bom@3.0.0: + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} - dev: true - /strip-final-newline@3.0.0: + strip-final-newline@3.0.0: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} - dev: true - /strip-literal@1.3.0: - resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} - dependencies: - acorn: 8.11.2 - dev: true + strip-literal@2.1.0: + resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} + + strtok3@7.0.0: + resolution: {integrity: sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==} + engines: {node: '>=14.16'} - /supports-color@5.5.0: + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} - dependencies: - has-flag: 3.0.0 - dev: true - /supports-color@9.4.0: + supports-color@9.4.0: resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==} engines: {node: '>=12'} - dev: true - /supports-preserve-symlinks-flag@1.0.0: + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - dev: true - /tabbable@6.2.0: + tabbable@6.2.0: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} - dev: false - /temp-dir@3.0.0: + temp-dir@3.0.0: resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} engines: {node: '>=14.16'} - dev: true - /tempfile@5.0.0: + tempfile@5.0.0: resolution: {integrity: sha512-bX655WZI/F7EoTDw9JvQURqAXiPHi8o8+yFxPF2lWYyz1aHnmMRuXWqL6YB6GmeO0o4DIYWHLgGNi/X64T+X4Q==} engines: {node: '>=14.18'} - dependencies: - temp-dir: 3.0.0 - dev: true - /text-extensions@2.4.0: + tempy@3.1.0: + resolution: {integrity: sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==} + engines: {node: '>=14.16'} + + text-extensions@2.4.0: resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} engines: {node: '>=8'} - dev: true - /through@2.3.8: + through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true - /tinybench@2.5.1: - resolution: {integrity: sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==} - dev: true + tinybench@2.7.0: + resolution: {integrity: sha512-Qgayeb106x2o4hNzNjsZEfFziw8IbKqtbXBjVh7VIZfBxfD5M4gWtpyx5+YTae2gJ6Y6Dz/KLepiv16RFeQWNA==} - /tinypool@0.8.1: - resolution: {integrity: sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==} + tinypool@0.8.4: + resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} engines: {node: '>=14.0.0'} - dev: true - /tinyspy@2.2.0: - resolution: {integrity: sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==} + tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} engines: {node: '>=14.0.0'} - dev: true - /to-fast-properties@2.0.0: + to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} - /to-regex-range@5.0.1: + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - dependencies: - is-number: 7.0.0 - dev: true - /totalist@3.0.1: + token-types@5.0.1: + resolution: {integrity: sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==} + engines: {node: '>=14.16'} + + totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} - dev: true - /tr46@0.0.3: + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: true - - /trim-lines@3.0.1: - resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} - dev: false - /trouter@3.2.1: - resolution: {integrity: sha512-oY3CmIiEYOe1YMEzh++I67lrNOUldtCeuLL0vRPydvQLHZpSJ03B5dgDFlpFsiriMq6e//NDjjopjUzXOztHow==} + trouter@4.0.0: + resolution: {integrity: sha512-bwwr76BThfiVwAFZqks5cJ+VoKNM3/2Yg1ZwJslkdmAUQ6S0UNoCoGYFDxdw+u1skfexggdmD2p35kW5Td4Cug==} engines: {node: '>=6'} - dependencies: - regexparam: 1.3.0 - dev: true - /tslib@2.6.2: + tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - dev: true - /type-detect@4.0.8: + type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} - dev: true - /type-fest@1.4.0: + type-fest@1.4.0: resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} engines: {node: '>=10'} - dev: true - /type-fest@3.13.1: + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-fest@3.13.1: resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} engines: {node: '>=14.16'} - dev: true - /type-fest@4.8.2: - resolution: {integrity: sha512-mcvrCjixA5166hSrUoJgGb9gBQN4loMYyj9zxuMs/66ibHNEFd5JXMw37YVDx58L4/QID9jIzdTBB4mDwDJ6KQ==} + type-fest@4.15.0: + resolution: {integrity: sha512-tB9lu0pQpX5KJq54g+oHOLumOx+pMep4RaM6liXh2PKmVRFF+/vAtUP0ZaJ0kOySfVNjF6doBWPHhBhISKdlIA==} engines: {node: '>=16'} - dev: true - /typed-array-buffer@1.0.0: - resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - is-typed-array: 1.1.12 - dev: true - /typed-array-byte-length@1.0.0: - resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.5 - for-each: 0.3.3 - has-proto: 1.0.1 - is-typed-array: 1.1.12 - dev: true - /typed-array-byte-offset@1.0.0: - resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 - for-each: 0.3.3 - has-proto: 1.0.1 - is-typed-array: 1.1.12 - dev: true - /typed-array-length@1.0.4: - resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} - dependencies: - call-bind: 1.0.5 - for-each: 0.3.3 - is-typed-array: 1.1.12 - dev: true + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} - /typescript@5.3.2: - resolution: {integrity: sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==} + typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} engines: {node: '>=14.17'} hasBin: true - /uc.micro@1.0.6: - resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} - dev: true + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - /ufo@1.3.2: - resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} - dev: true + ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} - /uglify-js@3.17.4: + uglify-js@3.17.4: resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} engines: {node: '>=0.8.0'} hasBin: true - requiresBuild: true - dev: true - optional: true - /unbox-primitive@1.0.2: + ultramatter@0.0.4: + resolution: {integrity: sha512-1f/hO3mR+/Hgue4eInOF/Qm/wzDqwhYha4DxM0hre9YIUyso3fE2XtrAU6B4njLqTC8CM49EZaYgsVSa+dXHGw==} + + unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - dependencies: - call-bind: 1.0.5 - has-bigints: 1.0.2 - has-symbols: 1.0.3 - which-boxed-primitive: 1.0.2 - dev: true - /undici-types@5.26.5: + undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - /unist-util-is@6.0.0: - resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} - dependencies: - '@types/unist': 3.0.2 - dev: false - - /unist-util-position@5.0.0: - resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} - dependencies: - '@types/unist': 3.0.2 - dev: false - - /unist-util-stringify-position@4.0.0: - resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} - dependencies: - '@types/unist': 3.0.2 - dev: false - - /unist-util-visit-parents@6.0.1: - resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} - dependencies: - '@types/unist': 3.0.2 - unist-util-is: 6.0.0 - dev: false - - /unist-util-visit@5.0.0: - resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} - dependencies: - '@types/unist': 3.0.2 - unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 - dev: false + unique-string@3.0.0: + resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} + engines: {node: '>=12'} - /universalify@2.0.1: + universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} - dev: true - /util-deprecate@1.0.2: + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: true - /valid-data-url@3.0.1: + valid-data-url@3.0.1: resolution: {integrity: sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==} engines: {node: '>=10'} - dev: true - /validate-npm-package-license@3.0.4: + validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - dependencies: - spdx-correct: 3.2.0 - spdx-expression-parse: 3.0.1 - dev: true - - /vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - dev: true - - /vfile-location@5.0.2: - resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==} - dependencies: - '@types/unist': 3.0.2 - vfile: 6.0.1 - dev: false - - /vfile-message@4.0.2: - resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} - dependencies: - '@types/unist': 3.0.2 - unist-util-stringify-position: 4.0.0 - dev: false - - /vfile@6.0.1: - resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} - dependencies: - '@types/unist': 3.0.2 - unist-util-stringify-position: 4.0.0 - vfile-message: 4.0.2 - dev: false - /vite-node@1.0.0-beta.5(@types/node@20.10.0)(supports-color@9.4.0): - resolution: {integrity: sha512-iXm+GTJbR9R6V/bCM1+LQqIohL/tncZVNGIcTtzpYThBD8yiTkDPvEjy1Mf7KFACtG3qY/0VDMrkuMtqG/JFhg==} + vite-node@1.5.0: + resolution: {integrity: sha512-tV8h6gMj6vPzVCa7l+VGq9lwoJjW8Y79vst8QZZGiuRAfijU+EEWuc0kFpmndQrWhMMhet1jdSF+40KSZUqIIw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - dependencies: - cac: 6.7.14 - debug: 4.3.4(supports-color@9.4.0) - pathe: 1.1.1 - picocolors: 1.0.0 - vite: 5.0.5(@types/node@20.10.0) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - dev: true - /vite@5.0.5(@types/node@20.10.0): - resolution: {integrity: sha512-OekeWqR9Ls56f3zd4CaxzbbS11gqYkEiBtnWFFgYR2WV8oPJRRKq0mpskYy/XaoCL3L7VINDhqqOMNDiYdGvGg==} + vite@5.2.9: + resolution: {integrity: sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -4734,23 +2860,16 @@ packages: optional: true terser: optional: true - dependencies: - '@types/node': 20.10.0 - esbuild: 0.19.7 - postcss: 8.4.32 - rollup: 4.5.2 - optionalDependencies: - fsevents: 2.3.3 - /vitest@1.0.0-beta.5(@types/node@20.10.0)(supports-color@9.4.0): - resolution: {integrity: sha512-wmrGmXMKysR+JBvIwy0COgLrRSsZTR00dN+IpWBxGC4ACF5Mt/uYyrPLJZ0ixK4P3bxI16vd92JXMsuGnm9gQQ==} + vitest@1.5.0: + resolution: {integrity: sha512-d8UKgR0m2kjdxDWX6911uwxout6GHS0XaGH1cksSIVVG8kRlE7G7aBw7myKQCvDI5dT4j7ZMa+l706BIORMDLw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': '*' - '@vitest/ui': '*' + '@vitest/browser': 1.5.0 + '@vitest/ui': 1.5.0 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -4766,226 +2885,2891 @@ packages: optional: true jsdom: optional: true - dependencies: - '@types/node': 20.10.0 - '@vitest/expect': 1.0.0-beta.5 - '@vitest/runner': 1.0.0-beta.5 - '@vitest/snapshot': 1.0.0-beta.5 - '@vitest/spy': 1.0.0-beta.5 - '@vitest/utils': 1.0.0-beta.5 - acorn-walk: 8.3.0 - cac: 6.7.14 - chai: 4.3.10 - debug: 4.3.4(supports-color@9.4.0) - execa: 8.0.1 - local-pkg: 0.5.0 - magic-string: 0.30.5 - pathe: 1.1.1 - picocolors: 1.0.0 - std-env: 3.5.0 - strip-literal: 1.3.0 - tinybench: 2.5.1 - tinypool: 0.8.1 - vite: 5.0.5(@types/node@20.10.0) - vite-node: 1.0.0-beta.5(@types/node@20.10.0)(supports-color@9.4.0) - why-is-node-running: 2.2.2 - transitivePeerDependencies: - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - dev: true - /vue-demi@0.14.6(vue@3.3.8): - resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==} + vue-demi@0.14.7: + resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==} engines: {node: '>=12'} hasBin: true - requiresBuild: true peerDependencies: '@vue/composition-api': ^1.0.0-rc.1 vue: ^3.0.0-0 || ^2.6.0 peerDependenciesMeta: '@vue/composition-api': optional: true - dependencies: - vue: 3.3.8(typescript@5.3.2) - dev: false - /vue-template-compiler@2.7.15: - resolution: {integrity: sha512-yQxjxMptBL7UAog00O8sANud99C6wJF+7kgbcwqkvA38vCGF7HWE66w0ZFnS/kX5gSoJr/PQ4/oS3Ne2pW37Og==} - dependencies: - de-indent: 1.0.2 - he: 1.2.0 - dev: true + vue-template-compiler@2.7.16: + resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} - /vue-tsc@1.8.22(typescript@5.3.2): - resolution: {integrity: sha512-j9P4kHtW6eEE08aS5McFZE/ivmipXy0JzrnTgbomfABMaVKx37kNBw//irL3+LlE3kOo63XpnRigyPC3w7+z+A==} + vue-tsc@2.0.13: + resolution: {integrity: sha512-a3nL3FvguCWVJUQW/jFrUxdeUtiEkbZoQjidqvMeBK//tuE2w6NWQAbdrEpY2+6nSa4kZoKZp8TZUMtHpjt4mQ==} hasBin: true peerDependencies: typescript: '*' - dependencies: - '@volar/typescript': 1.10.10 - '@vue/language-core': 1.8.22(typescript@5.3.2) - semver: 7.5.4 - typescript: 5.3.2 - dev: true - /vue@3.3.8(typescript@5.3.2): - resolution: {integrity: sha512-5VSX/3DabBikOXMsxzlW8JyfeLKlG9mzqnWgLQLty88vdZL7ZJgrdgBOmrArwxiLtmS+lNNpPcBYqrhE6TQW5w==} + vue@3.4.23: + resolution: {integrity: sha512-X1y6yyGJ28LMUBJ0k/qIeKHstGd+BlWQEOT40x3auJFTmpIhpbKLgN7EFsqalnJXq1Km5ybDEsp6BhuWKciUDg==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - dependencies: - '@vue/compiler-dom': 3.3.8 - '@vue/compiler-sfc': 3.3.8 - '@vue/runtime-dom': 3.3.8 - '@vue/server-renderer': 3.3.8(vue@3.3.8) - '@vue/shared': 3.3.8 - typescript: 5.3.2 - dev: false - /wait-on@7.2.0(debug@4.3.4): + wait-on@7.2.0: resolution: {integrity: sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==} engines: {node: '>=12.0.0'} hasBin: true - dependencies: - axios: 1.6.2(debug@4.3.4) - joi: 17.11.0 - lodash: 4.17.21 - minimist: 1.2.8 - rxjs: 7.8.1 - transitivePeerDependencies: - - debug - dev: true - - /web-namespaces@2.0.1: - resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} - dev: false - /web-resource-inliner@6.0.1: + web-resource-inliner@6.0.1: resolution: {integrity: sha512-kfqDxt5dTB1JhqsCUQVFDj0rmY+4HLwGQIsLPbyrsN9y9WV/1oFDSx3BQ4GfCv9X+jVeQ7rouTqwK53rA/7t8A==} engines: {node: '>=10.0.0'} - dependencies: - ansi-colors: 4.1.3 - escape-goat: 3.0.0 - htmlparser2: 5.0.1 - mime: 2.6.0 - node-fetch: 2.7.0 - valid-data-url: 3.0.1 - transitivePeerDependencies: - - encoding - dev: true - /webidl-conversions@3.0.1: + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: true - /whatwg-url@5.0.0: + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - dev: true - /which-boxed-primitive@1.0.2: + which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} - dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.7 - is-string: 1.0.7 - is-symbol: 1.0.4 - dev: true - /which-typed-array@1.1.13: - resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.0 - dev: true - /which@1.3.1: + which@1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} hasBin: true - dependencies: - isexe: 2.0.0 - dev: true - /which@2.0.2: + which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true - dependencies: - isexe: 2.0.0 - dev: true - /why-is-node-running@2.2.2: + why-is-node-running@2.2.2: resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} engines: {node: '>=8'} hasBin: true - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - dev: true - /wicked-good-xpath@1.3.0: + wicked-good-xpath@1.3.0: resolution: {integrity: sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw==} - dev: true - /wordwrap@1.0.0: + wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - dev: true - /wrap-ansi@7.0.0: + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - /wrap-ansi@8.1.0: + wrap-ansi@8.1.0: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - dev: true - /wrappy@1.0.2: + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true - /xmldom-sre@0.1.31: + xmldom-sre@0.1.31: resolution: {integrity: sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==} engines: {node: '>=0.1'} - dev: true - /yallist@4.0.0: + yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true - /yaml@2.3.4: + yaml@2.3.4: resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} engines: {node: '>= 14'} - dev: true - /yocto-queue@1.0.0: + yocto-queue@1.0.0: resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} engines: {node: '>=12.20'} - dev: true - /zwitch@2.0.4: - resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - dev: false + zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + +snapshots: + + '@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)': + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + + '@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)': + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)': + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) + '@algolia/client-search': 4.23.3 + algoliasearch: 4.23.3 + + '@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)': + dependencies: + '@algolia/client-search': 4.23.3 + algoliasearch: 4.23.3 + + '@algolia/cache-browser-local-storage@4.23.3': + dependencies: + '@algolia/cache-common': 4.23.3 + + '@algolia/cache-common@4.23.3': {} + + '@algolia/cache-in-memory@4.23.3': + dependencies: + '@algolia/cache-common': 4.23.3 + + '@algolia/client-account@4.23.3': + dependencies: + '@algolia/client-common': 4.23.3 + '@algolia/client-search': 4.23.3 + '@algolia/transporter': 4.23.3 + + '@algolia/client-analytics@4.23.3': + dependencies: + '@algolia/client-common': 4.23.3 + '@algolia/client-search': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/transporter': 4.23.3 + + '@algolia/client-common@4.23.3': + dependencies: + '@algolia/requester-common': 4.23.3 + '@algolia/transporter': 4.23.3 + + '@algolia/client-personalization@4.23.3': + dependencies: + '@algolia/client-common': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/transporter': 4.23.3 + + '@algolia/client-search@4.23.3': + dependencies: + '@algolia/client-common': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/transporter': 4.23.3 + + '@algolia/logger-common@4.23.3': {} + + '@algolia/logger-console@4.23.3': + dependencies: + '@algolia/logger-common': 4.23.3 + + '@algolia/recommend@4.23.3': + dependencies: + '@algolia/cache-browser-local-storage': 4.23.3 + '@algolia/cache-common': 4.23.3 + '@algolia/cache-in-memory': 4.23.3 + '@algolia/client-common': 4.23.3 + '@algolia/client-search': 4.23.3 + '@algolia/logger-common': 4.23.3 + '@algolia/logger-console': 4.23.3 + '@algolia/requester-browser-xhr': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/requester-node-http': 4.23.3 + '@algolia/transporter': 4.23.3 + + '@algolia/requester-browser-xhr@4.23.3': + dependencies: + '@algolia/requester-common': 4.23.3 + + '@algolia/requester-common@4.23.3': {} + + '@algolia/requester-node-http@4.23.3': + dependencies: + '@algolia/requester-common': 4.23.3 + + '@algolia/transporter@4.23.3': + dependencies: + '@algolia/cache-common': 4.23.3 + '@algolia/logger-common': 4.23.3 + '@algolia/requester-common': 4.23.3 + + '@babel/code-frame@7.24.2': + dependencies: + '@babel/highlight': 7.24.2 + picocolors: 1.0.0 + + '@babel/helper-string-parser@7.24.1': {} + + '@babel/helper-validator-identifier@7.22.20': {} + + '@babel/highlight@7.24.2': + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.0 + + '@babel/parser@7.24.4': + dependencies: + '@babel/types': 7.24.0 + + '@babel/types@7.24.0': + dependencies: + '@babel/helper-string-parser': 7.24.1 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + + '@clack/core@0.3.4': + dependencies: + picocolors: 1.0.0 + sisteransi: 1.0.5 + + '@clack/prompts@0.7.0': + dependencies: + '@clack/core': 0.3.4 + picocolors: 1.0.0 + sisteransi: 1.0.5 + + '@docsearch/css@3.6.0': {} + + '@docsearch/js@3.6.0(@algolia/client-search@4.23.3)': + dependencies: + '@docsearch/react': 3.6.0(@algolia/client-search@4.23.3) + preact: 10.20.2 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/react' + - react + - react-dom + - search-insights + + '@docsearch/react@3.6.0(@algolia/client-search@4.23.3)': + dependencies: + '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) + '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) + '@docsearch/css': 3.6.0 + algoliasearch: 4.23.3 + transitivePeerDependencies: + - '@algolia/client-search' + + '@esbuild/aix-ppc64@0.20.2': + optional: true + + '@esbuild/android-arm64@0.20.2': + optional: true + + '@esbuild/android-arm@0.20.2': + optional: true + + '@esbuild/android-x64@0.20.2': + optional: true + + '@esbuild/darwin-arm64@0.20.2': + optional: true + + '@esbuild/darwin-x64@0.20.2': + optional: true + + '@esbuild/freebsd-arm64@0.20.2': + optional: true + + '@esbuild/freebsd-x64@0.20.2': + optional: true + + '@esbuild/linux-arm64@0.20.2': + optional: true + + '@esbuild/linux-arm@0.20.2': + optional: true + + '@esbuild/linux-ia32@0.20.2': + optional: true + + '@esbuild/linux-loong64@0.20.2': + optional: true + + '@esbuild/linux-mips64el@0.20.2': + optional: true + + '@esbuild/linux-ppc64@0.20.2': + optional: true + + '@esbuild/linux-riscv64@0.20.2': + optional: true + + '@esbuild/linux-s390x@0.20.2': + optional: true + + '@esbuild/linux-x64@0.20.2': + optional: true + + '@esbuild/netbsd-x64@0.20.2': + optional: true + + '@esbuild/openbsd-x64@0.20.2': + optional: true + + '@esbuild/sunos-x64@0.20.2': + optional: true + + '@esbuild/win32-arm64@0.20.2': + optional: true + + '@esbuild/win32-ia32@0.20.2': + optional: true + + '@esbuild/win32-x64@0.20.2': + optional: true + + '@hapi/hoek@9.3.0': {} + + '@hapi/topo@5.1.0': + dependencies: + '@hapi/hoek': 9.3.0 + + '@hutson/parse-repository-url@5.0.0': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@kwsites/file-exists@1.1.1(supports-color@9.4.0)': + dependencies: + debug: 4.3.4(supports-color@9.4.0) + transitivePeerDependencies: + - supports-color + + '@kwsites/promise-deferred@1.1.1': {} + + '@lunariajs/core@0.0.32(supports-color@9.4.0)': + dependencies: + '@clack/core': 0.3.4 + fast-glob: 3.3.2 + get-port: 7.1.0 + jiti: 1.21.0 + micromatch: 4.0.5 + path-to-regexp: 6.2.2 + picocolors: 1.0.0 + simple-git: 3.24.0(supports-color@9.4.0) + ultramatter: 0.0.4 + zod: 3.22.4 + transitivePeerDependencies: + - supports-color + + '@mdit-vue/plugin-component@2.1.2': + dependencies: + '@types/markdown-it': 14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje) + markdown-it: 14.1.0 + + '@mdit-vue/plugin-frontmatter@2.1.2': + dependencies: + '@mdit-vue/types': 2.1.0 + '@types/markdown-it': 14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje) + gray-matter: 4.0.3 + markdown-it: 14.1.0 + + '@mdit-vue/plugin-headers@2.1.2': + dependencies: + '@mdit-vue/shared': 2.1.2 + '@mdit-vue/types': 2.1.0 + '@types/markdown-it': 14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje) + markdown-it: 14.1.0 + + '@mdit-vue/plugin-sfc@2.1.2': + dependencies: + '@mdit-vue/types': 2.1.0 + '@types/markdown-it': 14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje) + markdown-it: 14.1.0 + + '@mdit-vue/plugin-title@2.1.2': + dependencies: + '@mdit-vue/shared': 2.1.2 + '@mdit-vue/types': 2.1.0 + '@types/markdown-it': 14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje) + markdown-it: 14.1.0 + + '@mdit-vue/plugin-toc@2.1.2': + dependencies: + '@mdit-vue/shared': 2.1.2 + '@mdit-vue/types': 2.1.0 + '@types/markdown-it': 14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje) + markdown-it: 14.1.0 + + '@mdit-vue/shared@2.1.2': + dependencies: + '@mdit-vue/types': 2.1.0 + '@types/markdown-it': 14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje) + markdown-it: 14.1.0 + + '@mdit-vue/types@2.1.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@polka/compression@1.0.0-next.25': {} + + '@polka/url@1.0.0-next.25': {} + + '@rollup/plugin-alias@5.1.0(rollup@4.14.3)': + dependencies: + slash: 4.0.0 + optionalDependencies: + rollup: 4.14.3 + + '@rollup/plugin-commonjs@25.0.7(rollup@4.14.3)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.14.3) + commondir: 1.0.1 + estree-walker: 2.0.2 + glob: 8.1.0 + is-reference: 1.2.1 + magic-string: 0.30.10 + optionalDependencies: + rollup: 4.14.3 + + '@rollup/plugin-json@6.1.0(rollup@4.14.3)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.14.3) + optionalDependencies: + rollup: 4.14.3 + + '@rollup/plugin-node-resolve@15.2.3(rollup@4.14.3)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.14.3) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-builtin-module: 3.2.1 + is-module: 1.0.0 + resolve: 1.22.8 + optionalDependencies: + rollup: 4.14.3 + + '@rollup/plugin-replace@5.0.5(rollup@4.14.3)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.14.3) + magic-string: 0.30.10 + optionalDependencies: + rollup: 4.14.3 + + '@rollup/pluginutils@5.1.0(rollup@4.14.3)': + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: 4.14.3 + + '@rollup/rollup-android-arm-eabi@4.14.3': + optional: true + + '@rollup/rollup-android-arm64@4.14.3': + optional: true + + '@rollup/rollup-darwin-arm64@4.14.3': + optional: true + + '@rollup/rollup-darwin-x64@4.14.3': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.14.3': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.14.3': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.14.3': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.14.3': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.14.3': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.14.3': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.14.3': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.14.3': + optional: true + + '@rollup/rollup-linux-x64-musl@4.14.3': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.14.3': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.14.3': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.14.3': + optional: true + + '@shikijs/core@1.3.0': {} + + '@shikijs/transformers@1.3.0': + dependencies: + shiki: 1.3.0 + + '@sideway/address@4.1.5': + dependencies: + '@hapi/hoek': 9.3.0 + + '@sideway/formula@3.0.1': {} + + '@sideway/pinpoint@2.0.0': {} + + '@sinclair/typebox@0.27.8': {} + + '@tokenizer/token@0.3.0': {} + + '@types/braces@3.0.4': {} + + '@types/cross-spawn@6.0.6': + dependencies: + '@types/node': 20.12.7 + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 0.7.34 + + '@types/escape-html@1.0.4': {} + + '@types/estree@1.0.5': {} + + '@types/fs-extra@11.0.4': + dependencies: + '@types/jsonfile': 6.1.4 + '@types/node': 20.12.7 + + '@types/jquery@3.5.29': + dependencies: + '@types/sizzle': 2.3.8 + + '@types/jsonfile@6.1.4': + dependencies: + '@types/node': 20.12.7 + + '@types/linkify-it@3.0.5': {} + + '@types/lodash.template@4.5.3': + dependencies: + '@types/lodash': 4.17.0 + + '@types/lodash@4.17.0': {} + + '@types/mark.js@8.11.12': + dependencies: + '@types/jquery': 3.5.29 + + '@types/markdown-it-attrs@4.1.3': + dependencies: + '@types/markdown-it': 14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje) + + '@types/markdown-it-container@2.0.10': + dependencies: + '@types/markdown-it': 14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje) + + '@types/markdown-it-emoji@2.0.5': + dependencies: + '@types/markdown-it': 14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje) + + '@types/markdown-it@14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje)': + dependencies: + '@types/linkify-it': 3.0.5 + '@types/mdurl': 1.0.5 + + '@types/mdurl@1.0.5': {} + + '@types/micromatch@4.0.7': + dependencies: + '@types/braces': 3.0.4 + + '@types/minimist@1.2.5': {} + + '@types/ms@0.7.34': {} + + '@types/node@17.0.45': {} + + '@types/node@20.12.7': + dependencies: + undici-types: 5.26.5 + + '@types/normalize-package-data@2.4.4': {} + + '@types/postcss-prefix-selector@1.16.3': + dependencies: + postcss: 8.4.38 + + '@types/prompts@2.4.9': + dependencies: + '@types/node': 20.12.7 + kleur: 3.0.3 + + '@types/resolve@1.20.2': {} + + '@types/sax@1.2.7': + dependencies: + '@types/node': 20.12.7 + + '@types/sizzle@2.3.8': {} + + '@types/web-bluetooth@0.0.20': {} + + '@vitejs/plugin-vue@5.0.4(vite@5.2.9(@types/node@20.12.7))(vue@3.4.23(typescript@5.4.5))': + dependencies: + vite: 5.2.9(@types/node@20.12.7) + vue: 3.4.23(typescript@5.4.5) + + '@vitest/expect@1.5.0': + dependencies: + '@vitest/spy': 1.5.0 + '@vitest/utils': 1.5.0 + chai: 4.4.1 + + '@vitest/runner@1.5.0': + dependencies: + '@vitest/utils': 1.5.0 + p-limit: 5.0.0 + pathe: 1.1.2 + + '@vitest/snapshot@1.5.0': + dependencies: + magic-string: 0.30.10 + pathe: 1.1.2 + pretty-format: 29.7.0 + + '@vitest/spy@1.5.0': + dependencies: + tinyspy: 2.2.1 + + '@vitest/utils@1.5.0': + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + + '@volar/language-core@2.2.0-alpha.8': + dependencies: + '@volar/source-map': 2.2.0-alpha.8 + + '@volar/source-map@2.2.0-alpha.8': + dependencies: + muggle-string: 0.4.1 + + '@volar/typescript@2.2.0-alpha.8': + dependencies: + '@volar/language-core': 2.2.0-alpha.8 + path-browserify: 1.0.1 + + '@vue/compiler-core@3.4.23': + dependencies: + '@babel/parser': 7.24.4 + '@vue/shared': 3.4.23 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + + '@vue/compiler-dom@3.4.23': + dependencies: + '@vue/compiler-core': 3.4.23 + '@vue/shared': 3.4.23 + + '@vue/compiler-sfc@3.4.23': + dependencies: + '@babel/parser': 7.24.4 + '@vue/compiler-core': 3.4.23 + '@vue/compiler-dom': 3.4.23 + '@vue/compiler-ssr': 3.4.23 + '@vue/shared': 3.4.23 + estree-walker: 2.0.2 + magic-string: 0.30.10 + postcss: 8.4.38 + source-map-js: 1.2.0 + + '@vue/compiler-ssr@3.4.23': + dependencies: + '@vue/compiler-dom': 3.4.23 + '@vue/shared': 3.4.23 + + '@vue/devtools-api@7.0.27(vue@3.4.23(typescript@5.4.5))': + dependencies: + '@vue/devtools-kit': 7.0.27(vue@3.4.23(typescript@5.4.5)) + transitivePeerDependencies: + - vue + + '@vue/devtools-kit@7.0.27(vue@3.4.23(typescript@5.4.5))': + dependencies: + '@vue/devtools-shared': 7.0.27 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + vue: 3.4.23(typescript@5.4.5) + + '@vue/devtools-shared@7.0.27': + dependencies: + rfdc: 1.3.1 + + '@vue/language-core@2.0.13(typescript@5.4.5)': + dependencies: + '@volar/language-core': 2.2.0-alpha.8 + '@vue/compiler-dom': 3.4.23 + '@vue/shared': 3.4.23 + computeds: 0.0.1 + minimatch: 9.0.4 + path-browserify: 1.0.1 + vue-template-compiler: 2.7.16 + optionalDependencies: + typescript: 5.4.5 + + '@vue/reactivity@3.4.23': + dependencies: + '@vue/shared': 3.4.23 + + '@vue/runtime-core@3.4.23': + dependencies: + '@vue/reactivity': 3.4.23 + '@vue/shared': 3.4.23 + + '@vue/runtime-dom@3.4.23': + dependencies: + '@vue/runtime-core': 3.4.23 + '@vue/shared': 3.4.23 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.23(vue@3.4.23(typescript@5.4.5))': + dependencies: + '@vue/compiler-ssr': 3.4.23 + '@vue/shared': 3.4.23 + vue: 3.4.23(typescript@5.4.5) + + '@vue/shared@3.4.23': {} + + '@vueuse/core@10.9.0(vue@3.4.23(typescript@5.4.5))': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 10.9.0 + '@vueuse/shared': 10.9.0(vue@3.4.23(typescript@5.4.5)) + vue-demi: 0.14.7(vue@3.4.23(typescript@5.4.5)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/integrations@10.9.0(axios@1.6.8(debug@4.3.4(supports-color@9.4.0)))(focus-trap@7.5.4)(vue@3.4.23(typescript@5.4.5))': + dependencies: + '@vueuse/core': 10.9.0(vue@3.4.23(typescript@5.4.5)) + '@vueuse/shared': 10.9.0(vue@3.4.23(typescript@5.4.5)) + vue-demi: 0.14.7(vue@3.4.23(typescript@5.4.5)) + optionalDependencies: + axios: 1.6.8(debug@4.3.4(supports-color@9.4.0)) + focus-trap: 7.5.4 + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@10.9.0': {} + + '@vueuse/shared@10.9.0(vue@3.4.23(typescript@5.4.5))': + dependencies: + vue-demi: 0.14.7(vue@3.4.23(typescript@5.4.5)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + JSONStream@1.3.5: + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + + acorn-walk@8.3.2: {} + + acorn@8.11.3: {} + + add-stream@1.0.0: {} + + algoliasearch@4.23.3: + dependencies: + '@algolia/cache-browser-local-storage': 4.23.3 + '@algolia/cache-common': 4.23.3 + '@algolia/cache-in-memory': 4.23.3 + '@algolia/client-account': 4.23.3 + '@algolia/client-analytics': 4.23.3 + '@algolia/client-common': 4.23.3 + '@algolia/client-personalization': 4.23.3 + '@algolia/client-search': 4.23.3 + '@algolia/logger-common': 4.23.3 + '@algolia/logger-console': 4.23.3 + '@algolia/recommend': 4.23.3 + '@algolia/requester-browser-xhr': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/requester-node-http': 4.23.3 + '@algolia/transporter': 4.23.3 + + ansi-colors@4.1.3: {} + + ansi-escapes@6.2.1: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@5.0.2: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + + array-ify@1.0.0: {} + + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + + assertion-error@1.1.0: {} + + asynckit@0.4.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + axios@1.6.8(debug@4.3.4(supports-color@9.4.0)): + dependencies: + follow-redirects: 1.15.6(debug@4.3.4(supports-color@9.4.0)) + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + + boolbase@1.0.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.2: + dependencies: + fill-range: 7.0.1 + + builtin-modules@3.3.0: {} + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.0.0 + + cac@6.7.14: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + chai@4.4.1: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.3 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@5.3.0: {} + + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + cheerio-select@1.6.0: + dependencies: + css-select: 4.3.0 + css-what: 6.1.0 + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + + cheerio@1.0.0-rc.10: + dependencies: + cheerio-select: 1.6.0 + dom-serializer: 1.4.1 + domhandler: 4.3.1 + htmlparser2: 6.1.0 + parse5: 6.0.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + tslib: 2.6.2 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + cli-cursor@4.0.0: + dependencies: + restore-cursor: 4.0.0 + + cli-spinners@2.9.2: {} + + cli-truncate@4.0.0: + dependencies: + slice-ansi: 5.0.0 + string-width: 7.1.0 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + colorette@2.0.20: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@11.1.0: {} + + commander@6.2.1: {} + + commander@9.2.0: {} + + commondir@1.0.1: {} + + compare-func@2.0.0: + dependencies: + array-ify: 1.0.0 + dot-prop: 5.3.0 + + computeds@0.0.1: {} + + concat-map@0.0.1: {} + + conventional-changelog-angular@7.0.0: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-atom@4.0.0: {} + + conventional-changelog-cli@4.1.0: + dependencies: + add-stream: 1.0.0 + conventional-changelog: 5.1.0 + meow: 12.1.1 + tempfile: 5.0.0 + + conventional-changelog-codemirror@4.0.0: {} + + conventional-changelog-conventionalcommits@7.0.2: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-core@7.0.0: + dependencies: + '@hutson/parse-repository-url': 5.0.0 + add-stream: 1.0.0 + conventional-changelog-writer: 7.0.1 + conventional-commits-parser: 5.0.0 + git-raw-commits: 4.0.0 + git-semver-tags: 7.0.1 + hosted-git-info: 7.0.1 + normalize-package-data: 6.0.0 + read-pkg: 8.1.0 + read-pkg-up: 10.1.0 + + conventional-changelog-ember@4.0.0: {} + + conventional-changelog-eslint@5.0.0: {} + + conventional-changelog-express@4.0.0: {} + + conventional-changelog-jquery@5.0.0: {} + + conventional-changelog-jshint@4.0.0: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-preset-loader@4.1.0: {} + + conventional-changelog-writer@7.0.1: + dependencies: + conventional-commits-filter: 4.0.0 + handlebars: 4.7.8 + json-stringify-safe: 5.0.1 + meow: 12.1.1 + semver: 7.6.0 + split2: 4.2.0 + + conventional-changelog@5.1.0: + dependencies: + conventional-changelog-angular: 7.0.0 + conventional-changelog-atom: 4.0.0 + conventional-changelog-codemirror: 4.0.0 + conventional-changelog-conventionalcommits: 7.0.2 + conventional-changelog-core: 7.0.0 + conventional-changelog-ember: 4.0.0 + conventional-changelog-eslint: 5.0.0 + conventional-changelog-express: 4.0.0 + conventional-changelog-jquery: 5.0.0 + conventional-changelog-jshint: 4.0.0 + conventional-changelog-preset-loader: 4.1.0 + + conventional-commits-filter@4.0.0: {} + + conventional-commits-parser@5.0.0: + dependencies: + JSONStream: 1.3.5 + is-text-path: 2.0.0 + meow: 12.1.1 + split2: 4.2.0 + + cross-spawn@6.0.5: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-random-string@4.0.0: + dependencies: + type-fest: 1.4.0 + + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-what@6.1.0: {} + + csstype@3.1.3: {} + + dargs@8.1.0: {} + + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + de-indent@1.0.2: {} + + debug@4.3.4(supports-color@9.4.0): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 9.4.0 + + deep-eql@4.1.3: + dependencies: + type-detect: 4.0.8 + + deepmerge@4.3.1: {} + + default-browser-id@5.0.0: {} + + default-browser@5.2.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-lazy-prop@3.0.0: {} + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + detect-indent@7.0.1: {} + + detect-newline@4.0.1: {} + + diff-sequences@29.6.3: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + domelementtype@2.3.0: {} + + domhandler@3.3.0: + dependencies: + domelementtype: 2.3.0 + + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + + dot-prop@5.3.0: + dependencies: + is-obj: 2.0.0 + + eastasianwidth@0.2.0: {} + + emoji-regex@10.3.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + entities@2.2.0: {} + + entities@4.5.0: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-module-lexer@1.5.0: {} + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + + esbuild@0.20.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.20.2 + '@esbuild/android-arm': 0.20.2 + '@esbuild/android-arm64': 0.20.2 + '@esbuild/android-x64': 0.20.2 + '@esbuild/darwin-arm64': 0.20.2 + '@esbuild/darwin-x64': 0.20.2 + '@esbuild/freebsd-arm64': 0.20.2 + '@esbuild/freebsd-x64': 0.20.2 + '@esbuild/linux-arm': 0.20.2 + '@esbuild/linux-arm64': 0.20.2 + '@esbuild/linux-ia32': 0.20.2 + '@esbuild/linux-loong64': 0.20.2 + '@esbuild/linux-mips64el': 0.20.2 + '@esbuild/linux-ppc64': 0.20.2 + '@esbuild/linux-riscv64': 0.20.2 + '@esbuild/linux-s390x': 0.20.2 + '@esbuild/linux-x64': 0.20.2 + '@esbuild/netbsd-x64': 0.20.2 + '@esbuild/openbsd-x64': 0.20.2 + '@esbuild/sunos-x64': 0.20.2 + '@esbuild/win32-arm64': 0.20.2 + '@esbuild/win32-ia32': 0.20.2 + '@esbuild/win32-x64': 0.20.2 + + escape-goat@3.0.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + esm@3.2.25: {} + + esprima@4.0.1: {} + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + + eventemitter3@5.0.1: {} + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + file-type@18.7.0: + dependencies: + readable-web-to-node-stream: 3.0.2 + strtok3: 7.0.0 + token-types: 5.0.1 + + fill-range@7.0.1: + dependencies: + to-regex-range: 5.0.1 + + find-up-simple@1.0.0: {} + + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + + focus-trap@7.5.4: + dependencies: + tabbable: 6.2.0 + + follow-redirects@1.15.6(debug@4.3.4(supports-color@9.4.0)): + optionalDependencies: + debug: 4.3.4(supports-color@9.4.0) + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.1.1: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + + functions-have-names@1.2.3: {} + + get-east-asian-width@1.2.0: {} + + get-func-name@2.0.2: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-port@7.1.0: {} + + get-stdin@9.0.0: {} + + get-stream@8.0.1: {} + + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + + get-tsconfig@4.7.3: + dependencies: + resolve-pkg-maps: 1.0.0 + + git-hooks-list@3.1.0: {} + + git-raw-commits@4.0.0: + dependencies: + dargs: 8.1.0 + meow: 12.1.1 + split2: 4.2.0 + + git-semver-tags@7.0.1: + dependencies: + meow: 12.1.1 + semver: 7.6.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@10.3.12: + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.4 + minipass: 7.0.4 + path-scurry: 1.10.2 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + + globalthis@1.0.3: + dependencies: + define-properties: 1.2.1 + + globby@13.2.2: + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 4.0.0 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + graceful-fs@4.2.11: {} + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.1 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.17.4 + + has-bigints@1.0.2: {} + + has-flag@3.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + hookable@5.5.3: {} + + hosted-git-info@2.8.9: {} + + hosted-git-info@7.0.1: + dependencies: + lru-cache: 10.2.0 + + htmlparser2@5.0.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 3.3.0 + domutils: 2.8.0 + entities: 2.2.0 + + htmlparser2@6.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + entities: 2.2.0 + + human-signals@5.0.0: {} + + ieee754@1.2.1: {} + + ignore@5.3.1: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-arrayish@0.2.1: {} + + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + + is-callable@1.2.7: {} + + is-core-module@2.13.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + + is-docker@3.0.0: {} + + is-extendable@0.1.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-fullwidth-code-point@4.0.0: {} + + is-fullwidth-code-point@5.0.0: + dependencies: + get-east-asian-width: 1.2.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-interactive@2.0.0: {} + + is-module@1.0.0: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-obj@2.0.0: {} + + is-plain-obj@4.1.0: {} + + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.5 + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + + is-stream@3.0.0: {} + + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-text-path@2.0.0: + dependencies: + text-extensions: 2.4.0 + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + + is-unicode-supported@1.3.0: {} + + is-unicode-supported@2.0.0: {} + + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + jackspeak@2.3.6: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jiti@1.21.0: {} + + joi@17.12.3: + dependencies: + '@hapi/hoek': 9.3.0 + '@hapi/topo': 5.1.0 + '@sideway/address': 4.1.5 + '@sideway/formula': 3.0.1 + '@sideway/pinpoint': 2.0.0 + + js-tokens@4.0.0: {} + + js-tokens@9.0.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + json-parse-better-errors@1.0.2: {} + + json-parse-even-better-errors@3.0.1: {} + + json-stringify-safe@5.0.1: {} + + jsonc-parser@3.2.1: {} + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonparse@1.3.1: {} + + juice@8.1.0: + dependencies: + cheerio: 1.0.0-rc.10 + commander: 6.2.1 + mensch: 0.3.4 + slick: 1.12.2 + web-resource-inliner: 6.0.1 + transitivePeerDependencies: + - encoding + + kind-of@6.0.3: {} + + kleur@3.0.3: {} + + lilconfig@3.0.0: {} + + lines-and-columns@2.0.4: {} + + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + lint-staged@15.2.2(supports-color@9.4.0): + dependencies: + chalk: 5.3.0 + commander: 11.1.0 + debug: 4.3.4(supports-color@9.4.0) + execa: 8.0.1 + lilconfig: 3.0.0 + listr2: 8.0.1 + micromatch: 4.0.5 + pidtree: 0.6.0 + string-argv: 0.3.2 + yaml: 2.3.4 + transitivePeerDependencies: + - supports-color + + listr2@8.0.1: + dependencies: + cli-truncate: 4.0.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 6.0.0 + rfdc: 1.3.1 + wrap-ansi: 9.0.0 + + load-json-file@4.0.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + + local-pkg@0.5.0: + dependencies: + mlly: 1.6.1 + pkg-types: 1.0.3 + + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + + lodash._reinterpolate@3.0.0: {} + + lodash.template@4.5.0: + dependencies: + lodash._reinterpolate: 3.0.0 + lodash.templatesettings: 4.2.0 + + lodash.templatesettings@4.2.0: + dependencies: + lodash._reinterpolate: 3.0.0 + + lodash@4.17.21: {} + + log-symbols@6.0.0: + dependencies: + chalk: 5.3.0 + is-unicode-supported: 1.3.0 + + log-update@6.0.0: + dependencies: + ansi-escapes: 6.2.1 + cli-cursor: 4.0.0 + slice-ansi: 7.1.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 + + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + + lru-cache@10.2.0: {} + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + mark.js@8.11.1: {} + + markdown-it-anchor@8.6.7(patch_hash=7jac6clbacexfaqdjyv4p6a5n4)(@types/markdown-it@14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje))(markdown-it@14.1.0): + dependencies: + '@types/markdown-it': 14.0.1(patch_hash=f3sowjfcbslfedfcollco2ioje) + markdown-it: 14.1.0 + + markdown-it-attrs@4.1.6(markdown-it@14.1.0): + dependencies: + markdown-it: 14.1.0 + + markdown-it-container@4.0.0: {} + + markdown-it-emoji@3.0.0: {} + + markdown-it-mathjax3@4.3.2: + dependencies: + juice: 8.1.0 + mathjax-full: 3.2.2 + transitivePeerDependencies: + - encoding + + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + mathjax-full@3.2.2: + dependencies: + esm: 3.2.25 + mhchemparser: 4.2.1 + mj-context-menu: 0.6.1 + speech-rule-engine: 4.0.7 + + mdurl@2.0.0: {} + + memorystream@0.3.1: {} + + mensch@0.3.4: {} + + meow@12.1.1: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + mhchemparser@4.2.1: {} + + micromatch@4.0.5: + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@2.6.0: {} + + mimic-fn@2.1.0: {} + + mimic-fn@4.0.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.4: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@7.0.4: {} + + minisearch@6.3.0: {} + + mitt@3.0.1: {} + + mj-context-menu@0.6.1: {} + + mlly@1.6.1: + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.0.3 + ufo: 1.5.3 + + mrmime@2.0.0: {} + + ms@2.1.2: {} + + muggle-string@0.4.1: {} + + nanoid@3.3.7: {} + + nanoid@5.0.7: {} + + neo-async@2.6.2: {} + + nice-try@1.0.5: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.8 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + + normalize-package-data@6.0.0: + dependencies: + hosted-git-info: 7.0.1 + is-core-module: 2.13.1 + semver: 7.6.0 + validate-npm-package-license: 3.0.4 + + normalize-path@3.0.0: {} + + npm-run-all@4.1.5: + dependencies: + ansi-styles: 3.2.1 + chalk: 2.4.2 + cross-spawn: 6.0.5 + memorystream: 0.3.1 + minimatch: 3.1.2 + pidtree: 0.3.1 + read-pkg: 3.0.0 + shell-quote: 1.8.1 + string.prototype.padend: 3.1.6 + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + object-inspect@1.13.1: {} + + object-keys@1.1.1: {} + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + open-cli@8.0.0: + dependencies: + file-type: 18.7.0 + get-stdin: 9.0.0 + meow: 12.1.1 + open: 10.1.0 + tempy: 3.1.0 + + open@10.1.0: + dependencies: + default-browser: 5.2.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 3.1.0 + + ora@8.0.1: + dependencies: + chalk: 5.3.0 + cli-cursor: 4.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 2.0.0 + log-symbols: 6.0.0 + stdin-discarder: 0.2.2 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + p-limit@4.0.0: + dependencies: + yocto-queue: 1.0.0 + + p-limit@5.0.0: + dependencies: + yocto-queue: 1.0.0 + + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + + p-map@7.0.2: {} + + parse-json@4.0.0: + dependencies: + error-ex: 1.3.2 + json-parse-better-errors: 1.0.2 + + parse-json@7.1.1: + dependencies: + '@babel/code-frame': 7.24.2 + error-ex: 1.3.2 + json-parse-even-better-errors: 3.0.1 + lines-and-columns: 2.0.4 + type-fest: 3.13.1 + + parse5-htmlparser2-tree-adapter@6.0.1: + dependencies: + parse5: 6.0.1 + + parse5@6.0.1: {} + + path-browserify@1.0.1: {} + + path-exists@5.0.0: {} + + path-key@2.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-scurry@1.10.2: + dependencies: + lru-cache: 10.2.0 + minipass: 7.0.4 + + path-to-regexp@6.2.2: {} + + path-type@3.0.0: + dependencies: + pify: 3.0.0 + + path-type@4.0.0: {} + + pathe@1.1.2: {} + + pathval@1.1.1: {} + + peek-readable@5.0.0: {} + + perfect-debounce@1.0.0: {} + + picocolors@1.0.0: {} + + picomatch@2.3.1: {} + + pidtree@0.3.1: {} + + pidtree@0.6.0: {} + + pify@3.0.0: {} + + pkg-dir@8.0.0: + dependencies: + find-up-simple: 1.0.0 + + pkg-types@1.0.3: + dependencies: + jsonc-parser: 3.2.1 + mlly: 1.6.1 + pathe: 1.1.2 + + playwright-chromium@1.43.1: + dependencies: + playwright-core: 1.43.1 + + playwright-core@1.43.1: {} + + polka@1.0.0-next.25: + dependencies: + '@polka/url': 1.0.0-next.25 + trouter: 4.0.0 + + possible-typed-array-names@1.0.0: {} + + postcss-prefix-selector@1.16.0(postcss@8.4.38): + dependencies: + postcss: 8.4.38 + + postcss@8.4.38: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.2.0 + + preact@10.20.2: {} + + prettier@3.2.5: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.2.0 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + proxy-from-env@1.1.0: {} + + punycode.js@2.3.1: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + react-is@18.2.0: {} + + read-pkg-up@10.1.0: + dependencies: + find-up: 6.3.0 + read-pkg: 8.1.0 + type-fest: 4.15.0 + + read-pkg@3.0.0: + dependencies: + load-json-file: 4.0.0 + normalize-package-data: 2.5.0 + path-type: 3.0.0 + + read-pkg@8.1.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 6.0.0 + parse-json: 7.1.1 + type-fest: 4.15.0 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readable-web-to-node-stream@3.0.2: + dependencies: + readable-stream: 3.6.2 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + regexp.prototype.flags@1.5.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + regexparam@3.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + restore-cursor@4.0.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + reusify@1.0.4: {} + + rfdc@1.3.1: {} + + rimraf@5.0.5: + dependencies: + glob: 10.3.12 + + rollup-plugin-dts@6.1.0(rollup@4.14.3)(typescript@5.4.5): + dependencies: + magic-string: 0.30.10 + rollup: 4.14.3 + typescript: 5.4.5 + optionalDependencies: + '@babel/code-frame': 7.24.2 + + rollup-plugin-esbuild@6.1.1(esbuild@0.20.2)(rollup@4.14.3)(supports-color@9.4.0): + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.14.3) + debug: 4.3.4(supports-color@9.4.0) + es-module-lexer: 1.5.0 + esbuild: 0.20.2 + get-tsconfig: 4.7.3 + rollup: 4.14.3 + transitivePeerDependencies: + - supports-color + + rollup@4.14.3: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.14.3 + '@rollup/rollup-android-arm64': 4.14.3 + '@rollup/rollup-darwin-arm64': 4.14.3 + '@rollup/rollup-darwin-x64': 4.14.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.14.3 + '@rollup/rollup-linux-arm-musleabihf': 4.14.3 + '@rollup/rollup-linux-arm64-gnu': 4.14.3 + '@rollup/rollup-linux-arm64-musl': 4.14.3 + '@rollup/rollup-linux-powerpc64le-gnu': 4.14.3 + '@rollup/rollup-linux-riscv64-gnu': 4.14.3 + '@rollup/rollup-linux-s390x-gnu': 4.14.3 + '@rollup/rollup-linux-x64-gnu': 4.14.3 + '@rollup/rollup-linux-x64-musl': 4.14.3 + '@rollup/rollup-win32-arm64-msvc': 4.14.3 + '@rollup/rollup-win32-ia32-msvc': 4.14.3 + '@rollup/rollup-win32-x64-msvc': 4.14.3 + fsevents: 2.3.3 + + run-applescript@7.0.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rxjs@7.8.1: + dependencies: + tslib: 2.6.2 + + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + + safe-buffer@5.2.1: {} + + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + + sax@1.3.0: {} + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + semver@5.7.2: {} + + semver@7.6.0: + dependencies: + lru-cache: 6.0.0 + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@1.0.0: {} + + shebang-regex@3.0.0: {} + + shell-quote@1.8.1: {} + + shiki@1.3.0: + dependencies: + '@shikijs/core': 1.3.0 + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 + + siginfo@2.0.0: {} + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + simple-git-hooks@2.11.1: {} + + simple-git@3.24.0(supports-color@9.4.0): + dependencies: + '@kwsites/file-exists': 1.1.1(supports-color@9.4.0) + '@kwsites/promise-deferred': 1.1.1 + debug: 4.3.4(supports-color@9.4.0) + transitivePeerDependencies: + - supports-color + + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.25 + mrmime: 2.0.0 + totalist: 3.0.1 + + sisteransi@1.0.5: {} + + sitemap@7.1.1: + dependencies: + '@types/node': 17.0.45 + '@types/sax': 1.2.7 + arg: 5.0.2 + sax: 1.3.0 + + slash@4.0.0: {} + + slice-ansi@5.0.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + + slice-ansi@7.1.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + + slick@1.12.2: {} + + sort-object-keys@1.1.3: {} + + sort-package-json@2.10.0: + dependencies: + detect-indent: 7.0.1 + detect-newline: 4.0.1 + get-stdin: 9.0.0 + git-hooks-list: 3.1.0 + globby: 13.2.2 + is-plain-obj: 4.1.0 + semver: 7.6.0 + sort-object-keys: 1.1.3 + + source-map-js@1.2.0: {} + + source-map@0.6.1: {} + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.17 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.17 + + spdx-license-ids@3.0.17: {} + + speakingurl@14.0.1: {} + + speech-rule-engine@4.0.7: + dependencies: + commander: 9.2.0 + wicked-good-xpath: 1.3.0 + xmldom-sre: 0.1.31 + + split2@4.2.0: {} + + sprintf-js@1.0.3: {} + + stackback@0.0.2: {} + + std-env@3.7.0: {} + + stdin-discarder@0.2.2: {} + + string-argv@0.3.2: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string-width@7.1.0: + dependencies: + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 + + string.prototype.padend@3.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trimend@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + strip-bom-string@1.0.0: {} + + strip-bom@3.0.0: {} + + strip-final-newline@3.0.0: {} + + strip-literal@2.1.0: + dependencies: + js-tokens: 9.0.0 + + strtok3@7.0.0: + dependencies: + '@tokenizer/token': 0.3.0 + peek-readable: 5.0.0 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@9.4.0: {} + + supports-preserve-symlinks-flag@1.0.0: {} + + tabbable@6.2.0: {} + + temp-dir@3.0.0: {} + + tempfile@5.0.0: + dependencies: + temp-dir: 3.0.0 + + tempy@3.1.0: + dependencies: + is-stream: 3.0.0 + temp-dir: 3.0.0 + type-fest: 2.19.0 + unique-string: 3.0.0 + + text-extensions@2.4.0: {} + + through@2.3.8: {} + + tinybench@2.7.0: {} + + tinypool@0.8.4: {} + + tinyspy@2.2.1: {} + + to-fast-properties@2.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + token-types@5.0.1: + dependencies: + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + + totalist@3.0.1: {} + + tr46@0.0.3: {} + + trouter@4.0.0: + dependencies: + regexparam: 3.0.0 + + tslib@2.6.2: {} + + type-detect@4.0.8: {} + + type-fest@1.4.0: {} + + type-fest@2.19.0: {} + + type-fest@3.13.1: {} + + type-fest@4.15.0: {} + + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + + typescript@5.4.5: {} + + uc.micro@2.1.0: {} + + ufo@1.5.3: {} + + uglify-js@3.17.4: + optional: true + + ultramatter@0.0.4: {} + + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + + undici-types@5.26.5: {} + + unique-string@3.0.0: + dependencies: + crypto-random-string: 4.0.0 + + universalify@2.0.1: {} + + util-deprecate@1.0.2: {} + + valid-data-url@3.0.1: {} + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + vite-node@1.5.0(@types/node@20.12.7)(supports-color@9.4.0): + dependencies: + cac: 6.7.14 + debug: 4.3.4(supports-color@9.4.0) + pathe: 1.1.2 + picocolors: 1.0.0 + vite: 5.2.9(@types/node@20.12.7) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + vite@5.2.9(@types/node@20.12.7): + dependencies: + esbuild: 0.20.2 + postcss: 8.4.38 + rollup: 4.14.3 + optionalDependencies: + '@types/node': 20.12.7 + fsevents: 2.3.3 + + vitest@1.5.0(@types/node@20.12.7)(supports-color@9.4.0): + dependencies: + '@vitest/expect': 1.5.0 + '@vitest/runner': 1.5.0 + '@vitest/snapshot': 1.5.0 + '@vitest/spy': 1.5.0 + '@vitest/utils': 1.5.0 + acorn-walk: 8.3.2 + chai: 4.4.1 + debug: 4.3.4(supports-color@9.4.0) + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.10 + pathe: 1.1.2 + picocolors: 1.0.0 + std-env: 3.7.0 + strip-literal: 2.1.0 + tinybench: 2.7.0 + tinypool: 0.8.4 + vite: 5.2.9(@types/node@20.12.7) + vite-node: 1.5.0(@types/node@20.12.7)(supports-color@9.4.0) + why-is-node-running: 2.2.2 + optionalDependencies: + '@types/node': 20.12.7 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + vue-demi@0.14.7(vue@3.4.23(typescript@5.4.5)): + dependencies: + vue: 3.4.23(typescript@5.4.5) + + vue-template-compiler@2.7.16: + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + vue-tsc@2.0.13(typescript@5.4.5): + dependencies: + '@volar/typescript': 2.2.0-alpha.8 + '@vue/language-core': 2.0.13(typescript@5.4.5) + semver: 7.6.0 + typescript: 5.4.5 + + vue@3.4.23(typescript@5.4.5): + dependencies: + '@vue/compiler-dom': 3.4.23 + '@vue/compiler-sfc': 3.4.23 + '@vue/runtime-dom': 3.4.23 + '@vue/server-renderer': 3.4.23(vue@3.4.23(typescript@5.4.5)) + '@vue/shared': 3.4.23 + optionalDependencies: + typescript: 5.4.5 + + wait-on@7.2.0(debug@4.3.4(supports-color@9.4.0)): + dependencies: + axios: 1.6.8(debug@4.3.4(supports-color@9.4.0)) + joi: 17.12.3 + lodash: 4.17.21 + minimist: 1.2.8 + rxjs: 7.8.1 + transitivePeerDependencies: + - debug + + web-resource-inliner@6.0.1: + dependencies: + ansi-colors: 4.1.3 + escape-goat: 3.0.0 + htmlparser2: 5.0.1 + mime: 2.6.0 + node-fetch: 2.7.0 + valid-data-url: 3.0.1 + transitivePeerDependencies: + - encoding + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.2.2: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wicked-good-xpath@1.3.0: {} + + wordwrap@1.0.0: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrap-ansi@9.0.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 7.1.0 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + xmldom-sre@0.1.31: {} + + yallist@4.0.0: {} + + yaml@2.3.4: {} + + yocto-queue@1.0.0: {} + + zod@3.22.4: {} diff --git a/src/client/app/composables/copyCode.ts b/src/client/app/composables/copyCode.ts index 1b679359..2c458bb4 100644 --- a/src/client/app/composables/copyCode.ts +++ b/src/client/app/composables/copyCode.ts @@ -16,12 +16,15 @@ export function useCopyCode() { parent.className ) - let text = '' + const ignoredNodes = ['.vp-copy-ignore', '.diff.remove'] - sibling - .querySelectorAll('span.line:not(.diff.remove)') - .forEach((node) => (text += (node.textContent || '') + '\n')) - text = text.slice(0, -1) + // Clone the node and remove the ignored nodes + const clone = sibling.cloneNode(true) as HTMLElement + clone + .querySelectorAll(ignoredNodes.join(',')) + .forEach((node) => node.remove()) + + let text = clone.textContent || '' if (isShell) { text = text.replace(/^ *(\$|>) /gm, '').trim() diff --git a/src/client/app/composables/head.ts b/src/client/app/composables/head.ts index 76a607ae..708c16eb 100644 --- a/src/client/app/composables/head.ts +++ b/src/client/app/composables/head.ts @@ -8,14 +8,23 @@ import { import type { Route } from '../router' export function useUpdateHead(route: Route, siteDataByRouteRef: Ref) { - let managedHeadElements: (HTMLElement | undefined)[] = [] let isFirstUpdate = true + let managedHeadElements: (HTMLElement | undefined)[] = [] const updateHeadTags = (newTags: HeadConfig[]) => { if (import.meta.env.PROD && isFirstUpdate) { // in production, the initial meta tags are already pre-rendered so we // skip the first update. isFirstUpdate = false + newTags.forEach((tag) => { + const headEl = createHeadElement(tag) + for (const el of document.head.children) { + if (el.isEqualNode(headEl)) { + managedHeadElements.push(el as HTMLElement) + return + } + } + }) return } @@ -23,8 +32,8 @@ export function useUpdateHead(route: Route, siteDataByRouteRef: Ref) { newTags.map(createHeadElement) managedHeadElements.forEach((oldEl, oldIndex) => { - const matchedIndex = newElements.findIndex( - (newEl) => newEl?.isEqualNode(oldEl ?? null) + const matchedIndex = newElements.findIndex((newEl) => + newEl?.isEqualNode(oldEl ?? null) ) if (matchedIndex !== -1) { delete newElements[matchedIndex] diff --git a/src/client/app/data.ts b/src/client/app/data.ts index 77cc80d3..20fb1281 100644 --- a/src/client/app/data.ts +++ b/src/client/app/data.ts @@ -6,12 +6,14 @@ import { readonly, ref, shallowRef, + watch, type InjectionKey, type Ref } from 'vue' import { APPEARANCE_KEY, createTitle, + inBrowser, resolveSiteDataByRoute, type PageData, type SiteData @@ -44,9 +46,13 @@ export interface VitePressData { title: Ref description: Ref lang: Ref - isDark: Ref dir: Ref localeIndex: Ref + isDark: Ref + /** + * Current location hash + */ + hash: Ref } // site data is a singleton @@ -82,6 +88,21 @@ export function initData(route: Route): VitePressData { }) : ref(false) + const hashRef = ref(inBrowser ? location.hash : '') + + if (inBrowser) { + window.addEventListener('hashchange', () => { + hashRef.value = location.hash + }) + } + + watch( + () => route.data, + () => { + hashRef.value = inBrowser ? location.hash : '' + } + ) + return { site, theme: computed(() => site.value.themeConfig), @@ -89,15 +110,14 @@ export function initData(route: Route): VitePressData { frontmatter: computed(() => route.data.frontmatter), params: computed(() => route.data.params), lang: computed(() => site.value.lang), - dir: computed(() => site.value.dir), + dir: computed(() => route.data.frontmatter.dir || site.value.dir), localeIndex: computed(() => site.value.localeIndex || 'root'), - title: computed(() => { - return createTitle(site.value, route.data) - }), - description: computed(() => { - return route.data.description || site.value.description - }), - isDark + title: computed(() => createTitle(site.value, route.data)), + description: computed( + () => route.data.description || site.value.description + ), + isDark, + hash: computed(() => hashRef.value) } } diff --git a/src/client/app/devtools.ts b/src/client/app/devtools.ts index 81b91b66..e38bd080 100644 --- a/src/client/app/devtools.ts +++ b/src/client/app/devtools.ts @@ -1,4 +1,4 @@ -import { setupDevtoolsPlugin } from '@vue/devtools-api' +import { setupDevToolsPlugin } from '@vue/devtools-api' import type { App } from 'vue' import type { Router } from './router' import type { VitePressData } from './data' @@ -10,7 +10,7 @@ export const setupDevtools = ( router: Router, data: VitePressData ): void => { - setupDevtoolsPlugin( + setupDevToolsPlugin( { // fix recursive reference app: app as any, @@ -21,7 +21,8 @@ export const setupDevtools = ( componentStateTypes: [COMPONENT_STATE_TYPE] }, (api) => { - api.on.inspectComponent((payload) => { + // TODO: remove any + api.on.inspectComponent((payload: any) => { payload.instanceData.state.push({ type: COMPONENT_STATE_TYPE, key: 'route', diff --git a/src/client/app/index.ts b/src/client/app/index.ts index 023b93ae..911760a1 100644 --- a/src/client/app/index.ts +++ b/src/client/app/index.ts @@ -38,13 +38,13 @@ const Theme = resolveThemeExtends(RawTheme) const VitePressApp = defineComponent({ name: 'VitePressApp', setup() { - const { site } = useData() + const { site, lang, dir } = useData() // change the language on the HTML element based on the current lang onMounted(() => { watchEffect(() => { - document.documentElement.lang = site.value.lang - document.documentElement.dir = site.value.dir + document.documentElement.lang = lang.value + document.documentElement.dir = dir.value }) }) @@ -64,6 +64,8 @@ const VitePressApp = defineComponent({ }) export async function createApp() { + ;(globalThis as any).__VITEPRESS__ = true + const router = newRouter() const app = newApp() @@ -135,7 +137,11 @@ function newRouter(): Router { pageFilePath = pageFilePath.replace(/\.js$/, '.lean.js') } - pageModule = import(/*@vite-ignore*/ pageFilePath) + if (import.meta.env.SSR) { + pageModule = import(/*@vite-ignore*/ pageFilePath + '?t=' + Date.now()) + } else { + pageModule = import(/*@vite-ignore*/ pageFilePath) + } } if (inBrowser) { diff --git a/src/client/app/router.ts b/src/client/app/router.ts index c338afe0..3b3f6dda 100644 --- a/src/client/app/router.ts +++ b/src/client/app/router.ts @@ -1,10 +1,9 @@ -import { reactive, inject, markRaw, nextTick, readonly } from 'vue' import type { Component, InjectionKey } from 'vue' -import { lookup } from 'mrmime' -import { notFoundPageData } from '../shared' -import type { PageData, PageDataPayload, Awaitable } from '../shared' -import { inBrowser, withBase } from './utils' +import { inject, markRaw, nextTick, reactive, readonly } from 'vue' +import type { Awaitable, PageData, PageDataPayload } from '../shared' +import { notFoundPageData, treatAsHtml } from '../shared' import { siteDataRef } from './data' +import { getScrollOffset, inBrowser, withBase } from './utils' export interface Route { path: string @@ -67,7 +66,11 @@ export function createRouter( async function go(href: string = inBrowser ? location.href : '/') { href = normalizeHref(href) if ((await router.onBeforeRouteChange?.(href)) === false) return - updateHistory(href) + if (inBrowser && href !== normalizeHref(location.href)) { + // save scroll position before changing url + history.replaceState({ scrollPosition: window.scrollY }, '') + history.pushState({}, '', href) + } await loadPage(href) await router.onAfterRouteChanged?.(href) } @@ -115,7 +118,7 @@ export function createRouter( if (actualPathname !== targetLoc.pathname) { targetLoc.pathname = actualPathname href = actualPathname + targetLoc.search + targetLoc.hash - history.replaceState(null, '', href) + history.replaceState({}, '', href) } if (targetLoc.hash && !scrollPosition) { @@ -251,6 +254,9 @@ export function createRouter( } if (inBrowser) { + if (history.state === null) { + history.replaceState({}, '') + } window.addEventListener( 'click', (e) => { @@ -273,9 +279,8 @@ export function createRouter( : link.href, link.baseURI ) - const currentUrl = window.location - const mimeType = lookup(pathname) - // only intercept inbound links + const currentUrl = new URL(location.href) // copy to keep old data + // only intercept inbound html links if ( !e.ctrlKey && !e.shiftKey && @@ -283,8 +288,7 @@ export function createRouter( !e.metaKey && !target && origin === currentUrl.origin && - // intercept only html and unknown types (assume html) - (!mimeType || mimeType === 'text/html') + treatAsHtml(pathname) ) { e.preventDefault() if ( @@ -294,15 +298,19 @@ export function createRouter( // scroll between hash anchors in the same page // avoid duplicate history entries when the hash is same if (hash !== currentUrl.hash) { - history.pushState(null, '', hash) + history.pushState({}, '', href) // still emit the event so we can listen to it in themes - window.dispatchEvent(new Event('hashchange')) + window.dispatchEvent( + new HashChangeEvent('hashchange', { + oldURL: currentUrl.href, + newURL: href + }) + ) } if (hash) { // use smooth scroll when clicking on header anchor links scrollTo(link, hash, link.classList.contains('header-anchor')) } else { - updateHistory(href) window.scrollTo(0, 0) } } else { @@ -315,6 +323,9 @@ export function createRouter( ) window.addEventListener('popstate', async (e) => { + if (e.state === null) { + return + } await loadPage( normalizeHref(location.href), (e.state && e.state.scrollPosition) || 0 @@ -356,26 +367,6 @@ export function scrollTo(el: Element, hash: string, smooth = false) { } if (target) { - let scrollOffset = siteDataRef.value.scrollOffset - let offset = 0 - let padding = 24 - if (typeof scrollOffset === 'object' && 'padding' in scrollOffset) { - padding = scrollOffset.padding - scrollOffset = scrollOffset.selector - } - if (typeof scrollOffset === 'number') { - offset = scrollOffset - } else if (typeof scrollOffset === 'string') { - offset = tryOffsetSelector(scrollOffset, padding) - } else if (Array.isArray(scrollOffset)) { - for (const selector of scrollOffset) { - const res = tryOffsetSelector(selector, padding) - if (res) { - offset = res - break - } - } - } const targetPadding = parseInt( window.getComputedStyle(target).paddingTop, 10 @@ -383,7 +374,7 @@ export function scrollTo(el: Element, hash: string, smooth = false) { const targetTop = window.scrollY + target.getBoundingClientRect().top - - offset + + getScrollOffset() + targetPadding function scrollToTarget() { // only smooth scroll if distance is smaller than screen height. @@ -395,14 +386,6 @@ export function scrollTo(el: Element, hash: string, smooth = false) { } } -function tryOffsetSelector(selector: string, padding: number): number { - const el = document.querySelector(selector) - if (!el) return 0 - const bot = el.getBoundingClientRect().bottom - if (bot < 0) return 0 - return bot + padding -} - function handleHMR(route: Route): void { // update route.data on HMR updates of active page if (import.meta.hot) { @@ -423,14 +406,6 @@ function shouldHotReload(payload: PageDataPayload): boolean { return payloadPath === locationPath } -function updateHistory(href: string) { - if (inBrowser && href !== normalizeHref(location.href)) { - // save scroll position before changing url - history.replaceState({ scrollPosition: window.scrollY }, document.title) - history.pushState(null, '', href) - } -} - function normalizeHref(href: string): string { const url = new URL(href, fakeHost) url.pathname = url.pathname.replace(/(^|\/)index(\.html)?$/, '$1') diff --git a/src/client/app/utils.ts b/src/client/app/utils.ts index 5028483c..dfa5cffc 100644 --- a/src/client/app/utils.ts +++ b/src/client/app/utils.ts @@ -107,3 +107,36 @@ export function defineClientComponent( } } } + +export function getScrollOffset() { + let scrollOffset = siteDataRef.value.scrollOffset + let offset = 0 + let padding = 24 + if (typeof scrollOffset === 'object' && 'padding' in scrollOffset) { + padding = scrollOffset.padding + scrollOffset = scrollOffset.selector + } + if (typeof scrollOffset === 'number') { + offset = scrollOffset + } else if (typeof scrollOffset === 'string') { + offset = tryOffsetSelector(scrollOffset, padding) + } else if (Array.isArray(scrollOffset)) { + for (const selector of scrollOffset) { + const res = tryOffsetSelector(selector, padding) + if (res) { + offset = res + break + } + } + } + + return offset +} + +function tryOffsetSelector(selector: string, padding: number): number { + const el = document.querySelector(selector) + if (!el) return 0 + const bot = el.getBoundingClientRect().bottom + if (bot < 0) return 0 + return bot + padding +} diff --git a/src/client/index.ts b/src/client/index.ts index 072adba3..5fde6c5d 100644 --- a/src/client/index.ts +++ b/src/client/index.ts @@ -20,7 +20,8 @@ export { inBrowser, onContentUpdated, defineClientComponent, - withBase + withBase, + getScrollOffset } from './app/utils' // components diff --git a/src/client/theme-default/Layout.vue b/src/client/theme-default/Layout.vue index 0ecca7ec..69284148 100644 --- a/src/client/theme-default/Layout.vue +++ b/src/client/theme-default/Layout.vue @@ -56,7 +56,10 @@ provide('hero-image-slot-exists', heroImageSlotExists) + + + diff --git a/src/client/theme-default/components/VPAlgoliaSearchBox.vue b/src/client/theme-default/components/VPAlgoliaSearchBox.vue index 31bfd645..54901a97 100644 --- a/src/client/theme-default/components/VPAlgoliaSearchBox.vue +++ b/src/client/theme-default/components/VPAlgoliaSearchBox.vue @@ -42,7 +42,11 @@ async function update() { } function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) { - const options = Object.assign<{}, {}, DocSearchProps>({}, userOptions, { + const options = Object.assign< + {}, + DefaultTheme.AlgoliaSearchOptions, + Partial + >({}, userOptions, { container: '#docsearch', navigator: { @@ -69,7 +73,6 @@ function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) { }) }, - // @ts-expect-error vue-tsc thinks this should return Vue JSX but it returns the required React one hitComponent({ hit, children }) { return { __v: null, @@ -80,7 +83,7 @@ function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) { props: { href: hit.url, children } } } - }) + }) as DocSearchProps docsearch(options) } diff --git a/src/client/theme-default/components/VPBadge.vue b/src/client/theme-default/components/VPBadge.vue index b9c14aa9..1d5c1678 100644 --- a/src/client/theme-default/components/VPBadge.vue +++ b/src/client/theme-default/components/VPBadge.vue @@ -14,7 +14,7 @@ withDefaults(defineProps(), { - diff --git a/src/client/theme-default/components/VPDocAsideOutline.vue b/src/client/theme-default/components/VPDocAsideOutline.vue index f7b6dade..7c22fda1 100644 --- a/src/client/theme-default/components/VPDocAsideOutline.vue +++ b/src/client/theme-default/components/VPDocAsideOutline.vue @@ -80,9 +80,8 @@ useActiveAnchor(container, marker) } .outline-title { - letter-spacing: 0.4px; - line-height: 28px; - font-size: 13px; + line-height: 32px; + font-size: 14px; font-weight: 600; } diff --git a/src/client/theme-default/components/VPDocFooter.vue b/src/client/theme-default/components/VPDocFooter.vue index 6de55347..53f199ea 100644 --- a/src/client/theme-default/components/VPDocFooter.vue +++ b/src/client/theme-default/components/VPDocFooter.vue @@ -3,7 +3,6 @@ import { computed } from 'vue' import { useData } from '../composables/data' import { useEditLink } from '../composables/edit-link' import { usePrevNext } from '../composables/prev-next' -import VPIconEdit from './icons/VPIconEdit.vue' import VPLink from './VPLink.vue' import VPDocFooterLastUpdated from './VPDocFooterLastUpdated.vue' @@ -30,7 +29,7 @@ const showFooter = computed(() => {
@@ -92,9 +91,6 @@ const showFooter = computed(() => { .edit-link-icon { margin-right: 8px; - width: 14px; - height: 14px; - fill: currentColor; } .prev-next { diff --git a/src/client/theme-default/components/VPDocOutlineDropdown.vue b/src/client/theme-default/components/VPDocOutlineDropdown.vue deleted file mode 100644 index e6009402..00000000 --- a/src/client/theme-default/components/VPDocOutlineDropdown.vue +++ /dev/null @@ -1,85 +0,0 @@ - - - - - diff --git a/src/client/theme-default/components/VPDocOutlineItem.vue b/src/client/theme-default/components/VPDocOutlineItem.vue index 4ba55b99..89ea9710 100644 --- a/src/client/theme-default/components/VPDocOutlineItem.vue +++ b/src/client/theme-default/components/VPDocOutlineItem.vue @@ -14,7 +14,7 @@ function onClick({ target: el }: Event) {