├── .editorconfig ├── .git-hooks └── pre-commit ├── .github └── workflows │ ├── release.yaml │ └── test.yaml ├── .gitignore ├── .npmrc ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── docs └── example │ ├── icons │ ├── heart-red.svg │ ├── heart.svg │ ├── sun-alpha.svg │ ├── sun.svg │ ├── thumbup-alpha.svg │ └── thumbup.svg │ ├── index.html │ ├── stack.svg │ └── style.css ├── eslint.config.js ├── gulpfile.js ├── lib └── index.js ├── package.json ├── pnpm-lock.yaml └── test └── index.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = tab 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.md] 11 | trim_trailing_whitespace = false 12 | 13 | [pnpm-lock.yaml] 14 | indent_style = space 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /.git-hooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | git stash -ku 3 | trap "git stash pop" EXIT 4 | pnpm test 5 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - release 7 | 8 | permissions: 9 | contents: write 10 | id-token: write 11 | 12 | jobs: 13 | release: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: pnpm/action-setup@v4 18 | - uses: actions/setup-node@v4 19 | with: 20 | node-version-file: package.json 21 | cache: pnpm 22 | - run: pnpm install 23 | - run: | 24 | echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" >> ~/.npmrc 25 | git config --global user.email "actions@users.noreply.github.com" 26 | git config --global user.name "GitHub Actions" 27 | RELEASE_DESCRIPTION=$(awk '/## \[Unreleased\]/{flag=1; next} /## \[/{flag=0} flag' ./CHANGELOG.md | sed '/^[[:space:]]*$/d') 28 | if echo "$RELEASE_DESCRIPTION" | grep -q '### Changed'; then 29 | pnpm version major 30 | elif echo "$RELEASE_DESCRIPTION" | grep -q '### Added'; then 31 | pnpm version minor 32 | elif echo "$RELEASE_DESCRIPTION" | grep -q '### Fixed'; then 33 | pnpm version patch 34 | fi 35 | echo "TAG_NAME=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV 36 | echo "RELEASE_DESCRIPTION<> $GITHUB_ENV 37 | echo "$RELEASE_DESCRIPTION" >> $GITHUB_ENV 38 | echo "EOF" >> $GITHUB_ENV 39 | - uses: softprops/action-gh-release@v2 40 | env: 41 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 42 | with: 43 | tag_name: ${{ env.TAG_NAME }} 44 | name: "Release ${{ env.TAG_NAME }}" 45 | body: ${{ env.RELEASE_DESCRIPTION }} 46 | draft: false 47 | prerelease: false 48 | - run: git fetch --all && git switch main && git rebase release && git push origin main 49 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - '*' 10 | 11 | env: 12 | FORCE_COLOR: true 13 | 14 | jobs: 15 | test: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: pnpm/action-setup@v4 20 | - uses: actions/setup-node@v4 21 | with: 22 | node-version-file: package.json 23 | cache: pnpm 24 | - run: pnpm install 25 | - run: pnpm test 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | package-lock.json 4 | yarn.lock 5 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | manage-package-manager-versions=true 3 | package-manager-strict=true 4 | shell-emulator=true 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | # Changelog 3 | 4 | All notable changes to this project will be documented in this file. 5 | 6 | The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org). 7 | 8 | ## [Unreleased] 9 | 10 | ## [5.0.1] — 2024–11–01 11 | 12 | ### Fixed 13 | 14 | - The deprecation warning for the `fs.Stats` constructor no longer litters the output in the terminal. 15 | 16 | ## [5.0.0] — 2024–10–30 17 | 18 | ### Changed 19 | 20 | - The minimum required `node.js` version has been increased to `20.12.0`, except for version `21`. 21 | 22 | ## [4.0.0] — 2024–05–11 23 | 24 | ### Changed 25 | 26 | - The plugin no longer accepts any options. Previously option defaults are now the only possible values: 27 | - subdirectory delimiter substitute — underscore; 28 | - space substitute — hyphen; 29 | - output file name — `stack.svg`. 30 | 31 | ## [3.0.0] — 2023–10–29 32 | 33 | ### Changed 34 | 35 | - The required `node.js` to the latest maintained LTS versions. 36 | 37 | ## [2.0.3] — 2023–10–29 38 | 39 | No significant changes. 40 | 41 | ## [2.0.2] — 2023–06–16 42 | 43 | No significant changes. 44 | 45 | ## [2.0.1] — 2023–03–20 46 | 47 | No significant changes. 48 | 49 | ## [2.0.0] — 2022–12–21 50 | 51 | ### Changed 52 | 53 | - Improved namespace processing: 54 | - Namespace values are now checked for uniqueness, since they are essential. 55 | - Different aliases of the same namespace are now cast to the same name. 56 | - The declaration of the deprecated namespace `http://www.w3.org/1999/xlink` and its aliases in `href` attribute prefixes are now removed. 57 | - Duplicate aliases of different namespaces are now renamed. 58 | - Declarations of only used namespaces are now added to the root `svg` element. 59 | - Namespace processing takes into account aliases for both attributes and tag names. 60 | - The main namespace `xmlns="http://www.w3.org/2000/svg"` has been moved to the map object. 61 | 62 | ## [1.1.0] — 2022–12–12 63 | 64 | ### Added 65 | 66 | - Removing whitespace between tags when reading icon code. It will allow even well-optimized icons to be kept in source files in a readable form of formatted code. 67 | 68 | ## [1.0.6] — 2022–10–28 69 | 70 | ### Fixed 71 | 72 | - Rendering in Safari. 73 | 74 | ## [1.0.5] — 2022–10–27 75 | 76 | ### Fixed 77 | 78 | - Support `node@16`. 79 | 80 | ## [1.0.4] — 2022–09–22 81 | 82 | No significant changes. 83 | 84 | ## [1.0.3] — 2022–09–04 85 | 86 | ### Fixed 87 | 88 | - The unnecessary XML declaration is no longer added. Because it turns out that not only the DTD is not needed, but also the XML declaration, since the values ​​used are the default values. Stack works without all this XML prolog. More details can be found in [supplementary material](https://oreillymedia.github.io/Using_SVG/extras/ch01-XML.html) to the book “Using SVG with CSS3 and HTML5”. 89 | - File existence check, which became unnecessary after the previous code optimization. 90 | 91 | ## [1.0.2] — 2022–09–01 92 | 93 | ### Fixed 94 | 95 | - Different icons may contain the same identifiers. Previously, this was not taken into account in any way and could lead to erroneous rendering. This is now fixed, all identifiers on the stack are unique. 96 | 97 | ## [1.0.1] — 2022–08–29 98 | 99 | ### Fixed 100 | 101 | - The contents of `defs` tags are no longer transferring to `defs` of the root element since there is no need for this. 102 | - Optional namespace `xmlns:xlink` is now added only if it is necessary. 103 | - The content of the icons does not turn into the `g` tag and the attributes remain on the `svg` tag, except deprecated and interfering. 104 | 105 | ## [1.0.0] — 2022–08–29 106 | 107 | ### Changed 108 | 109 | - The project has been renamed to **gulp-stacksvg**. 110 | - Changed sprite assembly method from _symbol_ to _stack_. 111 | - Project converted to es-module. 112 | - The ability to inline a sprite into markup has been removed. 113 | - Missing `viewBoxes` are now created from icon sizes. 114 | 115 | ### Added 116 | 117 | - `output`, `separator`, and `spacer` options. 118 | - [LICENSE](./LICENSE.md) file. 119 | - [CHANGELOG](./CHANGELOG.md) file. 120 | 121 | ## [0.0.1] — 2022–08–27 122 | 123 | Just forked the [gulp-svgstore](https://github.com/w0rm/gulp-svgstore) project. 124 | 125 | [Unreleased]: https://github.com/firefoxic/gulp-stacksvg/compare/v5.0.1...HEAD 126 | [5.0.1]: https://github.com/firefoxic/gulp-stacksvg/compare/v5.0.0...v5.0.1 127 | [5.0.0]: https://github.com/firefoxic/gulp-stacksvg/compare/v4.0.0...v5.0.0 128 | [4.0.0]: https://github.com/firefoxic/gulp-stacksvg/compare/v3.0.0...v4.0.0 129 | [3.0.0]: https://github.com/firefoxic/gulp-stacksvg/compare/v2.0.3...v3.0.0 130 | [2.0.3]: https://github.com/firefoxic/gulp-stacksvg/compare/v2.0.2...v2.0.3 131 | [2.0.2]: https://github.com/firefoxic/gulp-stacksvg/compare/v2.0.1...v2.0.2 132 | [2.0.1]: https://github.com/firefoxic/gulp-stacksvg/compare/v2.0.0...v2.0.1 133 | [2.0.0]: https://github.com/firefoxic/gulp-stacksvg/compare/v1.1.0...v2.0.0 134 | [1.1.0]: https://github.com/firefoxic/gulp-stacksvg/compare/v1.0.6...v1.1.0 135 | [1.0.6]: https://github.com/firefoxic/gulp-stacksvg/compare/v1.0.5...v1.0.6 136 | [1.0.5]: https://github.com/firefoxic/gulp-stacksvg/compare/v1.0.4...v1.0.5 137 | [1.0.4]: https://github.com/firefoxic/gulp-stacksvg/compare/v1.0.3...v1.0.4 138 | [1.0.3]: https://github.com/firefoxic/gulp-stacksvg/compare/v1.0.2...v1.0.3 139 | [1.0.2]: https://github.com/firefoxic/gulp-stacksvg/compare/v1.0.1...v1.0.2 140 | [1.0.1]: https://github.com/firefoxic/gulp-stacksvg/compare/v1.0.0...v1.0.1 141 | [1.0.0]: https://github.com/firefoxic/gulp-stacksvg/compare/v0.0.1...v1.0.0 142 | [0.0.1]: https://github.com/firefoxic/gulp-stacksvg/releases/tag/v0.0.1 143 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright © Sergey Artemov , 2022 4 | Copyright © Andrey Kuzmin , 2014 5 | 6 | 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: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | 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. 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # gulp-stacksvg 3 | 4 | [![License: MIT][license-image]][license-url] 5 | [![Changelog][changelog-image]][changelog-url] 6 | [![NPM version][npm-image]][npm-url] 7 | [![Test Status][test-image]][test-url] 8 | 9 | The gulp plugin to combine svg files into one using the stack method. 10 | 11 | ## Installation 12 | 13 | ```shell 14 | pnpm add -D gulp gulp-stacksvg 15 | ``` 16 | 17 | ## Usage 18 | 19 | Add the following to your `gulpfile.js`: 20 | 21 | ```js 22 | import { stacksvg } from "gulp-stacksvg" 23 | import { dest, src } from "gulp" 24 | 25 | export function createStack () { 26 | return src(`./src/shared/icons/**/*.svg`) 27 | .pipe(stacksvg()) 28 | .pipe(dest(`./dist/shared/icons`)) 29 | } 30 | ``` 31 | 32 | To combine all icons from `./src/shared/icons/` into the `./dist/shared/icons/stack.svg` run: 33 | 34 | ```shell 35 | pnpm exec gulp createStack 36 | ``` 37 | 38 | ## Why a stack? 39 | 40 | Unlike all other methods for assembling a sprite, the stack does not limit us in choosing how to insert a vector into a page. Take a look at [the results](https://demos.frontend-design.ru/sprite/src/) of different ways to display fragments of different types of sprites. 41 | 42 | We can use the stack in all four possible ways: 43 | 44 | - in markup: 45 | 46 | - in `src` of `img` tag — static, 47 | - in the `href` of the `use` tag — with the possibility of repainting, 48 | 49 | - in styles: 50 | 51 | - in `url()` properties `background` — static, 52 | - in `url()` properties `mask` — with the possibility of repainting. 53 | 54 | [Demo page](https://firefoxic.github.io/gulp-stacksvg/example/) to prove it. 55 | 56 | ## Stack under the hood 57 | 58 | This method was first mentioned in a Simurai [article](https://simurai.com/blog/2012/04/02/svg-stacks) on April 2, 2012. But even it uses unnecessarily complex code transformations. 59 | 60 | This can be done much easier. In general, the stack is arranged almost like a symbol sprite, but without changing the icon tag (it remains the `svg` tag, as in the original icon files) and with the addition of a tiny bit of style. 61 | 62 | ```xml 63 | 64 | 65 | 66 | ``` 67 | 68 | 69 | 70 | ```xml 71 | 72 | 73 | 74 | ``` 75 | 76 | 77 | 78 | ```xml 79 | 80 | 81 | 82 | ``` 83 | 84 | 85 | 86 | ```xml 87 | 88 | 89 | 90 | ``` 91 | 92 | ```xml 93 | 94 | ``` 95 | 96 | The magic is in the stack inner style, which shows only the fragment requested by the link, hiding everything else: 97 | 98 | ```css 99 | :root svg:not(:target) { display: none } 100 | ``` 101 | 102 | And now the icons from the external sprite are available in the styles heart 103 | 104 | ```html 105 | 108 | ``` 109 | 110 | ```css 111 | .button { 112 | display: inline-flex; 113 | align-items: center; 114 | gap: 0.5em; 115 | 116 | &:hover { 117 | --fill: red; 118 | } 119 | 120 | &::before { 121 | content: ""; 122 | width: 1em; 123 | height: 1em; 124 | /* icon shape */ 125 | mask: var(--icon) no-repeat center / contain; 126 | /* icon color */ 127 | background: var(--fill, orangered); 128 | } 129 | 130 | &:where(.button--icon_heart) { 131 | --icon: url("../icons/stack.svg#heart"); 132 | } 133 | } 134 | ``` 135 | 136 | For an icon inserted via `mask`, simply change the `background`. Moreover, unlike `use`, you can draw anything in the background under the mask, for example, a gradient. 137 | 138 | ## More info 139 | 140 | - [SVG sprites: old-school, modern, unknown, and forgotten](https://pepelsbey.dev/articles/svg-sprites/#forgotten-stacks) by [Vadim Makeev](https://mastodon.social/@pepelsbey) 141 | 142 | [license-url]: https://github.com/firefoxic/gulp-stacksvg/blob/main/LICENSE.md 143 | [license-image]: https://img.shields.io/badge/License-MIT-limegreen.svg 144 | 145 | [changelog-url]: https://github.com/firefoxic/gulp-stacksvg/blob/main/CHANGELOG.md 146 | [changelog-image]: https://img.shields.io/badge/CHANGELOG-md-limegreen 147 | 148 | [npm-url]: https://npmjs.com/package/gulp-stacksvg 149 | [npm-image]: https://badge.fury.io/js/gulp-stacksvg.svg 150 | 151 | [test-url]: https://github.com/firefoxic/gulp-stacksvg/actions 152 | [test-image]: https://github.com/firefoxic/gulp-stacksvg/actions/workflows/test.yaml/badge.svg?branch=main 153 | -------------------------------------------------------------------------------- /docs/example/icons/heart-red.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/example/icons/heart.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/example/icons/sun-alpha.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/example/icons/sun.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/example/icons/thumbup-alpha.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/example/icons/thumbup.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | gulp-stacksvg 8 | 9 | 10 | 11 | 12 | 13 |

Drawing stack fragments

14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 32 | 40 | 41 | 42 | 43 | 51 | 59 | 60 | 61 |
StylesMarkup
Dynamic 25 |

mask

26 |
27 | 28 | 29 | 30 |
31 |
33 |

use

34 |
35 | 36 | 37 | 38 |
39 |
Static 44 |

background

45 |
46 | 47 | 48 | 49 |
50 |
52 |

img

53 |
54 | 55 | 56 | 57 |
58 |
62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /docs/example/stack.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/example/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: system-ui, sans-serif; 3 | text-align: center; 4 | } 5 | 6 | body { 7 | margin: 0 auto; 8 | padding: 1em; 9 | max-width: max-content; 10 | } 11 | 12 | .icon { 13 | display: inline-block; 14 | width: 80px; 15 | height: 80px; 16 | transition: all 0.2s; 17 | } 18 | 19 | .filled { 20 | --fill: hsl(42 100% 55%); 21 | } 22 | 23 | .filled:hover { 24 | --fill: hsl(12 100% 55%); 25 | } 26 | 27 | .mask { 28 | /* stylelint-disable-next-line */ 29 | -webkit-mask: var(--icon) no-repeat center / contain; 30 | mask: var(--icon) no-repeat center / contain; 31 | background-color: var(--fill, hsl(0 0% 0%)); 32 | } 33 | 34 | .background { 35 | background: var(--icon) no-repeat center / contain; 36 | } 37 | 38 | .heart { 39 | --icon: url("./stack.svg#heart"); 40 | } 41 | 42 | .sun { 43 | --icon: url("./stack.svg#sun"); 44 | } 45 | 46 | .thumbup { 47 | --icon: url("./stack.svg#thumbup"); 48 | } 49 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import { default as firefoxicEslintConfig, globals } from "@firefoxic/eslint-config" 2 | 3 | /** @type {import('eslint').Linter.Config[]} */ 4 | export default [ 5 | { 6 | languageOptions: { 7 | globals: { 8 | ...globals.nodeBuiltin, 9 | }, 10 | }, 11 | }, 12 | ...firefoxicEslintConfig, 13 | ] 14 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | import { dest, src } from "gulp" 2 | 3 | import { stacksvg } from "./lib/index.js" 4 | 5 | export function createStack () { 6 | return src(`./docs/example/icons/**/*.svg`) 7 | .pipe(stacksvg()) 8 | .pipe(dest(`./docs/example/`)) 9 | } 10 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | import { createHmac } from "node:crypto" 2 | import { Transform } from "node:stream" 3 | import { basename, extname, sep } from "node:path" 4 | 5 | import { parse } from "node-html-parser" 6 | import PluginError from "plugin-error" 7 | import Vinyl from "vinyl" 8 | 9 | // TODO: Remove this when vinyl-fs removes the deprecated fs.Stats constructor. 10 | process.emitWarning = (warning, type) => { 11 | if (type === `DeprecationWarning` && warning === `fs.Stats constructor is deprecated.`) return 12 | 13 | return process.emitWarning(warning, type) 14 | } 15 | // See: https://github.com/gulpjs/vinyl-fs/issues/356 16 | 17 | let excessAttrs = [ 18 | `enable-background`, 19 | `height`, 20 | `version`, 21 | `width`, 22 | `x`, 23 | `xml:space`, 24 | `y`, 25 | ] 26 | 27 | const XLINK = `http://www.w3.org/1999/xlink` 28 | 29 | /** 30 | * Gulp plugin for combining SVG icons into a single file. 31 | * 32 | * @exports {function} stacksvg - Gulp plugin. 33 | */ 34 | export function stacksvg () { 35 | let isEmpty = true 36 | let ids = {} 37 | let namespaces = new Map([[`http://www.w3.org/2000/svg`, `xmlns`]]) 38 | let stack = parse(``) 39 | let rootSvg = stack.querySelector(`svg`) 40 | let stream = new Transform({ objectMode: true }) 41 | 42 | /** 43 | * Transform function for the plugin. 44 | * 45 | * @param {Vinyl} file - Gulp file object. 46 | * @param {string} [enc=null] - Encoding to use when writing the file. 47 | * @param {function} cb - Callback function. 48 | */ 49 | function transform (file, _, cb) { 50 | if (file.isStream()) { 51 | return cb(new PluginError(`gulp-stacksvg`, `Streams are not supported!`)) 52 | } 53 | 54 | if (file.isNull() || !parse(file.contents.toString()).querySelector(`svg`)) { 55 | return cb() 56 | } 57 | 58 | let iconDom = parse(file.contents.toString()).removeWhitespace() 59 | let iconSvg = iconDom.querySelector(`svg`) 60 | 61 | isEmpty = false 62 | 63 | let iconId = basename( 64 | file.relative.split(sep).join(`_`).replace(/\s/g, `-`), 65 | extname(file.relative), 66 | ) 67 | 68 | if (iconId in ids) { 69 | return cb(new PluginError(`gulp-stacksvg`, `File name should be unique: ${iconId}`)) 70 | } 71 | 72 | ids[iconId] = true 73 | iconSvg.setAttribute(`id`, iconId) 74 | 75 | let viewBoxAttr = iconSvg.getAttribute(`viewBox`) 76 | let widthAttr = iconSvg.getAttribute(`width`)?.replace(/[^0-9]/g, ``) 77 | let heightAttr = iconSvg.getAttribute(`height`)?.replace(/[^0-9]/g, ``) 78 | 79 | if (!viewBoxAttr && widthAttr && heightAttr) { 80 | iconSvg.setAttribute(`viewBox`, `0 0 ${widthAttr} ${heightAttr}`) 81 | } 82 | 83 | excessAttrs.forEach((attr) => iconSvg.removeAttribute(attr)) 84 | iconSvg.querySelectorAll(`[id]`).forEach(changeInnerId) 85 | 86 | /** 87 | * Update the id of a child element if it has the same id. 88 | * 89 | * @param {Element} targetElem - Child element to update. 90 | * @param {string} suffix - Suffix to append to the id. 91 | */ 92 | function changeInnerId (targetElem, suffix) { 93 | let oldId = targetElem.id 94 | let newId = `${iconId}_${suffix}` 95 | 96 | targetElem.setAttribute(`id`, newId) 97 | iconSvg.querySelectorAll(`*`).forEach(updateUsingId) 98 | 99 | /** 100 | * Update the id of a child element if it has the same id. 101 | * 102 | * @param {Element} elem - Child element to update. 103 | */ 104 | function updateUsingId (elem) { 105 | if (~elem.rawAttrs.search(`#${oldId}`)) { 106 | // eslint-disable-next-line guard-for-in 107 | for (let attr in elem._attrs) { 108 | let attrValue = elem._attrs[attr].replace(`#${oldId}`, `#${newId}`) 109 | 110 | elem.setAttribute(attr, attrValue) 111 | } 112 | } 113 | } 114 | } 115 | 116 | let attrs = iconSvg._attrs 117 | 118 | for (let attrName in attrs) { 119 | if (attrName.startsWith(`xmlns`)) { 120 | let nsId = attrs[attrName] 121 | let oldNsAlias = attrName.slice(6) 122 | let newNsAlias = oldNsAlias 123 | 124 | if (namespaces.has(nsId)) { 125 | if (namespaces.get(nsId) !== attrName) { 126 | newNsAlias = namespaces.get(nsId).slice(6) 127 | changeNsAlias(iconDom, oldNsAlias, newNsAlias) 128 | } 129 | } else if (nsId === XLINK) { 130 | newNsAlias = `` 131 | changeNsAlias(iconDom, oldNsAlias, newNsAlias) 132 | } else { 133 | for (let ns of namespaces.values()) { 134 | if (ns === attrName) { 135 | newNsAlias = `${oldNsAlias}${getHash(nsId)}` 136 | changeNsAlias(iconDom, oldNsAlias, newNsAlias) 137 | break 138 | } 139 | } 140 | 141 | iconDom.querySelectorAll(`*`).some((elem) => { 142 | if ( 143 | elem.rawTagName.startsWith(`${newNsAlias}:`) 144 | || Object.keys(elem._attrs).some((attr) => attr.startsWith(`${newNsAlias}:`)) 145 | ) { 146 | namespaces.set(nsId, `xmlns:${newNsAlias}`) 147 | 148 | return true 149 | } 150 | }) 151 | } 152 | 153 | iconSvg.removeAttribute(attrName) 154 | } 155 | } 156 | 157 | rootSvg.appendChild(iconSvg) 158 | 159 | cb() 160 | } 161 | 162 | /** 163 | * Flush function for the plugin. 164 | * 165 | * @param {function} cb - Callback function. 166 | */ 167 | function flush (cb) { 168 | if (isEmpty) { 169 | return cb() 170 | } 171 | 172 | for (let [nsId, nsAttr] of namespaces) { 173 | rootSvg.setAttribute(nsAttr, nsId) 174 | } 175 | 176 | let file = new Vinyl({ path: `stack.svg`, contents: Buffer.from(stack.toString()) }) 177 | 178 | this.push(file) 179 | 180 | cb() 181 | } 182 | 183 | stream._transform = transform 184 | stream._flush = flush 185 | 186 | return stream 187 | } 188 | 189 | /** 190 | * Changes the namespace alias of an element and all its children. 191 | * 192 | * @param {Element} iconDom - Element to modify. 193 | * @param {string} oldAlias - Old namespace alias to replace. 194 | * @param {string} newAlias - New namespace alias. 195 | */ 196 | function changeNsAlias (iconDom, oldAlias, newAlias) { 197 | iconDom.querySelectorAll(`*`).forEach((elem) => { 198 | let prefix = newAlias === `` ? `` : `${newAlias}:` 199 | 200 | if (elem.rawTagName.startsWith(`${oldAlias}:`)) { 201 | elem.rawTagName = `${prefix}${elem.rawTagName.slice((oldAlias.length + 1))}` 202 | } 203 | 204 | for (let name of Object.keys(elem._attrs)) { 205 | if (name.startsWith(`${oldAlias}:`)) { 206 | elem.setAttribute(`${prefix}${name.slice((oldAlias.length + 1))}`, elem._attrs[name]) 207 | elem.removeAttribute(name) 208 | } 209 | } 210 | }) 211 | } 212 | 213 | /** 214 | * Get a hash for a given string. 215 | * 216 | * @param {string} str - String to hash. 217 | * @returns {string} Hash of the string. 218 | */ 219 | function getHash (str) { 220 | return createHmac(`sha1`, `xmlns`) 221 | .update(str) 222 | .digest(`hex`) 223 | .slice(0, 7) 224 | } 225 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gulp-stacksvg", 3 | "description": "The gulp plugin to combine svg files into one using the stack method.", 4 | "version": "5.0.1", 5 | "license": "MIT", 6 | "author": { 7 | "name": "Sergey Artemov", 8 | "email": "firefoxic.dev@gmail.com" 9 | }, 10 | "homepage": "https://github.com/firefoxic/gulp-stacksvg#readme", 11 | "bugs": { 12 | "url": "https://github.com/firefoxic/gulp-stacksvg/issues" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git://github.com/firefoxic/gulp-stacksvg.git" 17 | }, 18 | "type": "module", 19 | "exports": "./lib/index.js", 20 | "files": [ 21 | "./lib/" 22 | ], 23 | "engines": { 24 | "node": "^20.12 || >=22.11" 25 | }, 26 | "packageManager": "pnpm@9.12.3", 27 | "dependencies": { 28 | "node-html-parser": "^6.1.13", 29 | "plugin-error": "^2.0.1", 30 | "vinyl": "^3.0.0" 31 | }, 32 | "scripts": { 33 | "prepare": "git config core.hooksPath .git-hooks || true", 34 | "lint": "eslint", 35 | "test": "node --test", 36 | "pretest": "pnpm lint", 37 | "preversion": "pnpm test", 38 | "version": "update-changelog", 39 | "postversion": "pnpm publish --provenance --access public --no-git-checks", 40 | "postpublish": "git push --follow-tags" 41 | }, 42 | "devDependencies": { 43 | "@firefoxic/eslint-config": "^4.0.0", 44 | "@firefoxic/update-changelog": "^1.0.0", 45 | "eslint": "^9.13.0", 46 | "gulp": "^5.0.0" 47 | }, 48 | "keywords": [ 49 | "gulp", 50 | "gulpplugin", 51 | "svg", 52 | "icon", 53 | "sprite", 54 | "stack", 55 | "vector" 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | node-html-parser: 12 | specifier: ^6.1.13 13 | version: 6.1.13 14 | plugin-error: 15 | specifier: ^2.0.1 16 | version: 2.0.1 17 | vinyl: 18 | specifier: ^3.0.0 19 | version: 3.0.0 20 | devDependencies: 21 | '@firefoxic/eslint-config': 22 | specifier: ^4.0.0 23 | version: 4.0.0(eslint@9.13.0) 24 | '@firefoxic/update-changelog': 25 | specifier: ^1.0.0 26 | version: 1.0.0 27 | eslint: 28 | specifier: ^9.13.0 29 | version: 9.13.0 30 | gulp: 31 | specifier: ^5.0.0 32 | version: 5.0.0 33 | 34 | packages: 35 | 36 | '@eslint-community/eslint-utils@4.4.1': 37 | resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} 38 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 39 | peerDependencies: 40 | eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 41 | 42 | '@eslint-community/regexpp@4.12.1': 43 | resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} 44 | engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} 45 | 46 | '@eslint/config-array@0.18.0': 47 | resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} 48 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 49 | 50 | '@eslint/core@0.7.0': 51 | resolution: {integrity: sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==} 52 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 53 | 54 | '@eslint/eslintrc@3.1.0': 55 | resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} 56 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 57 | 58 | '@eslint/js@9.13.0': 59 | resolution: {integrity: sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==} 60 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 61 | 62 | '@eslint/object-schema@2.1.4': 63 | resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} 64 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 65 | 66 | '@eslint/plugin-kit@0.2.2': 67 | resolution: {integrity: sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==} 68 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 69 | 70 | '@firefoxic/eslint-config@4.0.0': 71 | resolution: {integrity: sha512-ljcU3wDUnWLAANe4oBnvWPKmbOC6IvUgD7eSi7u6JQhtdCoDMh2txBA1Xlplv4wwqqa6r5zVdAWvhS48J+/58g==} 72 | engines: {node: ^20.12 || >=22.11} 73 | peerDependencies: 74 | eslint: ^9.13.0 75 | 76 | '@firefoxic/update-changelog@1.0.0': 77 | resolution: {integrity: sha512-vfT3FNjbF11l3ZbFPrVGgyk7RIF7USvS/e/JCqSsDDB8AxD9cT0/dmII27YX6mpQdK4E0bm2UDSY/TN8l6AKtw==} 78 | engines: {node: ^20.12 || >=22.11} 79 | hasBin: true 80 | 81 | '@gulpjs/messages@1.1.0': 82 | resolution: {integrity: sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==} 83 | engines: {node: '>=10.13.0'} 84 | 85 | '@gulpjs/to-absolute-glob@4.0.0': 86 | resolution: {integrity: sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==} 87 | engines: {node: '>=10.13.0'} 88 | 89 | '@humanfs/core@0.19.1': 90 | resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} 91 | engines: {node: '>=18.18.0'} 92 | 93 | '@humanfs/node@0.16.6': 94 | resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} 95 | engines: {node: '>=18.18.0'} 96 | 97 | '@humanwhocodes/module-importer@1.0.1': 98 | resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} 99 | engines: {node: '>=12.22'} 100 | 101 | '@humanwhocodes/retry@0.3.1': 102 | resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} 103 | engines: {node: '>=18.18'} 104 | 105 | '@stylistic/eslint-plugin-js@2.9.0': 106 | resolution: {integrity: sha512-h08DQybPsXxIvHIvQqU1tFWcu74M7kZK/0S0jVIDdoHSFq7jB+TzxikBWAg5j0lPR17WsGGGHAS8GHFlAAQXHA==} 107 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 108 | peerDependencies: 109 | eslint: '>=8.40.0' 110 | 111 | '@types/estree@1.0.6': 112 | resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} 113 | 114 | '@types/json-schema@7.0.15': 115 | resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} 116 | 117 | acorn-jsx@5.3.2: 118 | resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 119 | peerDependencies: 120 | acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 121 | 122 | acorn@8.14.0: 123 | resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} 124 | engines: {node: '>=0.4.0'} 125 | hasBin: true 126 | 127 | ajv@6.12.6: 128 | resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 129 | 130 | ansi-colors@1.1.0: 131 | resolution: {integrity: sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==} 132 | engines: {node: '>=0.10.0'} 133 | 134 | ansi-regex@5.0.1: 135 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 136 | engines: {node: '>=8'} 137 | 138 | ansi-styles@4.3.0: 139 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 140 | engines: {node: '>=8'} 141 | 142 | ansi-wrap@0.1.0: 143 | resolution: {integrity: sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==} 144 | engines: {node: '>=0.10.0'} 145 | 146 | anymatch@3.1.3: 147 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 148 | engines: {node: '>= 8'} 149 | 150 | argparse@2.0.1: 151 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 152 | 153 | array-each@1.0.1: 154 | resolution: {integrity: sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==} 155 | engines: {node: '>=0.10.0'} 156 | 157 | array-slice@1.1.0: 158 | resolution: {integrity: sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==} 159 | engines: {node: '>=0.10.0'} 160 | 161 | async-done@2.0.0: 162 | resolution: {integrity: sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==} 163 | engines: {node: '>= 10.13.0'} 164 | 165 | async-settle@2.0.0: 166 | resolution: {integrity: sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==} 167 | engines: {node: '>= 10.13.0'} 168 | 169 | bach@2.0.1: 170 | resolution: {integrity: sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==} 171 | engines: {node: '>=10.13.0'} 172 | 173 | balanced-match@1.0.2: 174 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 175 | 176 | bare-events@2.5.0: 177 | resolution: {integrity: sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==} 178 | 179 | base64-js@1.5.1: 180 | resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} 181 | 182 | binary-extensions@2.3.0: 183 | resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} 184 | engines: {node: '>=8'} 185 | 186 | bl@5.1.0: 187 | resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} 188 | 189 | boolbase@1.0.0: 190 | resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} 191 | 192 | brace-expansion@1.1.11: 193 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 194 | 195 | braces@3.0.3: 196 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 197 | engines: {node: '>=8'} 198 | 199 | buffer@6.0.3: 200 | resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} 201 | 202 | callsites@3.1.0: 203 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 204 | engines: {node: '>=6'} 205 | 206 | chalk@4.1.2: 207 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 208 | engines: {node: '>=10'} 209 | 210 | chokidar@3.6.0: 211 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} 212 | engines: {node: '>= 8.10.0'} 213 | 214 | cliui@7.0.4: 215 | resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} 216 | 217 | clone-stats@1.0.0: 218 | resolution: {integrity: sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==} 219 | 220 | clone@2.1.2: 221 | resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} 222 | engines: {node: '>=0.8'} 223 | 224 | color-convert@2.0.1: 225 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 226 | engines: {node: '>=7.0.0'} 227 | 228 | color-name@1.1.4: 229 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 230 | 231 | concat-map@0.0.1: 232 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 233 | 234 | convert-source-map@2.0.0: 235 | resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} 236 | 237 | copy-props@4.0.0: 238 | resolution: {integrity: sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==} 239 | engines: {node: '>= 10.13.0'} 240 | 241 | cross-spawn@7.0.3: 242 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 243 | engines: {node: '>= 8'} 244 | 245 | css-select@5.1.0: 246 | resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} 247 | 248 | css-what@6.1.0: 249 | resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} 250 | engines: {node: '>= 6'} 251 | 252 | debug@4.3.7: 253 | resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} 254 | engines: {node: '>=6.0'} 255 | peerDependencies: 256 | supports-color: '*' 257 | peerDependenciesMeta: 258 | supports-color: 259 | optional: true 260 | 261 | deep-is@0.1.4: 262 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} 263 | 264 | detect-file@1.0.0: 265 | resolution: {integrity: sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==} 266 | engines: {node: '>=0.10.0'} 267 | 268 | dom-serializer@2.0.0: 269 | resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} 270 | 271 | domelementtype@2.3.0: 272 | resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} 273 | 274 | domhandler@5.0.3: 275 | resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} 276 | engines: {node: '>= 4'} 277 | 278 | domutils@3.1.0: 279 | resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} 280 | 281 | each-props@3.0.0: 282 | resolution: {integrity: sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==} 283 | engines: {node: '>= 10.13.0'} 284 | 285 | emoji-regex@8.0.0: 286 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 287 | 288 | end-of-stream@1.4.4: 289 | resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} 290 | 291 | entities@4.5.0: 292 | resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} 293 | engines: {node: '>=0.12'} 294 | 295 | escalade@3.2.0: 296 | resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} 297 | engines: {node: '>=6'} 298 | 299 | escape-string-regexp@4.0.0: 300 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 301 | engines: {node: '>=10'} 302 | 303 | eslint-plugin-prefer-let@4.0.0: 304 | resolution: {integrity: sha512-X4ep5PMO1320HKaNC9DM5+p6XvOhwv+RcqGjhv3aiw9iAtHhiFtdIUB5l0Zya0iM22ys2BGKzrNI9Xpw/ZHooQ==} 305 | engines: {node: '>=0.10.0'} 306 | 307 | eslint-scope@8.2.0: 308 | resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} 309 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 310 | 311 | eslint-visitor-keys@3.4.3: 312 | resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} 313 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 314 | 315 | eslint-visitor-keys@4.2.0: 316 | resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} 317 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 318 | 319 | eslint@9.13.0: 320 | resolution: {integrity: sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==} 321 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 322 | hasBin: true 323 | peerDependencies: 324 | jiti: '*' 325 | peerDependenciesMeta: 326 | jiti: 327 | optional: true 328 | 329 | espree@10.3.0: 330 | resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} 331 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 332 | 333 | esquery@1.6.0: 334 | resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} 335 | engines: {node: '>=0.10'} 336 | 337 | esrecurse@4.3.0: 338 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} 339 | engines: {node: '>=4.0'} 340 | 341 | estraverse@5.3.0: 342 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} 343 | engines: {node: '>=4.0'} 344 | 345 | esutils@2.0.3: 346 | resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} 347 | engines: {node: '>=0.10.0'} 348 | 349 | expand-tilde@2.0.2: 350 | resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} 351 | engines: {node: '>=0.10.0'} 352 | 353 | extend@3.0.2: 354 | resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} 355 | 356 | fast-deep-equal@3.1.3: 357 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 358 | 359 | fast-fifo@1.3.2: 360 | resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} 361 | 362 | fast-json-stable-stringify@2.1.0: 363 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 364 | 365 | fast-levenshtein@2.0.6: 366 | resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 367 | 368 | fast-levenshtein@3.0.0: 369 | resolution: {integrity: sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==} 370 | 371 | fastest-levenshtein@1.0.16: 372 | resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} 373 | engines: {node: '>= 4.9.1'} 374 | 375 | fastq@1.17.1: 376 | resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} 377 | 378 | file-entry-cache@8.0.0: 379 | resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} 380 | engines: {node: '>=16.0.0'} 381 | 382 | fill-range@7.1.1: 383 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 384 | engines: {node: '>=8'} 385 | 386 | find-up@5.0.0: 387 | resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} 388 | engines: {node: '>=10'} 389 | 390 | findup-sync@5.0.0: 391 | resolution: {integrity: sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==} 392 | engines: {node: '>= 10.13.0'} 393 | 394 | fined@2.0.0: 395 | resolution: {integrity: sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==} 396 | engines: {node: '>= 10.13.0'} 397 | 398 | flagged-respawn@2.0.0: 399 | resolution: {integrity: sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==} 400 | engines: {node: '>= 10.13.0'} 401 | 402 | flat-cache@4.0.1: 403 | resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} 404 | engines: {node: '>=16'} 405 | 406 | flatted@3.3.1: 407 | resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} 408 | 409 | for-in@1.0.2: 410 | resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} 411 | engines: {node: '>=0.10.0'} 412 | 413 | for-own@1.0.0: 414 | resolution: {integrity: sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==} 415 | engines: {node: '>=0.10.0'} 416 | 417 | fs-mkdirp-stream@2.0.1: 418 | resolution: {integrity: sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==} 419 | engines: {node: '>=10.13.0'} 420 | 421 | fsevents@2.3.3: 422 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 423 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 424 | os: [darwin] 425 | 426 | function-bind@1.1.2: 427 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} 428 | 429 | get-caller-file@2.0.5: 430 | resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} 431 | engines: {node: 6.* || 8.* || >= 10.*} 432 | 433 | glob-parent@5.1.2: 434 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 435 | engines: {node: '>= 6'} 436 | 437 | glob-parent@6.0.2: 438 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 439 | engines: {node: '>=10.13.0'} 440 | 441 | glob-stream@8.0.2: 442 | resolution: {integrity: sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==} 443 | engines: {node: '>=10.13.0'} 444 | 445 | glob-watcher@6.0.0: 446 | resolution: {integrity: sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==} 447 | engines: {node: '>= 10.13.0'} 448 | 449 | global-modules@1.0.0: 450 | resolution: {integrity: sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==} 451 | engines: {node: '>=0.10.0'} 452 | 453 | global-prefix@1.0.2: 454 | resolution: {integrity: sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==} 455 | engines: {node: '>=0.10.0'} 456 | 457 | globals@14.0.0: 458 | resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} 459 | engines: {node: '>=18'} 460 | 461 | globals@15.11.0: 462 | resolution: {integrity: sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==} 463 | engines: {node: '>=18'} 464 | 465 | glogg@2.2.0: 466 | resolution: {integrity: sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==} 467 | engines: {node: '>= 10.13.0'} 468 | 469 | graceful-fs@4.2.11: 470 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 471 | 472 | gulp-cli@3.0.0: 473 | resolution: {integrity: sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==} 474 | engines: {node: '>=10.13.0'} 475 | hasBin: true 476 | 477 | gulp@5.0.0: 478 | resolution: {integrity: sha512-S8Z8066SSileaYw1S2N1I64IUc/myI2bqe2ihOBzO6+nKpvNSg7ZcWJt/AwF8LC/NVN+/QZ560Cb/5OPsyhkhg==} 479 | engines: {node: '>=10.13.0'} 480 | hasBin: true 481 | 482 | gulplog@2.2.0: 483 | resolution: {integrity: sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==} 484 | engines: {node: '>= 10.13.0'} 485 | 486 | has-flag@4.0.0: 487 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 488 | engines: {node: '>=8'} 489 | 490 | hasown@2.0.2: 491 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} 492 | engines: {node: '>= 0.4'} 493 | 494 | he@1.2.0: 495 | resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} 496 | hasBin: true 497 | 498 | homedir-polyfill@1.0.3: 499 | resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} 500 | engines: {node: '>=0.10.0'} 501 | 502 | iconv-lite@0.6.3: 503 | resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} 504 | engines: {node: '>=0.10.0'} 505 | 506 | ieee754@1.2.1: 507 | resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} 508 | 509 | ignore@5.3.2: 510 | resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} 511 | engines: {node: '>= 4'} 512 | 513 | import-fresh@3.3.0: 514 | resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} 515 | engines: {node: '>=6'} 516 | 517 | imurmurhash@0.1.4: 518 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} 519 | engines: {node: '>=0.8.19'} 520 | 521 | inherits@2.0.4: 522 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 523 | 524 | ini@1.3.8: 525 | resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} 526 | 527 | interpret@3.1.1: 528 | resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} 529 | engines: {node: '>=10.13.0'} 530 | 531 | is-absolute@1.0.0: 532 | resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==} 533 | engines: {node: '>=0.10.0'} 534 | 535 | is-binary-path@2.1.0: 536 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 537 | engines: {node: '>=8'} 538 | 539 | is-core-module@2.15.1: 540 | resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} 541 | engines: {node: '>= 0.4'} 542 | 543 | is-extglob@2.1.1: 544 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 545 | engines: {node: '>=0.10.0'} 546 | 547 | is-fullwidth-code-point@3.0.0: 548 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 549 | engines: {node: '>=8'} 550 | 551 | is-glob@4.0.3: 552 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 553 | engines: {node: '>=0.10.0'} 554 | 555 | is-negated-glob@1.0.0: 556 | resolution: {integrity: sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==} 557 | engines: {node: '>=0.10.0'} 558 | 559 | is-number@7.0.0: 560 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 561 | engines: {node: '>=0.12.0'} 562 | 563 | is-plain-object@5.0.0: 564 | resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} 565 | engines: {node: '>=0.10.0'} 566 | 567 | is-relative@1.0.0: 568 | resolution: {integrity: sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==} 569 | engines: {node: '>=0.10.0'} 570 | 571 | is-unc-path@1.0.0: 572 | resolution: {integrity: sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==} 573 | engines: {node: '>=0.10.0'} 574 | 575 | is-valid-glob@1.0.0: 576 | resolution: {integrity: sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==} 577 | engines: {node: '>=0.10.0'} 578 | 579 | is-windows@1.0.2: 580 | resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} 581 | engines: {node: '>=0.10.0'} 582 | 583 | isexe@2.0.0: 584 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 585 | 586 | isobject@3.0.1: 587 | resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} 588 | engines: {node: '>=0.10.0'} 589 | 590 | js-yaml@4.1.0: 591 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} 592 | hasBin: true 593 | 594 | json-buffer@3.0.1: 595 | resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} 596 | 597 | json-schema-traverse@0.4.1: 598 | resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 599 | 600 | json-stable-stringify-without-jsonify@1.0.1: 601 | resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} 602 | 603 | keyv@4.5.4: 604 | resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} 605 | 606 | last-run@2.0.0: 607 | resolution: {integrity: sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==} 608 | engines: {node: '>= 10.13.0'} 609 | 610 | lead@4.0.0: 611 | resolution: {integrity: sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==} 612 | engines: {node: '>=10.13.0'} 613 | 614 | levn@0.4.1: 615 | resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} 616 | engines: {node: '>= 0.8.0'} 617 | 618 | liftoff@5.0.0: 619 | resolution: {integrity: sha512-a5BQjbCHnB+cy+gsro8lXJ4kZluzOijzJ1UVVfyJYZC+IP2pLv1h4+aysQeKuTmyO8NAqfyQAk4HWaP/HjcKTg==} 620 | engines: {node: '>=10.13.0'} 621 | 622 | locate-path@6.0.0: 623 | resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} 624 | engines: {node: '>=10'} 625 | 626 | lodash.merge@4.6.2: 627 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} 628 | 629 | map-cache@0.2.2: 630 | resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} 631 | engines: {node: '>=0.10.0'} 632 | 633 | micromatch@4.0.8: 634 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 635 | engines: {node: '>=8.6'} 636 | 637 | minimatch@3.1.2: 638 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 639 | 640 | ms@2.1.3: 641 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 642 | 643 | mute-stdout@2.0.0: 644 | resolution: {integrity: sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==} 645 | engines: {node: '>= 10.13.0'} 646 | 647 | natural-compare@1.4.0: 648 | resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 649 | 650 | node-html-parser@6.1.13: 651 | resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==} 652 | 653 | normalize-path@3.0.0: 654 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 655 | engines: {node: '>=0.10.0'} 656 | 657 | now-and-later@3.0.0: 658 | resolution: {integrity: sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==} 659 | engines: {node: '>= 10.13.0'} 660 | 661 | nth-check@2.1.1: 662 | resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} 663 | 664 | object.defaults@1.1.0: 665 | resolution: {integrity: sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==} 666 | engines: {node: '>=0.10.0'} 667 | 668 | object.pick@1.3.0: 669 | resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} 670 | engines: {node: '>=0.10.0'} 671 | 672 | once@1.4.0: 673 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 674 | 675 | optionator@0.9.4: 676 | resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} 677 | engines: {node: '>= 0.8.0'} 678 | 679 | p-limit@3.1.0: 680 | resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 681 | engines: {node: '>=10'} 682 | 683 | p-locate@5.0.0: 684 | resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} 685 | engines: {node: '>=10'} 686 | 687 | parent-module@1.0.1: 688 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 689 | engines: {node: '>=6'} 690 | 691 | parse-filepath@1.0.2: 692 | resolution: {integrity: sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==} 693 | engines: {node: '>=0.8'} 694 | 695 | parse-passwd@1.0.0: 696 | resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} 697 | engines: {node: '>=0.10.0'} 698 | 699 | path-exists@4.0.0: 700 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 701 | engines: {node: '>=8'} 702 | 703 | path-key@3.1.1: 704 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 705 | engines: {node: '>=8'} 706 | 707 | path-parse@1.0.7: 708 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 709 | 710 | path-root-regex@0.1.2: 711 | resolution: {integrity: sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==} 712 | engines: {node: '>=0.10.0'} 713 | 714 | path-root@0.1.1: 715 | resolution: {integrity: sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==} 716 | engines: {node: '>=0.10.0'} 717 | 718 | picomatch@2.3.1: 719 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 720 | engines: {node: '>=8.6'} 721 | 722 | plugin-error@2.0.1: 723 | resolution: {integrity: sha512-zMakqvIDyY40xHOvzXka0kUvf40nYIuwRE8dWhti2WtjQZ31xAgBZBhxsK7vK3QbRXS1Xms/LO7B5cuAsfB2Gg==} 724 | engines: {node: '>=10.13.0'} 725 | 726 | prelude-ls@1.2.1: 727 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} 728 | engines: {node: '>= 0.8.0'} 729 | 730 | punycode@2.3.1: 731 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} 732 | engines: {node: '>=6'} 733 | 734 | queue-tick@1.0.1: 735 | resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} 736 | 737 | readable-stream@3.6.2: 738 | resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} 739 | engines: {node: '>= 6'} 740 | 741 | readdirp@3.6.0: 742 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 743 | engines: {node: '>=8.10.0'} 744 | 745 | rechoir@0.8.0: 746 | resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} 747 | engines: {node: '>= 10.13.0'} 748 | 749 | remove-trailing-separator@1.1.0: 750 | resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} 751 | 752 | replace-ext@2.0.0: 753 | resolution: {integrity: sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==} 754 | engines: {node: '>= 10'} 755 | 756 | replace-homedir@2.0.0: 757 | resolution: {integrity: sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==} 758 | engines: {node: '>= 10.13.0'} 759 | 760 | require-directory@2.1.1: 761 | resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} 762 | engines: {node: '>=0.10.0'} 763 | 764 | requireindex@1.2.0: 765 | resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} 766 | engines: {node: '>=0.10.5'} 767 | 768 | resolve-dir@1.0.1: 769 | resolution: {integrity: sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==} 770 | engines: {node: '>=0.10.0'} 771 | 772 | resolve-from@4.0.0: 773 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 774 | engines: {node: '>=4'} 775 | 776 | resolve-options@2.0.0: 777 | resolution: {integrity: sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==} 778 | engines: {node: '>= 10.13.0'} 779 | 780 | resolve@1.22.8: 781 | resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} 782 | hasBin: true 783 | 784 | reusify@1.0.4: 785 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 786 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 787 | 788 | safe-buffer@5.2.1: 789 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 790 | 791 | safer-buffer@2.1.2: 792 | resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 793 | 794 | semver-greatest-satisfied-range@2.0.0: 795 | resolution: {integrity: sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==} 796 | engines: {node: '>= 10.13.0'} 797 | 798 | semver@6.3.1: 799 | resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} 800 | hasBin: true 801 | 802 | shebang-command@2.0.0: 803 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 804 | engines: {node: '>=8'} 805 | 806 | shebang-regex@3.0.0: 807 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 808 | engines: {node: '>=8'} 809 | 810 | sparkles@2.1.0: 811 | resolution: {integrity: sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==} 812 | engines: {node: '>= 10.13.0'} 813 | 814 | stream-composer@1.0.2: 815 | resolution: {integrity: sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==} 816 | 817 | stream-exhaust@1.0.2: 818 | resolution: {integrity: sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==} 819 | 820 | streamx@2.20.1: 821 | resolution: {integrity: sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==} 822 | 823 | string-width@4.2.3: 824 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 825 | engines: {node: '>=8'} 826 | 827 | string_decoder@1.3.0: 828 | resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} 829 | 830 | strip-ansi@6.0.1: 831 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 832 | engines: {node: '>=8'} 833 | 834 | strip-json-comments@3.1.1: 835 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} 836 | engines: {node: '>=8'} 837 | 838 | supports-color@7.2.0: 839 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 840 | engines: {node: '>=8'} 841 | 842 | supports-preserve-symlinks-flag@1.0.0: 843 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 844 | engines: {node: '>= 0.4'} 845 | 846 | sver@1.8.4: 847 | resolution: {integrity: sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==} 848 | 849 | teex@1.0.1: 850 | resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} 851 | 852 | text-decoder@1.2.1: 853 | resolution: {integrity: sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==} 854 | 855 | text-table@0.2.0: 856 | resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} 857 | 858 | to-regex-range@5.0.1: 859 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 860 | engines: {node: '>=8.0'} 861 | 862 | to-through@3.0.0: 863 | resolution: {integrity: sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==} 864 | engines: {node: '>=10.13.0'} 865 | 866 | type-check@0.4.0: 867 | resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} 868 | engines: {node: '>= 0.8.0'} 869 | 870 | unc-path-regex@0.1.2: 871 | resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==} 872 | engines: {node: '>=0.10.0'} 873 | 874 | undertaker-registry@2.0.0: 875 | resolution: {integrity: sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==} 876 | engines: {node: '>= 10.13.0'} 877 | 878 | undertaker@2.0.0: 879 | resolution: {integrity: sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==} 880 | engines: {node: '>=10.13.0'} 881 | 882 | uri-js@4.4.1: 883 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 884 | 885 | util-deprecate@1.0.2: 886 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 887 | 888 | v8flags@4.0.1: 889 | resolution: {integrity: sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==} 890 | engines: {node: '>= 10.13.0'} 891 | 892 | value-or-function@4.0.0: 893 | resolution: {integrity: sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==} 894 | engines: {node: '>= 10.13.0'} 895 | 896 | vinyl-contents@2.0.0: 897 | resolution: {integrity: sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==} 898 | engines: {node: '>=10.13.0'} 899 | 900 | vinyl-fs@4.0.0: 901 | resolution: {integrity: sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==} 902 | engines: {node: '>=10.13.0'} 903 | 904 | vinyl-sourcemap@2.0.0: 905 | resolution: {integrity: sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==} 906 | engines: {node: '>=10.13.0'} 907 | 908 | vinyl@3.0.0: 909 | resolution: {integrity: sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==} 910 | engines: {node: '>=10.13.0'} 911 | 912 | which@1.3.1: 913 | resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} 914 | hasBin: true 915 | 916 | which@2.0.2: 917 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 918 | engines: {node: '>= 8'} 919 | hasBin: true 920 | 921 | word-wrap@1.2.5: 922 | resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} 923 | engines: {node: '>=0.10.0'} 924 | 925 | wrap-ansi@7.0.0: 926 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 927 | engines: {node: '>=10'} 928 | 929 | wrappy@1.0.2: 930 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 931 | 932 | y18n@5.0.8: 933 | resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} 934 | engines: {node: '>=10'} 935 | 936 | yargs-parser@20.2.9: 937 | resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} 938 | engines: {node: '>=10'} 939 | 940 | yargs@16.2.0: 941 | resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} 942 | engines: {node: '>=10'} 943 | 944 | yocto-queue@0.1.0: 945 | resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} 946 | engines: {node: '>=10'} 947 | 948 | snapshots: 949 | 950 | '@eslint-community/eslint-utils@4.4.1(eslint@9.13.0)': 951 | dependencies: 952 | eslint: 9.13.0 953 | eslint-visitor-keys: 3.4.3 954 | 955 | '@eslint-community/regexpp@4.12.1': {} 956 | 957 | '@eslint/config-array@0.18.0': 958 | dependencies: 959 | '@eslint/object-schema': 2.1.4 960 | debug: 4.3.7 961 | minimatch: 3.1.2 962 | transitivePeerDependencies: 963 | - supports-color 964 | 965 | '@eslint/core@0.7.0': {} 966 | 967 | '@eslint/eslintrc@3.1.0': 968 | dependencies: 969 | ajv: 6.12.6 970 | debug: 4.3.7 971 | espree: 10.3.0 972 | globals: 14.0.0 973 | ignore: 5.3.2 974 | import-fresh: 3.3.0 975 | js-yaml: 4.1.0 976 | minimatch: 3.1.2 977 | strip-json-comments: 3.1.1 978 | transitivePeerDependencies: 979 | - supports-color 980 | 981 | '@eslint/js@9.13.0': {} 982 | 983 | '@eslint/object-schema@2.1.4': {} 984 | 985 | '@eslint/plugin-kit@0.2.2': 986 | dependencies: 987 | levn: 0.4.1 988 | 989 | '@firefoxic/eslint-config@4.0.0(eslint@9.13.0)': 990 | dependencies: 991 | '@eslint/js': 9.13.0 992 | '@stylistic/eslint-plugin-js': 2.9.0(eslint@9.13.0) 993 | eslint: 9.13.0 994 | eslint-plugin-prefer-let: 4.0.0 995 | globals: 15.11.0 996 | 997 | '@firefoxic/update-changelog@1.0.0': {} 998 | 999 | '@gulpjs/messages@1.1.0': {} 1000 | 1001 | '@gulpjs/to-absolute-glob@4.0.0': 1002 | dependencies: 1003 | is-negated-glob: 1.0.0 1004 | 1005 | '@humanfs/core@0.19.1': {} 1006 | 1007 | '@humanfs/node@0.16.6': 1008 | dependencies: 1009 | '@humanfs/core': 0.19.1 1010 | '@humanwhocodes/retry': 0.3.1 1011 | 1012 | '@humanwhocodes/module-importer@1.0.1': {} 1013 | 1014 | '@humanwhocodes/retry@0.3.1': {} 1015 | 1016 | '@stylistic/eslint-plugin-js@2.9.0(eslint@9.13.0)': 1017 | dependencies: 1018 | eslint: 9.13.0 1019 | eslint-visitor-keys: 4.2.0 1020 | espree: 10.3.0 1021 | 1022 | '@types/estree@1.0.6': {} 1023 | 1024 | '@types/json-schema@7.0.15': {} 1025 | 1026 | acorn-jsx@5.3.2(acorn@8.14.0): 1027 | dependencies: 1028 | acorn: 8.14.0 1029 | 1030 | acorn@8.14.0: {} 1031 | 1032 | ajv@6.12.6: 1033 | dependencies: 1034 | fast-deep-equal: 3.1.3 1035 | fast-json-stable-stringify: 2.1.0 1036 | json-schema-traverse: 0.4.1 1037 | uri-js: 4.4.1 1038 | 1039 | ansi-colors@1.1.0: 1040 | dependencies: 1041 | ansi-wrap: 0.1.0 1042 | 1043 | ansi-regex@5.0.1: {} 1044 | 1045 | ansi-styles@4.3.0: 1046 | dependencies: 1047 | color-convert: 2.0.1 1048 | 1049 | ansi-wrap@0.1.0: {} 1050 | 1051 | anymatch@3.1.3: 1052 | dependencies: 1053 | normalize-path: 3.0.0 1054 | picomatch: 2.3.1 1055 | 1056 | argparse@2.0.1: {} 1057 | 1058 | array-each@1.0.1: {} 1059 | 1060 | array-slice@1.1.0: {} 1061 | 1062 | async-done@2.0.0: 1063 | dependencies: 1064 | end-of-stream: 1.4.4 1065 | once: 1.4.0 1066 | stream-exhaust: 1.0.2 1067 | 1068 | async-settle@2.0.0: 1069 | dependencies: 1070 | async-done: 2.0.0 1071 | 1072 | bach@2.0.1: 1073 | dependencies: 1074 | async-done: 2.0.0 1075 | async-settle: 2.0.0 1076 | now-and-later: 3.0.0 1077 | 1078 | balanced-match@1.0.2: {} 1079 | 1080 | bare-events@2.5.0: 1081 | optional: true 1082 | 1083 | base64-js@1.5.1: {} 1084 | 1085 | binary-extensions@2.3.0: {} 1086 | 1087 | bl@5.1.0: 1088 | dependencies: 1089 | buffer: 6.0.3 1090 | inherits: 2.0.4 1091 | readable-stream: 3.6.2 1092 | 1093 | boolbase@1.0.0: {} 1094 | 1095 | brace-expansion@1.1.11: 1096 | dependencies: 1097 | balanced-match: 1.0.2 1098 | concat-map: 0.0.1 1099 | 1100 | braces@3.0.3: 1101 | dependencies: 1102 | fill-range: 7.1.1 1103 | 1104 | buffer@6.0.3: 1105 | dependencies: 1106 | base64-js: 1.5.1 1107 | ieee754: 1.2.1 1108 | 1109 | callsites@3.1.0: {} 1110 | 1111 | chalk@4.1.2: 1112 | dependencies: 1113 | ansi-styles: 4.3.0 1114 | supports-color: 7.2.0 1115 | 1116 | chokidar@3.6.0: 1117 | dependencies: 1118 | anymatch: 3.1.3 1119 | braces: 3.0.3 1120 | glob-parent: 5.1.2 1121 | is-binary-path: 2.1.0 1122 | is-glob: 4.0.3 1123 | normalize-path: 3.0.0 1124 | readdirp: 3.6.0 1125 | optionalDependencies: 1126 | fsevents: 2.3.3 1127 | 1128 | cliui@7.0.4: 1129 | dependencies: 1130 | string-width: 4.2.3 1131 | strip-ansi: 6.0.1 1132 | wrap-ansi: 7.0.0 1133 | 1134 | clone-stats@1.0.0: {} 1135 | 1136 | clone@2.1.2: {} 1137 | 1138 | color-convert@2.0.1: 1139 | dependencies: 1140 | color-name: 1.1.4 1141 | 1142 | color-name@1.1.4: {} 1143 | 1144 | concat-map@0.0.1: {} 1145 | 1146 | convert-source-map@2.0.0: {} 1147 | 1148 | copy-props@4.0.0: 1149 | dependencies: 1150 | each-props: 3.0.0 1151 | is-plain-object: 5.0.0 1152 | 1153 | cross-spawn@7.0.3: 1154 | dependencies: 1155 | path-key: 3.1.1 1156 | shebang-command: 2.0.0 1157 | which: 2.0.2 1158 | 1159 | css-select@5.1.0: 1160 | dependencies: 1161 | boolbase: 1.0.0 1162 | css-what: 6.1.0 1163 | domhandler: 5.0.3 1164 | domutils: 3.1.0 1165 | nth-check: 2.1.1 1166 | 1167 | css-what@6.1.0: {} 1168 | 1169 | debug@4.3.7: 1170 | dependencies: 1171 | ms: 2.1.3 1172 | 1173 | deep-is@0.1.4: {} 1174 | 1175 | detect-file@1.0.0: {} 1176 | 1177 | dom-serializer@2.0.0: 1178 | dependencies: 1179 | domelementtype: 2.3.0 1180 | domhandler: 5.0.3 1181 | entities: 4.5.0 1182 | 1183 | domelementtype@2.3.0: {} 1184 | 1185 | domhandler@5.0.3: 1186 | dependencies: 1187 | domelementtype: 2.3.0 1188 | 1189 | domutils@3.1.0: 1190 | dependencies: 1191 | dom-serializer: 2.0.0 1192 | domelementtype: 2.3.0 1193 | domhandler: 5.0.3 1194 | 1195 | each-props@3.0.0: 1196 | dependencies: 1197 | is-plain-object: 5.0.0 1198 | object.defaults: 1.1.0 1199 | 1200 | emoji-regex@8.0.0: {} 1201 | 1202 | end-of-stream@1.4.4: 1203 | dependencies: 1204 | once: 1.4.0 1205 | 1206 | entities@4.5.0: {} 1207 | 1208 | escalade@3.2.0: {} 1209 | 1210 | escape-string-regexp@4.0.0: {} 1211 | 1212 | eslint-plugin-prefer-let@4.0.0: 1213 | dependencies: 1214 | requireindex: 1.2.0 1215 | 1216 | eslint-scope@8.2.0: 1217 | dependencies: 1218 | esrecurse: 4.3.0 1219 | estraverse: 5.3.0 1220 | 1221 | eslint-visitor-keys@3.4.3: {} 1222 | 1223 | eslint-visitor-keys@4.2.0: {} 1224 | 1225 | eslint@9.13.0: 1226 | dependencies: 1227 | '@eslint-community/eslint-utils': 4.4.1(eslint@9.13.0) 1228 | '@eslint-community/regexpp': 4.12.1 1229 | '@eslint/config-array': 0.18.0 1230 | '@eslint/core': 0.7.0 1231 | '@eslint/eslintrc': 3.1.0 1232 | '@eslint/js': 9.13.0 1233 | '@eslint/plugin-kit': 0.2.2 1234 | '@humanfs/node': 0.16.6 1235 | '@humanwhocodes/module-importer': 1.0.1 1236 | '@humanwhocodes/retry': 0.3.1 1237 | '@types/estree': 1.0.6 1238 | '@types/json-schema': 7.0.15 1239 | ajv: 6.12.6 1240 | chalk: 4.1.2 1241 | cross-spawn: 7.0.3 1242 | debug: 4.3.7 1243 | escape-string-regexp: 4.0.0 1244 | eslint-scope: 8.2.0 1245 | eslint-visitor-keys: 4.2.0 1246 | espree: 10.3.0 1247 | esquery: 1.6.0 1248 | esutils: 2.0.3 1249 | fast-deep-equal: 3.1.3 1250 | file-entry-cache: 8.0.0 1251 | find-up: 5.0.0 1252 | glob-parent: 6.0.2 1253 | ignore: 5.3.2 1254 | imurmurhash: 0.1.4 1255 | is-glob: 4.0.3 1256 | json-stable-stringify-without-jsonify: 1.0.1 1257 | lodash.merge: 4.6.2 1258 | minimatch: 3.1.2 1259 | natural-compare: 1.4.0 1260 | optionator: 0.9.4 1261 | text-table: 0.2.0 1262 | transitivePeerDependencies: 1263 | - supports-color 1264 | 1265 | espree@10.3.0: 1266 | dependencies: 1267 | acorn: 8.14.0 1268 | acorn-jsx: 5.3.2(acorn@8.14.0) 1269 | eslint-visitor-keys: 4.2.0 1270 | 1271 | esquery@1.6.0: 1272 | dependencies: 1273 | estraverse: 5.3.0 1274 | 1275 | esrecurse@4.3.0: 1276 | dependencies: 1277 | estraverse: 5.3.0 1278 | 1279 | estraverse@5.3.0: {} 1280 | 1281 | esutils@2.0.3: {} 1282 | 1283 | expand-tilde@2.0.2: 1284 | dependencies: 1285 | homedir-polyfill: 1.0.3 1286 | 1287 | extend@3.0.2: {} 1288 | 1289 | fast-deep-equal@3.1.3: {} 1290 | 1291 | fast-fifo@1.3.2: {} 1292 | 1293 | fast-json-stable-stringify@2.1.0: {} 1294 | 1295 | fast-levenshtein@2.0.6: {} 1296 | 1297 | fast-levenshtein@3.0.0: 1298 | dependencies: 1299 | fastest-levenshtein: 1.0.16 1300 | 1301 | fastest-levenshtein@1.0.16: {} 1302 | 1303 | fastq@1.17.1: 1304 | dependencies: 1305 | reusify: 1.0.4 1306 | 1307 | file-entry-cache@8.0.0: 1308 | dependencies: 1309 | flat-cache: 4.0.1 1310 | 1311 | fill-range@7.1.1: 1312 | dependencies: 1313 | to-regex-range: 5.0.1 1314 | 1315 | find-up@5.0.0: 1316 | dependencies: 1317 | locate-path: 6.0.0 1318 | path-exists: 4.0.0 1319 | 1320 | findup-sync@5.0.0: 1321 | dependencies: 1322 | detect-file: 1.0.0 1323 | is-glob: 4.0.3 1324 | micromatch: 4.0.8 1325 | resolve-dir: 1.0.1 1326 | 1327 | fined@2.0.0: 1328 | dependencies: 1329 | expand-tilde: 2.0.2 1330 | is-plain-object: 5.0.0 1331 | object.defaults: 1.1.0 1332 | object.pick: 1.3.0 1333 | parse-filepath: 1.0.2 1334 | 1335 | flagged-respawn@2.0.0: {} 1336 | 1337 | flat-cache@4.0.1: 1338 | dependencies: 1339 | flatted: 3.3.1 1340 | keyv: 4.5.4 1341 | 1342 | flatted@3.3.1: {} 1343 | 1344 | for-in@1.0.2: {} 1345 | 1346 | for-own@1.0.0: 1347 | dependencies: 1348 | for-in: 1.0.2 1349 | 1350 | fs-mkdirp-stream@2.0.1: 1351 | dependencies: 1352 | graceful-fs: 4.2.11 1353 | streamx: 2.20.1 1354 | 1355 | fsevents@2.3.3: 1356 | optional: true 1357 | 1358 | function-bind@1.1.2: {} 1359 | 1360 | get-caller-file@2.0.5: {} 1361 | 1362 | glob-parent@5.1.2: 1363 | dependencies: 1364 | is-glob: 4.0.3 1365 | 1366 | glob-parent@6.0.2: 1367 | dependencies: 1368 | is-glob: 4.0.3 1369 | 1370 | glob-stream@8.0.2: 1371 | dependencies: 1372 | '@gulpjs/to-absolute-glob': 4.0.0 1373 | anymatch: 3.1.3 1374 | fastq: 1.17.1 1375 | glob-parent: 6.0.2 1376 | is-glob: 4.0.3 1377 | is-negated-glob: 1.0.0 1378 | normalize-path: 3.0.0 1379 | streamx: 2.20.1 1380 | 1381 | glob-watcher@6.0.0: 1382 | dependencies: 1383 | async-done: 2.0.0 1384 | chokidar: 3.6.0 1385 | 1386 | global-modules@1.0.0: 1387 | dependencies: 1388 | global-prefix: 1.0.2 1389 | is-windows: 1.0.2 1390 | resolve-dir: 1.0.1 1391 | 1392 | global-prefix@1.0.2: 1393 | dependencies: 1394 | expand-tilde: 2.0.2 1395 | homedir-polyfill: 1.0.3 1396 | ini: 1.3.8 1397 | is-windows: 1.0.2 1398 | which: 1.3.1 1399 | 1400 | globals@14.0.0: {} 1401 | 1402 | globals@15.11.0: {} 1403 | 1404 | glogg@2.2.0: 1405 | dependencies: 1406 | sparkles: 2.1.0 1407 | 1408 | graceful-fs@4.2.11: {} 1409 | 1410 | gulp-cli@3.0.0: 1411 | dependencies: 1412 | '@gulpjs/messages': 1.1.0 1413 | chalk: 4.1.2 1414 | copy-props: 4.0.0 1415 | gulplog: 2.2.0 1416 | interpret: 3.1.1 1417 | liftoff: 5.0.0 1418 | mute-stdout: 2.0.0 1419 | replace-homedir: 2.0.0 1420 | semver-greatest-satisfied-range: 2.0.0 1421 | string-width: 4.2.3 1422 | v8flags: 4.0.1 1423 | yargs: 16.2.0 1424 | 1425 | gulp@5.0.0: 1426 | dependencies: 1427 | glob-watcher: 6.0.0 1428 | gulp-cli: 3.0.0 1429 | undertaker: 2.0.0 1430 | vinyl-fs: 4.0.0 1431 | 1432 | gulplog@2.2.0: 1433 | dependencies: 1434 | glogg: 2.2.0 1435 | 1436 | has-flag@4.0.0: {} 1437 | 1438 | hasown@2.0.2: 1439 | dependencies: 1440 | function-bind: 1.1.2 1441 | 1442 | he@1.2.0: {} 1443 | 1444 | homedir-polyfill@1.0.3: 1445 | dependencies: 1446 | parse-passwd: 1.0.0 1447 | 1448 | iconv-lite@0.6.3: 1449 | dependencies: 1450 | safer-buffer: 2.1.2 1451 | 1452 | ieee754@1.2.1: {} 1453 | 1454 | ignore@5.3.2: {} 1455 | 1456 | import-fresh@3.3.0: 1457 | dependencies: 1458 | parent-module: 1.0.1 1459 | resolve-from: 4.0.0 1460 | 1461 | imurmurhash@0.1.4: {} 1462 | 1463 | inherits@2.0.4: {} 1464 | 1465 | ini@1.3.8: {} 1466 | 1467 | interpret@3.1.1: {} 1468 | 1469 | is-absolute@1.0.0: 1470 | dependencies: 1471 | is-relative: 1.0.0 1472 | is-windows: 1.0.2 1473 | 1474 | is-binary-path@2.1.0: 1475 | dependencies: 1476 | binary-extensions: 2.3.0 1477 | 1478 | is-core-module@2.15.1: 1479 | dependencies: 1480 | hasown: 2.0.2 1481 | 1482 | is-extglob@2.1.1: {} 1483 | 1484 | is-fullwidth-code-point@3.0.0: {} 1485 | 1486 | is-glob@4.0.3: 1487 | dependencies: 1488 | is-extglob: 2.1.1 1489 | 1490 | is-negated-glob@1.0.0: {} 1491 | 1492 | is-number@7.0.0: {} 1493 | 1494 | is-plain-object@5.0.0: {} 1495 | 1496 | is-relative@1.0.0: 1497 | dependencies: 1498 | is-unc-path: 1.0.0 1499 | 1500 | is-unc-path@1.0.0: 1501 | dependencies: 1502 | unc-path-regex: 0.1.2 1503 | 1504 | is-valid-glob@1.0.0: {} 1505 | 1506 | is-windows@1.0.2: {} 1507 | 1508 | isexe@2.0.0: {} 1509 | 1510 | isobject@3.0.1: {} 1511 | 1512 | js-yaml@4.1.0: 1513 | dependencies: 1514 | argparse: 2.0.1 1515 | 1516 | json-buffer@3.0.1: {} 1517 | 1518 | json-schema-traverse@0.4.1: {} 1519 | 1520 | json-stable-stringify-without-jsonify@1.0.1: {} 1521 | 1522 | keyv@4.5.4: 1523 | dependencies: 1524 | json-buffer: 3.0.1 1525 | 1526 | last-run@2.0.0: {} 1527 | 1528 | lead@4.0.0: {} 1529 | 1530 | levn@0.4.1: 1531 | dependencies: 1532 | prelude-ls: 1.2.1 1533 | type-check: 0.4.0 1534 | 1535 | liftoff@5.0.0: 1536 | dependencies: 1537 | extend: 3.0.2 1538 | findup-sync: 5.0.0 1539 | fined: 2.0.0 1540 | flagged-respawn: 2.0.0 1541 | is-plain-object: 5.0.0 1542 | rechoir: 0.8.0 1543 | resolve: 1.22.8 1544 | 1545 | locate-path@6.0.0: 1546 | dependencies: 1547 | p-locate: 5.0.0 1548 | 1549 | lodash.merge@4.6.2: {} 1550 | 1551 | map-cache@0.2.2: {} 1552 | 1553 | micromatch@4.0.8: 1554 | dependencies: 1555 | braces: 3.0.3 1556 | picomatch: 2.3.1 1557 | 1558 | minimatch@3.1.2: 1559 | dependencies: 1560 | brace-expansion: 1.1.11 1561 | 1562 | ms@2.1.3: {} 1563 | 1564 | mute-stdout@2.0.0: {} 1565 | 1566 | natural-compare@1.4.0: {} 1567 | 1568 | node-html-parser@6.1.13: 1569 | dependencies: 1570 | css-select: 5.1.0 1571 | he: 1.2.0 1572 | 1573 | normalize-path@3.0.0: {} 1574 | 1575 | now-and-later@3.0.0: 1576 | dependencies: 1577 | once: 1.4.0 1578 | 1579 | nth-check@2.1.1: 1580 | dependencies: 1581 | boolbase: 1.0.0 1582 | 1583 | object.defaults@1.1.0: 1584 | dependencies: 1585 | array-each: 1.0.1 1586 | array-slice: 1.1.0 1587 | for-own: 1.0.0 1588 | isobject: 3.0.1 1589 | 1590 | object.pick@1.3.0: 1591 | dependencies: 1592 | isobject: 3.0.1 1593 | 1594 | once@1.4.0: 1595 | dependencies: 1596 | wrappy: 1.0.2 1597 | 1598 | optionator@0.9.4: 1599 | dependencies: 1600 | deep-is: 0.1.4 1601 | fast-levenshtein: 2.0.6 1602 | levn: 0.4.1 1603 | prelude-ls: 1.2.1 1604 | type-check: 0.4.0 1605 | word-wrap: 1.2.5 1606 | 1607 | p-limit@3.1.0: 1608 | dependencies: 1609 | yocto-queue: 0.1.0 1610 | 1611 | p-locate@5.0.0: 1612 | dependencies: 1613 | p-limit: 3.1.0 1614 | 1615 | parent-module@1.0.1: 1616 | dependencies: 1617 | callsites: 3.1.0 1618 | 1619 | parse-filepath@1.0.2: 1620 | dependencies: 1621 | is-absolute: 1.0.0 1622 | map-cache: 0.2.2 1623 | path-root: 0.1.1 1624 | 1625 | parse-passwd@1.0.0: {} 1626 | 1627 | path-exists@4.0.0: {} 1628 | 1629 | path-key@3.1.1: {} 1630 | 1631 | path-parse@1.0.7: {} 1632 | 1633 | path-root-regex@0.1.2: {} 1634 | 1635 | path-root@0.1.1: 1636 | dependencies: 1637 | path-root-regex: 0.1.2 1638 | 1639 | picomatch@2.3.1: {} 1640 | 1641 | plugin-error@2.0.1: 1642 | dependencies: 1643 | ansi-colors: 1.1.0 1644 | 1645 | prelude-ls@1.2.1: {} 1646 | 1647 | punycode@2.3.1: {} 1648 | 1649 | queue-tick@1.0.1: {} 1650 | 1651 | readable-stream@3.6.2: 1652 | dependencies: 1653 | inherits: 2.0.4 1654 | string_decoder: 1.3.0 1655 | util-deprecate: 1.0.2 1656 | 1657 | readdirp@3.6.0: 1658 | dependencies: 1659 | picomatch: 2.3.1 1660 | 1661 | rechoir@0.8.0: 1662 | dependencies: 1663 | resolve: 1.22.8 1664 | 1665 | remove-trailing-separator@1.1.0: {} 1666 | 1667 | replace-ext@2.0.0: {} 1668 | 1669 | replace-homedir@2.0.0: {} 1670 | 1671 | require-directory@2.1.1: {} 1672 | 1673 | requireindex@1.2.0: {} 1674 | 1675 | resolve-dir@1.0.1: 1676 | dependencies: 1677 | expand-tilde: 2.0.2 1678 | global-modules: 1.0.0 1679 | 1680 | resolve-from@4.0.0: {} 1681 | 1682 | resolve-options@2.0.0: 1683 | dependencies: 1684 | value-or-function: 4.0.0 1685 | 1686 | resolve@1.22.8: 1687 | dependencies: 1688 | is-core-module: 2.15.1 1689 | path-parse: 1.0.7 1690 | supports-preserve-symlinks-flag: 1.0.0 1691 | 1692 | reusify@1.0.4: {} 1693 | 1694 | safe-buffer@5.2.1: {} 1695 | 1696 | safer-buffer@2.1.2: {} 1697 | 1698 | semver-greatest-satisfied-range@2.0.0: 1699 | dependencies: 1700 | sver: 1.8.4 1701 | 1702 | semver@6.3.1: 1703 | optional: true 1704 | 1705 | shebang-command@2.0.0: 1706 | dependencies: 1707 | shebang-regex: 3.0.0 1708 | 1709 | shebang-regex@3.0.0: {} 1710 | 1711 | sparkles@2.1.0: {} 1712 | 1713 | stream-composer@1.0.2: 1714 | dependencies: 1715 | streamx: 2.20.1 1716 | 1717 | stream-exhaust@1.0.2: {} 1718 | 1719 | streamx@2.20.1: 1720 | dependencies: 1721 | fast-fifo: 1.3.2 1722 | queue-tick: 1.0.1 1723 | text-decoder: 1.2.1 1724 | optionalDependencies: 1725 | bare-events: 2.5.0 1726 | 1727 | string-width@4.2.3: 1728 | dependencies: 1729 | emoji-regex: 8.0.0 1730 | is-fullwidth-code-point: 3.0.0 1731 | strip-ansi: 6.0.1 1732 | 1733 | string_decoder@1.3.0: 1734 | dependencies: 1735 | safe-buffer: 5.2.1 1736 | 1737 | strip-ansi@6.0.1: 1738 | dependencies: 1739 | ansi-regex: 5.0.1 1740 | 1741 | strip-json-comments@3.1.1: {} 1742 | 1743 | supports-color@7.2.0: 1744 | dependencies: 1745 | has-flag: 4.0.0 1746 | 1747 | supports-preserve-symlinks-flag@1.0.0: {} 1748 | 1749 | sver@1.8.4: 1750 | optionalDependencies: 1751 | semver: 6.3.1 1752 | 1753 | teex@1.0.1: 1754 | dependencies: 1755 | streamx: 2.20.1 1756 | 1757 | text-decoder@1.2.1: {} 1758 | 1759 | text-table@0.2.0: {} 1760 | 1761 | to-regex-range@5.0.1: 1762 | dependencies: 1763 | is-number: 7.0.0 1764 | 1765 | to-through@3.0.0: 1766 | dependencies: 1767 | streamx: 2.20.1 1768 | 1769 | type-check@0.4.0: 1770 | dependencies: 1771 | prelude-ls: 1.2.1 1772 | 1773 | unc-path-regex@0.1.2: {} 1774 | 1775 | undertaker-registry@2.0.0: {} 1776 | 1777 | undertaker@2.0.0: 1778 | dependencies: 1779 | bach: 2.0.1 1780 | fast-levenshtein: 3.0.0 1781 | last-run: 2.0.0 1782 | undertaker-registry: 2.0.0 1783 | 1784 | uri-js@4.4.1: 1785 | dependencies: 1786 | punycode: 2.3.1 1787 | 1788 | util-deprecate@1.0.2: {} 1789 | 1790 | v8flags@4.0.1: {} 1791 | 1792 | value-or-function@4.0.0: {} 1793 | 1794 | vinyl-contents@2.0.0: 1795 | dependencies: 1796 | bl: 5.1.0 1797 | vinyl: 3.0.0 1798 | 1799 | vinyl-fs@4.0.0: 1800 | dependencies: 1801 | fs-mkdirp-stream: 2.0.1 1802 | glob-stream: 8.0.2 1803 | graceful-fs: 4.2.11 1804 | iconv-lite: 0.6.3 1805 | is-valid-glob: 1.0.0 1806 | lead: 4.0.0 1807 | normalize-path: 3.0.0 1808 | resolve-options: 2.0.0 1809 | stream-composer: 1.0.2 1810 | streamx: 2.20.1 1811 | to-through: 3.0.0 1812 | value-or-function: 4.0.0 1813 | vinyl: 3.0.0 1814 | vinyl-sourcemap: 2.0.0 1815 | 1816 | vinyl-sourcemap@2.0.0: 1817 | dependencies: 1818 | convert-source-map: 2.0.0 1819 | graceful-fs: 4.2.11 1820 | now-and-later: 3.0.0 1821 | streamx: 2.20.1 1822 | vinyl: 3.0.0 1823 | vinyl-contents: 2.0.0 1824 | 1825 | vinyl@3.0.0: 1826 | dependencies: 1827 | clone: 2.1.2 1828 | clone-stats: 1.0.0 1829 | remove-trailing-separator: 1.1.0 1830 | replace-ext: 2.0.0 1831 | teex: 1.0.1 1832 | 1833 | which@1.3.1: 1834 | dependencies: 1835 | isexe: 2.0.0 1836 | 1837 | which@2.0.2: 1838 | dependencies: 1839 | isexe: 2.0.0 1840 | 1841 | word-wrap@1.2.5: {} 1842 | 1843 | wrap-ansi@7.0.0: 1844 | dependencies: 1845 | ansi-styles: 4.3.0 1846 | string-width: 4.2.3 1847 | strip-ansi: 6.0.1 1848 | 1849 | wrappy@1.0.2: {} 1850 | 1851 | y18n@5.0.8: {} 1852 | 1853 | yargs-parser@20.2.9: {} 1854 | 1855 | yargs@16.2.0: 1856 | dependencies: 1857 | cliui: 7.0.4 1858 | escalade: 3.2.0 1859 | get-caller-file: 2.0.5 1860 | require-directory: 2.1.1 1861 | string-width: 4.2.3 1862 | y18n: 5.0.8 1863 | yargs-parser: 20.2.9 1864 | 1865 | yocto-queue@0.1.0: {} 1866 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | import { test } from "node:test" 2 | import { equal, ok } from "node:assert/strict" 3 | 4 | import PluginError from "plugin-error" 5 | import Vinyl from "vinyl" 6 | 7 | import { stacksvg } from "../lib/index.js" 8 | 9 | test(`Plugin should not create empty svg file`, () => { 10 | let stream = stacksvg() 11 | let isEmpty = true 12 | 13 | stream.on(`data`, () => { isEmpty = false }) 14 | 15 | stream.on(`end`, () => { 16 | ok(isEmpty, `Created empty svg`) 17 | }) 18 | 19 | stream.end() 20 | }) 21 | 22 | test(`Plugin should correctly merge svg files`, () => { 23 | let stream = stacksvg() 24 | 25 | stream.on(`data`, (file) => { 26 | let actual = file.contents.toString() 27 | let expected = `` 28 | 29 | equal(actual, expected) 30 | }) 31 | 32 | stream.write(new Vinyl({ 33 | path: `circle.svg`, 34 | contents: Buffer.from(``), 35 | })) 36 | 37 | stream.write(new Vinyl({ 38 | path: `square.svg`, 39 | contents: Buffer.from(``), 40 | })) 41 | 42 | stream.end() 43 | }) 44 | 45 | test(`Plugin should not include null`, () => { 46 | let stream = stacksvg() 47 | 48 | stream.on(`data`, (file) => { 49 | let actual = file.contents.toString() 50 | let expected = `` 51 | 52 | equal(actual, expected) 53 | }) 54 | 55 | stream.write(new Vinyl({ 56 | path: `circle.svg`, 57 | contents: Buffer.from(``), 58 | })) 59 | 60 | stream.write(new Vinyl({ 61 | path: `square.svg`, 62 | contents: null, 63 | })) 64 | 65 | stream.end() 66 | }) 67 | 68 | test(`Plugin should not include invalid files`, () => { 69 | let stream = stacksvg() 70 | 71 | stream.on(`data`, (file) => { 72 | let actual = file.contents.toString() 73 | let expected = `` 74 | 75 | equal(actual, expected) 76 | }) 77 | 78 | stream.write(new Vinyl({ 79 | path: `circle.svg`, 80 | contents: Buffer.from(``), 81 | })) 82 | 83 | stream.write(new Vinyl({ 84 | path: `square.svg`, 85 | contents: Buffer.from(`not an svg`), 86 | })) 87 | 88 | stream.end() 89 | }) 90 | 91 | test(`Plugin should emit error if files have the same name`, () => { 92 | let stream = stacksvg() 93 | 94 | stream.on(`error`, (error) => { 95 | ok(error instanceof PluginError) 96 | equal(error.message, `File name should be unique: circle`) 97 | }) 98 | 99 | stream.write(new Vinyl({ 100 | path: `circle.svg`, 101 | contents: Buffer.from(``), 102 | })) 103 | stream.write(new Vinyl({ 104 | path: `circle.svg`, 105 | contents: Buffer.from(``), 106 | })) 107 | 108 | stream.end() 109 | }) 110 | 111 | test(`Plugin should generate stack.svg`, () => { 112 | let stream = stacksvg() 113 | 114 | stream.on(`data`, (file) => { 115 | equal(file.relative, `stack.svg`) 116 | }) 117 | 118 | stream.write(new Vinyl({ 119 | path: `circle.svg`, 120 | contents: Buffer.from(``), 121 | })) 122 | 123 | stream.write(new Vinyl({ 124 | path: `square.svg`, 125 | contents: Buffer.from(``), 126 | })) 127 | 128 | stream.end() 129 | }) 130 | 131 | test(`Plugin should replace the spaces with the hyphens`, () => { 132 | let stream = stacksvg() 133 | 134 | stream.on(`data`, (file) => { 135 | let actual = file.contents.toString() 136 | let expected = `` 137 | 138 | equal(actual, expected) 139 | }) 140 | 141 | stream.write(new Vinyl({ 142 | path: `icon like.svg`, 143 | contents: Buffer.from(``), 144 | })) 145 | 146 | stream.end() 147 | }) 148 | 149 | test(`Plugin should replace the directory separator with the underscore`, () => { 150 | let stream = stacksvg() 151 | 152 | stream.on(`data`, (file) => { 153 | let actual = file.contents.toString() 154 | let expected = `` 155 | 156 | equal(actual, expected) 157 | }) 158 | 159 | stream.write(new Vinyl({ 160 | path: `icons/like.svg`, 161 | contents: Buffer.from(``), 162 | })) 163 | 164 | stream.end() 165 | }) 166 | 167 | test(`Plugin should generate unique inner id`, () => { 168 | let stream = stacksvg() 169 | 170 | stream.on(`data`, (file) => { 171 | let actual = file.contents.toString() 172 | let expected = `` 173 | 174 | equal(actual, expected) 175 | }) 176 | 177 | stream.write(new Vinyl({ 178 | path: `one.svg`, 179 | contents: Buffer.from(``), 180 | })) 181 | 182 | stream.write(new Vinyl({ 183 | path: `two.svg`, 184 | contents: Buffer.from(``), 185 | })) 186 | 187 | stream.end() 188 | }) 189 | 190 | test(`Plugin should include all different namespaces into final svg`, () => { 191 | let stream = stacksvg() 192 | 193 | stream.on(`data`, (file) => { 194 | let actual = file.contents.toString() 195 | let expected = `` 196 | 197 | equal(actual, expected) 198 | }) 199 | 200 | stream.write(new Vinyl({ 201 | path: `rect1.svg`, 202 | contents: Buffer.from(``), 203 | })) 204 | 205 | stream.write(new Vinyl({ 206 | path: `rect2.svg`, 207 | contents: Buffer.from(``), 208 | })) 209 | 210 | stream.end() 211 | }) 212 | 213 | test(`Plugin should replace aliases of existing namespaces`, () => { 214 | let stream = stacksvg() 215 | 216 | stream.on(`data`, (file) => { 217 | let actual = file.contents.toString() 218 | let expected = `` 219 | 220 | equal(actual, expected) 221 | }) 222 | 223 | stream.write(new Vinyl({ 224 | path: `rect1.svg`, 225 | contents: Buffer.from(``), 226 | })) 227 | 228 | stream.write(new Vinyl({ 229 | path: `rect2.svg`, 230 | contents: Buffer.from(``), 231 | })) 232 | 233 | stream.end() 234 | }) 235 | 236 | test(`Plugin should rename duplicate aliases of different namespaces`, () => { 237 | let stream = stacksvg() 238 | 239 | stream.on(`data`, (file) => { 240 | let actual = file.contents.toString() 241 | let expected = `` 242 | 243 | equal(actual, expected) 244 | }) 245 | 246 | stream.write(new Vinyl({ 247 | path: `rect1.svg`, 248 | contents: Buffer.from(``), 249 | })) 250 | 251 | stream.write(new Vinyl({ 252 | path: `rect2.svg`, 253 | contents: Buffer.from(``), 254 | })) 255 | 256 | stream.write(new Vinyl({ 257 | path: `rect3.svg`, 258 | contents: Buffer.from(``), 259 | })) 260 | 261 | stream.end() 262 | }) 263 | 264 | test(`Plugin should remove "http://www.w3.org/1999/xlink" namespace`, () => { 265 | let stream = stacksvg() 266 | 267 | stream.on(`data`, (file) => { 268 | let actual = file.contents.toString() 269 | let expected = `` 270 | 271 | equal(actual, expected) 272 | }) 273 | 274 | stream.write(new Vinyl({ 275 | path: `burger.svg`, 276 | contents: Buffer.from(``), 277 | })) 278 | 279 | stream.write(new Vinyl({ 280 | path: `sandwich.svg`, 281 | contents: Buffer.from(``), 282 | })) 283 | 284 | stream.end() 285 | }) 286 | 287 | test(`Plugin should not add unused namespaces`, () => { 288 | let stream = stacksvg() 289 | 290 | stream.on(`data`, (file) => { 291 | let actual = file.contents.toString() 292 | let expected = `` 293 | 294 | equal(actual, expected) 295 | }) 296 | 297 | stream.write(new Vinyl({ 298 | path: `rect1.svg`, 299 | contents: Buffer.from(``), 300 | })) 301 | 302 | stream.write(new Vinyl({ 303 | path: `rect2.svg`, 304 | contents: Buffer.from(``), 305 | })) 306 | 307 | stream.end() 308 | }) 309 | --------------------------------------------------------------------------------