diff --git a/.gitignore b/.gitignore
index e6e95ca9..dafdcdea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,3 +17,6 @@ pnpm-global
TODOs.md
*.timestamp-*.mjs
.claude
+
+# base fixture builds
+__tests__/base/fixture/.vitepress/dist-*
diff --git a/THIRD-PARTY-NOTICES.md b/THIRD-PARTY-NOTICES.md
new file mode 100644
index 00000000..b5d9863b
--- /dev/null
+++ b/THIRD-PARTY-NOTICES.md
@@ -0,0 +1,1736 @@
+# Third-party notices
+
+VitePress is published under the MIT license (see LICENSE). The published vitepress package additionally bundles code and font files from the projects listed below, used under the following licenses: BSD-2-Clause, BlueOak-1.0.0, ISC, MIT, OFL-1.1. The bundled code has been mechanically transformed from its original source form (concatenated, tree-shaken, and minified), and the font files are subsets of their original releases.
+
+## @antfu/install-pkg
+
+License: MIT
+By: Anthony Fu
+Repository: https://github.com/antfu/install-pkg
+
+> MIT License
+>
+> Copyright (c) 2021 Anthony Fu
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+> SOFTWARE.
+
+## @clack/core, @clack/prompts
+
+License: MIT
+By: Nate Moore (https://twitter.com/n_moore)
+Repository: https://github.com/bombshell-dev/clack
+
+> MIT License
+>
+> MIT License Copyright (c) 2025-Present [Bombshell contributors](https://bomb.sh/team)
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+## @iconify/utils
+
+License: MIT
+By: Vjacheslav Trushkin
+Repository: https://github.com/iconify/iconify
+
+> MIT License
+>
+> Copyright (c) 2021-PRESENT Vjacheslav Trushkin
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+> SOFTWARE.
+
+## @mdit-vue/plugin-component, @mdit-vue/plugin-frontmatter, @mdit-vue/plugin-headers, @mdit-vue/plugin-sfc, @mdit-vue/plugin-title, @mdit-vue/plugin-toc, @mdit-vue/shared, @mdit-vue/types
+
+License: MIT
+By: meteorlxy
+Repository: https://github.com/mdit-vue/mdit-vue
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2022-present, mdit-vue Contributors
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## @mdit/plugin-anchor
+
+License: MIT
+By: Mr.Hope (https://mister-hope.com)
+Repository: https://github.com/mdit-plugins/mdit-plugins
+
+> The MIT License (MIT)
+>
+> Copyright (C) 2022 - PRESENT by MrHope
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## @mdit/plugin-attrs
+
+License: MIT
+By: Mr.Hope (https://mister-hope.com)
+Repository: https://github.com/mdit-plugins/mdit-plugins
+
+> The MIT License (MIT)
+>
+> Copyright (c) Arve Seljebu (arve0.github.io)
+> Copyright (C) 2022 - PRESENT by MrHope
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## @mdit/plugin-container
+
+License: MIT
+By: Mr.Hope (https://mister-hope.com)
+Repository: https://github.com/mdit-plugins/mdit-plugins
+
+> The MIT License (MIT)
+>
+> Copyright (C) 2022 - PRESENT by MrHope
+> Copyright (c) 2015 Vitaly Puzrin, Alex Kocharin.
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## @mdit/plugin-emoji
+
+License: MIT
+Repository: https://github.com/mdit-plugins/mdit-plugins
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2014 Vitaly Puzrin.
+> Copyright (C) 2026 - PRESENT by MrHope
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## @mdit/plugin-footnote
+
+License: MIT
+By: Mr.Hope (https://mister-hope.com)
+Repository: https://github.com/mdit-plugins/mdit-plugins
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2014-2015 Vitaly Puzrin, Alex Kocharin.
+> Copyright (C) 2022 - PRESENT by MrHope
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## @mdit/plugin-tasklist
+
+License: MIT
+By: Mr.Hope (https://mister-hope.com)
+Repository: https://github.com/mdit-plugins/mdit-plugins
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2016, Revin Guillen
+> Modified code Copyright (c) 2016, linsir, MIT License
+> Copyright (C) 2022 - PRESENT by MrHope
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## @polka/compression, @polka/url, polka, sirv
+
+License: MIT
+By: Luke Edwards (https://lukeed.com)
+Repository: https://github.com/lukeed/polka, https://github.com/lukeed/sirv
+
+> MIT License
+>
+> Copyright (c) Luke Edwards (https://lukeed.com)
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+> SOFTWARE.
+
+## @rolldown/pluginutils
+
+License: MIT
+Repository: https://github.com/rolldown/plugins
+
+> MIT License
+>
+> Copyright (c) 2026-present, rolldown/plugins repository contributors
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+> SOFTWARE.
+
+## Inter
+
+License: OFL-1.1
+By: The Inter Project Authors
+Repository: https://github.com/rsms/inter
+
+> Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter)
+>
+> This Font Software is licensed under the SIL Open Font License, Version 1.1.
+> This license is copied below, and is also available with a FAQ at:
+> http://scripts.sil.org/OFL
+>
+> -----------------------------------------------------------
+> SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+> -----------------------------------------------------------
+>
+> PREAMBLE
+> The goals of the Open Font License (OFL) are to stimulate worldwide
+> development of collaborative font projects, to support the font creation
+> efforts of academic and linguistic communities, and to provide a free and
+> open framework in which fonts may be shared and improved in partnership
+> with others.
+>
+> The OFL allows the licensed fonts to be used, studied, modified and
+> redistributed freely as long as they are not sold by themselves. The
+> fonts, including any derivative works, can be bundled, embedded,
+> redistributed and/or sold with any software provided that any reserved
+> names are not used by derivative works. The fonts and derivatives,
+> however, cannot be released under any other type of license. The
+> requirement for fonts to remain under this license does not apply
+> to any document created using the fonts or their derivatives.
+>
+> DEFINITIONS
+> "Font Software" refers to the set of files released by the Copyright
+> Holder(s) under this license and clearly marked as such. This may
+> include source files, build scripts and documentation.
+>
+> "Reserved Font Name" refers to any names specified as such after the
+> copyright statement(s).
+>
+> "Original Version" refers to the collection of Font Software components as
+> distributed by the Copyright Holder(s).
+>
+> "Modified Version" refers to any derivative made by adding to, deleting,
+> or substituting -- in part or in whole -- any of the components of the
+> Original Version, by changing formats or by porting the Font Software to a
+> new environment.
+>
+> "Author" refers to any designer, engineer, programmer, technical
+> writer or other person who contributed to the Font Software.
+>
+> PERMISSION AND CONDITIONS
+> Permission is hereby granted, free of charge, to any person obtaining
+> a copy of the Font Software, to use, study, copy, merge, embed, modify,
+> redistribute, and sell modified and unmodified copies of the Font
+> Software, subject to the following conditions:
+>
+> 1) Neither the Font Software nor any of its individual components,
+> in Original or Modified Versions, may be sold by itself.
+>
+> 2) Original or Modified Versions of the Font Software may be bundled,
+> redistributed and/or sold with any software, provided that each copy
+> contains the above copyright notice and this license. These can be
+> included either as stand-alone text files, human-readable headers or
+> in the appropriate machine-readable metadata fields within text or
+> binary files as long as those fields can be easily viewed by the user.
+>
+> 3) No Modified Version of the Font Software may use the Reserved Font
+> Name(s) unless explicit written permission is granted by the corresponding
+> Copyright Holder. This restriction only applies to the primary font name as
+> presented to the users.
+>
+> 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+> Software shall not be used to promote, endorse or advertise any
+> Modified Version, except to acknowledge the contribution(s) of the
+> Copyright Holder(s) and the Author(s) or with their explicit written
+> permission.
+>
+> 5) The Font Software, modified or unmodified, in part or in whole,
+> must be distributed entirely under this license, and must not be
+> distributed under any other license. The requirement for fonts to
+> remain under this license does not apply to any document created
+> using the Font Software.
+>
+> TERMINATION
+> This license becomes null and void if any of the above conditions are
+> not met.
+>
+> DISCLAIMER
+> THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+> OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+> COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+> INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+> DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+> FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+> OTHER DEALINGS IN THE FONT SOFTWARE.
+
+## ansi-regex, chalk, cli-cursor, cli-spinners, find-up-simple, get-east-asian-width, is-interactive, is-unicode-supported, log-symbols, mimic-function, onetime, ora, p-map, package-directory, restore-cursor, stdin-discarder, string-width, strip-ansi, yoctocolors
+
+License: MIT
+By: Sindre Sorhus (https://sindresorhus.com)
+Repository: https://github.com/chalk/ansi-regex, https://github.com/chalk/chalk, https://github.com/chalk/strip-ansi, https://github.com/sindresorhus/cli-cursor, https://github.com/sindresorhus/cli-spinners, https://github.com/sindresorhus/find-up-simple, https://github.com/sindresorhus/get-east-asian-width, https://github.com/sindresorhus/is-interactive, https://github.com/sindresorhus/is-unicode-supported, https://github.com/sindresorhus/log-symbols, https://github.com/sindresorhus/mimic-function, https://github.com/sindresorhus/onetime, https://github.com/sindresorhus/ora, https://github.com/sindresorhus/p-map, https://github.com/sindresorhus/package-directory, https://github.com/sindresorhus/restore-cursor, https://github.com/sindresorhus/stdin-discarder, https://github.com/sindresorhus/string-width, https://github.com/sindresorhus/yoctocolors
+
+> MIT License
+>
+> Copyright (c) Sindre Sorhus (https://sindresorhus.com)
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+## cross-spawn
+
+License: MIT
+By: André Cruz
+Repository: https://github.com/moxystudio/node-cross-spawn
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2018 Made With MOXY Lda
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## cssesc, punycode.js
+
+License: MIT
+By: Mathias Bynens (https://mathiasbynens.be/)
+Repository: https://github.com/mathiasbynens/cssesc, https://github.com/mathiasbynens/punycode.js
+
+> Copyright Mathias Bynens
+>
+> Permission is hereby granted, free of charge, to any person obtaining
+> a copy of this software and associated documentation files (the
+> "Software"), to deal in the Software without restriction, including
+> without limitation the rights to use, copy, modify, merge, publish,
+> distribute, sublicense, and/or sell copies of the Software, and to
+> permit persons to whom the Software is furnished to do so, subject to
+> the following conditions:
+>
+> The above copyright notice and this permission notice shall be
+> included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+> LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+> OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+> WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+## entities
+
+License: BSD-2-Clause
+By: Felix Boehm
+Repository: https://github.com/fb55/entities
+
+> Copyright (c) Felix Böhm
+> All rights reserved.
+>
+> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+>
+> Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+>
+> Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+>
+> THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS,
+> EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+## esprima
+
+License: BSD-2-Clause
+By: Ariya Hidayat
+Repository: https://github.com/jquery/esprima
+
+> Copyright JS Foundation and other contributors, https://js.foundation/
+>
+> Redistribution and use in source and binary forms, with or without
+> modification, are permitted provided that the following conditions are met:
+>
+> * Redistributions of source code must retain the above copyright
+> notice, this list of conditions and the following disclaimer.
+> * Redistributions in binary form must reproduce the above copyright
+> notice, this list of conditions and the following disclaimer in the
+> documentation and/or other materials provided with the distribution.
+>
+> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+> AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+> IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+> ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
+> DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+> (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+> ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+> (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+> THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+## eta
+
+License: MIT
+By: Ben Gubler
+Repository: https://github.com/bgub/eta
+
+> Copyright 2025 Ben Gubler
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+## extend-shallow
+
+License: MIT
+By: Jon Schlinkert (https://github.com/jonschlinkert)
+Repository: https://github.com/jonschlinkert/extend-shallow
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2014-2015, Jon Schlinkert.
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## fast-string-truncated-width, fast-string-width
+
+License: MIT
+Repository: https://github.com/fabiospampinato/fast-string-truncated-width, https://github.com/fabiospampinato/fast-string-width
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2024-present Fabio Spampinato
+>
+> Permission is hereby granted, free of charge, to any person obtaining a
+> copy of this software and associated documentation files (the "Software"),
+> to deal in the Software without restriction, including without limitation
+> the rights to use, copy, modify, merge, publish, distribute, sublicense,
+> and/or sell copies of the Software, and to permit persons to whom the
+> Software is furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+> DEALINGS IN THE SOFTWARE.
+
+## fast-wrap-ansi
+
+License: MIT
+By: James Garbutt (https://github.com/43081j)
+Repository: https://github.com/43081j/fast-wrap-ansi
+
+> MIT License
+>
+> Copyright (c) 2025 James Garbutt
+>
+> Copyright (c) Sindre Sorhus (https://sindresorhus.com)
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+> SOFTWARE.
+
+## fdir
+
+License: MIT
+By: thecodrr
+Repository: https://github.com/thecodrr/fdir
+
+> Copyright 2023 Abdullah Atta
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+## gray-matter
+
+License: MIT
+By: Jon Schlinkert (https://github.com/jonschlinkert), Andrew Meyer (https://github.com/Ajedi32), Brian Woodward (https://twitter.com/doowb), Caesar Schinas (https://caesarschinas.com), Ian Storm Taylor (http://ianstormtaylor.com), Jon Schlinkert (http://twitter.com/jonschlinkert), Osman Nuri Okumuş (http://onokumus.com), Pawel Kadluczka (http://blog.3d-logic.com), Rob Loach (http://robloach.net), (https://github.com/heymind), Zach Whaley (http://zachwhaleys.website)
+Repository: https://github.com/jonschlinkert/gray-matter
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2014-2018, Jon Schlinkert.
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## image-size
+
+License: MIT
+By: netroy (http://netroy.in/)
+Repository: https://github.com/image-size/image-size
+
+> The MIT License (MIT)
+>
+> Copyright © 2013-Present Aditya Yadav, http://netroy.in
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+## import-meta-resolve
+
+License: MIT
+By: Titus Wormer (https://wooorm.com)
+Repository: https://github.com/wooorm/import-meta-resolve
+
+> (The MIT License)
+>
+> Copyright (c) Titus Wormer
+>
+> Permission is hereby granted, free of charge, to any person obtaining
+> a copy of this software and associated documentation files (the
+> 'Software'), to deal in the Software without restriction, including
+> without limitation the rights to use, copy, modify, merge, publish,
+> distribute, sublicense, and/or sell copies of the Software, and to
+> permit persons to whom the Software is furnished to do so, subject to
+> the following conditions:
+>
+> The above copyright notice and this permission notice shall be
+> included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+> IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+> CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+> TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+> SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+>
+> ---
+>
+> This is a derivative work based on:
+> .
+> Which is licensed:
+>
+> """
+> Copyright Node.js contributors. All rights reserved.
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to
+> deal in the Software without restriction, including without limitation the
+> rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+> sell copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+> IN THE SOFTWARE.
+> """
+>
+> This license applies to parts of Node.js originating from the
+> https://github.com/joyent/node repository:
+>
+> """
+> Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to
+> deal in the Software without restriction, including without limitation the
+> rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+> sell copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+> IN THE SOFTWARE.
+> """
+
+## is-extendable
+
+License: MIT
+By: Jon Schlinkert (https://github.com/jonschlinkert)
+Repository: https://github.com/jonschlinkert/is-extendable
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2015, Jon Schlinkert.
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## isexe, which
+
+License: ISC
+By: Isaac Z. Schlueter (http://blog.izs.me), Isaac Z. Schlueter (http://blog.izs.me/)
+Repository: https://github.com/isaacs/isexe, https://github.com/isaacs/node-which
+
+> The ISC License
+>
+> Copyright (c) Isaac Z. Schlueter and Contributors
+>
+> Permission to use, copy, modify, and/or distribute this software for any
+> purpose with or without fee is hereby granted, provided that the above
+> copyright notice and this permission notice appear in all copies.
+>
+> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+> WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+> MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+> ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+> WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+> ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+> IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+## js-yaml
+
+License: MIT
+By: Vladimir Zapparov , Aleksey V Zapparov (http://www.ixti.net/), Vitaly Puzrin (https://github.com/puzrin), Martin Grenfell (http://got-ravings.blogspot.com)
+Repository: https://github.com/nodeca/js-yaml
+
+> (The MIT License)
+>
+> Copyright (C) 2011-2015 by Vitaly Puzrin
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## kind-of
+
+License: MIT
+By: Jon Schlinkert (https://github.com/jonschlinkert), David Fox-Powell (https://dtothefp.github.io/me), James (https://twitter.com/aretecode), Jon Schlinkert (http://twitter.com/jonschlinkert), Ken Sheedlo (kensheedlo.com), laggingreflex (https://github.com/laggingreflex), Miguel Mota (https://miguelmota.com), Peter deHaan (http://about.me/peterdehaan), tunnckoCore (https://i.am.charlike.online)
+Repository: https://github.com/jonschlinkert/kind-of
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2014-2017, Jon Schlinkert.
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## linkify-it
+
+License: MIT
+Repository: https://github.com/markdown-it/linkify-it
+
+> Copyright (c) 2015 Vitaly Puzrin.
+>
+> Permission is hereby granted, free of charge, to any person
+> obtaining a copy of this software and associated documentation
+> files (the "Software"), to deal in the Software without
+> restriction, including without limitation the rights to use,
+> copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the
+> Software is furnished to do so, subject to the following
+> conditions:
+>
+> The above copyright notice and this permission notice shall be
+> included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+> OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+> HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+> WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+> OTHER DEALINGS IN THE SOFTWARE.
+
+## lru-cache
+
+License: BlueOak-1.0.0
+By: Isaac Z. Schlueter
+Repository: https://github.com/isaacs/node-lru-cache
+
+> # Blue Oak Model License
+>
+> Version 1.0.0
+>
+> ## Purpose
+>
+> This license gives everyone as much permission to work with
+> this software as possible, while protecting contributors
+> from liability.
+>
+> ## Acceptance
+>
+> In order to receive this license, you must agree to its
+> rules. The rules of this license are both obligations
+> under that agreement and conditions to your license.
+> You must not do anything with this software that triggers
+> a rule that you cannot or will not follow.
+>
+> ## Copyright
+>
+> Each contributor licenses you to do everything with this
+> software that would otherwise infringe that contributor's
+> copyright in it.
+>
+> ## Notices
+>
+> You must ensure that everyone who gets a copy of
+> any part of this software from you, with or without
+> changes, also gets the text of this license or a link to
+> .
+>
+> ## Excuse
+>
+> If anyone notifies you in writing that you have not
+> complied with [Notices](#notices), you can keep your
+> license by taking all practical steps to comply within 30
+> days after the notice. If you do not do so, your license
+> ends immediately.
+>
+> ## Patent
+>
+> Each contributor licenses you to do everything with this
+> software that would otherwise infringe any patent claims
+> they can license or become able to license.
+>
+> ## Reliability
+>
+> No contributor can revoke this license.
+>
+> ## No Liability
+>
+> ***As far as the law allows, this software comes as is,
+> without any warranty or condition, and no contributor
+> will be liable to anyone for any damages related to this
+> software or this license, under any kind of legal claim.***
+
+## markdown-it
+
+License: MIT
+Repository: https://github.com/markdown-it/markdown-it
+
+> Copyright (c) 2014 Vitaly Puzrin, Alex Kocharin.
+>
+> Permission is hereby granted, free of charge, to any person
+> obtaining a copy of this software and associated documentation
+> files (the "Software"), to deal in the Software without
+> restriction, including without limitation the rights to use,
+> copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the
+> Software is furnished to do so, subject to the following
+> conditions:
+>
+> The above copyright notice and this permission notice shall be
+> included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+> OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+> HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+> WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+> OTHER DEALINGS IN THE SOFTWARE.
+
+## markdown-it-async
+
+License: MIT
+By: Anthony Fu
+Repository: https://github.com/antfu/markdown-it-async
+
+> MIT License
+>
+> Copyright (c) 2022 Anthony Fu
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+> SOFTWARE.
+
+## markdown-it-cjk-friendly
+
+License: MIT
+By: Tatsunori Uchino (https://github.com/tats-u)
+Repository: https://github.com/tats-u/markdown-cjk-friendly
+
+> Copyright (c) 2024 Tatsunori Uchino
+>
+> markdown-it:
+>
+> Copyright (c) 2014 Vitaly Puzrin, Alex Kocharin.
+>
+> Permission is hereby granted, free of charge, to any person
+> obtaining a copy of this software and associated documentation
+> files (the "Software"), to deal in the Software without
+> restriction, including without limitation the rights to use,
+> copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the
+> Software is furnished to do so, subject to the following
+> conditions:
+>
+> The above copyright notice and this permission notice shall be
+> included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+> OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+> HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+> WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+> OTHER DEALINGS IN THE SOFTWARE.
+
+## mdurl
+
+License: MIT
+Repository: https://github.com/markdown-it/mdurl
+
+> Copyright (c) 2015 Vitaly Puzrin, Alex Kocharin.
+>
+> Permission is hereby granted, free of charge, to any person
+> obtaining a copy of this software and associated documentation
+> files (the "Software"), to deal in the Software without
+> restriction, including without limitation the rights to use,
+> copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the
+> Software is furnished to do so, subject to the following
+> conditions:
+>
+> The above copyright notice and this permission notice shall be
+> included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+> OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+> HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+> WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+> OTHER DEALINGS IN THE SOFTWARE.
+>
+> --------------------------------------------------------------------------------
+>
+> .parse() is based on Joyent's node.js `url` code:
+>
+> Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to
+> deal in the Software without restriction, including without limitation the
+> rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+> sell copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+> IN THE SOFTWARE.
+
+## minimist
+
+License: MIT
+By: James Halliday (http://substack.net)
+Repository: https://github.com/minimistjs/minimist
+
+> This software is released under the MIT license:
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy of
+> this software and associated documentation files (the "Software"), to deal in
+> the Software without restriction, including without limitation the rights to
+> use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+> the Software, and to permit persons to whom the Software is furnished to do so,
+> subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+> FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+> COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+> IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+> CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+## mrmime
+
+License: MIT
+By: Luke Edwards (https://lukeed.com)
+Repository: https://github.com/lukeed/mrmime
+
+> The MIT License (MIT)
+>
+> Copyright (c) Luke Edwards (https://lukeed.com)
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## nanoid
+
+License: MIT
+By: Andrey Sitnik
+Repository: https://github.com/ai/nanoid
+
+> The MIT License (MIT)
+>
+> Copyright 2017 Andrey Sitnik
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy of
+> this software and associated documentation files (the "Software"), to deal in
+> the Software without restriction, including without limitation the rights to
+> use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+> the Software, and to permit persons to whom the Software is furnished to do so,
+> subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+> FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+> COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+> IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+> CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+## obug
+
+License: MIT
+By: Kevin Deng
+Repository: https://github.com/sxzz/obug
+
+> The MIT License (MIT)
+>
+> Copyright © 2025-PRESENT Kevin Deng (https://github.com/sxzz)
+> Copyright (c) 2014-2017 TJ Holowaychuk
+> Copyright (c) 2018-2021 Josh Junon
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+> SOFTWARE.
+
+## package-manager-detector
+
+License: MIT
+By: Anthony Fu
+Repository: https://github.com/antfu-collective/package-manager-detector
+
+> MIT License
+>
+> Copyright (c) 2020-PRESENT Anthony Fu
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+> SOFTWARE.
+
+## path-key, shebang-regex
+
+License: MIT
+By: Sindre Sorhus (sindresorhus.com)
+Repository: https://github.com/sindresorhus/path-key, https://github.com/sindresorhus/shebang-regex
+
+> MIT License
+>
+> Copyright (c) Sindre Sorhus (sindresorhus.com)
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+## path-to-regexp
+
+License: MIT
+Repository: https://github.com/pillarjs/path-to-regexp
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## picocolors
+
+License: ISC
+By: Alexey Raspopov
+Repository: https://github.com/alexeyraspopov/picocolors
+
+> ISC License
+>
+> Copyright (c) 2021-2024 Oleksii Raspopov, Kostiantyn Denysov, Anton Verinov
+>
+> Permission to use, copy, modify, and/or distribute this software for any
+> purpose with or without fee is hereby granted, provided that the above
+> copyright notice and this permission notice appear in all copies.
+>
+> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+> WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+> MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+> ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+> WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+> ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+> OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+## picomatch
+
+License: MIT
+By: Jon Schlinkert (https://github.com/jonschlinkert)
+Repository: https://github.com/micromatch/picomatch
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2017-present, Jon Schlinkert.
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## postcss-selector-parser
+
+License: MIT
+By: Maxime Thirouin (https://moox.io), Ben Briggs (http://beneb.info), Chris Eppstein
+Repository: https://github.com/postcss/postcss-selector-parser
+
+> Copyright (c) Ben Briggs (http://beneb.info)
+>
+> Permission is hereby granted, free of charge, to any person
+> obtaining a copy of this software and associated documentation
+> files (the "Software"), to deal in the Software without
+> restriction, including without limitation the rights to use,
+> copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the
+> Software is furnished to do so, subject to the following
+> conditions:
+>
+> The above copyright notice and this permission notice shall be
+> included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+> OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+> HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+> WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+> OTHER DEALINGS IN THE SOFTWARE.
+
+## regexparam, totalist, trouter
+
+License: MIT
+By: Luke Edwards (https://lukeed.com)
+Repository: https://github.com/lukeed/regexparam, https://github.com/lukeed/totalist, https://github.com/lukeed/trouter
+
+> The MIT License (MIT)
+>
+> Copyright (c) Luke Edwards (lukeed.com)
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## sax
+
+License: BlueOak-1.0.0
+By: Isaac Z. Schlueter (http://blog.izs.me/)
+Repository: https://github.com/isaacs/sax-js
+
+> # Blue Oak Model License
+>
+> Version 1.0.0
+>
+> ## Purpose
+>
+> This license gives everyone as much permission to work with
+> this software as possible, while protecting contributors
+> from liability.
+>
+> ## Acceptance
+>
+> In order to receive this license, you must agree to its
+> rules. The rules of this license are both obligations
+> under that agreement and conditions to your license.
+> You must not do anything with this software that triggers
+> a rule that you cannot or will not follow.
+>
+> ## Copyright
+>
+> Each contributor licenses you to do everything with this
+> software that would otherwise infringe that contributor's
+> copyright in it.
+>
+> ## Notices
+>
+> You must ensure that everyone who gets a copy of
+> any part of this software from you, with or without
+> changes, also gets the text of this license or a link to
+> .
+>
+> ## Excuse
+>
+> If anyone notifies you in writing that you have not
+> complied with [Notices](#notices), you can keep your
+> license by taking all practical steps to comply within 30
+> days after the notice. If you do not do so, your license
+> ends immediately.
+>
+> ## Patent
+>
+> Each contributor licenses you to do everything with this
+> software that would otherwise infringe any patent claims
+> they can license or become able to license.
+>
+> ## Reliability
+>
+> No contributor can revoke this license.
+>
+> ## No Liability
+>
+> ***As far as the law allows, this software comes as is,
+> without any warranty or condition, and no contributor
+> will be liable to anyone for any damages related to this
+> software or this license, under any kind of legal claim.***
+
+## section-matter
+
+License: MIT
+By: Jon Schlinkert (https://github.com/jonschlinkert)
+Repository: https://github.com/jonschlinkert/section-matter
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2017, Jon Schlinkert.
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+> SOFTWARE.
+
+## shebang-command
+
+License: MIT
+By: Kevin Mårtensson (github.com/kevva)
+Repository: https://github.com/kevva/shebang-command
+
+> MIT License
+>
+> Copyright (c) Kevin Mårtensson (github.com/kevva)
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+## signal-exit
+
+License: ISC
+By: Ben Coe
+Repository: https://github.com/tapjs/signal-exit
+
+> The ISC License
+>
+> Copyright (c) 2015-2023 Benjamin Coe, Isaac Z. Schlueter, and Contributors
+>
+> Permission to use, copy, modify, and/or distribute this software
+> for any purpose with or without fee is hereby granted, provided
+> that the above copyright notice and this permission notice
+> appear in all copies.
+>
+> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+> WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+> OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE
+> LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
+> OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+> WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+> ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+## sisteransi
+
+License: MIT
+By: Terkel Gjervig (https://terkel.com)
+Repository: https://github.com/terkelg/sisteransi
+
+> MIT License
+>
+> Copyright (c) 2018 Terkel Gjervig Nielsen
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+> SOFTWARE.
+
+## sitemap
+
+License: MIT
+By: Eugene Kalinin
+Repository: https://github.com/ekalinin/sitemap.js
+
+> (The MIT License)
+>
+> Copyright (c) 2011 Eugene Kalinin
+>
+> Permission is hereby granted, free of charge, to any person obtaining
+> a copy of this software and associated documentation files (the
+> 'Software'), to deal in the Software without restriction, including
+> without limitation the rights to use, copy, modify, merge, publish,
+> distribute, sublicense, and/or sell copies of the Software, and to
+> permit persons to whom the Software is furnished to do so, subject to
+> the following conditions:
+>
+> The above copyright notice and this permission notice shall be
+> included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+> IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+> CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+> TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+> SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+## strip-bom-string
+
+License: MIT
+By: Jon Schlinkert (https://github.com/jonschlinkert)
+Repository: https://github.com/jonschlinkert/strip-bom-string
+
+> The MIT License (MIT)
+>
+> Copyright (c) 2015, 2017, Jon Schlinkert
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+## tinyexec
+
+License: MIT
+By: James Garbutt (https://github.com/43081j)
+Repository: https://github.com/tinylibs/tinyexec
+
+> MIT License
+>
+> Copyright (c) 2024 Tinylibs
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+> SOFTWARE.
+
+## tinyglobby
+
+License: MIT
+By: Superchupu
+Repository: https://github.com/SuperchupuDev/tinyglobby
+
+> MIT License
+>
+> Copyright (c) 2024 Madeline Gurriarán
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in all
+> copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+> SOFTWARE.
+
+## uc.micro
+
+License: MIT
+Repository: https://github.com/markdown-it/uc.micro
+
+> Copyright Mathias Bynens
+>
+> Permission is hereby granted, free of charge, to any person obtaining
+> a copy of this software and associated documentation files (the
+> "Software"), to deal in the Software without restriction, including
+> without limitation the rights to use, copy, modify, merge, publish,
+> distribute, sublicense, and/or sell copies of the Software, and to
+> permit persons to whom the Software is furnished to do so, subject to
+> the following conditions:
+>
+> The above copyright notice and this permission notice shall be
+> included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+> LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+> OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+> WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+## util-deprecate
+
+License: MIT
+By: Nathan Rajlich (http://n8.io/)
+Repository: https://github.com/TooTallNate/util-deprecate
+
+> (The MIT License)
+>
+> Copyright (c) 2014 Nathan Rajlich
+>
+> Permission is hereby granted, free of charge, to any person
+> obtaining a copy of this software and associated documentation
+> files (the "Software"), to deal in the Software without
+> restriction, including without limitation the rights to use,
+> copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the
+> Software is furnished to do so, subject to the following
+> conditions:
+>
+> The above copyright notice and this permission notice shall be
+> included in all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+> OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+> HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+> WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+> OTHER DEALINGS IN THE SOFTWARE.
diff --git a/__tests__/base/cdn.test.ts b/__tests__/base/cdn.test.ts
new file mode 100644
index 00000000..7b8ce80b
--- /dev/null
+++ b/__tests__/base/cdn.test.ts
@@ -0,0 +1,63 @@
+import { newPage, realErrors, waitForHydration, type TestPage } from './helpers'
+
+const origin = () => `http://localhost:${process.env['PAGES_PORT']}`
+const cdnPort = () => process.env['VP_CDN_PORT']
+
+let t: TestPage
+
+beforeAll(async () => {
+ t = await newPage()
+})
+
+afterAll(async () => {
+ await t.page.close()
+ await t.browser.close()
+})
+
+describe('assetsBase with a separate cdn origin', () => {
+ test('pages hydrate from cross-origin assets', async () => {
+ await t.page.goto(`${origin()}/`)
+ await waitForHydration(t.page)
+ const cdnResources = await t.page.evaluate(
+ (port) =>
+ performance
+ .getEntriesByType('resource')
+ .filter((r) => r.name.includes(`:${port}/`)).length,
+ cdnPort()
+ )
+ expect(cdnResources).toBeGreaterThan(5)
+ })
+
+ test('client-side navigation loads page chunks from the cdn', async () => {
+ await t.page.evaluate(() => ((window as any).__spa_marker = 1))
+ await t.page.click('.vp-doc a[href="/sub/page.html"]')
+ await t.page.waitForFunction(() =>
+ document.querySelector('h1')?.textContent?.includes('Sub page')
+ )
+ expect(
+ await t.page.evaluate(() => (window as any).__spa_marker === 1)
+ ).toBe(true)
+ const chunkFromCdn = await t.page.evaluate(
+ (port) =>
+ performance
+ .getEntriesByType('resource')
+ .some((r) => r.name.includes(`:${port}/`) && r.name.includes('.md.')),
+ cdnPort()
+ )
+ expect(chunkFromCdn).toBe(true)
+ })
+
+ test('search works with the index chunk on the cdn', async () => {
+ await t.page.click('.VPNavBarSearchButton')
+ const input = await t.page.waitForSelector('input#localsearch-input')
+ await input.type('xylophone')
+ await t.page.waitForSelector('#localsearch-list li[role=option] a')
+ expect(
+ await t.page.getAttribute('#localsearch-list li[role=option] a', 'href')
+ ).toBe('/sub/deep/page2.html#deep-heading')
+ })
+
+ test('no console or page errors across the whole flow', () => {
+ expect(realErrors(t.errors)).toEqual([])
+ })
+})
diff --git a/__tests__/base/constants.ts b/__tests__/base/constants.ts
new file mode 100644
index 00000000..a2d5bcbe
--- /dev/null
+++ b/__tests__/base/constants.ts
@@ -0,0 +1,2 @@
+export const SUB_PREFIX = '/ipfs/QmRelocatableTest123/'
+export const ALT_PREFIX = '/some/other/place/'
diff --git a/__tests__/base/emit.test.ts b/__tests__/base/emit.test.ts
new file mode 100644
index 00000000..aa805e6a
--- /dev/null
+++ b/__tests__/base/emit.test.ts
@@ -0,0 +1,210 @@
+import { readFileSync, readdirSync } from 'node:fs'
+import { basename, join, resolve } from 'node:path'
+import { fileURLToPath } from 'node:url'
+
+const dir = resolve(fileURLToPath(import.meta.url), '..')
+const dist = (mode: string, ...p: string[]) =>
+ join(dir, `fixture/.vitepress/dist-${mode}`, ...p)
+const read = (mode: string, file: string) =>
+ readFileSync(dist(mode, file), 'utf-8')
+
+const walk = (root: string): string[] =>
+ readdirSync(root, { recursive: true, withFileTypes: true })
+ .filter((e) => e.isFile())
+ .map((e) => join(e.parentPath, e.name))
+
+describe('relative base emit', () => {
+ test('root page references everything at ./', () => {
+ const html = read('relative', 'index.html')
+ expect(html).toContain(
+ 'window.__VP_SITE_ROOT__=new URL("./",location).href'
+ )
+ expect(html).toMatch(/href="\.\/assets\/style\.[\w-]+\.css"/)
+ expect(html).toMatch(/src="\.\/assets\/app\.[\w-]+\.js"/)
+ expect(html).toMatch(/src="\.\/assets\/chunks\/metadata\.[\w-]+\.js"/)
+ expect(html).toMatch(/href="\.\/assets\/vp-icons\.[\w-]+\.css"/)
+ expect(
+ walk(dist('relative', 'assets')).some((f) =>
+ /vp-icons\.[\w-]+\.css$/.test(f)
+ )
+ ).toBe(true)
+ })
+
+ test('markdown links compile page-relative with explicit index.html', () => {
+ const html = read('relative', 'index.html')
+ expect(html).toContain('href="./sub/page.html"')
+ expect(html).toContain('href="./sub/index.html"')
+ expect(html).toContain('href="./moved/target.html"')
+ })
+
+ test('non-page links get the prefix but no .html', () => {
+ const html = read('relative', 'index.html')
+ expect(html).toContain('href="./file.zip"')
+ expect(html).not.toContain('file.zip.html')
+ })
+
+ test('public and hashed assets in content are page-relative', () => {
+ const html = read('relative', 'index.html')
+ expect(html).toContain('src="./logo.png"')
+ expect(html).toMatch(/src="\.\/assets\/photo\.[\w-]+\.png"/)
+ })
+
+ test('depth 1 pages use ../', () => {
+ const html = read('relative', 'sub/page.html')
+ expect(html).toContain(
+ 'window.__VP_SITE_ROOT__=new URL("../",location).href'
+ )
+ expect(html).toMatch(/href="\.\.\/assets\/style\.[\w-]+\.css"/)
+ expect(html).toMatch(/href="\.\.\/assets\/vp-icons\.[\w-]+\.css"/)
+ expect(html).toContain('src="../logo.png"')
+ expect(html).toContain('href="../index.html"')
+ expect(html).toContain('href="../sub/deep/page2.html"')
+ })
+
+ test('hash and external links stay untouched', () => {
+ const html = read('relative', 'sub/page.html')
+ expect(html).toContain('href="#local-anchor"')
+ expect(html).toContain('href="https://example.com/x"')
+ })
+
+ test('depth 2 pages use ../../', () => {
+ const html = read('relative', 'sub/deep/page2.html')
+ expect(html).toContain(
+ 'window.__VP_SITE_ROOT__=new URL("../../",location).href'
+ )
+ expect(html).toMatch(/href="\.\.\/\.\.\/assets\/style\.[\w-]+\.css"/)
+ })
+
+ test('rewritten page lands at its rewrite depth', () => {
+ const html = read('relative', 'moved/target.html')
+ expect(html).toContain(
+ 'window.__VP_SITE_ROOT__=new URL("../",location).href'
+ )
+ expect(html).toMatch(/href="\.\.\/assets\/style\.[\w-]+\.css"/)
+ })
+
+ test('404 renders at root depth', () => {
+ const html = read('relative', '404.html')
+ expect(html).toContain(
+ 'window.__VP_SITE_ROOT__=new URL("./",location).href'
+ )
+ expect(html).toMatch(/href="\.\/assets\/style\.[\w-]+\.css"/)
+ })
+
+ test('no sentinel leaks into emitted html or css', () => {
+ for (const file of walk(dist('relative'))) {
+ if (!/\.(html|css)$/.test(file)) continue
+ expect(readFileSync(file, 'utf-8'), file).not.toContain('__VP_BASE__')
+ }
+ })
+
+ test('content-loader html keeps site-absolute links', () => {
+ const html = read('relative', 'blog.html')
+ // the loader source lives at posts/deep/, the consumer at the root —
+ // per-source relativizing would point above the site root
+ expect(html).toContain('href="/sub/page.html"')
+ expect(html).not.toContain('../../sub/page.html')
+ // the consuming page's own chrome is still relative
+ expect(html).toMatch(/href="\.\/assets\/style\.[\w-]+\.css"/)
+ })
+})
+
+describe('assetsBase emit', () => {
+ const cdn = () => `http://localhost:${process.env['VP_CDN_PORT']}/`
+
+ test('scripts, styles and preloads move to the cdn with crossorigin', () => {
+ const html = read('cdn', 'index.html')
+ expect(html).toMatch(
+ new RegExp(
+ `
+
+
diff --git a/__tests__/base/fixture/img/photo.png b/__tests__/base/fixture/img/photo.png
new file mode 100644
index 00000000..f37764b1
Binary files /dev/null and b/__tests__/base/fixture/img/photo.png differ
diff --git a/__tests__/base/fixture/index.md b/__tests__/base/fixture/index.md
new file mode 100644
index 00000000..50f40608
--- /dev/null
+++ b/__tests__/base/fixture/index.md
@@ -0,0 +1,13 @@
+# Home
+
+
+
+
+
+[to sub](/sub/page)
+
+[to dir](/sub/)
+
+[zip](/file.zip)
+
+[moved](/moved/target)
diff --git a/__tests__/base/fixture/posts.data.ts b/__tests__/base/fixture/posts.data.ts
new file mode 100644
index 00000000..8a3fb96b
--- /dev/null
+++ b/__tests__/base/fixture/posts.data.ts
@@ -0,0 +1,3 @@
+import { createContentLoader } from 'vitepress'
+
+export default createContentLoader('posts/**/*.md', { render: true })
diff --git a/__tests__/base/fixture/posts/deep/post1.md b/__tests__/base/fixture/posts/deep/post1.md
new file mode 100644
index 00000000..abcd0e35
--- /dev/null
+++ b/__tests__/base/fixture/posts/deep/post1.md
@@ -0,0 +1,5 @@
+# Post one
+
+This is the intro of post one with a [site link](/sub/page) and .
+
+More body.
diff --git a/__tests__/base/fixture/public/file.zip b/__tests__/base/fixture/public/file.zip
new file mode 100644
index 00000000..8c3b76fb
--- /dev/null
+++ b/__tests__/base/fixture/public/file.zip
@@ -0,0 +1 @@
+PKtest
\ No newline at end of file
diff --git a/__tests__/base/fixture/public/logo.png b/__tests__/base/fixture/public/logo.png
new file mode 100644
index 00000000..f37764b1
Binary files /dev/null and b/__tests__/base/fixture/public/logo.png differ
diff --git a/__tests__/base/fixture/src-moved.md b/__tests__/base/fixture/src-moved.md
new file mode 100644
index 00000000..92f16eaa
--- /dev/null
+++ b/__tests__/base/fixture/src-moved.md
@@ -0,0 +1,3 @@
+# Moved page
+
+Rewritten target.
diff --git a/__tests__/base/fixture/sub/deep/page2.md b/__tests__/base/fixture/sub/deep/page2.md
new file mode 100644
index 00000000..21f56a29
--- /dev/null
+++ b/__tests__/base/fixture/sub/deep/page2.md
@@ -0,0 +1,7 @@
+# Deep page
+
+[up](/sub/page)
+
+## Deep heading
+
+The xylophone paragraph for search.
diff --git a/__tests__/base/fixture/sub/index.md b/__tests__/base/fixture/sub/index.md
new file mode 100644
index 00000000..2a28bbf3
--- /dev/null
+++ b/__tests__/base/fixture/sub/index.md
@@ -0,0 +1,3 @@
+# Sub index
+
+Index of sub.
diff --git a/__tests__/base/fixture/sub/page.md b/__tests__/base/fixture/sub/page.md
new file mode 100644
index 00000000..6a5ca71a
--- /dev/null
+++ b/__tests__/base/fixture/sub/page.md
@@ -0,0 +1,15 @@
+# Sub page
+
+
+
+[home](/)
+
+[deep](/sub/deep/page2)
+
+[hash](#local-anchor)
+
+[external](https://example.com/x)
+
+## Local anchor
+
+Body text here.
diff --git a/__tests__/base/helpers.ts b/__tests__/base/helpers.ts
new file mode 100644
index 00000000..05b9723d
--- /dev/null
+++ b/__tests__/base/helpers.ts
@@ -0,0 +1,29 @@
+import { chromium, type Browser, type Page } from 'playwright-chromium'
+
+export interface TestPage {
+ browser: Browser
+ page: Page
+ errors: string[]
+}
+
+export async function newPage(): Promise {
+ const browser = await chromium.connect(process.env['WS_ENDPOINT']!)
+ const page = await browser.newPage()
+ const errors: string[] = []
+ page.on('console', (msg) => {
+ if (msg.type() === 'error') errors.push(msg.text())
+ })
+ page.on('pageerror', (err) => errors.push(String(err)))
+ return { browser, page, errors }
+}
+
+export function realErrors(errors: string[]): string[] {
+ return errors.filter((e) => !e.includes('favicon'))
+}
+
+export async function waitForHydration(page: Page): Promise {
+ await page.waitForSelector('#app .Layout')
+ await page.waitForFunction(
+ () => (document.querySelector('#app') as any)?.__vue_app__ !== undefined
+ )
+}
diff --git a/__tests__/base/package.json b/__tests__/base/package.json
new file mode 100644
index 00000000..555db084
--- /dev/null
+++ b/__tests__/base/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "tests-base",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "test": "vitest run",
+ "watch": "DEBUG=1 vitest"
+ },
+ "devDependencies": {
+ "vitepress": "workspace:*"
+ }
+}
diff --git a/__tests__/base/relative-file.test.ts b/__tests__/base/relative-file.test.ts
new file mode 100644
index 00000000..7e839416
--- /dev/null
+++ b/__tests__/base/relative-file.test.ts
@@ -0,0 +1,60 @@
+import { join, resolve } from 'node:path'
+import { fileURLToPath, pathToFileURL } from 'node:url'
+
+import { newPage, type TestPage } from './helpers'
+
+const dist = resolve(
+ fileURLToPath(import.meta.url),
+ '..',
+ 'fixture/.vitepress/dist-relative'
+)
+
+const fileUrl = (...p: string[]) => pathToFileURL(join(dist, ...p)).href
+
+let t: TestPage
+
+beforeAll(async () => {
+ t = await newPage()
+})
+
+afterAll(async () => {
+ await t.page.close()
+ await t.browser.close()
+})
+
+// module scripts are cors-blocked from disk, so nothing hydrates here; the
+// pre-rendered site must still be styled and navigable
+describe('relative base opened over file://', () => {
+ test('pages render styled with working images', async () => {
+ await t.page.goto(fileUrl('sub/page.html'))
+ expect(await t.page.textContent('h1')).toContain('Sub page')
+ const fontFamily = await t.page.evaluate(
+ () => getComputedStyle(document.body).fontFamily
+ )
+ expect(fontFamily).toContain('Inter')
+ const logoLoaded = await t.page.evaluate(
+ () =>
+ document.querySelector('img[alt="logo again"]')!
+ .naturalWidth
+ )
+ expect(logoLoaded).toBe(1)
+ })
+
+ test('content links navigate between files', async () => {
+ await t.page.click('.vp-doc a[href="../sub/deep/page2.html"]')
+ expect(await t.page.textContent('h1')).toContain('Deep page')
+ expect(t.page.url()).toBe(fileUrl('sub/deep/page2.html'))
+ })
+
+ test('theme links navigate between files', async () => {
+ await t.page.click('.VPSidebar a[href="../../moved/target.html"]')
+ expect(await t.page.textContent('h1')).toContain('Moved page')
+ expect(t.page.url()).toBe(fileUrl('moved/target.html'))
+ })
+
+ test('the root page reaches nested pages', async () => {
+ await t.page.goto(fileUrl('index.html'))
+ await t.page.click('.vp-doc a[href="./sub/index.html"]')
+ expect(await t.page.textContent('h1')).toContain('Sub index')
+ })
+})
diff --git a/__tests__/base/relative-spa.test.ts b/__tests__/base/relative-spa.test.ts
new file mode 100644
index 00000000..04e0732e
--- /dev/null
+++ b/__tests__/base/relative-spa.test.ts
@@ -0,0 +1,92 @@
+import { ALT_PREFIX, SUB_PREFIX } from './constants'
+import { newPage, realErrors, waitForHydration, type TestPage } from './helpers'
+
+const origin = () => `http://localhost:${process.env['SUB_PORT']}`
+
+let t: TestPage
+
+beforeAll(async () => {
+ t = await newPage()
+})
+
+afterAll(async () => {
+ await t.page.close()
+ await t.browser.close()
+})
+
+// mark the window with a marker that only survives client-side navigation,
+// proving no full document reload occurred
+const mark = () => t.page.evaluate(() => ((window as any).__spa_marker = 1))
+const marked = () => t.page.evaluate(() => (window as any).__spa_marker === 1)
+
+describe('relative base served from a deep subpath', () => {
+ test('deep link loads and hydrates', async () => {
+ await t.page.goto(`${origin()}${SUB_PREFIX}sub/deep/page2.html`)
+ await waitForHydration(t.page)
+ expect(await t.page.textContent('h1')).toContain('Deep page')
+ expect(await t.page.evaluate(() => (window as any).__VP_SITE_ROOT__)).toBe(
+ `${origin()}${SUB_PREFIX}`
+ )
+ })
+
+ test('sidebar navigation is client-side and lands on the right url', async () => {
+ await mark()
+ await t.page.click(`.VPSidebar a[href="${SUB_PREFIX}sub/page.html"]`)
+ await t.page.waitForFunction(() =>
+ document.querySelector('h1')?.textContent?.includes('Sub page')
+ )
+ expect(await marked()).toBe(true)
+ expect(new URL(t.page.url()).pathname).toBe(`${SUB_PREFIX}sub/page.html`)
+ })
+
+ test('content links navigate client-side', async () => {
+ await t.page.click('.vp-doc a[href="../index.html"]')
+ await t.page.waitForFunction(() =>
+ document.querySelector('h1')?.textContent?.includes('Home')
+ )
+ expect(await marked()).toBe(true)
+ // the router strips index.html from the address bar
+ expect(new URL(t.page.url()).pathname).toBe(SUB_PREFIX)
+ })
+
+ test('search finds pages and navigates to them', async () => {
+ await t.page.click('.VPNavBarSearchButton')
+ const input = await t.page.waitForSelector('input#localsearch-input')
+ await input.type('xylophone')
+ await t.page.waitForSelector('#localsearch-list li[role=option] a')
+ const href = await t.page.getAttribute(
+ '#localsearch-list li[role=option] a',
+ 'href'
+ )
+ expect(href).toBe(`${SUB_PREFIX}sub/deep/page2.html#deep-heading`)
+ await t.page.click('#localsearch-list li[role=option] a')
+ await t.page.waitForFunction(() =>
+ document.querySelector('h1')?.textContent?.includes('Deep page')
+ )
+ expect(await marked()).toBe(true)
+ })
+
+ test('history back keeps working', async () => {
+ await t.page.goBack()
+ await t.page.waitForFunction(() =>
+ document.querySelector('h1')?.textContent?.includes('Home')
+ )
+ expect(new URL(t.page.url()).pathname).toBe(SUB_PREFIX)
+ })
+
+ test('the same build works mounted at a different prefix', async () => {
+ await t.page.goto(`${origin()}${ALT_PREFIX}index.html`)
+ await waitForHydration(t.page)
+ await mark()
+ await t.page.click('.vp-doc a[href="./sub/page.html"]')
+ await t.page.waitForFunction(() =>
+ document.querySelector('h1')?.textContent?.includes('Sub page')
+ )
+ expect(await marked()).toBe(true)
+ expect(new URL(t.page.url()).pathname).toBe(`${ALT_PREFIX}sub/page.html`)
+ })
+
+ test('no console or page errors across the whole flow', () => {
+ expect(realErrors(t.errors)).toEqual([])
+ })
+})
diff --git a/__tests__/base/tsconfig.json b/__tests__/base/tsconfig.json
new file mode 100644
index 00000000..1759c08d
--- /dev/null
+++ b/__tests__/base/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "../tsconfig.json",
+ "include": ["**/*"],
+ "exclude": ["fixture/.vitepress/dist-*", "fixture/.vitepress/cache"]
+}
diff --git a/__tests__/base/vitest.config.ts b/__tests__/base/vitest.config.ts
new file mode 100644
index 00000000..43f17310
--- /dev/null
+++ b/__tests__/base/vitest.config.ts
@@ -0,0 +1,14 @@
+import { defineConfig } from 'vitest/config'
+
+const timeout = 60_000
+
+export default defineConfig({
+ test: {
+ globalSetup: ['vitestGlobalSetup.ts'],
+ testTimeout: timeout,
+ hookTimeout: timeout,
+ teardownTimeout: timeout,
+ globals: true,
+ fileParallelism: false
+ }
+})
diff --git a/__tests__/base/vitestGlobalSetup.ts b/__tests__/base/vitestGlobalSetup.ts
new file mode 100644
index 00000000..62953c6d
--- /dev/null
+++ b/__tests__/base/vitestGlobalSetup.ts
@@ -0,0 +1,120 @@
+import { spawnSync } from 'node:child_process'
+import { readFile, rm } from 'node:fs/promises'
+import { createServer, type Server } from 'node:http'
+import type { AddressInfo } from 'node:net'
+import { extname, join, resolve } from 'node:path'
+import { fileURLToPath } from 'node:url'
+
+import { chromium, type BrowserServer } from 'playwright-chromium'
+
+import { ALT_PREFIX, SUB_PREFIX } from './constants'
+
+const dir = resolve(fileURLToPath(import.meta.url), '..')
+const bin = resolve(dir, '../../bin/vitepress.js')
+const dist = (mode: string) => resolve(dir, `fixture/.vitepress/dist-${mode}`)
+
+const types: Record = {
+ '.html': 'text/html',
+ '.js': 'text/javascript',
+ '.css': 'text/css',
+ '.json': 'application/json',
+ '.png': 'image/png',
+ '.woff2': 'font/woff2',
+ '.zip': 'application/zip'
+}
+
+// listens on an os-assigned port (the other suites run in parallel on CI,
+// so a pre-picked "free" port can be taken before we bind it)
+function serveStatic(
+ mounts: [prefix: string, root: string][],
+ cors: boolean
+): Promise {
+ const server = createServer(async (req, res) => {
+ const url = decodeURIComponent(new URL(req.url!, 'http://x').pathname)
+ for (const [prefix, root] of mounts) {
+ if (!url.startsWith(prefix)) continue
+ let file = url.slice(prefix.length) || 'index.html'
+ if (file.endsWith('/')) file += 'index.html'
+ try {
+ const data = await readFile(join(root, file))
+ const headers: Record = {
+ 'content-type': types[extname(file)] ?? 'application/octet-stream'
+ }
+ if (cors) headers['access-control-allow-origin'] = '*'
+ res.writeHead(200, headers)
+ res.end(data)
+ return
+ } catch {}
+ }
+ res.writeHead(404)
+ res.end('not found')
+ })
+ return new Promise((r) => server.listen(0, () => r(server)))
+}
+
+const portOf = (server: Server) => (server.address() as AddressInfo).port
+
+let browserServer: BrowserServer
+let servers: Server[] = []
+
+export async function setup() {
+ // started before its dist exists so its real port can go into assetsBase
+ const cdnServer = await serveStatic([['/', dist('cdn')]], true)
+ const cdnPort = portOf(cdnServer)
+
+ // one process per flavor: the markdown renderer is a module-level
+ // singleton, so in-process builds would leak the first base into the rest
+ for (const mode of ['plain', 'relative', 'cdn', 'mpa']) {
+ // mpa builds never empty outDir, so stale assets would survive reruns
+ await rm(dist(mode), { recursive: true, force: true })
+ const res = spawnSync(process.execPath, [bin, 'build', 'fixture'], {
+ cwd: dir,
+ env: {
+ ...process.env,
+ VP_TEST_MODE: mode,
+ VP_CDN_PORT: String(cdnPort)
+ },
+ encoding: 'utf-8'
+ })
+ if (res.status !== 0) {
+ throw new Error(`build (${mode}) failed:\n${res.stdout}\n${res.stderr}`)
+ }
+ }
+
+ servers = [
+ // one relative-base build mounted at two unrelated prefixes
+ await serveStatic(
+ [
+ [SUB_PREFIX, dist('relative')],
+ [ALT_PREFIX, dist('relative')]
+ ],
+ false
+ ),
+ await serveStatic([['/', dist('cdn')]], false),
+ cdnServer
+ ]
+
+ browserServer = await chromium.launchServer({
+ headless: !process.env.DEBUG,
+ args: process.env.CI
+ ? ['--no-sandbox', '--disable-setuid-sandbox']
+ : undefined
+ })
+
+ process.env['WS_ENDPOINT'] = browserServer.wsEndpoint()
+ process.env['SUB_PORT'] = String(portOf(servers[0]!))
+ process.env['PAGES_PORT'] = String(portOf(servers[1]!))
+ process.env['VP_CDN_PORT'] = String(cdnPort)
+}
+
+export async function teardown() {
+ await browserServer.close()
+ await Promise.all(
+ servers.map(
+ (server) =>
+ new Promise((resolve, reject) =>
+ server.close((err) => (err ? reject(err) : resolve()))
+ )
+ )
+ )
+}
diff --git a/__tests__/e2e/.vitepress/config.ts b/__tests__/e2e/.vitepress/config.ts
index acd74892..2525f02b 100644
--- a/__tests__/e2e/.vitepress/config.ts
+++ b/__tests__/e2e/.vitepress/config.ts
@@ -201,6 +201,8 @@ export default defineConfig({
markdown: {
image: { lazyLoad: true }
},
+ // exercises force-inclusion of icons SSR never renders
+ icons: { include: ['lucide:egg'] },
themeConfig: {
nav,
sidebar,
@@ -210,11 +212,22 @@ export default defineConfig({
link: '/home',
ariaLabel: 'Home social link',
target: '_self'
+ },
+ {
+ icon: 'lucide:heart',
+ link: '/home',
+ ariaLabel: 'Heart social link'
}
],
search: {
provider: 'local',
options: {
+ miniSearch: {
+ options: {
+ tokenize: (text) =>
+ text.split(/[\n\r\p{Z}\p{Terminal_Punctuation}]+/u)
+ }
+ },
async _render(src, env, md) {
const html = await md.renderAsync(src, env)
if (env.frontmatter?.search === false) return ''
diff --git a/__tests__/e2e/icons/icons.test.ts b/__tests__/e2e/icons/icons.test.ts
new file mode 100644
index 00000000..e1127b2e
--- /dev/null
+++ b/__tests__/e2e/icons/icons.test.ts
@@ -0,0 +1,158 @@
+import { readFileSync, readdirSync } from 'node:fs'
+import { join, resolve } from 'node:path'
+import { fileURLToPath } from 'node:url'
+
+const isBuild = !!process.env.VITE_TEST_BUILD
+
+const maskImage = (selector: string) =>
+ page.$eval(selector, (el) => {
+ const styles = getComputedStyle(el)
+ return styles.maskImage || styles.webkitMaskImage
+ })
+
+describe('icons', () => {
+ const externalRequests: string[] = []
+ const devIconRequests: string[] = []
+
+ beforeAll(() => {
+ page.on('request', (request) => {
+ const url = request.url()
+ if (!url.startsWith(`http://localhost:${process.env['PORT']}`)) {
+ externalRequests.push(url)
+ }
+ if (url.includes('/_vpi/')) devIconRequests.push(url)
+ })
+ })
+
+ test('social links render from both collections', async () => {
+ await goto('/')
+
+ for (const [label, cls] of [
+ ['Home social link', '.vpi-simple-icons-github'],
+ ['Heart social link', '.vpi-lucide-heart']
+ ]) {
+ const selector = `a[aria-label="${label}"] span`
+ expect(await page.getAttribute(selector, 'class')).toBe(cls.slice(1))
+ // an unresolved icon computes to mask-image: none and renders nothing
+ await page.waitForFunction(
+ (sel) => {
+ const el = document.querySelector(sel)
+ if (!el) return false
+ const styles = getComputedStyle(el)
+ return (styles.maskImage || styles.webkitMaskImage) !== 'none'
+ },
+ selector,
+ { timeout: 3000 }
+ )
+ }
+ })
+
+ test('VPIcon renders collection, default-collection and raw svg icons', async () => {
+ await goto('/icons/')
+
+ expect(await page.getAttribute('[data-test-icon="lucide"]', 'class')).toBe(
+ 'vpi-lucide-rocket'
+ )
+ expect(await page.getAttribute('[data-test-icon="simple"]', 'class')).toBe(
+ 'vpi-simple-icons-vuedotjs'
+ )
+ expect(
+ await page.$eval('[data-test-icon="raw"]', (el) => el.innerHTML)
+ ).toContain('
')
+ })
+
+ test('skips v-pre scopes from attrs', async () => {
+ const html = await renderBody(
+ '**{{ $frontmatter.title }}**{v-pre} {{ $frontmatter.title }}'
+ )
+ expect(html).toContain(
+ '{{ $frontmatter.title }} Hello World'
+ )
+ })
+
+ test('tracks raw inline v-pre elements the way Vue parses them', async () => {
+ // a quoted attribute value may contain `>`
+ expect(
+ await renderBody(
+ '{{ $frontmatter.title }}'
+ )
+ ).toContain('{{ $frontmatter.title }}')
+ // tag names match case-insensitively, so the inner pair nests
+ expect(
+ await renderBody(
+ 'z abc {{ $frontmatter.title }} {{ $frontmatter.title }}'
+ )
+ ).toContain('c {{ $frontmatter.title }} Hello World')
+ // a self-closing same-name tag does not affect the scope
+ expect(
+ await renderBody('ab {{ $frontmatter.title }}')
+ ).toContain(' Hello World')
+ })
+
+ test('scopes v-pre in raw html blocks instead of bailing out', async () => {
+ // mentions of v-pre that open no scope leave the page alone
+ for (const block of [
+ '',
+ '',
+ '',
+ '{{ literal }}
'
+ ]) {
+ const html = await renderBody(`${block}\n\n{{ $frontmatter.title }}`)
+ expect(html).toContain('Hello World
')
+ }
+
+ // a scope that spans markdown ends at its closing tag
+ const html = await renderBody(
+ '\n\n{{ $frontmatter.title }}\n\n
\n\n{{ $frontmatter.title }}'
+ )
+ expect(html).toContain('{{ $frontmatter.title }}
')
+ expect(html).toContain('Hello World
')
+
+ // an unclosed scope spans the rest of the page
+ expect(
+ await renderBody('\n\n{{ $frontmatter.title }}')
+ ).not.toContain('Hello World')
+ })
+
+ test('leaves whitespace-sensitive spots inside raw inline elements', async () => {
+ // the runtime drops whitespace-only text nodes at element edges; an
+ // inlined value would merge with that whitespace and keep it
+ expect(
+ await renderBody('a
{{ $frontmatter.title }} b')
+ ).toContain('
{{ $frontmatter.title }} ')
+ expect(
+ await renderBody('a
\n{{ $frontmatter.title }}\nb')
+ ).toContain('{{ $frontmatter.title }}')
+ // non-whitespace neighbors and closing-tag adjacency are safe
+ expect(await renderBody('a
x {{ $frontmatter.title }}b')).toContain(
+ '
x Hello World'
+ )
+ expect(await renderBody('
x {{ $frontmatter.title }}')).toContain(
+ ' Hello World'
+ )
+ })
+
+ test('keeps values safe when the text renderer rule is replaced', async () => {
+ const md = await createMd({
+ config: (md) => {
+ md.renderer.rules.text = (tokens, idx) =>
+ escapeHtml(tokens[idx].content)
+ }
+ })
+ const html = await md.renderAsync(
+ frontmatter + '{{ $frontmatter.mustache }} and {{ $frontmatter.title }}'
+ )
+ // the unsafe value renders through its own token, not the text rule
+ expect(html).toContain('{{ x }} and Hello World')
+ expect(html).not.toContain('{{ x }}')
+ })
+
+ test('keeps toc titles escaped like the heading', async () => {
+ const html = await renderBody(
+ '## {{ $frontmatter.mustache }} {{ $frontmatter.amp }}\n\n[[toc]]'
+ )
+ expect(html).toContain('{{ x }} a < b')
+ // no live interpolation may reach the toc markup, and the toc must show
+ // the same text as the heading
+ const toc = html.slice(html.indexOf('