summaryrefslogtreecommitdiff
path: root/node_modules/svgo/plugins
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2026-05-18 23:10:59 +0800
committerlittleblack111 <littleblack11111@gmail.com>2026-05-18 23:41:44 +0800
commitfc87c009806dcc98867f6b58efe29b042aa01dee (patch)
tree8f59b3f4a5b66e9dfef2d40c8d318e258a521228 /node_modules/svgo/plugins
parent3336b2356ee6152d9c6ae59bd9b87ccbc0958407 (diff)
node: updatemain
Diffstat (limited to 'node_modules/svgo/plugins')
-rw-r--r--node_modules/svgo/plugins/_collections.js2339
-rw-r--r--node_modules/svgo/plugins/_path.js815
-rw-r--r--node_modules/svgo/plugins/_transforms.js410
-rw-r--r--node_modules/svgo/plugins/addAttributesToSVGElement.js82
-rw-r--r--node_modules/svgo/plugins/addClassesToSVGElement.js82
-rw-r--r--node_modules/svgo/plugins/applyTransforms.js388
-rw-r--r--node_modules/svgo/plugins/cleanupAttrs.js49
-rw-r--r--node_modules/svgo/plugins/cleanupEnableBackground.js165
-rw-r--r--node_modules/svgo/plugins/cleanupIds.js265
-rw-r--r--node_modules/svgo/plugins/cleanupListOfValues.js147
-rw-r--r--node_modules/svgo/plugins/cleanupNumericValues.js106
-rw-r--r--node_modules/svgo/plugins/collapseGroups.js134
-rw-r--r--node_modules/svgo/plugins/convertColors.js144
-rw-r--r--node_modules/svgo/plugins/convertEllipseToCircle.js37
-rw-r--r--node_modules/svgo/plugins/convertOneStopGradients.js168
-rw-r--r--node_modules/svgo/plugins/convertPathData.js1284
-rw-r--r--node_modules/svgo/plugins/convertShapeToPath.js170
-rw-r--r--node_modules/svgo/plugins/convertStyleToAttrs.js136
-rw-r--r--node_modules/svgo/plugins/convertTransform.js418
-rw-r--r--node_modules/svgo/plugins/inlineStyles.js390
-rw-r--r--node_modules/svgo/plugins/mergePaths.js148
-rw-r--r--node_modules/svgo/plugins/mergeStyles.js98
-rw-r--r--node_modules/svgo/plugins/minifyStyles.js141
-rw-r--r--node_modules/svgo/plugins/moveElemsAttrsToGroup.js128
-rw-r--r--node_modules/svgo/plugins/moveGroupAttrsToElems.js65
-rw-r--r--node_modules/svgo/plugins/plugins-types.d.ts291
-rw-r--r--node_modules/svgo/plugins/prefixIds.js268
-rw-r--r--node_modules/svgo/plugins/preset-default.js82
-rw-r--r--node_modules/svgo/plugins/removeAttributesBySelector.js97
-rw-r--r--node_modules/svgo/plugins/removeAttrs.js151
-rw-r--r--node_modules/svgo/plugins/removeComments.js51
-rw-r--r--node_modules/svgo/plugins/removeDesc.js39
-rw-r--r--node_modules/svgo/plugins/removeDimensions.js43
-rw-r--r--node_modules/svgo/plugins/removeDoctype.js40
-rw-r--r--node_modules/svgo/plugins/removeEditorsNSData.js64
-rw-r--r--node_modules/svgo/plugins/removeElementsByAttr.js73
-rw-r--r--node_modules/svgo/plugins/removeEmptyAttrs.js31
-rw-r--r--node_modules/svgo/plugins/removeEmptyContainers.js59
-rw-r--r--node_modules/svgo/plugins/removeEmptyText.js51
-rw-r--r--node_modules/svgo/plugins/removeHiddenElems.js440
-rw-r--r--node_modules/svgo/plugins/removeMetadata.js27
-rw-r--r--node_modules/svgo/plugins/removeNonInheritableGroupAttrs.js38
-rw-r--r--node_modules/svgo/plugins/removeOffCanvasPaths.js136
-rw-r--r--node_modules/svgo/plugins/removeRasterImages.js31
-rw-r--r--node_modules/svgo/plugins/removeScriptElement.js70
-rw-r--r--node_modules/svgo/plugins/removeStyleElement.js27
-rw-r--r--node_modules/svgo/plugins/removeTitle.js27
-rw-r--r--node_modules/svgo/plugins/removeUnknownsAndDefaults.js212
-rw-r--r--node_modules/svgo/plugins/removeUnusedNS.js59
-rw-r--r--node_modules/svgo/plugins/removeUselessDefs.js65
-rw-r--r--node_modules/svgo/plugins/removeUselessStrokeAndFill.js139
-rw-r--r--node_modules/svgo/plugins/removeViewBox.js49
-rw-r--r--node_modules/svgo/plugins/removeXMLNS.js29
-rw-r--r--node_modules/svgo/plugins/removeXMLProcInst.js28
-rw-r--r--node_modules/svgo/plugins/removeXlink.js226
-rw-r--r--node_modules/svgo/plugins/reusePaths.js195
-rw-r--r--node_modules/svgo/plugins/sortAttrs.js108
-rw-r--r--node_modules/svgo/plugins/sortDefsChildren.js58
58 files changed, 0 insertions, 11613 deletions
diff --git a/node_modules/svgo/plugins/_collections.js b/node_modules/svgo/plugins/_collections.js
deleted file mode 100644
index 6f11b136..00000000
--- a/node_modules/svgo/plugins/_collections.js
+++ /dev/null
@@ -1,2339 +0,0 @@
-'use strict';
-
-// https://www.w3.org/TR/SVG11/intro.html#Definitions
-
-/**
- * @type {Record<string, Set<string>>}
- */
-exports.elemsGroups = {
- animation: new Set([
- 'animate',
- 'animateColor',
- 'animateMotion',
- 'animateTransform',
- 'set',
- ]),
- descriptive: new Set(['desc', 'metadata', 'title']),
- shape: new Set([
- 'circle',
- 'ellipse',
- 'line',
- 'path',
- 'polygon',
- 'polyline',
- 'rect',
- ]),
- structural: new Set(['defs', 'g', 'svg', 'symbol', 'use']),
- paintServer: new Set([
- 'hatch',
- 'linearGradient',
- 'meshGradient',
- 'pattern',
- 'radialGradient',
- 'solidColor',
- ]),
- nonRendering: new Set([
- 'clipPath',
- 'filter',
- 'linearGradient',
- 'marker',
- 'mask',
- 'pattern',
- 'radialGradient',
- 'solidColor',
- 'symbol',
- ]),
- container: new Set([
- 'a',
- 'defs',
- 'foreignObject',
- 'g',
- 'marker',
- 'mask',
- 'missing-glyph',
- 'pattern',
- 'svg',
- 'switch',
- 'symbol',
- ]),
- textContent: new Set([
- 'altGlyph',
- 'altGlyphDef',
- 'altGlyphItem',
- 'glyph',
- 'glyphRef',
- 'text',
- 'textPath',
- 'tref',
- 'tspan',
- ]),
- textContentChild: new Set(['altGlyph', 'textPath', 'tref', 'tspan']),
- lightSource: new Set([
- 'feDiffuseLighting',
- 'feDistantLight',
- 'fePointLight',
- 'feSpecularLighting',
- 'feSpotLight',
- ]),
- filterPrimitive: new Set([
- 'feBlend',
- 'feColorMatrix',
- 'feComponentTransfer',
- 'feComposite',
- 'feConvolveMatrix',
- 'feDiffuseLighting',
- 'feDisplacementMap',
- 'feDropShadow',
- 'feFlood',
- 'feFuncA',
- 'feFuncB',
- 'feFuncG',
- 'feFuncR',
- 'feGaussianBlur',
- 'feImage',
- 'feMerge',
- 'feMergeNode',
- 'feMorphology',
- 'feOffset',
- 'feSpecularLighting',
- 'feTile',
- 'feTurbulence',
- ]),
-};
-
-/**
- * Elements where adding or removing whitespace may effect rendering, metadata,
- * or semantic meaning.
- *
- * @see https://developer.mozilla.org/docs/Web/HTML/Element/pre
- */
-exports.textElems = new Set([
- ...exports.elemsGroups.textContent,
- 'pre',
- 'title',
-]);
-
-exports.pathElems = new Set(['glyph', 'missing-glyph', 'path']);
-
-/**
- * @type {Record<string, Set<string>>}
- * @see https://www.w3.org/TR/SVG11/intro.html#Definitions
- */
-exports.attrsGroups = {
- animationAddition: new Set(['additive', 'accumulate']),
- animationAttributeTarget: new Set(['attributeType', 'attributeName']),
- animationEvent: new Set(['onbegin', 'onend', 'onrepeat', 'onload']),
- animationTiming: new Set([
- 'begin',
- 'dur',
- 'end',
- 'fill',
- 'max',
- 'min',
- 'repeatCount',
- 'repeatDur',
- 'restart',
- ]),
- animationValue: new Set([
- 'by',
- 'calcMode',
- 'from',
- 'keySplines',
- 'keyTimes',
- 'to',
- 'values',
- ]),
- conditionalProcessing: new Set([
- 'requiredExtensions',
- 'requiredFeatures',
- 'systemLanguage',
- ]),
- core: new Set(['id', 'tabindex', 'xml:base', 'xml:lang', 'xml:space']),
- graphicalEvent: new Set([
- 'onactivate',
- 'onclick',
- 'onfocusin',
- 'onfocusout',
- 'onload',
- 'onmousedown',
- 'onmousemove',
- 'onmouseout',
- 'onmouseover',
- 'onmouseup',
- ]),
- presentation: new Set([
- 'alignment-baseline',
- 'baseline-shift',
- 'clip-path',
- 'clip-rule',
- 'clip',
- 'color-interpolation-filters',
- 'color-interpolation',
- 'color-profile',
- 'color-rendering',
- 'color',
- 'cursor',
- 'direction',
- 'display',
- 'dominant-baseline',
- 'enable-background',
- 'fill-opacity',
- 'fill-rule',
- 'fill',
- 'filter',
- 'flood-color',
- 'flood-opacity',
- 'font-family',
- 'font-size-adjust',
- 'font-size',
- 'font-stretch',
- 'font-style',
- 'font-variant',
- 'font-weight',
- 'glyph-orientation-horizontal',
- 'glyph-orientation-vertical',
- 'image-rendering',
- 'letter-spacing',
- 'lighting-color',
- 'marker-end',
- 'marker-mid',
- 'marker-start',
- 'mask',
- 'opacity',
- 'overflow',
- 'paint-order',
- 'pointer-events',
- 'shape-rendering',
- 'stop-color',
- 'stop-opacity',
- 'stroke-dasharray',
- 'stroke-dashoffset',
- 'stroke-linecap',
- 'stroke-linejoin',
- 'stroke-miterlimit',
- 'stroke-opacity',
- 'stroke-width',
- 'stroke',
- 'text-anchor',
- 'text-decoration',
- 'text-overflow',
- 'text-rendering',
- 'transform-origin',
- 'transform',
- 'unicode-bidi',
- 'vector-effect',
- 'visibility',
- 'word-spacing',
- 'writing-mode',
- ]),
- xlink: new Set([
- 'xlink:actuate',
- 'xlink:arcrole',
- 'xlink:href',
- 'xlink:role',
- 'xlink:show',
- 'xlink:title',
- 'xlink:type',
- ]),
- documentEvent: new Set([
- 'onabort',
- 'onerror',
- 'onresize',
- 'onscroll',
- 'onunload',
- 'onzoom',
- ]),
- documentElementEvent: new Set(['oncopy', 'oncut', 'onpaste']),
- globalEvent: new Set([
- 'oncancel',
- 'oncanplay',
- 'oncanplaythrough',
- 'onchange',
- 'onclick',
- 'onclose',
- 'oncuechange',
- 'ondblclick',
- 'ondrag',
- 'ondragend',
- 'ondragenter',
- 'ondragleave',
- 'ondragover',
- 'ondragstart',
- 'ondrop',
- 'ondurationchange',
- 'onemptied',
- 'onended',
- 'onerror',
- 'onfocus',
- 'oninput',
- 'oninvalid',
- 'onkeydown',
- 'onkeypress',
- 'onkeyup',
- 'onload',
- 'onloadeddata',
- 'onloadedmetadata',
- 'onloadstart',
- 'onmousedown',
- 'onmouseenter',
- 'onmouseleave',
- 'onmousemove',
- 'onmouseout',
- 'onmouseover',
- 'onmouseup',
- 'onmousewheel',
- 'onpause',
- 'onplay',
- 'onplaying',
- 'onprogress',
- 'onratechange',
- 'onreset',
- 'onresize',
- 'onscroll',
- 'onseeked',
- 'onseeking',
- 'onselect',
- 'onshow',
- 'onstalled',
- 'onsubmit',
- 'onsuspend',
- 'ontimeupdate',
- 'ontoggle',
- 'onvolumechange',
- 'onwaiting',
- ]),
- filterPrimitive: new Set(['x', 'y', 'width', 'height', 'result']),
- transferFunction: new Set([
- 'amplitude',
- 'exponent',
- 'intercept',
- 'offset',
- 'slope',
- 'tableValues',
- 'type',
- ]),
-};
-
-/**
- * @type {Record<string, Record<string, string>>}
- */
-exports.attrsGroupsDefaults = {
- core: { 'xml:space': 'default' },
- presentation: {
- clip: 'auto',
- 'clip-path': 'none',
- 'clip-rule': 'nonzero',
- mask: 'none',
- opacity: '1',
- 'stop-color': '#000',
- 'stop-opacity': '1',
- 'fill-opacity': '1',
- 'fill-rule': 'nonzero',
- fill: '#000',
- stroke: 'none',
- 'stroke-width': '1',
- 'stroke-linecap': 'butt',
- 'stroke-linejoin': 'miter',
- 'stroke-miterlimit': '4',
- 'stroke-dasharray': 'none',
- 'stroke-dashoffset': '0',
- 'stroke-opacity': '1',
- 'paint-order': 'normal',
- 'vector-effect': 'none',
- display: 'inline',
- visibility: 'visible',
- 'marker-start': 'none',
- 'marker-mid': 'none',
- 'marker-end': 'none',
- 'color-interpolation': 'sRGB',
- 'color-interpolation-filters': 'linearRGB',
- 'color-rendering': 'auto',
- 'shape-rendering': 'auto',
- 'text-rendering': 'auto',
- 'image-rendering': 'auto',
- 'font-style': 'normal',
- 'font-variant': 'normal',
- 'font-weight': 'normal',
- 'font-stretch': 'normal',
- 'font-size': 'medium',
- 'font-size-adjust': 'none',
- kerning: 'auto',
- 'letter-spacing': 'normal',
- 'word-spacing': 'normal',
- 'text-decoration': 'none',
- 'text-anchor': 'start',
- 'text-overflow': 'clip',
- 'writing-mode': 'lr-tb',
- 'glyph-orientation-vertical': 'auto',
- 'glyph-orientation-horizontal': '0deg',
- direction: 'ltr',
- 'unicode-bidi': 'normal',
- 'dominant-baseline': 'auto',
- 'alignment-baseline': 'baseline',
- 'baseline-shift': 'baseline',
- },
- transferFunction: {
- slope: '1',
- intercept: '0',
- amplitude: '1',
- exponent: '1',
- offset: '0',
- },
-};
-
-/**
- * @type {Record<string, {
- * attrsGroups: Set<string>,
- * attrs?: Set<string>,
- * defaults?: Record<string, string>,
- * contentGroups?: Set<string>,
- * content?: Set<string>,
- * }>}
- * @see https://www.w3.org/TR/SVG11/eltindex.html
- */
-exports.elems = {
- a: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- 'xlink',
- ]),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'style',
- 'target',
- 'transform',
- ]),
- defaults: {
- target: '_self',
- },
- contentGroups: new Set([
- 'animation',
- 'descriptive',
- 'paintServer',
- 'shape',
- 'structural',
- ]),
- content: new Set([
- 'a',
- 'altGlyphDef',
- 'clipPath',
- 'color-profile',
- 'cursor',
- 'filter',
- 'font-face',
- 'font',
- 'foreignObject',
- 'image',
- 'marker',
- 'mask',
- 'pattern',
- 'script',
- 'style',
- 'switch',
- 'text',
- 'view',
- // not spec compliant
- 'tspan',
- ]),
- },
- altGlyph: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- 'xlink',
- ]),
- attrs: new Set([
- 'class',
- 'dx',
- 'dy',
- 'externalResourcesRequired',
- 'format',
- 'glyphRef',
- 'rotate',
- 'style',
- 'x',
- 'y',
- ]),
- },
- altGlyphDef: {
- attrsGroups: new Set(['core']),
- content: new Set(['glyphRef']),
- },
- altGlyphItem: {
- attrsGroups: new Set(['core']),
- content: new Set(['glyphRef', 'altGlyphItem']),
- },
- animate: {
- attrsGroups: new Set([
- 'animationAddition',
- 'animationAttributeTarget',
- 'animationEvent',
- 'animationTiming',
- 'animationValue',
- 'conditionalProcessing',
- 'core',
- 'presentation',
- 'xlink',
- ]),
- attrs: new Set(['externalResourcesRequired']),
- contentGroups: new Set(['descriptive']),
- },
- animateColor: {
- attrsGroups: new Set([
- 'animationAddition',
- 'animationAttributeTarget',
- 'animationEvent',
- 'animationTiming',
- 'animationValue',
- 'conditionalProcessing',
- 'core',
- 'presentation',
- 'xlink',
- ]),
- attrs: new Set(['externalResourcesRequired']),
- contentGroups: new Set(['descriptive']),
- },
- animateMotion: {
- attrsGroups: new Set([
- 'animationAddition',
- 'animationEvent',
- 'animationTiming',
- 'animationValue',
- 'conditionalProcessing',
- 'core',
- 'xlink',
- ]),
- attrs: new Set([
- 'externalResourcesRequired',
- 'keyPoints',
- 'origin',
- 'path',
- 'rotate',
- ]),
- defaults: {
- rotate: '0',
- },
- contentGroups: new Set(['descriptive']),
- content: new Set(['mpath']),
- },
- animateTransform: {
- attrsGroups: new Set([
- 'animationAddition',
- 'animationAttributeTarget',
- 'animationEvent',
- 'animationTiming',
- 'animationValue',
- 'conditionalProcessing',
- 'core',
- 'xlink',
- ]),
- attrs: new Set(['externalResourcesRequired', 'type']),
- contentGroups: new Set(['descriptive']),
- },
- circle: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'class',
- 'cx',
- 'cy',
- 'externalResourcesRequired',
- 'r',
- 'style',
- 'transform',
- ]),
- defaults: {
- cx: '0',
- cy: '0',
- },
- contentGroups: new Set(['animation', 'descriptive']),
- },
- clipPath: {
- attrsGroups: new Set(['conditionalProcessing', 'core', 'presentation']),
- attrs: new Set([
- 'class',
- 'clipPathUnits',
- 'externalResourcesRequired',
- 'style',
- 'transform',
- ]),
- defaults: {
- clipPathUnits: 'userSpaceOnUse',
- },
- contentGroups: new Set(['animation', 'descriptive', 'shape']),
- content: new Set(['text', 'use']),
- },
- 'color-profile': {
- attrsGroups: new Set(['core', 'xlink']),
- attrs: new Set(['local', 'name', 'rendering-intent']),
- defaults: {
- name: 'sRGB',
- 'rendering-intent': 'auto',
- },
- contentGroups: new Set(['descriptive']),
- },
- cursor: {
- attrsGroups: new Set(['core', 'conditionalProcessing', 'xlink']),
- attrs: new Set(['externalResourcesRequired', 'x', 'y']),
- defaults: {
- x: '0',
- y: '0',
- },
- contentGroups: new Set(['descriptive']),
- },
- defs: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'style',
- 'transform',
- ]),
- contentGroups: new Set([
- 'animation',
- 'descriptive',
- 'paintServer',
- 'shape',
- 'structural',
- ]),
- content: new Set([
- 'a',
- 'altGlyphDef',
- 'clipPath',
- 'color-profile',
- 'cursor',
- 'filter',
- 'font-face',
- 'font',
- 'foreignObject',
- 'image',
- 'marker',
- 'mask',
- 'pattern',
- 'script',
- 'style',
- 'switch',
- 'text',
- 'view',
- ]),
- },
- desc: {
- attrsGroups: new Set(['core']),
- attrs: new Set(['class', 'style']),
- },
- ellipse: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'class',
- 'cx',
- 'cy',
- 'externalResourcesRequired',
- 'rx',
- 'ry',
- 'style',
- 'transform',
- ]),
- defaults: {
- cx: '0',
- cy: '0',
- },
- contentGroups: new Set(['animation', 'descriptive']),
- },
- feBlend: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set([
- 'class',
- 'style',
- // TODO: in - 'If no value is provided and this is the first filter primitive,
- // then this filter primitive will use SourceGraphic as its input'
- 'in',
- 'in2',
- 'mode',
- ]),
- defaults: {
- mode: 'normal',
- },
- content: new Set(['animate', 'set']),
- },
- feColorMatrix: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set(['class', 'style', 'in', 'type', 'values']),
- defaults: {
- type: 'matrix',
- },
- content: new Set(['animate', 'set']),
- },
- feComponentTransfer: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set(['class', 'style', 'in']),
- content: new Set(['feFuncA', 'feFuncB', 'feFuncG', 'feFuncR']),
- },
- feComposite: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set([
- 'class',
- 'in',
- 'in2',
- 'k1',
- 'k2',
- 'k3',
- 'k4',
- 'operator',
- 'style',
- ]),
- defaults: {
- operator: 'over',
- k1: '0',
- k2: '0',
- k3: '0',
- k4: '0',
- },
- content: new Set(['animate', 'set']),
- },
- feConvolveMatrix: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set([
- 'class',
- 'in',
- 'kernelMatrix',
- 'order',
- 'style',
- // TODO: divisor - 'The default value is the sum of all values in kernelMatrix,
- // with the exception that if the sum is zero, then the divisor is set to 1'
- 'bias',
- 'divisor',
- // TODO: targetX - 'By default, the convolution matrix is centered in X over each
- // pixel of the input image (i.e., targetX = floor ( orderX / 2 ))'
- 'edgeMode',
- 'targetX',
- 'targetY',
- // TODO: kernelUnitLength - 'The first number is the <dx> value. The second number
- // is the <dy> value. If the <dy> value is not specified, it defaults to the same value as <dx>'
- 'kernelUnitLength',
- 'preserveAlpha',
- ]),
- defaults: {
- order: '3',
- bias: '0',
- edgeMode: 'duplicate',
- preserveAlpha: 'false',
- },
- content: new Set(['animate', 'set']),
- },
- feDiffuseLighting: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set([
- 'class',
- 'diffuseConstant',
- 'in',
- 'kernelUnitLength',
- 'style',
- 'surfaceScale',
- ]),
- defaults: {
- surfaceScale: '1',
- diffuseConstant: '1',
- },
- contentGroups: new Set(['descriptive']),
- content: new Set([
- // TODO: 'exactly one light source element, in any order'
- 'feDistantLight',
- 'fePointLight',
- 'feSpotLight',
- ]),
- },
- feDisplacementMap: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set([
- 'class',
- 'in',
- 'in2',
- 'scale',
- 'style',
- 'xChannelSelector',
- 'yChannelSelector',
- ]),
- defaults: {
- scale: '0',
- xChannelSelector: 'A',
- yChannelSelector: 'A',
- },
- content: new Set(['animate', 'set']),
- },
- feDistantLight: {
- attrsGroups: new Set(['core']),
- attrs: new Set(['azimuth', 'elevation']),
- defaults: {
- azimuth: '0',
- elevation: '0',
- },
- content: new Set(['animate', 'set']),
- },
- feFlood: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set(['class', 'style']),
- content: new Set(['animate', 'animateColor', 'set']),
- },
- feFuncA: {
- attrsGroups: new Set(['core', 'transferFunction']),
- content: new Set(['set', 'animate']),
- },
- feFuncB: {
- attrsGroups: new Set(['core', 'transferFunction']),
- content: new Set(['set', 'animate']),
- },
- feFuncG: {
- attrsGroups: new Set(['core', 'transferFunction']),
- content: new Set(['set', 'animate']),
- },
- feFuncR: {
- attrsGroups: new Set(['core', 'transferFunction']),
- content: new Set(['set', 'animate']),
- },
- feGaussianBlur: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set(['class', 'style', 'in', 'stdDeviation']),
- defaults: {
- stdDeviation: '0',
- },
- content: new Set(['set', 'animate']),
- },
- feImage: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive', 'xlink']),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'href',
- 'preserveAspectRatio',
- 'style',
- 'xlink:href',
- ]),
- defaults: {
- preserveAspectRatio: 'xMidYMid meet',
- },
- content: new Set(['animate', 'animateTransform', 'set']),
- },
- feMerge: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set(['class', 'style']),
- content: new Set(['feMergeNode']),
- },
- feMergeNode: {
- attrsGroups: new Set(['core']),
- attrs: new Set(['in']),
- content: new Set(['animate', 'set']),
- },
- feMorphology: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set(['class', 'style', 'in', 'operator', 'radius']),
- defaults: {
- operator: 'erode',
- radius: '0',
- },
- content: new Set(['animate', 'set']),
- },
- feOffset: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set(['class', 'style', 'in', 'dx', 'dy']),
- defaults: {
- dx: '0',
- dy: '0',
- },
- content: new Set(['animate', 'set']),
- },
- fePointLight: {
- attrsGroups: new Set(['core']),
- attrs: new Set(['x', 'y', 'z']),
- defaults: {
- x: '0',
- y: '0',
- z: '0',
- },
- content: new Set(['animate', 'set']),
- },
- feSpecularLighting: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set([
- 'class',
- 'in',
- 'kernelUnitLength',
- 'specularConstant',
- 'specularExponent',
- 'style',
- 'surfaceScale',
- ]),
- defaults: {
- surfaceScale: '1',
- specularConstant: '1',
- specularExponent: '1',
- },
- contentGroups: new Set([
- 'descriptive',
- // TODO: exactly one 'light source element'
- 'lightSource',
- ]),
- },
- feSpotLight: {
- attrsGroups: new Set(['core']),
- attrs: new Set([
- 'limitingConeAngle',
- 'pointsAtX',
- 'pointsAtY',
- 'pointsAtZ',
- 'specularExponent',
- 'x',
- 'y',
- 'z',
- ]),
- defaults: {
- x: '0',
- y: '0',
- z: '0',
- pointsAtX: '0',
- pointsAtY: '0',
- pointsAtZ: '0',
- specularExponent: '1',
- },
- content: new Set(['animate', 'set']),
- },
- feTile: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set(['class', 'style', 'in']),
- content: new Set(['animate', 'set']),
- },
- feTurbulence: {
- attrsGroups: new Set(['core', 'presentation', 'filterPrimitive']),
- attrs: new Set([
- 'baseFrequency',
- 'class',
- 'numOctaves',
- 'seed',
- 'stitchTiles',
- 'style',
- 'type',
- ]),
- defaults: {
- baseFrequency: '0',
- numOctaves: '1',
- seed: '0',
- stitchTiles: 'noStitch',
- type: 'turbulence',
- },
- content: new Set(['animate', 'set']),
- },
- filter: {
- attrsGroups: new Set(['core', 'presentation', 'xlink']),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'filterRes',
- 'filterUnits',
- 'height',
- 'href',
- 'primitiveUnits',
- 'style',
- 'width',
- 'x',
- 'xlink:href',
- 'y',
- ]),
- defaults: {
- primitiveUnits: 'userSpaceOnUse',
- x: '-10%',
- y: '-10%',
- width: '120%',
- height: '120%',
- },
- contentGroups: new Set(['descriptive', 'filterPrimitive']),
- content: new Set(['animate', 'set']),
- },
- font: {
- attrsGroups: new Set(['core', 'presentation']),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'horiz-adv-x',
- 'horiz-origin-x',
- 'horiz-origin-y',
- 'style',
- 'vert-adv-y',
- 'vert-origin-x',
- 'vert-origin-y',
- ]),
- defaults: {
- 'horiz-origin-x': '0',
- 'horiz-origin-y': '0',
- },
- contentGroups: new Set(['descriptive']),
- content: new Set(['font-face', 'glyph', 'hkern', 'missing-glyph', 'vkern']),
- },
- 'font-face': {
- attrsGroups: new Set(['core']),
- attrs: new Set([
- 'font-family',
- 'font-style',
- 'font-variant',
- 'font-weight',
- 'font-stretch',
- 'font-size',
- 'unicode-range',
- 'units-per-em',
- 'panose-1',
- 'stemv',
- 'stemh',
- 'slope',
- 'cap-height',
- 'x-height',
- 'accent-height',
- 'ascent',
- 'descent',
- 'widths',
- 'bbox',
- 'ideographic',
- 'alphabetic',
- 'mathematical',
- 'hanging',
- 'v-ideographic',
- 'v-alphabetic',
- 'v-mathematical',
- 'v-hanging',
- 'underline-position',
- 'underline-thickness',
- 'strikethrough-position',
- 'strikethrough-thickness',
- 'overline-position',
- 'overline-thickness',
- ]),
- defaults: {
- 'font-style': 'all',
- 'font-variant': 'normal',
- 'font-weight': 'all',
- 'font-stretch': 'normal',
- 'unicode-range': 'U+0-10FFFF',
- 'units-per-em': '1000',
- 'panose-1': '0 0 0 0 0 0 0 0 0 0',
- slope: '0',
- },
- contentGroups: new Set(['descriptive']),
- content: new Set([
- // TODO: "at most one 'font-face-src' element"
- 'font-face-src',
- ]),
- },
- // TODO: empty content
- 'font-face-format': {
- attrsGroups: new Set(['core']),
- attrs: new Set(['string']),
- },
- 'font-face-name': {
- attrsGroups: new Set(['core']),
- attrs: new Set(['name']),
- },
- 'font-face-src': {
- attrsGroups: new Set(['core']),
- content: new Set(['font-face-name', 'font-face-uri']),
- },
- 'font-face-uri': {
- attrsGroups: new Set(['core', 'xlink']),
- attrs: new Set(['href', 'xlink:href']),
- content: new Set(['font-face-format']),
- },
- foreignObject: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'height',
- 'style',
- 'transform',
- 'width',
- 'x',
- 'y',
- ]),
- defaults: {
- x: '0',
- y: '0',
- },
- },
- g: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'style',
- 'transform',
- ]),
- contentGroups: new Set([
- 'animation',
- 'descriptive',
- 'paintServer',
- 'shape',
- 'structural',
- ]),
- content: new Set([
- 'a',
- 'altGlyphDef',
- 'clipPath',
- 'color-profile',
- 'cursor',
- 'filter',
- 'font-face',
- 'font',
- 'foreignObject',
- 'image',
- 'marker',
- 'mask',
- 'pattern',
- 'script',
- 'style',
- 'switch',
- 'text',
- 'view',
- ]),
- },
- glyph: {
- attrsGroups: new Set(['core', 'presentation']),
- attrs: new Set([
- 'arabic-form',
- 'class',
- 'd',
- 'glyph-name',
- 'horiz-adv-x',
- 'lang',
- 'orientation',
- 'style',
- 'unicode',
- 'vert-adv-y',
- 'vert-origin-x',
- 'vert-origin-y',
- ]),
- defaults: {
- 'arabic-form': 'initial',
- },
- contentGroups: new Set([
- 'animation',
- 'descriptive',
- 'paintServer',
- 'shape',
- 'structural',
- ]),
- content: new Set([
- 'a',
- 'altGlyphDef',
- 'clipPath',
- 'color-profile',
- 'cursor',
- 'filter',
- 'font-face',
- 'font',
- 'foreignObject',
- 'image',
- 'marker',
- 'mask',
- 'pattern',
- 'script',
- 'style',
- 'switch',
- 'text',
- 'view',
- ]),
- },
- glyphRef: {
- attrsGroups: new Set(['core', 'presentation']),
- attrs: new Set([
- 'class',
- 'd',
- 'horiz-adv-x',
- 'style',
- 'vert-adv-y',
- 'vert-origin-x',
- 'vert-origin-y',
- ]),
- contentGroups: new Set([
- 'animation',
- 'descriptive',
- 'paintServer',
- 'shape',
- 'structural',
- ]),
- content: new Set([
- 'a',
- 'altGlyphDef',
- 'clipPath',
- 'color-profile',
- 'cursor',
- 'filter',
- 'font-face',
- 'font',
- 'foreignObject',
- 'image',
- 'marker',
- 'mask',
- 'pattern',
- 'script',
- 'style',
- 'switch',
- 'text',
- 'view',
- ]),
- },
- hatch: {
- attrsGroups: new Set(['core', 'presentation', 'xlink']),
- attrs: new Set([
- 'class',
- 'hatchContentUnits',
- 'hatchUnits',
- 'pitch',
- 'rotate',
- 'style',
- 'transform',
- 'x',
- 'y',
- ]),
- defaults: {
- hatchUnits: 'objectBoundingBox',
- hatchContentUnits: 'userSpaceOnUse',
- x: '0',
- y: '0',
- pitch: '0',
- rotate: '0',
- },
- contentGroups: new Set(['animation', 'descriptive']),
- content: new Set(['hatchPath']),
- },
- hatchPath: {
- attrsGroups: new Set(['core', 'presentation', 'xlink']),
- attrs: new Set(['class', 'style', 'd', 'offset']),
- defaults: {
- offset: '0',
- },
- contentGroups: new Set(['animation', 'descriptive']),
- },
- hkern: {
- attrsGroups: new Set(['core']),
- attrs: new Set(['u1', 'g1', 'u2', 'g2', 'k']),
- },
- image: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- 'xlink',
- ]),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'height',
- 'href',
- 'preserveAspectRatio',
- 'style',
- 'transform',
- 'width',
- 'x',
- 'xlink:href',
- 'y',
- ]),
- defaults: {
- x: '0',
- y: '0',
- preserveAspectRatio: 'xMidYMid meet',
- },
- contentGroups: new Set(['animation', 'descriptive']),
- },
- line: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'style',
- 'transform',
- 'x1',
- 'x2',
- 'y1',
- 'y2',
- ]),
- defaults: {
- x1: '0',
- y1: '0',
- x2: '0',
- y2: '0',
- },
- contentGroups: new Set(['animation', 'descriptive']),
- },
- linearGradient: {
- attrsGroups: new Set(['core', 'presentation', 'xlink']),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'gradientTransform',
- 'gradientUnits',
- 'href',
- 'spreadMethod',
- 'style',
- 'x1',
- 'x2',
- 'xlink:href',
- 'y1',
- 'y2',
- ]),
- defaults: {
- x1: '0',
- y1: '0',
- x2: '100%',
- y2: '0',
- spreadMethod: 'pad',
- },
- contentGroups: new Set(['descriptive']),
- content: new Set(['animate', 'animateTransform', 'set', 'stop']),
- },
- marker: {
- attrsGroups: new Set(['core', 'presentation']),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'markerHeight',
- 'markerUnits',
- 'markerWidth',
- 'orient',
- 'preserveAspectRatio',
- 'refX',
- 'refY',
- 'style',
- 'viewBox',
- ]),
- defaults: {
- markerUnits: 'strokeWidth',
- refX: '0',
- refY: '0',
- markerWidth: '3',
- markerHeight: '3',
- },
- contentGroups: new Set([
- 'animation',
- 'descriptive',
- 'paintServer',
- 'shape',
- 'structural',
- ]),
- content: new Set([
- 'a',
- 'altGlyphDef',
- 'clipPath',
- 'color-profile',
- 'cursor',
- 'filter',
- 'font-face',
- 'font',
- 'foreignObject',
- 'image',
- 'marker',
- 'mask',
- 'pattern',
- 'script',
- 'style',
- 'switch',
- 'text',
- 'view',
- ]),
- },
- mask: {
- attrsGroups: new Set(['conditionalProcessing', 'core', 'presentation']),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'height',
- 'mask-type',
- 'maskContentUnits',
- 'maskUnits',
- 'style',
- 'width',
- 'x',
- 'y',
- ]),
- defaults: {
- maskUnits: 'objectBoundingBox',
- maskContentUnits: 'userSpaceOnUse',
- x: '-10%',
- y: '-10%',
- width: '120%',
- height: '120%',
- },
- contentGroups: new Set([
- 'animation',
- 'descriptive',
- 'paintServer',
- 'shape',
- 'structural',
- ]),
- content: new Set([
- 'a',
- 'altGlyphDef',
- 'clipPath',
- 'color-profile',
- 'cursor',
- 'filter',
- 'font-face',
- 'font',
- 'foreignObject',
- 'image',
- 'marker',
- 'mask',
- 'pattern',
- 'script',
- 'style',
- 'switch',
- 'text',
- 'view',
- ]),
- },
- metadata: {
- attrsGroups: new Set(['core']),
- },
- 'missing-glyph': {
- attrsGroups: new Set(['core', 'presentation']),
- attrs: new Set([
- 'class',
- 'd',
- 'horiz-adv-x',
- 'style',
- 'vert-adv-y',
- 'vert-origin-x',
- 'vert-origin-y',
- ]),
- contentGroups: new Set([
- 'animation',
- 'descriptive',
- 'paintServer',
- 'shape',
- 'structural',
- ]),
- content: new Set([
- 'a',
- 'altGlyphDef',
- 'clipPath',
- 'color-profile',
- 'cursor',
- 'filter',
- 'font-face',
- 'font',
- 'foreignObject',
- 'image',
- 'marker',
- 'mask',
- 'pattern',
- 'script',
- 'style',
- 'switch',
- 'text',
- 'view',
- ]),
- },
- mpath: {
- attrsGroups: new Set(['core', 'xlink']),
- attrs: new Set(['externalResourcesRequired', 'href', 'xlink:href']),
- contentGroups: new Set(['descriptive']),
- },
- path: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'class',
- 'd',
- 'externalResourcesRequired',
- 'pathLength',
- 'style',
- 'transform',
- ]),
- contentGroups: new Set(['animation', 'descriptive']),
- },
- pattern: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'presentation',
- 'xlink',
- ]),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'height',
- 'href',
- 'patternContentUnits',
- 'patternTransform',
- 'patternUnits',
- 'preserveAspectRatio',
- 'style',
- 'viewBox',
- 'width',
- 'x',
- 'xlink:href',
- 'y',
- ]),
- defaults: {
- patternUnits: 'objectBoundingBox',
- patternContentUnits: 'userSpaceOnUse',
- x: '0',
- y: '0',
- width: '0',
- height: '0',
- preserveAspectRatio: 'xMidYMid meet',
- },
- contentGroups: new Set([
- 'animation',
- 'descriptive',
- 'paintServer',
- 'shape',
- 'structural',
- ]),
- content: new Set([
- 'a',
- 'altGlyphDef',
- 'clipPath',
- 'color-profile',
- 'cursor',
- 'filter',
- 'font-face',
- 'font',
- 'foreignObject',
- 'image',
- 'marker',
- 'mask',
- 'pattern',
- 'script',
- 'style',
- 'switch',
- 'text',
- 'view',
- ]),
- },
- polygon: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'points',
- 'style',
- 'transform',
- ]),
- contentGroups: new Set(['animation', 'descriptive']),
- },
- polyline: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'points',
- 'style',
- 'transform',
- ]),
- contentGroups: new Set(['animation', 'descriptive']),
- },
- radialGradient: {
- attrsGroups: new Set(['core', 'presentation', 'xlink']),
- attrs: new Set([
- 'class',
- 'cx',
- 'cy',
- 'externalResourcesRequired',
- 'fr',
- 'fx',
- 'fy',
- 'gradientTransform',
- 'gradientUnits',
- 'href',
- 'r',
- 'spreadMethod',
- 'style',
- 'xlink:href',
- ]),
- defaults: {
- gradientUnits: 'objectBoundingBox',
- cx: '50%',
- cy: '50%',
- r: '50%',
- },
- contentGroups: new Set(['descriptive']),
- content: new Set(['animate', 'animateTransform', 'set', 'stop']),
- },
- meshGradient: {
- attrsGroups: new Set(['core', 'presentation', 'xlink']),
- attrs: new Set(['class', 'style', 'x', 'y', 'gradientUnits', 'transform']),
- contentGroups: new Set(['descriptive', 'paintServer', 'animation']),
- content: new Set(['meshRow']),
- },
- meshRow: {
- attrsGroups: new Set(['core', 'presentation']),
- attrs: new Set(['class', 'style']),
- contentGroups: new Set(['descriptive']),
- content: new Set(['meshPatch']),
- },
- meshPatch: {
- attrsGroups: new Set(['core', 'presentation']),
- attrs: new Set(['class', 'style']),
- contentGroups: new Set(['descriptive']),
- content: new Set(['stop']),
- },
- rect: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'height',
- 'rx',
- 'ry',
- 'style',
- 'transform',
- 'width',
- 'x',
- 'y',
- ]),
- defaults: {
- x: '0',
- y: '0',
- },
- contentGroups: new Set(['animation', 'descriptive']),
- },
- script: {
- attrsGroups: new Set(['core', 'xlink']),
- attrs: new Set(['externalResourcesRequired', 'type', 'href', 'xlink:href']),
- },
- set: {
- attrsGroups: new Set([
- 'animation',
- 'animationAttributeTarget',
- 'animationTiming',
- 'conditionalProcessing',
- 'core',
- 'xlink',
- ]),
- attrs: new Set(['externalResourcesRequired', 'to']),
- contentGroups: new Set(['descriptive']),
- },
- solidColor: {
- attrsGroups: new Set(['core', 'presentation']),
- attrs: new Set(['class', 'style']),
- contentGroups: new Set(['paintServer']),
- },
- stop: {
- attrsGroups: new Set(['core', 'presentation']),
- attrs: new Set(['class', 'style', 'offset', 'path']),
- content: new Set(['animate', 'animateColor', 'set']),
- },
- style: {
- attrsGroups: new Set(['core']),
- attrs: new Set(['type', 'media', 'title']),
- defaults: {
- type: 'text/css',
- },
- },
- svg: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'documentEvent',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'baseProfile',
- 'class',
- 'contentScriptType',
- 'contentStyleType',
- 'height',
- 'preserveAspectRatio',
- 'style',
- 'version',
- 'viewBox',
- 'width',
- 'x',
- 'y',
- 'zoomAndPan',
- ]),
- defaults: {
- x: '0',
- y: '0',
- width: '100%',
- height: '100%',
- preserveAspectRatio: 'xMidYMid meet',
- zoomAndPan: 'magnify',
- version: '1.1',
- baseProfile: 'none',
- contentScriptType: 'application/ecmascript',
- contentStyleType: 'text/css',
- },
- contentGroups: new Set([
- 'animation',
- 'descriptive',
- 'paintServer',
- 'shape',
- 'structural',
- ]),
- content: new Set([
- 'a',
- 'altGlyphDef',
- 'clipPath',
- 'color-profile',
- 'cursor',
- 'filter',
- 'font-face',
- 'font',
- 'foreignObject',
- 'image',
- 'marker',
- 'mask',
- 'pattern',
- 'script',
- 'style',
- 'switch',
- 'text',
- 'view',
- ]),
- },
- switch: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'style',
- 'transform',
- ]),
- contentGroups: new Set(['animation', 'descriptive', 'shape']),
- content: new Set([
- 'a',
- 'foreignObject',
- 'g',
- 'image',
- 'svg',
- 'switch',
- 'text',
- 'use',
- ]),
- },
- symbol: {
- attrsGroups: new Set(['core', 'graphicalEvent', 'presentation']),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'preserveAspectRatio',
- 'refX',
- 'refY',
- 'style',
- 'viewBox',
- ]),
- defaults: {
- refX: '0',
- refY: '0',
- },
- contentGroups: new Set([
- 'animation',
- 'descriptive',
- 'paintServer',
- 'shape',
- 'structural',
- ]),
- content: new Set([
- 'a',
- 'altGlyphDef',
- 'clipPath',
- 'color-profile',
- 'cursor',
- 'filter',
- 'font-face',
- 'font',
- 'foreignObject',
- 'image',
- 'marker',
- 'mask',
- 'pattern',
- 'script',
- 'style',
- 'switch',
- 'text',
- 'view',
- ]),
- },
- text: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'class',
- 'dx',
- 'dy',
- 'externalResourcesRequired',
- 'lengthAdjust',
- 'rotate',
- 'style',
- 'textLength',
- 'transform',
- 'x',
- 'y',
- ]),
- defaults: {
- x: '0',
- y: '0',
- lengthAdjust: 'spacing',
- },
- contentGroups: new Set(['animation', 'descriptive', 'textContentChild']),
- content: new Set(['a']),
- },
- textPath: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- 'xlink',
- ]),
- attrs: new Set([
- 'class',
- 'd',
- 'externalResourcesRequired',
- 'href',
- 'method',
- 'spacing',
- 'startOffset',
- 'style',
- 'xlink:href',
- ]),
- defaults: {
- startOffset: '0',
- method: 'align',
- spacing: 'exact',
- },
- contentGroups: new Set(['descriptive']),
- content: new Set([
- 'a',
- 'altGlyph',
- 'animate',
- 'animateColor',
- 'set',
- 'tref',
- 'tspan',
- ]),
- },
- title: {
- attrsGroups: new Set(['core']),
- attrs: new Set(['class', 'style']),
- },
- tref: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- 'xlink',
- ]),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'href',
- 'style',
- 'xlink:href',
- ]),
- contentGroups: new Set(['descriptive']),
- content: new Set(['animate', 'animateColor', 'set']),
- },
- tspan: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- ]),
- attrs: new Set([
- 'class',
- 'dx',
- 'dy',
- 'externalResourcesRequired',
- 'lengthAdjust',
- 'rotate',
- 'style',
- 'textLength',
- 'x',
- 'y',
- ]),
- contentGroups: new Set(['descriptive']),
- content: new Set([
- 'a',
- 'altGlyph',
- 'animate',
- 'animateColor',
- 'set',
- 'tref',
- 'tspan',
- ]),
- },
- use: {
- attrsGroups: new Set([
- 'conditionalProcessing',
- 'core',
- 'graphicalEvent',
- 'presentation',
- 'xlink',
- ]),
- attrs: new Set([
- 'class',
- 'externalResourcesRequired',
- 'height',
- 'href',
- 'style',
- 'transform',
- 'width',
- 'x',
- 'xlink:href',
- 'y',
- ]),
- defaults: {
- x: '0',
- y: '0',
- },
- contentGroups: new Set(['animation', 'descriptive']),
- },
- view: {
- attrsGroups: new Set(['core']),
- attrs: new Set([
- 'externalResourcesRequired',
- 'preserveAspectRatio',
- 'viewBox',
- 'viewTarget',
- 'zoomAndPan',
- ]),
- contentGroups: new Set(['descriptive']),
- },
- vkern: {
- attrsGroups: new Set(['core']),
- attrs: new Set(['u1', 'g1', 'u2', 'g2', 'k']),
- },
-};
-
-// https://wiki.inkscape.org/wiki/index.php/Inkscape-specific_XML_attributes
-exports.editorNamespaces = new Set([
- 'http://creativecommons.org/ns#',
- 'http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd',
- 'http://ns.adobe.com/AdobeIllustrator/10.0/',
- 'http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/',
- 'http://ns.adobe.com/Extensibility/1.0/',
- 'http://ns.adobe.com/Flows/1.0/',
- 'http://ns.adobe.com/GenericCustomNamespace/1.0/',
- 'http://ns.adobe.com/Graphs/1.0/',
- 'http://ns.adobe.com/ImageReplacement/1.0/',
- 'http://ns.adobe.com/SaveForWeb/1.0/',
- 'http://ns.adobe.com/Variables/1.0/',
- 'http://ns.adobe.com/XPath/1.0/',
- 'http://purl.org/dc/elements/1.1/',
- 'http://schemas.microsoft.com/visio/2003/SVGExtensions/',
- 'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd',
- 'http://taptrix.com/vectorillustrator/svg_extensions',
- 'http://www.bohemiancoding.com/sketch/ns',
- 'http://www.figma.com/figma/ns',
- 'http://www.inkscape.org/namespaces/inkscape',
- 'http://www.serif.com/',
- 'http://www.vector.evaxdesign.sk',
- 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
-]);
-
-/**
- * @see https://www.w3.org/TR/SVG11/linking.html#processingIRI
- */
-exports.referencesProps = new Set([
- 'clip-path',
- 'color-profile',
- 'fill',
- 'filter',
- 'marker-end',
- 'marker-mid',
- 'marker-start',
- 'mask',
- 'stroke',
- 'style',
-]);
-
-/**
- * @see https://www.w3.org/TR/SVG11/propidx.html
- */
-exports.inheritableAttrs = new Set([
- 'clip-rule',
- 'color-interpolation-filters',
- 'color-interpolation',
- 'color-profile',
- 'color-rendering',
- 'color',
- 'cursor',
- 'direction',
- 'dominant-baseline',
- 'fill-opacity',
- 'fill-rule',
- 'fill',
- 'font-family',
- 'font-size-adjust',
- 'font-size',
- 'font-stretch',
- 'font-style',
- 'font-variant',
- 'font-weight',
- 'font',
- 'glyph-orientation-horizontal',
- 'glyph-orientation-vertical',
- 'image-rendering',
- 'letter-spacing',
- 'marker-end',
- 'marker-mid',
- 'marker-start',
- 'marker',
- 'paint-order',
- 'pointer-events',
- 'shape-rendering',
- 'stroke-dasharray',
- 'stroke-dashoffset',
- 'stroke-linecap',
- 'stroke-linejoin',
- 'stroke-miterlimit',
- 'stroke-opacity',
- 'stroke-width',
- 'stroke',
- 'text-anchor',
- 'text-rendering',
- 'transform',
- 'visibility',
- 'word-spacing',
- 'writing-mode',
-]);
-
-exports.presentationNonInheritableGroupAttrs = new Set([
- 'clip-path',
- 'display',
- 'filter',
- 'mask',
- 'opacity',
- 'text-decoration',
- 'transform',
- 'unicode-bidi',
-]);
-
-/**
- * https://www.w3.org/TR/SVG11/single-page.html#types-ColorKeywords
- *
- * @type {Record<string, string>}
- */
-exports.colorsNames = {
- aliceblue: '#f0f8ff',
- antiquewhite: '#faebd7',
- aqua: '#0ff',
- aquamarine: '#7fffd4',
- azure: '#f0ffff',
- beige: '#f5f5dc',
- bisque: '#ffe4c4',
- black: '#000',
- blanchedalmond: '#ffebcd',
- blue: '#00f',
- blueviolet: '#8a2be2',
- brown: '#a52a2a',
- burlywood: '#deb887',
- cadetblue: '#5f9ea0',
- chartreuse: '#7fff00',
- chocolate: '#d2691e',
- coral: '#ff7f50',
- cornflowerblue: '#6495ed',
- cornsilk: '#fff8dc',
- crimson: '#dc143c',
- cyan: '#0ff',
- darkblue: '#00008b',
- darkcyan: '#008b8b',
- darkgoldenrod: '#b8860b',
- darkgray: '#a9a9a9',
- darkgreen: '#006400',
- darkgrey: '#a9a9a9',
- darkkhaki: '#bdb76b',
- darkmagenta: '#8b008b',
- darkolivegreen: '#556b2f',
- darkorange: '#ff8c00',
- darkorchid: '#9932cc',
- darkred: '#8b0000',
- darksalmon: '#e9967a',
- darkseagreen: '#8fbc8f',
- darkslateblue: '#483d8b',
- darkslategray: '#2f4f4f',
- darkslategrey: '#2f4f4f',
- darkturquoise: '#00ced1',
- darkviolet: '#9400d3',
- deeppink: '#ff1493',
- deepskyblue: '#00bfff',
- dimgray: '#696969',
- dimgrey: '#696969',
- dodgerblue: '#1e90ff',
- firebrick: '#b22222',
- floralwhite: '#fffaf0',
- forestgreen: '#228b22',
- fuchsia: '#f0f',
- gainsboro: '#dcdcdc',
- ghostwhite: '#f8f8ff',
- gold: '#ffd700',
- goldenrod: '#daa520',
- gray: '#808080',
- green: '#008000',
- greenyellow: '#adff2f',
- grey: '#808080',
- honeydew: '#f0fff0',
- hotpink: '#ff69b4',
- indianred: '#cd5c5c',
- indigo: '#4b0082',
- ivory: '#fffff0',
- khaki: '#f0e68c',
- lavender: '#e6e6fa',
- lavenderblush: '#fff0f5',
- lawngreen: '#7cfc00',
- lemonchiffon: '#fffacd',
- lightblue: '#add8e6',
- lightcoral: '#f08080',
- lightcyan: '#e0ffff',
- lightgoldenrodyellow: '#fafad2',
- lightgray: '#d3d3d3',
- lightgreen: '#90ee90',
- lightgrey: '#d3d3d3',
- lightpink: '#ffb6c1',
- lightsalmon: '#ffa07a',
- lightseagreen: '#20b2aa',
- lightskyblue: '#87cefa',
- lightslategray: '#789',
- lightslategrey: '#789',
- lightsteelblue: '#b0c4de',
- lightyellow: '#ffffe0',
- lime: '#0f0',
- limegreen: '#32cd32',
- linen: '#faf0e6',
- magenta: '#f0f',
- maroon: '#800000',
- mediumaquamarine: '#66cdaa',
- mediumblue: '#0000cd',
- mediumorchid: '#ba55d3',
- mediumpurple: '#9370db',
- mediumseagreen: '#3cb371',
- mediumslateblue: '#7b68ee',
- mediumspringgreen: '#00fa9a',
- mediumturquoise: '#48d1cc',
- mediumvioletred: '#c71585',
- midnightblue: '#191970',
- mintcream: '#f5fffa',
- mistyrose: '#ffe4e1',
- moccasin: '#ffe4b5',
- navajowhite: '#ffdead',
- navy: '#000080',
- oldlace: '#fdf5e6',
- olive: '#808000',
- olivedrab: '#6b8e23',
- orange: '#ffa500',
- orangered: '#ff4500',
- orchid: '#da70d6',
- palegoldenrod: '#eee8aa',
- palegreen: '#98fb98',
- paleturquoise: '#afeeee',
- palevioletred: '#db7093',
- papayawhip: '#ffefd5',
- peachpuff: '#ffdab9',
- peru: '#cd853f',
- pink: '#ffc0cb',
- plum: '#dda0dd',
- powderblue: '#b0e0e6',
- purple: '#800080',
- rebeccapurple: '#639',
- red: '#f00',
- rosybrown: '#bc8f8f',
- royalblue: '#4169e1',
- saddlebrown: '#8b4513',
- salmon: '#fa8072',
- sandybrown: '#f4a460',
- seagreen: '#2e8b57',
- seashell: '#fff5ee',
- sienna: '#a0522d',
- silver: '#c0c0c0',
- skyblue: '#87ceeb',
- slateblue: '#6a5acd',
- slategray: '#708090',
- slategrey: '#708090',
- snow: '#fffafa',
- springgreen: '#00ff7f',
- steelblue: '#4682b4',
- tan: '#d2b48c',
- teal: '#008080',
- thistle: '#d8bfd8',
- tomato: '#ff6347',
- turquoise: '#40e0d0',
- violet: '#ee82ee',
- wheat: '#f5deb3',
- white: '#fff',
- whitesmoke: '#f5f5f5',
- yellow: '#ff0',
- yellowgreen: '#9acd32',
-};
-
-/**
- * @type {Record<string, string>}
- */
-exports.colorsShortNames = {
- '#f0ffff': 'azure',
- '#f5f5dc': 'beige',
- '#ffe4c4': 'bisque',
- '#a52a2a': 'brown',
- '#ff7f50': 'coral',
- '#ffd700': 'gold',
- '#808080': 'gray',
- '#008000': 'green',
- '#4b0082': 'indigo',
- '#fffff0': 'ivory',
- '#f0e68c': 'khaki',
- '#faf0e6': 'linen',
- '#800000': 'maroon',
- '#000080': 'navy',
- '#808000': 'olive',
- '#ffa500': 'orange',
- '#da70d6': 'orchid',
- '#cd853f': 'peru',
- '#ffc0cb': 'pink',
- '#dda0dd': 'plum',
- '#800080': 'purple',
- '#f00': 'red',
- '#ff0000': 'red',
- '#fa8072': 'salmon',
- '#a0522d': 'sienna',
- '#c0c0c0': 'silver',
- '#fffafa': 'snow',
- '#d2b48c': 'tan',
- '#008080': 'teal',
- '#ff6347': 'tomato',
- '#ee82ee': 'violet',
- '#f5deb3': 'wheat',
-};
-
-/**
- * @see https://www.w3.org/TR/SVG11/single-page.html#types-DataTypeColor
- */
-exports.colorsProps = new Set([
- 'color',
- 'fill',
- 'flood-color',
- 'lighting-color',
- 'stop-color',
- 'stroke',
-]);
-
-/** @see https://developer.mozilla.org/docs/Web/CSS/Pseudo-classes */
-exports.pseudoClasses = {
- displayState: new Set(['fullscreen', 'modal', 'picture-in-picture']),
- input: new Set([
- 'autofill',
- 'blank',
- 'checked',
- 'default',
- 'disabled',
- 'enabled',
- 'in-range',
- 'indetermined',
- 'invalid',
- 'optional',
- 'out-of-range',
- 'placeholder-shown',
- 'read-only',
- 'read-write',
- 'required',
- 'user-invalid',
- 'valid',
- ]),
- linguistic: new Set(['dir', 'lang']),
- location: new Set([
- 'any-link',
- 'link',
- 'local-link',
- 'scope',
- 'target-within',
- 'target',
- 'visited',
- ]),
- resourceState: new Set(['playing', 'paused']),
- timeDimensional: new Set(['current', 'past', 'future']),
- treeStructural: new Set([
- 'empty',
- 'first-child',
- 'first-of-type',
- 'last-child',
- 'last-of-type',
- 'nth-child',
- 'nth-last-child',
- 'nth-last-of-type',
- 'nth-of-type',
- 'only-child',
- 'only-of-type',
- 'root',
- ]),
- userAction: new Set([
- 'active',
- 'focus-visible',
- 'focus-within',
- 'focus',
- 'hover',
- ]),
- functional: new Set(['is', 'not', 'where', 'has']),
-};
diff --git a/node_modules/svgo/plugins/_path.js b/node_modules/svgo/plugins/_path.js
deleted file mode 100644
index 7c3a28b9..00000000
--- a/node_modules/svgo/plugins/_path.js
+++ /dev/null
@@ -1,815 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types').XastElement} XastElement
- * @typedef {import('../lib/types').PathDataItem} PathDataItem
- */
-
-const { parsePathData, stringifyPathData } = require('../lib/path.js');
-
-/**
- * @type {[number, number]}
- */
-var prevCtrlPoint;
-
-/**
- * Convert path string to JS representation.
- *
- * @type {(path: XastElement) => PathDataItem[]}
- */
-const path2js = (path) => {
- // @ts-ignore legacy
- if (path.pathJS) return path.pathJS;
- /**
- * @type {PathDataItem[]}
- */
- const pathData = []; // JS representation of the path data
- const newPathData = parsePathData(path.attributes.d);
- for (const { command, args } of newPathData) {
- pathData.push({ command, args });
- }
- // First moveto is actually absolute. Subsequent coordinates were separated above.
- if (pathData.length && pathData[0].command == 'm') {
- pathData[0].command = 'M';
- }
- // @ts-ignore legacy
- path.pathJS = pathData;
- return pathData;
-};
-exports.path2js = path2js;
-
-/**
- * Convert relative Path data to absolute.
- *
- * @type {(data: PathDataItem[]) => PathDataItem[]}
- *
- */
-const convertRelativeToAbsolute = (data) => {
- /**
- * @type {PathDataItem[]}
- */
- const newData = [];
- let start = [0, 0];
- let cursor = [0, 0];
-
- for (let { command, args } of data) {
- args = args.slice();
-
- // moveto (x y)
- if (command === 'm') {
- args[0] += cursor[0];
- args[1] += cursor[1];
- command = 'M';
- }
- if (command === 'M') {
- cursor[0] = args[0];
- cursor[1] = args[1];
- start[0] = cursor[0];
- start[1] = cursor[1];
- }
-
- // horizontal lineto (x)
- if (command === 'h') {
- args[0] += cursor[0];
- command = 'H';
- }
- if (command === 'H') {
- cursor[0] = args[0];
- }
-
- // vertical lineto (y)
- if (command === 'v') {
- args[0] += cursor[1];
- command = 'V';
- }
- if (command === 'V') {
- cursor[1] = args[0];
- }
-
- // lineto (x y)
- if (command === 'l') {
- args[0] += cursor[0];
- args[1] += cursor[1];
- command = 'L';
- }
- if (command === 'L') {
- cursor[0] = args[0];
- cursor[1] = args[1];
- }
-
- // curveto (x1 y1 x2 y2 x y)
- if (command === 'c') {
- args[0] += cursor[0];
- args[1] += cursor[1];
- args[2] += cursor[0];
- args[3] += cursor[1];
- args[4] += cursor[0];
- args[5] += cursor[1];
- command = 'C';
- }
- if (command === 'C') {
- cursor[0] = args[4];
- cursor[1] = args[5];
- }
-
- // smooth curveto (x2 y2 x y)
- if (command === 's') {
- args[0] += cursor[0];
- args[1] += cursor[1];
- args[2] += cursor[0];
- args[3] += cursor[1];
- command = 'S';
- }
- if (command === 'S') {
- cursor[0] = args[2];
- cursor[1] = args[3];
- }
-
- // quadratic Bézier curveto (x1 y1 x y)
- if (command === 'q') {
- args[0] += cursor[0];
- args[1] += cursor[1];
- args[2] += cursor[0];
- args[3] += cursor[1];
- command = 'Q';
- }
- if (command === 'Q') {
- cursor[0] = args[2];
- cursor[1] = args[3];
- }
-
- // smooth quadratic Bézier curveto (x y)
- if (command === 't') {
- args[0] += cursor[0];
- args[1] += cursor[1];
- command = 'T';
- }
- if (command === 'T') {
- cursor[0] = args[0];
- cursor[1] = args[1];
- }
-
- // elliptical arc (rx ry x-axis-rotation large-arc-flag sweep-flag x y)
- if (command === 'a') {
- args[5] += cursor[0];
- args[6] += cursor[1];
- command = 'A';
- }
- if (command === 'A') {
- cursor[0] = args[5];
- cursor[1] = args[6];
- }
-
- // closepath
- if (command === 'z' || command === 'Z') {
- cursor[0] = start[0];
- cursor[1] = start[1];
- command = 'z';
- }
-
- newData.push({ command, args });
- }
- return newData;
-};
-
-/**
- * @typedef {{ floatPrecision?: number, noSpaceAfterFlags?: boolean }} Js2PathParams
- */
-
-/**
- * Convert path array to string.
- *
- * @type {(path: XastElement, data: PathDataItem[], params: Js2PathParams) => void}
- */
-exports.js2path = function (path, data, params) {
- // @ts-ignore legacy
- path.pathJS = data;
-
- const pathData = [];
- for (const item of data) {
- // remove moveto commands which are followed by moveto commands
- if (
- pathData.length !== 0 &&
- (item.command === 'M' || item.command === 'm')
- ) {
- const last = pathData[pathData.length - 1];
- if (last.command === 'M' || last.command === 'm') {
- pathData.pop();
- }
- }
- pathData.push({
- command: item.command,
- args: item.args,
- });
- }
-
- path.attributes.d = stringifyPathData({
- pathData,
- precision: params.floatPrecision,
- disableSpaceAfterFlags: params.noSpaceAfterFlags,
- });
-};
-
-/**
- * @type {(dest: number[], source: number[]) => number[]}
- */
-function set(dest, source) {
- dest[0] = source[source.length - 2];
- dest[1] = source[source.length - 1];
- return dest;
-}
-
-/**
- * Checks if two paths have an intersection by checking convex hulls
- * collision using Gilbert-Johnson-Keerthi distance algorithm
- * https://web.archive.org/web/20180822200027/http://entropyinteractive.com/2011/04/gjk-algorithm/
- *
- * @type {(path1: PathDataItem[], path2: PathDataItem[]) => boolean}
- */
-exports.intersects = function (path1, path2) {
- // Collect points of every subpath.
- const points1 = gatherPoints(convertRelativeToAbsolute(path1));
- const points2 = gatherPoints(convertRelativeToAbsolute(path2));
-
- // Axis-aligned bounding box check.
- if (
- points1.maxX <= points2.minX ||
- points2.maxX <= points1.minX ||
- points1.maxY <= points2.minY ||
- points2.maxY <= points1.minY ||
- points1.list.every((set1) => {
- return points2.list.every((set2) => {
- return (
- set1.list[set1.maxX][0] <= set2.list[set2.minX][0] ||
- set2.list[set2.maxX][0] <= set1.list[set1.minX][0] ||
- set1.list[set1.maxY][1] <= set2.list[set2.minY][1] ||
- set2.list[set2.maxY][1] <= set1.list[set1.minY][1]
- );
- });
- })
- )
- return false;
-
- // Get a convex hull from points of each subpath. Has the most complexity O(n·log n).
- const hullNest1 = points1.list.map(convexHull);
- const hullNest2 = points2.list.map(convexHull);
-
- // Check intersection of every subpath of the first path with every subpath of the second.
- return hullNest1.some(function (hull1) {
- if (hull1.list.length < 3) return false;
-
- return hullNest2.some(function (hull2) {
- if (hull2.list.length < 3) return false;
-
- var simplex = [getSupport(hull1, hull2, [1, 0])], // create the initial simplex
- direction = minus(simplex[0]); // set the direction to point towards the origin
-
- var iterations = 1e4; // infinite loop protection, 10 000 iterations is more than enough
- // eslint-disable-next-line no-constant-condition
- while (true) {
- if (iterations-- == 0) {
- console.error(
- 'Error: infinite loop while processing mergePaths plugin.',
- );
- return true; // true is the safe value that means “do nothing with paths”
- }
- // add a new point
- simplex.push(getSupport(hull1, hull2, direction));
- // see if the new point was on the correct side of the origin
- if (dot(direction, simplex[simplex.length - 1]) <= 0) return false;
- // process the simplex
- if (processSimplex(simplex, direction)) return true;
- }
- });
- });
-
- /**
- * @type {(a: Point, b: Point, direction: number[]) => number[]}
- */
- function getSupport(a, b, direction) {
- return sub(supportPoint(a, direction), supportPoint(b, minus(direction)));
- }
-
- // Computes farthest polygon point in particular direction.
- // Thanks to knowledge of min/max x and y coordinates we can choose a quadrant to search in.
- // Since we're working on convex hull, the dot product is increasing until we find the farthest point.
- /**
- * @type {(polygon: Point, direction: number[]) => number[]}
- */
- function supportPoint(polygon, direction) {
- var index =
- direction[1] >= 0
- ? direction[0] < 0
- ? polygon.maxY
- : polygon.maxX
- : direction[0] < 0
- ? polygon.minX
- : polygon.minY,
- max = -Infinity,
- value;
- while ((value = dot(polygon.list[index], direction)) > max) {
- max = value;
- index = ++index % polygon.list.length;
- }
- return polygon.list[(index || polygon.list.length) - 1];
- }
-};
-
-/**
- * @type {(simplex: number[][], direction: number[]) => boolean}
- */
-function processSimplex(simplex, direction) {
- // we only need to handle to 1-simplex and 2-simplex
- if (simplex.length == 2) {
- // 1-simplex
- let a = simplex[1],
- b = simplex[0],
- AO = minus(simplex[1]),
- AB = sub(b, a);
- // AO is in the same direction as AB
- if (dot(AO, AB) > 0) {
- // get the vector perpendicular to AB facing O
- set(direction, orth(AB, a));
- } else {
- set(direction, AO);
- // only A remains in the simplex
- simplex.shift();
- }
- } else {
- // 2-simplex
- let a = simplex[2], // [a, b, c] = simplex
- b = simplex[1],
- c = simplex[0],
- AB = sub(b, a),
- AC = sub(c, a),
- AO = minus(a),
- ACB = orth(AB, AC), // the vector perpendicular to AB facing away from C
- ABC = orth(AC, AB); // the vector perpendicular to AC facing away from B
-
- if (dot(ACB, AO) > 0) {
- if (dot(AB, AO) > 0) {
- // region 4
- set(direction, ACB);
- simplex.shift(); // simplex = [b, a]
- } else {
- // region 5
- set(direction, AO);
- simplex.splice(0, 2); // simplex = [a]
- }
- } else if (dot(ABC, AO) > 0) {
- if (dot(AC, AO) > 0) {
- // region 6
- set(direction, ABC);
- simplex.splice(1, 1); // simplex = [c, a]
- } else {
- // region 5 (again)
- set(direction, AO);
- simplex.splice(0, 2); // simplex = [a]
- }
- } // region 7
- else return true;
- }
- return false;
-}
-
-/**
- * @type {(v: number[]) => number[]}
- */
-function minus(v) {
- return [-v[0], -v[1]];
-}
-
-/**
- * @type {(v1: number[], v2: number[]) => number[]}
- */
-function sub(v1, v2) {
- return [v1[0] - v2[0], v1[1] - v2[1]];
-}
-
-/**
- * @type {(v1: number[], v2: number[]) => number}
- */
-function dot(v1, v2) {
- return v1[0] * v2[0] + v1[1] * v2[1];
-}
-
-/**
- * @type {(v1: number[], v2: number[]) => number[]}
- */
-function orth(v, from) {
- var o = [-v[1], v[0]];
- return dot(o, minus(from)) < 0 ? minus(o) : o;
-}
-
-/**
- * @typedef {{
- * list: number[][],
- * minX: number,
- * minY: number,
- * maxX: number,
- * maxY: number
- * }} Point
- */
-
-/**
- * @typedef {{
- * list: Point[],
- * minX: number,
- * minY: number,
- * maxX: number,
- * maxY: number
- * }} Points
- */
-
-/**
- * @type {(pathData: PathDataItem[]) => Points}
- */
-function gatherPoints(pathData) {
- /**
- * @type {Points}
- */
- const points = { list: [], minX: 0, minY: 0, maxX: 0, maxY: 0 };
-
- // Writes data about the extreme points on each axle
- /**
- * @type {(path: Point, point: number[]) => void}
- */
- const addPoint = (path, point) => {
- if (!path.list.length || point[1] > path.list[path.maxY][1]) {
- path.maxY = path.list.length;
- points.maxY = points.list.length
- ? Math.max(point[1], points.maxY)
- : point[1];
- }
- if (!path.list.length || point[0] > path.list[path.maxX][0]) {
- path.maxX = path.list.length;
- points.maxX = points.list.length
- ? Math.max(point[0], points.maxX)
- : point[0];
- }
- if (!path.list.length || point[1] < path.list[path.minY][1]) {
- path.minY = path.list.length;
- points.minY = points.list.length
- ? Math.min(point[1], points.minY)
- : point[1];
- }
- if (!path.list.length || point[0] < path.list[path.minX][0]) {
- path.minX = path.list.length;
- points.minX = points.list.length
- ? Math.min(point[0], points.minX)
- : point[0];
- }
- path.list.push(point);
- };
-
- for (let i = 0; i < pathData.length; i += 1) {
- const pathDataItem = pathData[i];
- let subPath =
- points.list.length === 0
- ? { list: [], minX: 0, minY: 0, maxX: 0, maxY: 0 }
- : points.list[points.list.length - 1];
- let prev = i === 0 ? null : pathData[i - 1];
- let basePoint =
- subPath.list.length === 0 ? null : subPath.list[subPath.list.length - 1];
- let data = pathDataItem.args;
- let ctrlPoint = basePoint;
-
- /**
- * @type {(n: number, i: number) => number}
- * TODO fix null hack
- */
- const toAbsolute = (n, i) => n + (basePoint == null ? 0 : basePoint[i % 2]);
-
- switch (pathDataItem.command) {
- case 'M':
- subPath = { list: [], minX: 0, minY: 0, maxX: 0, maxY: 0 };
- points.list.push(subPath);
- break;
-
- case 'H':
- if (basePoint != null) {
- addPoint(subPath, [data[0], basePoint[1]]);
- }
- break;
-
- case 'V':
- if (basePoint != null) {
- addPoint(subPath, [basePoint[0], data[0]]);
- }
- break;
-
- case 'Q':
- addPoint(subPath, data.slice(0, 2));
- prevCtrlPoint = [data[2] - data[0], data[3] - data[1]]; // Save control point for shorthand
- break;
-
- case 'T':
- if (
- basePoint != null &&
- prev != null &&
- (prev.command == 'Q' || prev.command == 'T')
- ) {
- ctrlPoint = [
- basePoint[0] + prevCtrlPoint[0],
- basePoint[1] + prevCtrlPoint[1],
- ];
- addPoint(subPath, ctrlPoint);
- prevCtrlPoint = [data[0] - ctrlPoint[0], data[1] - ctrlPoint[1]];
- }
- break;
-
- case 'C':
- if (basePoint != null) {
- // Approximate quibic Bezier curve with middle points between control points
- addPoint(subPath, [
- 0.5 * (basePoint[0] + data[0]),
- 0.5 * (basePoint[1] + data[1]),
- ]);
- }
- addPoint(subPath, [
- 0.5 * (data[0] + data[2]),
- 0.5 * (data[1] + data[3]),
- ]);
- addPoint(subPath, [
- 0.5 * (data[2] + data[4]),
- 0.5 * (data[3] + data[5]),
- ]);
- prevCtrlPoint = [data[4] - data[2], data[5] - data[3]]; // Save control point for shorthand
- break;
-
- case 'S':
- if (
- basePoint != null &&
- prev != null &&
- (prev.command == 'C' || prev.command == 'S')
- ) {
- addPoint(subPath, [
- basePoint[0] + 0.5 * prevCtrlPoint[0],
- basePoint[1] + 0.5 * prevCtrlPoint[1],
- ]);
- ctrlPoint = [
- basePoint[0] + prevCtrlPoint[0],
- basePoint[1] + prevCtrlPoint[1],
- ];
- }
- if (ctrlPoint != null) {
- addPoint(subPath, [
- 0.5 * (ctrlPoint[0] + data[0]),
- 0.5 * (ctrlPoint[1] + data[1]),
- ]);
- }
- addPoint(subPath, [
- 0.5 * (data[0] + data[2]),
- 0.5 * (data[1] + data[3]),
- ]);
- prevCtrlPoint = [data[2] - data[0], data[3] - data[1]];
- break;
-
- case 'A':
- if (basePoint != null) {
- // Convert the arc to bezier curves and use the same approximation
- // @ts-ignore no idea what's going on here
- var curves = a2c.apply(0, basePoint.concat(data));
- for (
- var cData;
- (cData = curves.splice(0, 6).map(toAbsolute)).length;
-
- ) {
- if (basePoint != null) {
- addPoint(subPath, [
- 0.5 * (basePoint[0] + cData[0]),
- 0.5 * (basePoint[1] + cData[1]),
- ]);
- }
- addPoint(subPath, [
- 0.5 * (cData[0] + cData[2]),
- 0.5 * (cData[1] + cData[3]),
- ]);
- addPoint(subPath, [
- 0.5 * (cData[2] + cData[4]),
- 0.5 * (cData[3] + cData[5]),
- ]);
- if (curves.length) addPoint(subPath, (basePoint = cData.slice(-2)));
- }
- }
- break;
- }
-
- // Save final command coordinates
- if (data.length >= 2) addPoint(subPath, data.slice(-2));
- }
-
- return points;
-}
-
-/**
- * Forms a convex hull from set of points of every subpath using monotone chain convex hull algorithm.
- * https://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain
- *
- * @type {(points: Point) => Point}
- */
-function convexHull(points) {
- points.list.sort(function (a, b) {
- return a[0] == b[0] ? a[1] - b[1] : a[0] - b[0];
- });
-
- var lower = [],
- minY = 0,
- bottom = 0;
- for (let i = 0; i < points.list.length; i++) {
- while (
- lower.length >= 2 &&
- cross(lower[lower.length - 2], lower[lower.length - 1], points.list[i]) <=
- 0
- ) {
- lower.pop();
- }
- if (points.list[i][1] < points.list[minY][1]) {
- minY = i;
- bottom = lower.length;
- }
- lower.push(points.list[i]);
- }
-
- var upper = [],
- maxY = points.list.length - 1,
- top = 0;
- for (let i = points.list.length; i--; ) {
- while (
- upper.length >= 2 &&
- cross(upper[upper.length - 2], upper[upper.length - 1], points.list[i]) <=
- 0
- ) {
- upper.pop();
- }
- if (points.list[i][1] > points.list[maxY][1]) {
- maxY = i;
- top = upper.length;
- }
- upper.push(points.list[i]);
- }
-
- // last points are equal to starting points of the other part
- upper.pop();
- lower.pop();
-
- const hullList = lower.concat(upper);
-
- /**
- * @type {Point}
- */
- const hull = {
- list: hullList,
- minX: 0, // by sorting
- maxX: lower.length,
- minY: bottom,
- maxY: (lower.length + top) % hullList.length,
- };
-
- return hull;
-}
-
-/**
- * @type {(o: number[], a: number[], b: number[]) => number}
- */
-function cross(o, a, b) {
- return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
-}
-
-/**
- * Based on code from Snap.svg (Apache 2 license). http://snapsvg.io/
- * Thanks to Dmitry Baranovskiy for his great work!
- *
- * @type {(
- * x1: number,
- * y1: number,
- * rx: number,
- * ry: number,
- * angle: number,
- * large_arc_flag: number,
- * sweep_flag: number,
- * x2: number,
- * y2: number,
- * recursive: number[]
- * ) => number[]}
- */
-const a2c = (
- x1,
- y1,
- rx,
- ry,
- angle,
- large_arc_flag,
- sweep_flag,
- x2,
- y2,
- recursive,
-) => {
- // for more information of where this Math came from visit:
- // https://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
- const _120 = (Math.PI * 120) / 180;
- const rad = (Math.PI / 180) * (+angle || 0);
- /**
- * @type {number[]}
- */
- let res = [];
- /**
- * @type {(x: number, y: number, rad: number) => number}
- */
- const rotateX = (x, y, rad) => {
- return x * Math.cos(rad) - y * Math.sin(rad);
- };
- /**
- * @type {(x: number, y: number, rad: number) => number}
- */
- const rotateY = (x, y, rad) => {
- return x * Math.sin(rad) + y * Math.cos(rad);
- };
- if (!recursive) {
- x1 = rotateX(x1, y1, -rad);
- y1 = rotateY(x1, y1, -rad);
- x2 = rotateX(x2, y2, -rad);
- y2 = rotateY(x2, y2, -rad);
- var x = (x1 - x2) / 2,
- y = (y1 - y2) / 2;
- var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
- if (h > 1) {
- h = Math.sqrt(h);
- rx = h * rx;
- ry = h * ry;
- }
- var rx2 = rx * rx;
- var ry2 = ry * ry;
- var k =
- (large_arc_flag == sweep_flag ? -1 : 1) *
- Math.sqrt(
- Math.abs(
- (rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x),
- ),
- );
- var cx = (k * rx * y) / ry + (x1 + x2) / 2;
- var cy = (k * -ry * x) / rx + (y1 + y2) / 2;
- var f1 = Math.asin(Number(((y1 - cy) / ry).toFixed(9)));
- var f2 = Math.asin(Number(((y2 - cy) / ry).toFixed(9)));
-
- f1 = x1 < cx ? Math.PI - f1 : f1;
- f2 = x2 < cx ? Math.PI - f2 : f2;
- f1 < 0 && (f1 = Math.PI * 2 + f1);
- f2 < 0 && (f2 = Math.PI * 2 + f2);
- if (sweep_flag && f1 > f2) {
- f1 = f1 - Math.PI * 2;
- }
- if (!sweep_flag && f2 > f1) {
- f2 = f2 - Math.PI * 2;
- }
- } else {
- f1 = recursive[0];
- f2 = recursive[1];
- cx = recursive[2];
- cy = recursive[3];
- }
- var df = f2 - f1;
- if (Math.abs(df) > _120) {
- var f2old = f2,
- x2old = x2,
- y2old = y2;
- f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
- x2 = cx + rx * Math.cos(f2);
- y2 = cy + ry * Math.sin(f2);
- res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [
- f2,
- f2old,
- cx,
- cy,
- ]);
- }
- df = f2 - f1;
- var c1 = Math.cos(f1),
- s1 = Math.sin(f1),
- c2 = Math.cos(f2),
- s2 = Math.sin(f2),
- t = Math.tan(df / 4),
- hx = (4 / 3) * rx * t,
- hy = (4 / 3) * ry * t,
- m = [
- -hx * s1,
- hy * c1,
- x2 + hx * s2 - x1,
- y2 - hy * c2 - y1,
- x2 - x1,
- y2 - y1,
- ];
- if (recursive) {
- return m.concat(res);
- } else {
- res = m.concat(res);
- var newres = [];
- for (var i = 0, n = res.length; i < n; i++) {
- newres[i] =
- i % 2
- ? rotateY(res[i - 1], res[i], rad)
- : rotateX(res[i], res[i + 1], rad);
- }
- return newres;
- }
-};
diff --git a/node_modules/svgo/plugins/_transforms.js b/node_modules/svgo/plugins/_transforms.js
deleted file mode 100644
index 1ab6d648..00000000
--- a/node_modules/svgo/plugins/_transforms.js
+++ /dev/null
@@ -1,410 +0,0 @@
-'use strict';
-
-const { toFixed } = require('../lib/svgo/tools');
-
-/**
- * @typedef {{ name: string, data: number[] }} TransformItem
- * @typedef {{
- * convertToShorts: boolean,
- * floatPrecision: number,
- * transformPrecision: number,
- * matrixToTransform: boolean,
- * shortTranslate: boolean,
- * shortScale: boolean,
- * shortRotate: boolean,
- * removeUseless: boolean,
- * collapseIntoOne: boolean,
- * leadingZero: boolean,
- * negativeExtraSpace: boolean,
- * }} TransformParams
- */
-
-const transformTypes = new Set([
- 'matrix',
- 'rotate',
- 'scale',
- 'skewX',
- 'skewY',
- 'translate',
-]);
-
-const regTransformSplit =
- /\s*(matrix|translate|scale|rotate|skewX|skewY)\s*\(\s*(.+?)\s*\)[\s,]*/;
-const regNumericValues = /[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/g;
-
-/**
- * Convert transform string to JS representation.
- *
- * @param {string} transformString
- * @returns {TransformItem[]} Object representation of transform, or an empty array if it was malformed.
- */
-exports.transform2js = (transformString) => {
- /** @type {TransformItem[]} */
- const transforms = [];
- /** @type {?TransformItem} */
- let currentTransform = null;
-
- // split value into ['', 'translate', '10 50', '', 'scale', '2', '', 'rotate', '-45', '']
- for (const item of transformString.split(regTransformSplit)) {
- if (!item) {
- continue;
- }
-
- if (transformTypes.has(item)) {
- currentTransform = { name: item, data: [] };
- transforms.push(currentTransform);
- } else {
- let num;
- // then split it into [10, 50] and collect as context.data
- while ((num = regNumericValues.exec(item))) {
- num = Number(num);
- if (currentTransform != null) {
- currentTransform.data.push(num);
- }
- }
- }
- }
-
- return currentTransform == null || currentTransform.data.length == 0
- ? []
- : transforms;
-};
-
-/**
- * Multiply transforms into one.
- *
- * @param {TransformItem[]} transforms
- * @returns {TransformItem}
- */
-exports.transformsMultiply = (transforms) => {
- const matrixData = transforms.map((transform) => {
- if (transform.name === 'matrix') {
- return transform.data;
- }
- return transformToMatrix(transform);
- });
-
- const matrixTransform = {
- name: 'matrix',
- data:
- matrixData.length > 0 ? matrixData.reduce(multiplyTransformMatrices) : [],
- };
-
- return matrixTransform;
-};
-
-/**
- * Math utilities in radians.
- */
-const mth = {
- /**
- * @param {number} deg
- * @returns {number}
- */
- rad: (deg) => {
- return (deg * Math.PI) / 180;
- },
-
- /**
- * @param {number} rad
- * @returns {number}
- */
- deg: (rad) => {
- return (rad * 180) / Math.PI;
- },
-
- /**
- * @param {number} deg
- * @returns {number}
- */
- cos: (deg) => {
- return Math.cos(mth.rad(deg));
- },
-
- /**
- * @param {number} val
- * @param {number} floatPrecision
- * @returns {number}
- */
- acos: (val, floatPrecision) => {
- return toFixed(mth.deg(Math.acos(val)), floatPrecision);
- },
-
- /**
- * @param {number} deg
- * @returns {number}
- */
- sin: (deg) => {
- return Math.sin(mth.rad(deg));
- },
-
- /**
- * @param {number} val
- * @param {number} floatPrecision
- * @returns {number}
- */
- asin: (val, floatPrecision) => {
- return toFixed(mth.deg(Math.asin(val)), floatPrecision);
- },
-
- /**
- * @param {number} deg
- * @returns {number}
- */
- tan: (deg) => {
- return Math.tan(mth.rad(deg));
- },
-
- /**
- * @param {number} val
- * @param {number} floatPrecision
- * @returns {number}
- */
- atan: (val, floatPrecision) => {
- return toFixed(mth.deg(Math.atan(val)), floatPrecision);
- },
-};
-
-/**
- * Decompose matrix into simple transforms.
- *
- * @param {TransformItem} transform
- * @param {TransformParams} params
- * @returns {TransformItem[]}
- * @see https://frederic-wang.fr/decomposition-of-2d-transform-matrices.html
- */
-exports.matrixToTransform = (transform, params) => {
- const floatPrecision = params.floatPrecision;
- const data = transform.data;
- const transforms = [];
-
- // [..., ..., ..., ..., tx, ty] → translate(tx, ty)
- if (data[4] || data[5]) {
- transforms.push({
- name: 'translate',
- data: data.slice(4, data[5] ? 6 : 5),
- });
- }
-
- let sx = toFixed(Math.hypot(data[0], data[1]), params.transformPrecision);
- let sy = toFixed(
- (data[0] * data[3] - data[1] * data[2]) / sx,
- params.transformPrecision,
- );
- const colsSum = data[0] * data[2] + data[1] * data[3];
- const rowsSum = data[0] * data[1] + data[2] * data[3];
- const scaleBefore = rowsSum !== 0 || sx === sy;
-
- // [sx, 0, tan(a)·sy, sy, 0, 0] → skewX(a)·scale(sx, sy)
- if (!data[1] && data[2]) {
- transforms.push({
- name: 'skewX',
- data: [mth.atan(data[2] / sy, floatPrecision)],
- });
-
- // [sx, sx·tan(a), 0, sy, 0, 0] → skewY(a)·scale(sx, sy)
- } else if (data[1] && !data[2]) {
- transforms.push({
- name: 'skewY',
- data: [mth.atan(data[1] / data[0], floatPrecision)],
- });
- sx = data[0];
- sy = data[3];
-
- // [sx·cos(a), sx·sin(a), sy·-sin(a), sy·cos(a), x, y] → rotate(a[, cx, cy])·(scale or skewX) or
- // [sx·cos(a), sy·sin(a), sx·-sin(a), sy·cos(a), x, y] → scale(sx, sy)·rotate(a[, cx, cy]) (if !scaleBefore)
- } else if (!colsSum || (sx === 1 && sy === 1) || !scaleBefore) {
- if (!scaleBefore) {
- sx = Math.hypot(data[0], data[2]);
- sy = Math.hypot(data[1], data[3]);
-
- if (toFixed(data[0], params.transformPrecision) < 0) {
- sx = -sx;
- }
-
- if (
- data[3] < 0 ||
- (Math.sign(data[1]) === Math.sign(data[2]) &&
- toFixed(data[3], params.transformPrecision) === 0)
- ) {
- sy = -sy;
- }
-
- transforms.push({ name: 'scale', data: [sx, sy] });
- }
- const angle = Math.min(Math.max(-1, data[0] / sx), 1);
- const rotate = [
- mth.acos(angle, floatPrecision) *
- ((scaleBefore ? 1 : sy) * data[1] < 0 ? -1 : 1),
- ];
-
- if (rotate[0]) {
- transforms.push({ name: 'rotate', data: rotate });
- }
-
- if (rowsSum && colsSum)
- transforms.push({
- name: 'skewX',
- data: [mth.atan(colsSum / (sx * sx), floatPrecision)],
- });
-
- // rotate(a, cx, cy) can consume translate() within optional arguments cx, cy (rotation point)
- if (rotate[0] && (data[4] || data[5])) {
- transforms.shift();
- const oneOverCos = 1 - data[0] / sx;
- const sin = data[1] / (scaleBefore ? sx : sy);
- const x = data[4] * (scaleBefore ? 1 : sy);
- const y = data[5] * (scaleBefore ? 1 : sx);
- const denom = (oneOverCos ** 2 + sin ** 2) * (scaleBefore ? 1 : sx * sy);
- rotate.push(
- (oneOverCos * x - sin * y) / denom,
- (oneOverCos * y + sin * x) / denom,
- );
- }
-
- // Too many transformations, return original matrix if it isn't just a scale/translate
- } else if (data[1] || data[2]) {
- return [transform];
- }
-
- if ((scaleBefore && (sx != 1 || sy != 1)) || !transforms.length) {
- transforms.push({
- name: 'scale',
- data: sx == sy ? [sx] : [sx, sy],
- });
- }
-
- return transforms;
-};
-
-/**
- * Convert transform to the matrix data.
- *
- * @type {(transform: TransformItem) => number[] }
- */
-const transformToMatrix = (transform) => {
- if (transform.name === 'matrix') {
- return transform.data;
- }
- switch (transform.name) {
- case 'translate':
- // [1, 0, 0, 1, tx, ty]
- return [1, 0, 0, 1, transform.data[0], transform.data[1] || 0];
- case 'scale':
- // [sx, 0, 0, sy, 0, 0]
- return [
- transform.data[0],
- 0,
- 0,
- transform.data[1] || transform.data[0],
- 0,
- 0,
- ];
- case 'rotate':
- // [cos(a), sin(a), -sin(a), cos(a), x, y]
- var cos = mth.cos(transform.data[0]),
- sin = mth.sin(transform.data[0]),
- cx = transform.data[1] || 0,
- cy = transform.data[2] || 0;
- return [
- cos,
- sin,
- -sin,
- cos,
- (1 - cos) * cx + sin * cy,
- (1 - cos) * cy - sin * cx,
- ];
- case 'skewX':
- // [1, 0, tan(a), 1, 0, 0]
- return [1, 0, mth.tan(transform.data[0]), 1, 0, 0];
- case 'skewY':
- // [1, tan(a), 0, 1, 0, 0]
- return [1, mth.tan(transform.data[0]), 0, 1, 0, 0];
- default:
- throw Error(`Unknown transform ${transform.name}`);
- }
-};
-
-/**
- * Applies transformation to an arc. To do so, we represent ellipse as a matrix, multiply it
- * by the transformation matrix and use a singular value decomposition to represent in a form
- * rotate(θ)·scale(a b)·rotate(φ). This gives us new ellipse params a, b and θ.
- * SVD is being done with the formulae provided by Wolffram|Alpha (svd {{m0, m2}, {m1, m3}})
- *
- * @type {(
- * cursor: [x: number, y: number],
- * arc: number[],
- * transform: number[]
- * ) => number[]}
- */
-exports.transformArc = (cursor, arc, transform) => {
- const x = arc[5] - cursor[0];
- const y = arc[6] - cursor[1];
- let a = arc[0];
- let b = arc[1];
- const rot = (arc[2] * Math.PI) / 180;
- const cos = Math.cos(rot);
- const sin = Math.sin(rot);
- // skip if radius is 0
- if (a > 0 && b > 0) {
- let h =
- Math.pow(x * cos + y * sin, 2) / (4 * a * a) +
- Math.pow(y * cos - x * sin, 2) / (4 * b * b);
- if (h > 1) {
- h = Math.sqrt(h);
- a *= h;
- b *= h;
- }
- }
- const ellipse = [a * cos, a * sin, -b * sin, b * cos, 0, 0];
- const m = multiplyTransformMatrices(transform, ellipse);
- // Decompose the new ellipse matrix
- const lastCol = m[2] * m[2] + m[3] * m[3];
- const squareSum = m[0] * m[0] + m[1] * m[1] + lastCol;
- const root =
- Math.hypot(m[0] - m[3], m[1] + m[2]) * Math.hypot(m[0] + m[3], m[1] - m[2]);
-
- if (!root) {
- // circle
- arc[0] = arc[1] = Math.sqrt(squareSum / 2);
- arc[2] = 0;
- } else {
- const majorAxisSqr = (squareSum + root) / 2;
- const minorAxisSqr = (squareSum - root) / 2;
- const major = Math.abs(majorAxisSqr - lastCol) > 1e-6;
- const sub = (major ? majorAxisSqr : minorAxisSqr) - lastCol;
- const rowsSum = m[0] * m[2] + m[1] * m[3];
- const term1 = m[0] * sub + m[2] * rowsSum;
- const term2 = m[1] * sub + m[3] * rowsSum;
- arc[0] = Math.sqrt(majorAxisSqr);
- arc[1] = Math.sqrt(minorAxisSqr);
- arc[2] =
- (((major ? term2 < 0 : term1 > 0) ? -1 : 1) *
- Math.acos((major ? term1 : term2) / Math.hypot(term1, term2)) *
- 180) /
- Math.PI;
- }
-
- if (transform[0] < 0 !== transform[3] < 0) {
- // Flip the sweep flag if coordinates are being flipped horizontally XOR vertically
- arc[4] = 1 - arc[4];
- }
-
- return arc;
-};
-
-/**
- * Multiply transformation matrices.
- *
- * @type {(a: number[], b: number[]) => number[]}
- */
-const multiplyTransformMatrices = (a, b) => {
- return [
- a[0] * b[0] + a[2] * b[1],
- a[1] * b[0] + a[3] * b[1],
- a[0] * b[2] + a[2] * b[3],
- a[1] * b[2] + a[3] * b[3],
- a[0] * b[4] + a[2] * b[5] + a[4],
- a[1] * b[4] + a[3] * b[5] + a[5],
- ];
-};
diff --git a/node_modules/svgo/plugins/addAttributesToSVGElement.js b/node_modules/svgo/plugins/addAttributesToSVGElement.js
deleted file mode 100644
index 845cb056..00000000
--- a/node_modules/svgo/plugins/addAttributesToSVGElement.js
+++ /dev/null
@@ -1,82 +0,0 @@
-'use strict';
-
-exports.name = 'addAttributesToSVGElement';
-exports.description = 'adds attributes to an outer <svg> element';
-
-var ENOCLS = `Error in plugin "addAttributesToSVGElement": absent parameters.
-It should have a list of "attributes" or one "attribute".
-Config example:
-
-plugins: [
- {
- name: 'addAttributesToSVGElement',
- params: {
- attribute: "mySvg"
- }
- }
-]
-
-plugins: [
- {
- name: 'addAttributesToSVGElement',
- params: {
- attributes: ["mySvg", "size-big"]
- }
- }
-]
-
-plugins: [
- {
- name: 'addAttributesToSVGElement',
- params: {
- attributes: [
- {
- focusable: false
- },
- {
- 'data-image': icon
- }
- ]
- }
- }
-]
-`;
-
-/**
- * Add attributes to an outer <svg> element. Example config:
- *
- * @author April Arcus
- *
- * @type {import('./plugins-types').Plugin<'addAttributesToSVGElement'>}
- */
-exports.fn = (root, params) => {
- if (!Array.isArray(params.attributes) && !params.attribute) {
- console.error(ENOCLS);
- return null;
- }
- const attributes = params.attributes || [params.attribute];
- return {
- element: {
- enter: (node, parentNode) => {
- if (node.name === 'svg' && parentNode.type === 'root') {
- for (const attribute of attributes) {
- if (typeof attribute === 'string') {
- if (node.attributes[attribute] == null) {
- // @ts-ignore disallow explicit nullable attribute value
- node.attributes[attribute] = undefined;
- }
- }
- if (typeof attribute === 'object') {
- for (const key of Object.keys(attribute)) {
- if (node.attributes[key] == null) {
- // @ts-ignore disallow explicit nullable attribute value
- node.attributes[key] = attribute[key];
- }
- }
- }
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/addClassesToSVGElement.js b/node_modules/svgo/plugins/addClassesToSVGElement.js
deleted file mode 100644
index 1e773d85..00000000
--- a/node_modules/svgo/plugins/addClassesToSVGElement.js
+++ /dev/null
@@ -1,82 +0,0 @@
-'use strict';
-
-exports.name = 'addClassesToSVGElement';
-exports.description = 'adds classnames to an outer <svg> element';
-
-var ENOCLS = `Error in plugin "addClassesToSVGElement": absent parameters.
-It should have a list of classes in "classNames" or one "className".
-Config example:
-
-plugins: [
- {
- name: "addClassesToSVGElement",
- params: {
- className: "mySvg"
- }
- }
-]
-
-plugins: [
- {
- name: "addClassesToSVGElement",
- params: {
- classNames: ["mySvg", "size-big"]
- }
- }
-]
-`;
-
-/**
- * Add classnames to an outer <svg> element. Example config:
- *
- * plugins: [
- * {
- * name: "addClassesToSVGElement",
- * params: {
- * className: "mySvg"
- * }
- * }
- * ]
- *
- * plugins: [
- * {
- * name: "addClassesToSVGElement",
- * params: {
- * classNames: ["mySvg", "size-big"]
- * }
- * }
- * ]
- *
- * @author April Arcus
- *
- * @type {import('./plugins-types').Plugin<'addClassesToSVGElement'>}
- */
-exports.fn = (root, params) => {
- if (
- !(Array.isArray(params.classNames) && params.classNames.some(String)) &&
- !params.className
- ) {
- console.error(ENOCLS);
- return null;
- }
- const classNames = params.classNames || [params.className];
- return {
- element: {
- enter: (node, parentNode) => {
- if (node.name === 'svg' && parentNode.type === 'root') {
- const classList = new Set(
- node.attributes.class == null
- ? null
- : node.attributes.class.split(' '),
- );
- for (const className of classNames) {
- if (className != null) {
- classList.add(className);
- }
- }
- node.attributes.class = Array.from(classList).join(' ');
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/applyTransforms.js b/node_modules/svgo/plugins/applyTransforms.js
deleted file mode 100644
index ae492d54..00000000
--- a/node_modules/svgo/plugins/applyTransforms.js
+++ /dev/null
@@ -1,388 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types').PathDataItem} PathDataItem
- * @typedef {import('../lib/types').XastElement} XastElement
- */
-
-const { collectStylesheet, computeStyle } = require('../lib/style.js');
-const {
- transformsMultiply,
- transform2js,
- transformArc,
-} = require('./_transforms.js');
-const { path2js } = require('./_path.js');
-const {
- removeLeadingZero,
- includesUrlReference,
-} = require('../lib/svgo/tools.js');
-const { referencesProps, attrsGroupsDefaults } = require('./_collections.js');
-
-/**
- * @typedef {PathDataItem[]} PathData
- * @typedef {number[]} Matrix
- */
-
-const regNumericValues = /[-+]?(\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/g;
-
-/**
- * Apply transformation(s) to the Path data.
- *
- * @type {import('../lib/types').Plugin<{
- * transformPrecision: number,
- * applyTransformsStroked: boolean,
- * }>}
- */
-const applyTransforms = (root, params) => {
- const stylesheet = collectStylesheet(root);
- return {
- element: {
- enter: (node) => {
- if (node.attributes.d == null) {
- return;
- }
-
- // stroke and stroke-width can be redefined with <use>
- if (node.attributes.id != null) {
- return;
- }
-
- // if there are no 'stroke' attr and references to other objects such as
- // gradients or clip-path which are also subjects to transform.
- if (
- node.attributes.transform == null ||
- node.attributes.transform === '' ||
- // styles are not considered when applying transform
- // can be fixed properly with new style engine
- node.attributes.style != null ||
- Object.entries(node.attributes).some(
- ([name, value]) =>
- referencesProps.has(name) && includesUrlReference(value),
- )
- ) {
- return;
- }
-
- const computedStyle = computeStyle(stylesheet, node);
- const transformStyle = computedStyle.transform;
-
- // Transform overridden in <style> tag which is not considered
- if (
- transformStyle.type === 'static' &&
- transformStyle.value !== node.attributes.transform
- ) {
- return;
- }
-
- const matrix = transformsMultiply(
- transform2js(node.attributes.transform),
- );
-
- const stroke =
- computedStyle.stroke?.type === 'static'
- ? computedStyle.stroke.value
- : null;
-
- const strokeWidth =
- computedStyle['stroke-width']?.type === 'static'
- ? computedStyle['stroke-width'].value
- : null;
- const transformPrecision = params.transformPrecision;
-
- if (
- computedStyle.stroke?.type === 'dynamic' ||
- computedStyle['stroke-width']?.type === 'dynamic'
- ) {
- return;
- }
-
- const scale = Number(
- Math.sqrt(
- matrix.data[0] * matrix.data[0] + matrix.data[1] * matrix.data[1],
- ).toFixed(transformPrecision),
- );
-
- if (stroke && stroke != 'none') {
- if (!params.applyTransformsStroked) {
- return;
- }
-
- // stroke cannot be transformed with different vertical and horizontal scale or skew
- if (
- (matrix.data[0] !== matrix.data[3] ||
- matrix.data[1] !== -matrix.data[2]) &&
- (matrix.data[0] !== -matrix.data[3] ||
- matrix.data[1] !== matrix.data[2])
- ) {
- return;
- }
-
- // apply transform to stroke-width, stroke-dashoffset and stroke-dasharray
- if (scale !== 1) {
- if (node.attributes['vector-effect'] !== 'non-scaling-stroke') {
- node.attributes['stroke-width'] = (
- strokeWidth || attrsGroupsDefaults.presentation['stroke-width']
- )
- .trim()
- .replace(regNumericValues, (num) =>
- removeLeadingZero(Number(num) * scale),
- );
-
- if (node.attributes['stroke-dashoffset'] != null) {
- node.attributes['stroke-dashoffset'] = node.attributes[
- 'stroke-dashoffset'
- ]
- .trim()
- .replace(regNumericValues, (num) =>
- removeLeadingZero(Number(num) * scale),
- );
- }
-
- if (node.attributes['stroke-dasharray'] != null) {
- node.attributes['stroke-dasharray'] = node.attributes[
- 'stroke-dasharray'
- ]
- .trim()
- .replace(regNumericValues, (num) =>
- removeLeadingZero(Number(num) * scale),
- );
- }
- }
- }
- }
-
- const pathData = path2js(node);
- applyMatrixToPathData(pathData, matrix.data);
-
- // remove transform attr
- delete node.attributes.transform;
- },
- },
- };
-};
-exports.applyTransforms = applyTransforms;
-
-/**
- * @type {(matrix: Matrix, x: number, y: number) => [number, number]}
- */
-const transformAbsolutePoint = (matrix, x, y) => {
- const newX = matrix[0] * x + matrix[2] * y + matrix[4];
- const newY = matrix[1] * x + matrix[3] * y + matrix[5];
- return [newX, newY];
-};
-
-/**
- * @type {(matrix: Matrix, x: number, y: number) => [number, number]}
- */
-const transformRelativePoint = (matrix, x, y) => {
- const newX = matrix[0] * x + matrix[2] * y;
- const newY = matrix[1] * x + matrix[3] * y;
- return [newX, newY];
-};
-
-/**
- * @type {(pathData: PathData, matrix: Matrix) => void}
- */
-const applyMatrixToPathData = (pathData, matrix) => {
- /**
- * @type {[number, number]}
- */
- const start = [0, 0];
- /**
- * @type {[number, number]}
- */
- const cursor = [0, 0];
-
- for (const pathItem of pathData) {
- let { command, args } = pathItem;
-
- // moveto (x y)
- if (command === 'M') {
- cursor[0] = args[0];
- cursor[1] = args[1];
- start[0] = cursor[0];
- start[1] = cursor[1];
- const [x, y] = transformAbsolutePoint(matrix, args[0], args[1]);
- args[0] = x;
- args[1] = y;
- }
- if (command === 'm') {
- cursor[0] += args[0];
- cursor[1] += args[1];
- start[0] = cursor[0];
- start[1] = cursor[1];
- const [x, y] = transformRelativePoint(matrix, args[0], args[1]);
- args[0] = x;
- args[1] = y;
- }
-
- // horizontal lineto (x)
- // convert to lineto to handle two-dimentional transforms
- if (command === 'H') {
- command = 'L';
- args = [args[0], cursor[1]];
- }
- if (command === 'h') {
- command = 'l';
- args = [args[0], 0];
- }
-
- // vertical lineto (y)
- // convert to lineto to handle two-dimentional transforms
- if (command === 'V') {
- command = 'L';
- args = [cursor[0], args[0]];
- }
- if (command === 'v') {
- command = 'l';
- args = [0, args[0]];
- }
-
- // lineto (x y)
- if (command === 'L') {
- cursor[0] = args[0];
- cursor[1] = args[1];
- const [x, y] = transformAbsolutePoint(matrix, args[0], args[1]);
- args[0] = x;
- args[1] = y;
- }
- if (command === 'l') {
- cursor[0] += args[0];
- cursor[1] += args[1];
- const [x, y] = transformRelativePoint(matrix, args[0], args[1]);
- args[0] = x;
- args[1] = y;
- }
-
- // curveto (x1 y1 x2 y2 x y)
- if (command === 'C') {
- cursor[0] = args[4];
- cursor[1] = args[5];
- const [x1, y1] = transformAbsolutePoint(matrix, args[0], args[1]);
- const [x2, y2] = transformAbsolutePoint(matrix, args[2], args[3]);
- const [x, y] = transformAbsolutePoint(matrix, args[4], args[5]);
- args[0] = x1;
- args[1] = y1;
- args[2] = x2;
- args[3] = y2;
- args[4] = x;
- args[5] = y;
- }
- if (command === 'c') {
- cursor[0] += args[4];
- cursor[1] += args[5];
- const [x1, y1] = transformRelativePoint(matrix, args[0], args[1]);
- const [x2, y2] = transformRelativePoint(matrix, args[2], args[3]);
- const [x, y] = transformRelativePoint(matrix, args[4], args[5]);
- args[0] = x1;
- args[1] = y1;
- args[2] = x2;
- args[3] = y2;
- args[4] = x;
- args[5] = y;
- }
-
- // smooth curveto (x2 y2 x y)
- if (command === 'S') {
- cursor[0] = args[2];
- cursor[1] = args[3];
- const [x2, y2] = transformAbsolutePoint(matrix, args[0], args[1]);
- const [x, y] = transformAbsolutePoint(matrix, args[2], args[3]);
- args[0] = x2;
- args[1] = y2;
- args[2] = x;
- args[3] = y;
- }
- if (command === 's') {
- cursor[0] += args[2];
- cursor[1] += args[3];
- const [x2, y2] = transformRelativePoint(matrix, args[0], args[1]);
- const [x, y] = transformRelativePoint(matrix, args[2], args[3]);
- args[0] = x2;
- args[1] = y2;
- args[2] = x;
- args[3] = y;
- }
-
- // quadratic Bézier curveto (x1 y1 x y)
- if (command === 'Q') {
- cursor[0] = args[2];
- cursor[1] = args[3];
- const [x1, y1] = transformAbsolutePoint(matrix, args[0], args[1]);
- const [x, y] = transformAbsolutePoint(matrix, args[2], args[3]);
- args[0] = x1;
- args[1] = y1;
- args[2] = x;
- args[3] = y;
- }
- if (command === 'q') {
- cursor[0] += args[2];
- cursor[1] += args[3];
- const [x1, y1] = transformRelativePoint(matrix, args[0], args[1]);
- const [x, y] = transformRelativePoint(matrix, args[2], args[3]);
- args[0] = x1;
- args[1] = y1;
- args[2] = x;
- args[3] = y;
- }
-
- // smooth quadratic Bézier curveto (x y)
- if (command === 'T') {
- cursor[0] = args[0];
- cursor[1] = args[1];
- const [x, y] = transformAbsolutePoint(matrix, args[0], args[1]);
- args[0] = x;
- args[1] = y;
- }
- if (command === 't') {
- cursor[0] += args[0];
- cursor[1] += args[1];
- const [x, y] = transformRelativePoint(matrix, args[0], args[1]);
- args[0] = x;
- args[1] = y;
- }
-
- // elliptical arc (rx ry x-axis-rotation large-arc-flag sweep-flag x y)
- if (command === 'A') {
- transformArc(cursor, args, matrix);
- cursor[0] = args[5];
- cursor[1] = args[6];
- // reduce number of digits in rotation angle
- if (Math.abs(args[2]) > 80) {
- const a = args[0];
- const rotation = args[2];
- args[0] = args[1];
- args[1] = a;
- args[2] = rotation + (rotation > 0 ? -90 : 90);
- }
- const [x, y] = transformAbsolutePoint(matrix, args[5], args[6]);
- args[5] = x;
- args[6] = y;
- }
- if (command === 'a') {
- transformArc([0, 0], args, matrix);
- cursor[0] += args[5];
- cursor[1] += args[6];
- // reduce number of digits in rotation angle
- if (Math.abs(args[2]) > 80) {
- const a = args[0];
- const rotation = args[2];
- args[0] = args[1];
- args[1] = a;
- args[2] = rotation + (rotation > 0 ? -90 : 90);
- }
- const [x, y] = transformRelativePoint(matrix, args[5], args[6]);
- args[5] = x;
- args[6] = y;
- }
-
- // closepath
- if (command === 'z' || command === 'Z') {
- cursor[0] = start[0];
- cursor[1] = start[1];
- }
-
- pathItem.command = command;
- pathItem.args = args;
- }
-};
diff --git a/node_modules/svgo/plugins/cleanupAttrs.js b/node_modules/svgo/plugins/cleanupAttrs.js
deleted file mode 100644
index 7b4c6b70..00000000
--- a/node_modules/svgo/plugins/cleanupAttrs.js
+++ /dev/null
@@ -1,49 +0,0 @@
-'use strict';
-
-exports.name = 'cleanupAttrs';
-exports.description =
- 'cleanups attributes from newlines, trailing and repeating spaces';
-
-const regNewlinesNeedSpace = /(\S)\r?\n(\S)/g;
-const regNewlines = /\r?\n/g;
-const regSpaces = /\s{2,}/g;
-
-/**
- * Cleanup attributes values from newlines, trailing and repeating spaces.
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'cleanupAttrs'>}
- */
-exports.fn = (root, params) => {
- const { newlines = true, trim = true, spaces = true } = params;
- return {
- element: {
- enter: (node) => {
- for (const name of Object.keys(node.attributes)) {
- if (newlines) {
- // new line which requires a space instead of themself
- node.attributes[name] = node.attributes[name].replace(
- regNewlinesNeedSpace,
- (match, p1, p2) => p1 + ' ' + p2,
- );
- // simple new line
- node.attributes[name] = node.attributes[name].replace(
- regNewlines,
- '',
- );
- }
- if (trim) {
- node.attributes[name] = node.attributes[name].trim();
- }
- if (spaces) {
- node.attributes[name] = node.attributes[name].replace(
- regSpaces,
- ' ',
- );
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/cleanupEnableBackground.js b/node_modules/svgo/plugins/cleanupEnableBackground.js
deleted file mode 100644
index 330cfb57..00000000
--- a/node_modules/svgo/plugins/cleanupEnableBackground.js
+++ /dev/null
@@ -1,165 +0,0 @@
-'use strict';
-
-const csstree = require('css-tree');
-const { visit } = require('../lib/xast.js');
-
-exports.name = 'cleanupEnableBackground';
-exports.description =
- 'remove or cleanup enable-background attribute when possible';
-
-const regEnableBackground =
- /^new\s0\s0\s([-+]?\d*\.?\d+([eE][-+]?\d+)?)\s([-+]?\d*\.?\d+([eE][-+]?\d+)?)$/;
-
-/**
- * Remove or cleanup enable-background attr which coincides with a width/height box.
- *
- * @see https://www.w3.org/TR/SVG11/filters.html#EnableBackgroundProperty
- * @example
- * <svg width="100" height="50" enable-background="new 0 0 100 50">
- * ⬇
- * <svg width="100" height="50">
- * @author Kir Belevich
- * @type {import('./plugins-types').Plugin<'cleanupEnableBackground'>}
- */
-exports.fn = (root) => {
- let hasFilter = false;
-
- visit(root, {
- element: {
- enter: (node) => {
- if (node.name === 'filter') {
- hasFilter = true;
- }
- },
- },
- });
-
- return {
- element: {
- enter: (node) => {
- /** @type {?csstree.CssNode} */
- let newStyle = null;
- /** @type {?csstree.ListItem<csstree.CssNode>} */
- let enableBackgroundDeclaration = null;
-
- if (node.attributes.style != null) {
- newStyle = csstree.parse(node.attributes.style, {
- context: 'declarationList',
- });
-
- if (newStyle.type === 'DeclarationList') {
- /** @type {csstree.ListItem<csstree.CssNode>[]} */
- const enableBackgroundDeclarations = [];
-
- csstree.walk(newStyle, (node, nodeItem) => {
- if (
- node.type === 'Declaration' &&
- node.property === 'enable-background'
- ) {
- enableBackgroundDeclarations.push(nodeItem);
- enableBackgroundDeclaration = nodeItem;
- }
- });
-
- for (let i = 0; i < enableBackgroundDeclarations.length - 1; i++) {
- newStyle.children.remove(enableBackgroundDeclarations[i]);
- }
- }
- }
-
- if (!hasFilter) {
- delete node.attributes['enable-background'];
-
- if (newStyle?.type === 'DeclarationList') {
- if (enableBackgroundDeclaration) {
- newStyle.children.remove(enableBackgroundDeclaration);
- }
-
- if (newStyle.children.isEmpty) {
- delete node.attributes.style;
- } else {
- node.attributes.style = csstree.generate(newStyle);
- }
- }
-
- return;
- }
-
- const hasDimensions =
- node.attributes.width != null && node.attributes.height != null;
-
- if (
- (node.name === 'svg' ||
- node.name === 'mask' ||
- node.name === 'pattern') &&
- hasDimensions
- ) {
- const attrValue = node.attributes['enable-background'];
- const attrCleaned = cleanupValue(
- attrValue,
- node.name,
- node.attributes.width,
- node.attributes.height,
- );
-
- if (attrCleaned) {
- node.attributes['enable-background'] = attrCleaned;
- } else {
- delete node.attributes['enable-background'];
- }
-
- if (
- newStyle?.type === 'DeclarationList' &&
- enableBackgroundDeclaration
- ) {
- const styleValue = csstree.generate(
- // @ts-ignore
- enableBackgroundDeclaration.data.value,
- );
- const styleCleaned = cleanupValue(
- styleValue,
- node.name,
- node.attributes.width,
- node.attributes.height,
- );
-
- if (styleCleaned) {
- // @ts-ignore
- enableBackgroundDeclaration.data.value = {
- type: 'Raw',
- value: styleCleaned,
- };
- } else {
- newStyle.children.remove(enableBackgroundDeclaration);
- }
- }
- }
-
- if (newStyle?.type === 'DeclarationList') {
- if (newStyle.children.isEmpty) {
- delete node.attributes.style;
- } else {
- node.attributes.style = csstree.generate(newStyle);
- }
- }
- },
- },
- };
-};
-
-/**
- * @param {string} value Value of a enable-background attribute or style declaration.
- * @param {string} nodeName Name of the node the value was assigned to.
- * @param {string} width Width of the node the value was assigned to.
- * @param {string} height Height of the node the value was assigned to.
- * @returns {string | undefined} Cleaned up value, or undefined if it's redundant.
- */
-const cleanupValue = (value, nodeName, width, height) => {
- const match = regEnableBackground.exec(value);
-
- if (match != null && width === match[1] && height === match[3]) {
- return nodeName === 'svg' ? undefined : 'new';
- }
-
- return value;
-};
diff --git a/node_modules/svgo/plugins/cleanupIds.js b/node_modules/svgo/plugins/cleanupIds.js
deleted file mode 100644
index bfabcca5..00000000
--- a/node_modules/svgo/plugins/cleanupIds.js
+++ /dev/null
@@ -1,265 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types').XastElement} XastElement
- */
-
-const { visitSkip } = require('../lib/xast.js');
-const { hasScripts, findReferences } = require('../lib/svgo/tools');
-
-exports.name = 'cleanupIds';
-exports.description = 'removes unused IDs and minifies used';
-
-const generateIdChars = [
- 'a',
- 'b',
- 'c',
- 'd',
- 'e',
- 'f',
- 'g',
- 'h',
- 'i',
- 'j',
- 'k',
- 'l',
- 'm',
- 'n',
- 'o',
- 'p',
- 'q',
- 'r',
- 's',
- 't',
- 'u',
- 'v',
- 'w',
- 'x',
- 'y',
- 'z',
- 'A',
- 'B',
- 'C',
- 'D',
- 'E',
- 'F',
- 'G',
- 'H',
- 'I',
- 'J',
- 'K',
- 'L',
- 'M',
- 'N',
- 'O',
- 'P',
- 'Q',
- 'R',
- 'S',
- 'T',
- 'U',
- 'V',
- 'W',
- 'X',
- 'Y',
- 'Z',
-];
-const maxIdIndex = generateIdChars.length - 1;
-
-/**
- * Check if an ID starts with any one of a list of strings.
- *
- * @type {(string: string, prefixes: string[]) => boolean}
- */
-const hasStringPrefix = (string, prefixes) => {
- for (const prefix of prefixes) {
- if (string.startsWith(prefix)) {
- return true;
- }
- }
- return false;
-};
-
-/**
- * Generate unique minimal ID.
- *
- * @param {?number[]} currentId
- * @returns {number[]}
- */
-const generateId = (currentId) => {
- if (currentId == null) {
- return [0];
- }
- currentId[currentId.length - 1] += 1;
- for (let i = currentId.length - 1; i > 0; i--) {
- if (currentId[i] > maxIdIndex) {
- currentId[i] = 0;
- if (currentId[i - 1] !== undefined) {
- currentId[i - 1]++;
- }
- }
- }
- if (currentId[0] > maxIdIndex) {
- currentId[0] = 0;
- currentId.unshift(0);
- }
- return currentId;
-};
-
-/**
- * Get string from generated ID array.
- *
- * @type {(arr: number[]) => string}
- */
-const getIdString = (arr) => {
- return arr.map((i) => generateIdChars[i]).join('');
-};
-
-/**
- * Remove unused and minify used IDs
- * (only if there are no any <style> or <script>).
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'cleanupIds'>}
- */
-exports.fn = (_root, params) => {
- const {
- remove = true,
- minify = true,
- preserve = [],
- preservePrefixes = [],
- force = false,
- } = params;
- const preserveIds = new Set(
- Array.isArray(preserve) ? preserve : preserve ? [preserve] : [],
- );
- const preserveIdPrefixes = Array.isArray(preservePrefixes)
- ? preservePrefixes
- : preservePrefixes
- ? [preservePrefixes]
- : [];
- /**
- * @type {Map<string, XastElement>}
- */
- const nodeById = new Map();
- /**
- * @type {Map<string, {element: XastElement, name: string }[]>}
- */
- const referencesById = new Map();
- let deoptimized = false;
-
- return {
- element: {
- enter: (node) => {
- if (!force) {
- // deoptimize if style or scripts are present
- if (
- (node.name === 'style' && node.children.length !== 0) ||
- hasScripts(node)
- ) {
- deoptimized = true;
- return;
- }
-
- // avoid removing IDs if the whole SVG consists only of defs
- if (node.name === 'svg') {
- let hasDefsOnly = true;
- for (const child of node.children) {
- if (child.type !== 'element' || child.name !== 'defs') {
- hasDefsOnly = false;
- break;
- }
- }
- if (hasDefsOnly) {
- return visitSkip;
- }
- }
- }
-
- for (const [name, value] of Object.entries(node.attributes)) {
- if (name === 'id') {
- // collect all ids
- const id = value;
- if (nodeById.has(id)) {
- delete node.attributes.id; // remove repeated id
- } else {
- nodeById.set(id, node);
- }
- } else {
- const ids = findReferences(name, value);
- for (const id of ids) {
- let refs = referencesById.get(id);
- if (refs == null) {
- refs = [];
- referencesById.set(id, refs);
- }
- refs.push({ element: node, name });
- }
- }
- }
- },
- },
-
- root: {
- exit: () => {
- if (deoptimized) {
- return;
- }
- /**
- * @param {string} id
- * @returns {boolean}
- */
- const isIdPreserved = (id) =>
- preserveIds.has(id) || hasStringPrefix(id, preserveIdPrefixes);
- /** @type {?number[]} */
- let currentId = null;
- for (const [id, refs] of referencesById) {
- const node = nodeById.get(id);
- if (node != null) {
- // replace referenced IDs with the minified ones
- if (minify && isIdPreserved(id) === false) {
- /** @type {?string} */
- let currentIdString = null;
- do {
- currentId = generateId(currentId);
- currentIdString = getIdString(currentId);
- } while (
- isIdPreserved(currentIdString) ||
- (referencesById.has(currentIdString) &&
- nodeById.get(currentIdString) == null)
- );
- node.attributes.id = currentIdString;
- for (const { element, name } of refs) {
- const value = element.attributes[name];
- if (value.includes('#')) {
- // replace id in href and url()
- element.attributes[name] = value.replace(
- `#${encodeURI(id)}`,
- `#${currentIdString}`,
- );
- } else {
- // replace id in begin attribute
- element.attributes[name] = value.replace(
- `${id}.`,
- `${currentIdString}.`,
- );
- }
- }
- }
- // keep referenced node
- nodeById.delete(id);
- }
- }
- // remove non-referenced IDs attributes from elements
- if (remove) {
- for (const [id, node] of nodeById) {
- if (isIdPreserved(id) === false) {
- delete node.attributes.id;
- }
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/cleanupListOfValues.js b/node_modules/svgo/plugins/cleanupListOfValues.js
deleted file mode 100644
index 618fd062..00000000
--- a/node_modules/svgo/plugins/cleanupListOfValues.js
+++ /dev/null
@@ -1,147 +0,0 @@
-'use strict';
-
-const { removeLeadingZero } = require('../lib/svgo/tools.js');
-
-exports.name = 'cleanupListOfValues';
-exports.description = 'rounds list of values to the fixed precision';
-
-const regNumericValues =
- /^([-+]?\d*\.?\d+([eE][-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|em|ex|%)?$/;
-const regSeparator = /\s+,?\s*|,\s*/;
-const absoluteLengths = {
- // relative to px
- cm: 96 / 2.54,
- mm: 96 / 25.4,
- in: 96,
- pt: 4 / 3,
- pc: 16,
- px: 1,
-};
-
-/**
- * Round list of values to the fixed precision.
- *
- * @example
- * <svg viewBox="0 0 200.28423 200.28423" enable-background="new 0 0 200.28423 200.28423">
- * ⬇
- * <svg viewBox="0 0 200.284 200.284" enable-background="new 0 0 200.284 200.284">
- *
- * <polygon points="208.250977 77.1308594 223.069336 ... "/>
- * ⬇
- * <polygon points="208.251 77.131 223.069 ... "/>
- *
- * @author kiyopikko
- *
- * @type {import('./plugins-types').Plugin<'cleanupListOfValues'>}
- */
-exports.fn = (_root, params) => {
- const {
- floatPrecision = 3,
- leadingZero = true,
- defaultPx = true,
- convertToPx = true,
- } = params;
-
- /**
- * @type {(lists: string) => string}
- */
- const roundValues = (lists) => {
- const roundedList = [];
-
- for (const elem of lists.split(regSeparator)) {
- const match = elem.match(regNumericValues);
- const matchNew = elem.match(/new/);
-
- // if attribute value matches regNumericValues
- if (match) {
- // round it to the fixed precision
- let num = Number(Number(match[1]).toFixed(floatPrecision));
- /**
- * @type {any}
- */
- let matchedUnit = match[3] || '';
- /**
- * @type{'' | keyof typeof absoluteLengths}
- */
- let units = matchedUnit;
-
- // convert absolute values to pixels
- if (convertToPx && units && units in absoluteLengths) {
- const pxNum = Number(
- (absoluteLengths[units] * Number(match[1])).toFixed(floatPrecision),
- );
-
- if (pxNum.toString().length < match[0].length) {
- num = pxNum;
- units = 'px';
- }
- }
-
- // and remove leading zero
- let str;
- if (leadingZero) {
- str = removeLeadingZero(num);
- } else {
- str = num.toString();
- }
-
- // remove default 'px' units
- if (defaultPx && units === 'px') {
- units = '';
- }
-
- roundedList.push(str + units);
- }
- // if attribute value is "new"(only enable-background).
- else if (matchNew) {
- roundedList.push('new');
- } else if (elem) {
- roundedList.push(elem);
- }
- }
-
- return roundedList.join(' ');
- };
-
- return {
- element: {
- enter: (node) => {
- if (node.attributes.points != null) {
- node.attributes.points = roundValues(node.attributes.points);
- }
-
- if (node.attributes['enable-background'] != null) {
- node.attributes['enable-background'] = roundValues(
- node.attributes['enable-background'],
- );
- }
-
- if (node.attributes.viewBox != null) {
- node.attributes.viewBox = roundValues(node.attributes.viewBox);
- }
-
- if (node.attributes['stroke-dasharray'] != null) {
- node.attributes['stroke-dasharray'] = roundValues(
- node.attributes['stroke-dasharray'],
- );
- }
-
- if (node.attributes.dx != null) {
- node.attributes.dx = roundValues(node.attributes.dx);
- }
-
- if (node.attributes.dy != null) {
- node.attributes.dy = roundValues(node.attributes.dy);
- }
-
- if (node.attributes.x != null) {
- node.attributes.x = roundValues(node.attributes.x);
- }
-
- if (node.attributes.y != null) {
- node.attributes.y = roundValues(node.attributes.y);
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/cleanupNumericValues.js b/node_modules/svgo/plugins/cleanupNumericValues.js
deleted file mode 100644
index 9b782c3d..00000000
--- a/node_modules/svgo/plugins/cleanupNumericValues.js
+++ /dev/null
@@ -1,106 +0,0 @@
-'use strict';
-
-const { removeLeadingZero } = require('../lib/svgo/tools');
-
-exports.name = 'cleanupNumericValues';
-exports.description =
- 'rounds numeric values to the fixed precision, removes default ‘px’ units';
-
-const regNumericValues =
- /^([-+]?\d*\.?\d+([eE][-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|em|ex|%)?$/;
-
-const absoluteLengths = {
- // relative to px
- cm: 96 / 2.54,
- mm: 96 / 25.4,
- in: 96,
- pt: 4 / 3,
- pc: 16,
- px: 1,
-};
-
-/**
- * Round numeric values to the fixed precision,
- * remove default 'px' units.
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'cleanupNumericValues'>}
- */
-exports.fn = (_root, params) => {
- const {
- floatPrecision = 3,
- leadingZero = true,
- defaultPx = true,
- convertToPx = true,
- } = params;
-
- return {
- element: {
- enter: (node) => {
- if (node.attributes.viewBox != null) {
- const nums = node.attributes.viewBox.split(/\s,?\s*|,\s*/g);
- node.attributes.viewBox = nums
- .map((value) => {
- const num = Number(value);
- return Number.isNaN(num)
- ? value
- : Number(num.toFixed(floatPrecision));
- })
- .join(' ');
- }
-
- for (const [name, value] of Object.entries(node.attributes)) {
- // The `version` attribute is a text string and cannot be rounded
- if (name === 'version') {
- continue;
- }
-
- const match = value.match(regNumericValues);
-
- // if attribute value matches regNumericValues
- if (match) {
- // round it to the fixed precision
- let num = Number(Number(match[1]).toFixed(floatPrecision));
- /**
- * @type {any}
- */
- let matchedUnit = match[3] || '';
- /**
- * @type{'' | keyof typeof absoluteLengths}
- */
- let units = matchedUnit;
-
- // convert absolute values to pixels
- if (convertToPx && units !== '' && units in absoluteLengths) {
- const pxNum = Number(
- (absoluteLengths[units] * Number(match[1])).toFixed(
- floatPrecision,
- ),
- );
- if (pxNum.toString().length < match[0].length) {
- num = pxNum;
- units = 'px';
- }
- }
-
- // and remove leading zero
- let str;
- if (leadingZero) {
- str = removeLeadingZero(num);
- } else {
- str = num.toString();
- }
-
- // remove default 'px' units
- if (defaultPx && units === 'px') {
- units = '';
- }
-
- node.attributes[name] = str + units;
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/collapseGroups.js b/node_modules/svgo/plugins/collapseGroups.js
deleted file mode 100644
index 0534ad77..00000000
--- a/node_modules/svgo/plugins/collapseGroups.js
+++ /dev/null
@@ -1,134 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types').XastNode} XastNode
- */
-
-const { inheritableAttrs, elemsGroups } = require('./_collections.js');
-
-exports.name = 'collapseGroups';
-exports.description = 'collapses useless groups';
-
-/**
- * @type {(node: XastNode, name: string) => boolean}
- */
-const hasAnimatedAttr = (node, name) => {
- if (node.type === 'element') {
- if (
- elemsGroups.animation.has(node.name) &&
- node.attributes.attributeName === name
- ) {
- return true;
- }
- for (const child of node.children) {
- if (hasAnimatedAttr(child, name)) {
- return true;
- }
- }
- }
- return false;
-};
-
-/**
- * Collapse useless groups.
- *
- * @example
- * <g>
- * <g attr1="val1">
- * <path d="..."/>
- * </g>
- * </g>
- * ⬇
- * <g>
- * <g>
- * <path attr1="val1" d="..."/>
- * </g>
- * </g>
- * ⬇
- * <path attr1="val1" d="..."/>
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'collapseGroups'>}
- */
-exports.fn = () => {
- return {
- element: {
- exit: (node, parentNode) => {
- if (parentNode.type === 'root' || parentNode.name === 'switch') {
- return;
- }
- // non-empty groups
- if (node.name !== 'g' || node.children.length === 0) {
- return;
- }
-
- // move group attributes to the single child element
- if (
- Object.keys(node.attributes).length !== 0 &&
- node.children.length === 1
- ) {
- const firstChild = node.children[0];
- // TODO untangle this mess
- if (
- firstChild.type === 'element' &&
- firstChild.attributes.id == null &&
- node.attributes.filter == null &&
- (node.attributes.class == null ||
- firstChild.attributes.class == null) &&
- ((node.attributes['clip-path'] == null &&
- node.attributes.mask == null) ||
- (firstChild.name === 'g' &&
- node.attributes.transform == null &&
- firstChild.attributes.transform == null))
- ) {
- for (const [name, value] of Object.entries(node.attributes)) {
- // avoid copying to not conflict with animated attribute
- if (hasAnimatedAttr(firstChild, name)) {
- return;
- }
- if (firstChild.attributes[name] == null) {
- firstChild.attributes[name] = value;
- } else if (name === 'transform') {
- firstChild.attributes[name] =
- value + ' ' + firstChild.attributes[name];
- } else if (firstChild.attributes[name] === 'inherit') {
- firstChild.attributes[name] = value;
- } else if (
- inheritableAttrs.has(name) === false &&
- firstChild.attributes[name] !== value
- ) {
- return;
- }
- delete node.attributes[name];
- }
- }
- }
-
- // collapse groups without attributes
- if (Object.keys(node.attributes).length === 0) {
- // animation elements "add" attributes to group
- // group should be preserved
- for (const child of node.children) {
- if (
- child.type === 'element' &&
- elemsGroups.animation.has(child.name)
- ) {
- return;
- }
- }
- // replace current node with all its children
- const index = parentNode.children.indexOf(node);
- parentNode.children.splice(index, 1, ...node.children);
- // TODO remove legacy parentNode in v4
- for (const child of node.children) {
- Object.defineProperty(child, 'parentNode', {
- writable: true,
- value: parentNode,
- });
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/convertColors.js b/node_modules/svgo/plugins/convertColors.js
deleted file mode 100644
index d894283f..00000000
--- a/node_modules/svgo/plugins/convertColors.js
+++ /dev/null
@@ -1,144 +0,0 @@
-'use strict';
-
-const collections = require('./_collections.js');
-
-exports.name = 'convertColors';
-exports.description = 'converts colors: rgb() to #rrggbb and #rrggbb to #rgb';
-
-const rNumber = '([+-]?(?:\\d*\\.\\d+|\\d+\\.?)%?)';
-const rComma = '\\s*,\\s*';
-const regRGB = new RegExp(
- '^rgb\\(\\s*' + rNumber + rComma + rNumber + rComma + rNumber + '\\s*\\)$',
-);
-const regHEX = /^#(([a-fA-F0-9])\2){3}$/;
-
-/**
- * Convert [r, g, b] to #rrggbb.
- *
- * @see https://gist.github.com/983535
- *
- * @example
- * rgb2hex([255, 255, 255]) // '#ffffff'
- *
- * @author Jed Schmidt
- *
- * @type {(rgb: number[]) => string}
- */
-const convertRgbToHex = ([r, g, b]) => {
- // combine the octets into a 32-bit integer as: [1][r][g][b]
- const hexNumber =
- // operator precedence is (+) > (<<) > (|)
- ((((256 + // [1][0]
- r) << // [1][r]
- 8) | // [1][r][0]
- g) << // [1][r][g]
- 8) | // [1][r][g][0]
- b;
- // serialize [1][r][g][b] to a hex string, and
- // remove the 1 to get the number with 0s intact
- return '#' + hexNumber.toString(16).slice(1).toUpperCase();
-};
-
-/**
- * Convert different colors formats in element attributes to hex.
- *
- * @see https://www.w3.org/TR/SVG11/types.html#DataTypeColor
- * @see https://www.w3.org/TR/SVG11/single-page.html#types-ColorKeywords
- *
- * @example
- * Convert color name keyword to long hex:
- * fuchsia ➡ #ff00ff
- *
- * Convert rgb() to long hex:
- * rgb(255, 0, 255) ➡ #ff00ff
- * rgb(50%, 100, 100%) ➡ #7f64ff
- *
- * Convert long hex to short hex:
- * #aabbcc ➡ #abc
- *
- * Convert hex to short name
- * #000080 ➡ navy
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'convertColors'>}
- */
-exports.fn = (_root, params) => {
- const {
- currentColor = false,
- names2hex = true,
- rgb2hex = true,
- shorthex = true,
- shortname = true,
- } = params;
-
- return {
- element: {
- enter: (node) => {
- for (const [name, value] of Object.entries(node.attributes)) {
- if (collections.colorsProps.has(name)) {
- let val = value;
-
- // convert colors to currentColor
- if (currentColor) {
- let matched;
- if (typeof currentColor === 'string') {
- matched = val === currentColor;
- } else if (currentColor instanceof RegExp) {
- matched = currentColor.exec(val) != null;
- } else {
- matched = val !== 'none';
- }
- if (matched) {
- val = 'currentColor';
- }
- }
-
- // convert color name keyword to long hex
- if (names2hex) {
- const colorName = val.toLowerCase();
- if (collections.colorsNames[colorName] != null) {
- val = collections.colorsNames[colorName];
- }
- }
-
- // convert rgb() to long hex
- if (rgb2hex) {
- let match = val.match(regRGB);
- if (match != null) {
- let nums = match.slice(1, 4).map((m) => {
- let n;
- if (m.indexOf('%') > -1) {
- n = Math.round(parseFloat(m) * 2.55);
- } else {
- n = Number(m);
- }
- return Math.max(0, Math.min(n, 255));
- });
- val = convertRgbToHex(nums);
- }
- }
-
- // convert long hex to short hex
- if (shorthex) {
- let match = val.match(regHEX);
- if (match != null) {
- val = '#' + match[0][1] + match[0][3] + match[0][5];
- }
- }
-
- // convert hex to short name
- if (shortname) {
- const colorName = val.toLowerCase();
- if (collections.colorsShortNames[colorName] != null) {
- val = collections.colorsShortNames[colorName];
- }
- }
-
- node.attributes[name] = val;
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/convertEllipseToCircle.js b/node_modules/svgo/plugins/convertEllipseToCircle.js
deleted file mode 100644
index 50fa20db..00000000
--- a/node_modules/svgo/plugins/convertEllipseToCircle.js
+++ /dev/null
@@ -1,37 +0,0 @@
-'use strict';
-
-exports.name = 'convertEllipseToCircle';
-exports.description = 'converts non-eccentric <ellipse>s to <circle>s';
-
-/**
- * Converts non-eccentric <ellipse>s to <circle>s.
- *
- * @see https://www.w3.org/TR/SVG11/shapes.html
- *
- * @author Taylor Hunt
- *
- * @type {import('./plugins-types').Plugin<'convertEllipseToCircle'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node) => {
- if (node.name === 'ellipse') {
- const rx = node.attributes.rx || '0';
- const ry = node.attributes.ry || '0';
- if (
- rx === ry ||
- rx === 'auto' ||
- ry === 'auto' // SVG2
- ) {
- node.name = 'circle';
- const radius = rx === 'auto' ? ry : rx;
- delete node.attributes.rx;
- delete node.attributes.ry;
- node.attributes.r = radius;
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/convertOneStopGradients.js b/node_modules/svgo/plugins/convertOneStopGradients.js
deleted file mode 100644
index 1cf0d66b..00000000
--- a/node_modules/svgo/plugins/convertOneStopGradients.js
+++ /dev/null
@@ -1,168 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types').XastElement} XastElement
- * @typedef {import('../lib/types').XastParent} XastParent
- */
-
-const { attrsGroupsDefaults, colorsProps } = require('./_collections');
-const {
- detachNodeFromParent,
- querySelectorAll,
- querySelector,
-} = require('../lib/xast');
-const { computeStyle, collectStylesheet } = require('../lib/style');
-
-exports.name = 'convertOneStopGradients';
-exports.description =
- 'converts one-stop (single color) gradients to a plain color';
-
-/**
- * Converts one-stop (single color) gradients to a plain color.
- *
- * @author Seth Falco <seth@falco.fun>
- * @type {import('./plugins-types').Plugin<'convertOneStopGradients'>}
- * @see https://developer.mozilla.org/docs/Web/SVG/Element/linearGradient
- * @see https://developer.mozilla.org/docs/Web/SVG/Element/radialGradient
- */
-exports.fn = (root) => {
- const stylesheet = collectStylesheet(root);
-
- /**
- * Parent defs that had gradients elements removed from them.
- *
- * @type {Set<XastElement>}
- */
- const effectedDefs = new Set();
-
- /**
- * @type {Map<XastElement, XastParent>}
- */
- const allDefs = new Map();
-
- /**
- * @type {Map<XastElement, XastParent>}
- */
- const gradientsToDetach = new Map();
-
- /** Number of references to the xlink:href attribute. */
- let xlinkHrefCount = 0;
-
- return {
- element: {
- enter: (node, parentNode) => {
- if (node.attributes['xlink:href'] != null) {
- xlinkHrefCount++;
- }
-
- if (node.name === 'defs') {
- allDefs.set(node, parentNode);
- return;
- }
-
- if (node.name !== 'linearGradient' && node.name !== 'radialGradient') {
- return;
- }
-
- const stops = node.children.filter((child) => {
- return child.type === 'element' && child.name === 'stop';
- });
-
- const href = node.attributes['xlink:href'] || node.attributes['href'];
- let effectiveNode =
- stops.length === 0 && href != null && href.startsWith('#')
- ? querySelector(root, href)
- : node;
-
- if (effectiveNode == null || effectiveNode.type !== 'element') {
- gradientsToDetach.set(node, parentNode);
- return;
- }
-
- const effectiveStops = effectiveNode.children.filter((child) => {
- return child.type === 'element' && child.name === 'stop';
- });
-
- if (
- effectiveStops.length !== 1 ||
- effectiveStops[0].type !== 'element'
- ) {
- return;
- }
-
- if (parentNode.type === 'element' && parentNode.name === 'defs') {
- effectedDefs.add(parentNode);
- }
-
- gradientsToDetach.set(node, parentNode);
-
- let color;
- const style = computeStyle(stylesheet, effectiveStops[0])['stop-color'];
- if (style != null && style.type === 'static') {
- color = style.value;
- }
-
- const selectorVal = `url(#${node.attributes.id})`;
-
- const selector = [...colorsProps]
- .map((attr) => `[${attr}="${selectorVal}"]`)
- .join(',');
- const elements = querySelectorAll(root, selector);
- for (const element of elements) {
- if (element.type !== 'element') {
- continue;
- }
-
- for (const attr of colorsProps) {
- if (element.attributes[attr] !== selectorVal) {
- continue;
- }
-
- if (color != null) {
- element.attributes[attr] = color;
- } else {
- delete element.attributes[attr];
- }
- }
- }
-
- const styledElements = querySelectorAll(
- root,
- `[style*=${selectorVal}]`,
- );
- for (const element of styledElements) {
- if (element.type !== 'element') {
- continue;
- }
-
- element.attributes.style = element.attributes.style.replace(
- selectorVal,
- color || attrsGroupsDefaults.presentation['stop-color'],
- );
- }
- },
-
- exit: (node) => {
- if (node.name === 'svg') {
- for (const [gradient, parent] of gradientsToDetach.entries()) {
- if (gradient.attributes['xlink:href'] != null) {
- xlinkHrefCount--;
- }
-
- detachNodeFromParent(gradient, parent);
- }
-
- if (xlinkHrefCount === 0) {
- delete node.attributes['xmlns:xlink'];
- }
-
- for (const [defs, parent] of allDefs.entries()) {
- if (effectedDefs.has(defs) && defs.children.length === 0) {
- detachNodeFromParent(defs, parent);
- }
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/convertPathData.js b/node_modules/svgo/plugins/convertPathData.js
deleted file mode 100644
index de7b357f..00000000
--- a/node_modules/svgo/plugins/convertPathData.js
+++ /dev/null
@@ -1,1284 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib//types').PathDataItem} PathDataItem
- */
-
-const { collectStylesheet, computeStyle } = require('../lib/style.js');
-const { visit } = require('../lib/xast.js');
-const { pathElems } = require('./_collections.js');
-const { path2js, js2path } = require('./_path.js');
-const { applyTransforms } = require('./applyTransforms.js');
-const { cleanupOutData, toFixed } = require('../lib/svgo/tools');
-
-exports.name = 'convertPathData';
-exports.description =
- 'optimizes path data: writes in shorter form, applies transformations';
-
-/** @type {(data: number[]) => number[]} */
-let roundData;
-/** @type {number | false} */
-let precision;
-/** @type {number} */
-let error;
-/** @type {number} */
-let arcThreshold;
-/** @type {number} */
-let arcTolerance;
-
-/**
- * @typedef {{
- * applyTransforms: boolean,
- * applyTransformsStroked: boolean,
- * makeArcs: {
- * threshold: number,
- * tolerance: number,
- * },
- * straightCurves: boolean,
- * convertToQ: boolean,
- * lineShorthands: boolean,
- * convertToZ: boolean,
- * curveSmoothShorthands: boolean,
- * floatPrecision: number | false,
- * transformPrecision: number,
- * smartArcRounding: boolean,
- * removeUseless: boolean,
- * collapseRepeated: boolean,
- * utilizeAbsolute: boolean,
- * leadingZero: boolean,
- * negativeExtraSpace: boolean,
- * noSpaceAfterFlags: boolean,
- * forceAbsolutePath: boolean,
- * }} InternalParams
- */
-
-/**
- * @typedef {[number, number]} Point
- */
-
-/**
- * @typedef {{
- * center: Point,
- * radius: number
- * }} Circle
- */
-
-/**
- * Convert absolute Path to relative,
- * collapse repeated instructions,
- * detect and convert Lineto shorthands,
- * remove useless instructions like "l0,0",
- * trim useless delimiters and leading zeros,
- * decrease accuracy of floating-point numbers.
- *
- * @see https://www.w3.org/TR/SVG11/paths.html#PathData
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'convertPathData'>}
- */
-exports.fn = (root, params) => {
- const {
- // TODO convert to separate plugin in v3
- applyTransforms: _applyTransforms = true,
- applyTransformsStroked = true,
- makeArcs = {
- threshold: 2.5, // coefficient of rounding error
- tolerance: 0.5, // percentage of radius
- },
- straightCurves = true,
- convertToQ = true,
- lineShorthands = true,
- convertToZ = true,
- curveSmoothShorthands = true,
- floatPrecision = 3,
- transformPrecision = 5,
- smartArcRounding = true,
- removeUseless = true,
- collapseRepeated = true,
- utilizeAbsolute = true,
- leadingZero = true,
- negativeExtraSpace = true,
- noSpaceAfterFlags = false, // a20 60 45 0 1 30 20 → a20 60 45 0130 20
- forceAbsolutePath = false,
- } = params;
-
- /**
- * @type {InternalParams}
- */
- const newParams = {
- applyTransforms: _applyTransforms,
- applyTransformsStroked,
- makeArcs,
- straightCurves,
- convertToQ,
- lineShorthands,
- convertToZ,
- curveSmoothShorthands,
- floatPrecision,
- transformPrecision,
- smartArcRounding,
- removeUseless,
- collapseRepeated,
- utilizeAbsolute,
- leadingZero,
- negativeExtraSpace,
- noSpaceAfterFlags,
- forceAbsolutePath,
- };
-
- // invoke applyTransforms plugin
- if (_applyTransforms) {
- visit(
- root,
- // @ts-ignore
- applyTransforms(root, {
- transformPrecision,
- applyTransformsStroked,
- }),
- );
- }
-
- const stylesheet = collectStylesheet(root);
- return {
- element: {
- enter: (node) => {
- if (pathElems.has(node.name) && node.attributes.d != null) {
- const computedStyle = computeStyle(stylesheet, node);
- precision = floatPrecision;
- error =
- precision !== false
- ? +Math.pow(0.1, precision).toFixed(precision)
- : 1e-2;
- roundData =
- precision && precision > 0 && precision < 20 ? strongRound : round;
- if (makeArcs) {
- arcThreshold = makeArcs.threshold;
- arcTolerance = makeArcs.tolerance;
- }
- const hasMarkerMid = computedStyle['marker-mid'] != null;
-
- const maybeHasStroke =
- computedStyle.stroke &&
- (computedStyle.stroke.type === 'dynamic' ||
- computedStyle.stroke.value !== 'none');
- const maybeHasLinecap =
- computedStyle['stroke-linecap'] &&
- (computedStyle['stroke-linecap'].type === 'dynamic' ||
- computedStyle['stroke-linecap'].value !== 'butt');
- const maybeHasStrokeAndLinecap = maybeHasStroke && maybeHasLinecap;
- const isSafeToUseZ = maybeHasStroke
- ? computedStyle['stroke-linecap']?.type === 'static' &&
- computedStyle['stroke-linecap'].value === 'round' &&
- computedStyle['stroke-linejoin']?.type === 'static' &&
- computedStyle['stroke-linejoin'].value === 'round'
- : true;
-
- var data = path2js(node);
-
- // TODO: get rid of functions returns
- if (data.length) {
- convertToRelative(data);
-
- data = filters(data, newParams, {
- isSafeToUseZ,
- maybeHasStrokeAndLinecap,
- hasMarkerMid,
- });
-
- if (utilizeAbsolute) {
- data = convertToMixed(data, newParams);
- }
-
- // @ts-ignore
- js2path(node, data, newParams);
- }
- }
- },
- },
- };
-};
-
-/**
- * Convert absolute path data coordinates to relative.
- *
- * @type {(pathData: PathDataItem[]) => PathDataItem[]}
- */
-const convertToRelative = (pathData) => {
- let start = [0, 0];
- let cursor = [0, 0];
- let prevCoords = [0, 0];
-
- for (let i = 0; i < pathData.length; i += 1) {
- const pathItem = pathData[i];
- let { command, args } = pathItem;
-
- // moveto (x y)
- if (command === 'm') {
- // update start and cursor
- cursor[0] += args[0];
- cursor[1] += args[1];
- start[0] = cursor[0];
- start[1] = cursor[1];
- }
- if (command === 'M') {
- // M → m
- // skip first moveto
- if (i !== 0) {
- command = 'm';
- }
- args[0] -= cursor[0];
- args[1] -= cursor[1];
- // update start and cursor
- cursor[0] += args[0];
- cursor[1] += args[1];
- start[0] = cursor[0];
- start[1] = cursor[1];
- }
-
- // lineto (x y)
- if (command === 'l') {
- cursor[0] += args[0];
- cursor[1] += args[1];
- }
- if (command === 'L') {
- // L → l
- command = 'l';
- args[0] -= cursor[0];
- args[1] -= cursor[1];
- cursor[0] += args[0];
- cursor[1] += args[1];
- }
-
- // horizontal lineto (x)
- if (command === 'h') {
- cursor[0] += args[0];
- }
- if (command === 'H') {
- // H → h
- command = 'h';
- args[0] -= cursor[0];
- cursor[0] += args[0];
- }
-
- // vertical lineto (y)
- if (command === 'v') {
- cursor[1] += args[0];
- }
- if (command === 'V') {
- // V → v
- command = 'v';
- args[0] -= cursor[1];
- cursor[1] += args[0];
- }
-
- // curveto (x1 y1 x2 y2 x y)
- if (command === 'c') {
- cursor[0] += args[4];
- cursor[1] += args[5];
- }
- if (command === 'C') {
- // C → c
- command = 'c';
- args[0] -= cursor[0];
- args[1] -= cursor[1];
- args[2] -= cursor[0];
- args[3] -= cursor[1];
- args[4] -= cursor[0];
- args[5] -= cursor[1];
- cursor[0] += args[4];
- cursor[1] += args[5];
- }
-
- // smooth curveto (x2 y2 x y)
- if (command === 's') {
- cursor[0] += args[2];
- cursor[1] += args[3];
- }
- if (command === 'S') {
- // S → s
- command = 's';
- args[0] -= cursor[0];
- args[1] -= cursor[1];
- args[2] -= cursor[0];
- args[3] -= cursor[1];
- cursor[0] += args[2];
- cursor[1] += args[3];
- }
-
- // quadratic Bézier curveto (x1 y1 x y)
- if (command === 'q') {
- cursor[0] += args[2];
- cursor[1] += args[3];
- }
- if (command === 'Q') {
- // Q → q
- command = 'q';
- args[0] -= cursor[0];
- args[1] -= cursor[1];
- args[2] -= cursor[0];
- args[3] -= cursor[1];
- cursor[0] += args[2];
- cursor[1] += args[3];
- }
-
- // smooth quadratic Bézier curveto (x y)
- if (command === 't') {
- cursor[0] += args[0];
- cursor[1] += args[1];
- }
- if (command === 'T') {
- // T → t
- command = 't';
- args[0] -= cursor[0];
- args[1] -= cursor[1];
- cursor[0] += args[0];
- cursor[1] += args[1];
- }
-
- // elliptical arc (rx ry x-axis-rotation large-arc-flag sweep-flag x y)
- if (command === 'a') {
- cursor[0] += args[5];
- cursor[1] += args[6];
- }
- if (command === 'A') {
- // A → a
- command = 'a';
- args[5] -= cursor[0];
- args[6] -= cursor[1];
- cursor[0] += args[5];
- cursor[1] += args[6];
- }
-
- // closepath
- if (command === 'Z' || command === 'z') {
- // reset cursor
- cursor[0] = start[0];
- cursor[1] = start[1];
- }
-
- pathItem.command = command;
- pathItem.args = args;
- // store absolute coordinates for later use
- // base should preserve reference from other element
- // @ts-ignore
- pathItem.base = prevCoords;
- // @ts-ignore
- pathItem.coords = [cursor[0], cursor[1]];
- // @ts-ignore
- prevCoords = pathItem.coords;
- }
-
- return pathData;
-};
-
-/**
- * Main filters loop.
- *
- * @type {(
- * path: PathDataItem[],
- * params: InternalParams,
- * aux: { isSafeToUseZ: boolean, maybeHasStrokeAndLinecap: boolean, hasMarkerMid: boolean }
- * ) => PathDataItem[]}
- */
-function filters(
- path,
- params,
- { isSafeToUseZ, maybeHasStrokeAndLinecap, hasMarkerMid },
-) {
- const stringify = data2Path.bind(null, params);
- const relSubpoint = [0, 0];
- const pathBase = [0, 0];
- /** @type {any} */
- let prev = {};
- /** @type {Point | undefined} */
- let prevQControlPoint;
-
- path = path.filter(function (item, index, path) {
- const qControlPoint = prevQControlPoint;
- prevQControlPoint = undefined;
-
- let command = item.command;
- let data = item.args;
- let next = path[index + 1];
-
- if (command !== 'Z' && command !== 'z') {
- var sdata = data,
- circle;
-
- if (command === 's') {
- sdata = [0, 0].concat(data);
-
- const pdata = prev.args;
- const n = pdata.length;
-
- // (-x, -y) of the prev tangent point relative to the current point
- sdata[0] = pdata[n - 2] - pdata[n - 4];
- sdata[1] = pdata[n - 1] - pdata[n - 3];
- }
-
- // convert curves to arcs if possible
- if (
- params.makeArcs &&
- (command == 'c' || command == 's') &&
- isConvex(sdata) &&
- (circle = findCircle(sdata))
- ) {
- var r = roundData([circle.radius])[0],
- angle = findArcAngle(sdata, circle),
- sweep = sdata[5] * sdata[0] - sdata[4] * sdata[1] > 0 ? 1 : 0,
- /**
- * @type {PathDataItem}
- */
- arc = {
- command: 'a',
- args: [r, r, 0, 0, sweep, sdata[4], sdata[5]],
- // @ts-ignore
- coords: item.coords.slice(),
- // @ts-ignore
- base: item.base,
- },
- /**
- * @type {PathDataItem[]}
- */
- output = [arc],
- // relative coordinates to adjust the found circle
- /**
- * @type {Point}
- */
- relCenter = [
- circle.center[0] - sdata[4],
- circle.center[1] - sdata[5],
- ],
- relCircle = { center: relCenter, radius: circle.radius },
- arcCurves = [item],
- hasPrev = 0,
- suffix = '',
- nextLonghand;
-
- if (
- (prev.command == 'c' &&
- isConvex(prev.args) &&
- isArcPrev(prev.args, circle)) ||
- (prev.command == 'a' && prev.sdata && isArcPrev(prev.sdata, circle))
- ) {
- arcCurves.unshift(prev);
- // @ts-ignore
- arc.base = prev.base;
- // @ts-ignore
- arc.args[5] = arc.coords[0] - arc.base[0];
- // @ts-ignore
- arc.args[6] = arc.coords[1] - arc.base[1];
- var prevData = prev.command == 'a' ? prev.sdata : prev.args;
- var prevAngle = findArcAngle(prevData, {
- center: [
- prevData[4] + circle.center[0],
- prevData[5] + circle.center[1],
- ],
- radius: circle.radius,
- });
- angle += prevAngle;
- if (angle > Math.PI) arc.args[3] = 1;
- hasPrev = 1;
- }
-
- // check if next curves are fitting the arc
- for (
- var j = index;
- (next = path[++j]) && (next.command === 'c' || next.command === 's');
-
- ) {
- var nextData = next.args;
- if (next.command == 's') {
- nextLonghand = makeLonghand(
- { command: 's', args: next.args.slice() },
- path[j - 1].args,
- );
- nextData = nextLonghand.args;
- nextLonghand.args = nextData.slice(0, 2);
- suffix = stringify([nextLonghand]);
- }
- if (isConvex(nextData) && isArc(nextData, relCircle)) {
- angle += findArcAngle(nextData, relCircle);
- if (angle - 2 * Math.PI > 1e-3) break; // more than 360°
- if (angle > Math.PI) arc.args[3] = 1;
- arcCurves.push(next);
- if (2 * Math.PI - angle > 1e-3) {
- // less than 360°
- // @ts-ignore
- arc.coords = next.coords;
- // @ts-ignore
- arc.args[5] = arc.coords[0] - arc.base[0];
- // @ts-ignore
- arc.args[6] = arc.coords[1] - arc.base[1];
- } else {
- // full circle, make a half-circle arc and add a second one
- arc.args[5] = 2 * (relCircle.center[0] - nextData[4]);
- arc.args[6] = 2 * (relCircle.center[1] - nextData[5]);
- // @ts-ignore
- arc.coords = [
- // @ts-ignore
- arc.base[0] + arc.args[5],
- // @ts-ignore
- arc.base[1] + arc.args[6],
- ];
- arc = {
- command: 'a',
- args: [
- r,
- r,
- 0,
- 0,
- sweep,
- // @ts-ignore
- next.coords[0] - arc.coords[0],
- // @ts-ignore
- next.coords[1] - arc.coords[1],
- ],
- // @ts-ignore
- coords: next.coords,
- // @ts-ignore
- base: arc.coords,
- };
- output.push(arc);
- j++;
- break;
- }
- relCenter[0] -= nextData[4];
- relCenter[1] -= nextData[5];
- } else break;
- }
-
- if ((stringify(output) + suffix).length < stringify(arcCurves).length) {
- if (path[j] && path[j].command == 's') {
- makeLonghand(path[j], path[j - 1].args);
- }
- if (hasPrev) {
- var prevArc = output.shift();
- // @ts-ignore
- roundData(prevArc.args);
- // @ts-ignore
- relSubpoint[0] += prevArc.args[5] - prev.args[prev.args.length - 2];
- // @ts-ignore
- relSubpoint[1] += prevArc.args[6] - prev.args[prev.args.length - 1];
- prev.command = 'a';
- // @ts-ignore
- prev.args = prevArc.args;
- // @ts-ignore
- item.base = prev.coords = prevArc.coords;
- }
- // @ts-ignore
- arc = output.shift();
- if (arcCurves.length == 1) {
- // @ts-ignore
- item.sdata = sdata.slice(); // preserve curve data for future checks
- } else if (arcCurves.length - 1 - hasPrev > 0) {
- // filter out consumed next items
- path.splice(index + 1, arcCurves.length - 1 - hasPrev, ...output);
- }
- if (!arc) return false;
- command = 'a';
- data = arc.args;
- // @ts-ignore
- item.coords = arc.coords;
- }
- }
-
- // Rounding relative coordinates, taking in account accumulating error
- // to get closer to absolute coordinates. Sum of rounded value remains same:
- // l .25 3 .25 2 .25 3 .25 2 -> l .3 3 .2 2 .3 3 .2 2
- if (precision !== false) {
- if (
- command === 'm' ||
- command === 'l' ||
- command === 't' ||
- command === 'q' ||
- command === 's' ||
- command === 'c'
- ) {
- for (var i = data.length; i--; ) {
- // @ts-ignore
- data[i] += item.base[i % 2] - relSubpoint[i % 2];
- }
- } else if (command == 'h') {
- // @ts-ignore
- data[0] += item.base[0] - relSubpoint[0];
- } else if (command == 'v') {
- // @ts-ignore
- data[0] += item.base[1] - relSubpoint[1];
- } else if (command == 'a') {
- // @ts-ignore
- data[5] += item.base[0] - relSubpoint[0];
- // @ts-ignore
- data[6] += item.base[1] - relSubpoint[1];
- }
- roundData(data);
-
- if (command == 'h') relSubpoint[0] += data[0];
- else if (command == 'v') relSubpoint[1] += data[0];
- else {
- relSubpoint[0] += data[data.length - 2];
- relSubpoint[1] += data[data.length - 1];
- }
- roundData(relSubpoint);
-
- if (command === 'M' || command === 'm') {
- pathBase[0] = relSubpoint[0];
- pathBase[1] = relSubpoint[1];
- }
- }
-
- // round arc radius more accurately
- // eg m 0 0 a 1234.567 1234.567 0 0 1 10 0 -> m 0 0 a 1235 1235 0 0 1 10 0
- const sagitta = command === 'a' ? calculateSagitta(data) : undefined;
- if (params.smartArcRounding && sagitta !== undefined && precision) {
- for (let precisionNew = precision; precisionNew >= 0; precisionNew--) {
- const radius = toFixed(data[0], precisionNew);
- const sagittaNew = /** @type {number} */ (
- calculateSagitta([radius, radius, ...data.slice(2)])
- );
- if (Math.abs(sagitta - sagittaNew) < error) {
- data[0] = radius;
- data[1] = radius;
- } else {
- break;
- }
- }
- }
-
- // convert straight curves into lines segments
- if (params.straightCurves) {
- if (
- (command === 'c' && isCurveStraightLine(data)) ||
- (command === 's' && isCurveStraightLine(sdata))
- ) {
- if (next && next.command == 's') makeLonghand(next, data); // fix up next curve
- command = 'l';
- data = data.slice(-2);
- } else if (command === 'q' && isCurveStraightLine(data)) {
- if (next && next.command == 't') makeLonghand(next, data); // fix up next curve
- command = 'l';
- data = data.slice(-2);
- } else if (
- command === 't' &&
- prev.command !== 'q' &&
- prev.command !== 't'
- ) {
- command = 'l';
- data = data.slice(-2);
- } else if (
- command === 'a' &&
- (data[0] === 0 ||
- data[1] === 0 ||
- (sagitta !== undefined && sagitta < error))
- ) {
- command = 'l';
- data = data.slice(-2);
- }
- }
-
- // degree-lower c to q when possible
- // m 0 12 C 4 4 8 4 12 12 → M 0 12 Q 6 0 12 12
- if (params.convertToQ && command == 'c') {
- const x1 =
- // @ts-ignore
- 0.75 * (item.base[0] + data[0]) - 0.25 * item.base[0];
- const x2 =
- // @ts-ignore
- 0.75 * (item.base[0] + data[2]) - 0.25 * (item.base[0] + data[4]);
- if (Math.abs(x1 - x2) < error * 2) {
- const y1 =
- // @ts-ignore
- 0.75 * (item.base[1] + data[1]) - 0.25 * item.base[1];
- const y2 =
- // @ts-ignore
- 0.75 * (item.base[1] + data[3]) - 0.25 * (item.base[1] + data[5]);
- if (Math.abs(y1 - y2) < error * 2) {
- const newData = data.slice();
- newData.splice(
- 0,
- 4,
- // @ts-ignore
- x1 + x2 - item.base[0],
- // @ts-ignore
- y1 + y2 - item.base[1],
- );
- roundData(newData);
- const originalLength = cleanupOutData(data, params).length,
- newLength = cleanupOutData(newData, params).length;
- if (newLength < originalLength) {
- command = 'q';
- data = newData;
- if (next && next.command == 's') makeLonghand(next, data); // fix up next curve
- }
- }
- }
- }
-
- // horizontal and vertical line shorthands
- // l 50 0 → h 50
- // l 0 50 → v 50
- if (params.lineShorthands && command === 'l') {
- if (data[1] === 0) {
- command = 'h';
- data.pop();
- } else if (data[0] === 0) {
- command = 'v';
- data.shift();
- }
- }
-
- // collapse repeated commands
- // h 20 h 30 -> h 50
- if (
- params.collapseRepeated &&
- hasMarkerMid === false &&
- (command === 'm' || command === 'h' || command === 'v') &&
- prev.command &&
- command == prev.command.toLowerCase() &&
- ((command != 'h' && command != 'v') ||
- prev.args[0] >= 0 == data[0] >= 0)
- ) {
- prev.args[0] += data[0];
- if (command != 'h' && command != 'v') {
- prev.args[1] += data[1];
- }
- // @ts-ignore
- prev.coords = item.coords;
- path[index] = prev;
- return false;
- }
-
- // convert curves into smooth shorthands
- if (params.curveSmoothShorthands && prev.command) {
- // curveto
- if (command === 'c') {
- // c + c → c + s
- if (
- prev.command === 'c' &&
- Math.abs(data[0] - -(prev.args[2] - prev.args[4])) < error &&
- Math.abs(data[1] - -(prev.args[3] - prev.args[5])) < error
- ) {
- command = 's';
- data = data.slice(2);
- }
-
- // s + c → s + s
- else if (
- prev.command === 's' &&
- Math.abs(data[0] - -(prev.args[0] - prev.args[2])) < error &&
- Math.abs(data[1] - -(prev.args[1] - prev.args[3])) < error
- ) {
- command = 's';
- data = data.slice(2);
- }
-
- // [^cs] + c → [^cs] + s
- else if (
- prev.command !== 'c' &&
- prev.command !== 's' &&
- Math.abs(data[0]) < error &&
- Math.abs(data[1]) < error
- ) {
- command = 's';
- data = data.slice(2);
- }
- }
-
- // quadratic Bézier curveto
- else if (command === 'q') {
- // q + q → q + t
- if (
- prev.command === 'q' &&
- Math.abs(data[0] - (prev.args[2] - prev.args[0])) < error &&
- Math.abs(data[1] - (prev.args[3] - prev.args[1])) < error
- ) {
- command = 't';
- data = data.slice(2);
- }
-
- // t + q → t + t
- else if (prev.command === 't') {
- const predictedControlPoint = reflectPoint(
- // @ts-ignore
- qControlPoint,
- // @ts-ignore
- item.base,
- );
- const realControlPoint = [
- // @ts-ignore
- data[0] + item.base[0],
- // @ts-ignore
- data[1] + item.base[1],
- ];
- if (
- Math.abs(predictedControlPoint[0] - realControlPoint[0]) <
- error &&
- Math.abs(predictedControlPoint[1] - realControlPoint[1]) < error
- ) {
- command = 't';
- data = data.slice(2);
- }
- }
- }
- }
-
- // remove useless non-first path segments
- if (params.removeUseless && !maybeHasStrokeAndLinecap) {
- // l 0,0 / h 0 / v 0 / q 0,0 0,0 / t 0,0 / c 0,0 0,0 0,0 / s 0,0 0,0
- if (
- (command === 'l' ||
- command === 'h' ||
- command === 'v' ||
- command === 'q' ||
- command === 't' ||
- command === 'c' ||
- command === 's') &&
- data.every(function (i) {
- return i === 0;
- })
- ) {
- path[index] = prev;
- return false;
- }
-
- // a 25,25 -30 0,1 0,0
- if (command === 'a' && data[5] === 0 && data[6] === 0) {
- path[index] = prev;
- return false;
- }
- }
-
- // convert going home to z
- // m 0 0 h 5 v 5 l -5 -5 -> m 0 0 h 5 v 5 z
- if (
- params.convertToZ &&
- (isSafeToUseZ || next?.command === 'Z' || next?.command === 'z') &&
- (command === 'l' || command === 'h' || command === 'v')
- ) {
- if (
- // @ts-ignore
- Math.abs(pathBase[0] - item.coords[0]) < error &&
- // @ts-ignore
- Math.abs(pathBase[1] - item.coords[1]) < error
- ) {
- command = 'z';
- data = [];
- }
- }
-
- item.command = command;
- item.args = data;
- } else {
- // z resets coordinates
- relSubpoint[0] = pathBase[0];
- relSubpoint[1] = pathBase[1];
- if (prev.command === 'Z' || prev.command === 'z') return false;
- }
- if (
- (command === 'Z' || command === 'z') &&
- params.removeUseless &&
- isSafeToUseZ &&
- // @ts-ignore
- Math.abs(item.base[0] - item.coords[0]) < error / 10 &&
- // @ts-ignore
- Math.abs(item.base[1] - item.coords[1]) < error / 10
- )
- return false;
-
- if (command === 'q') {
- // @ts-ignore
- prevQControlPoint = [data[0] + item.base[0], data[1] + item.base[1]];
- } else if (command === 't') {
- if (qControlPoint) {
- // @ts-ignore
- prevQControlPoint = reflectPoint(qControlPoint, item.base);
- } else {
- // @ts-ignore
- prevQControlPoint = item.coords;
- }
- }
- prev = item;
- return true;
- });
-
- return path;
-}
-
-/**
- * Writes data in shortest form using absolute or relative coordinates.
- *
- * @type {(path: PathDataItem[], params: InternalParams) => PathDataItem[]}
- */
-function convertToMixed(path, params) {
- var prev = path[0];
-
- path = path.filter(function (item, index) {
- if (index == 0) return true;
- if (item.command === 'Z' || item.command === 'z') {
- prev = item;
- return true;
- }
-
- var command = item.command,
- data = item.args,
- adata = data.slice(),
- rdata = data.slice();
-
- if (
- command === 'm' ||
- command === 'l' ||
- command === 't' ||
- command === 'q' ||
- command === 's' ||
- command === 'c'
- ) {
- for (var i = adata.length; i--; ) {
- // @ts-ignore
- adata[i] += item.base[i % 2];
- }
- } else if (command == 'h') {
- // @ts-ignore
- adata[0] += item.base[0];
- } else if (command == 'v') {
- // @ts-ignore
- adata[0] += item.base[1];
- } else if (command == 'a') {
- // @ts-ignore
- adata[5] += item.base[0];
- // @ts-ignore
- adata[6] += item.base[1];
- }
-
- roundData(adata);
- roundData(rdata);
-
- var absoluteDataStr = cleanupOutData(adata, params),
- relativeDataStr = cleanupOutData(rdata, params);
-
- // Convert to absolute coordinates if it's shorter or forceAbsolutePath is true.
- // v-20 -> V0
- // Don't convert if it fits following previous command.
- // l20 30-10-50 instead of l20 30L20 30
- if (
- params.forceAbsolutePath ||
- (absoluteDataStr.length < relativeDataStr.length &&
- !(
- params.negativeExtraSpace &&
- command == prev.command &&
- prev.command.charCodeAt(0) > 96 &&
- absoluteDataStr.length == relativeDataStr.length - 1 &&
- (data[0] < 0 ||
- (Math.floor(data[0]) === 0 &&
- !Number.isInteger(data[0]) &&
- prev.args[prev.args.length - 1] % 1))
- ))
- ) {
- // @ts-ignore
- item.command = command.toUpperCase();
- item.args = adata;
- }
-
- prev = item;
- return true;
- });
-
- return path;
-}
-
-/**
- * Checks if curve is convex. Control points of such a curve must form
- * a convex quadrilateral with diagonals crosspoint inside of it.
- *
- * @type {(data: number[]) => boolean}
- */
-function isConvex(data) {
- var center = getIntersection([
- 0,
- 0,
- data[2],
- data[3],
- data[0],
- data[1],
- data[4],
- data[5],
- ]);
-
- return (
- center != null &&
- data[2] < center[0] == center[0] < 0 &&
- data[3] < center[1] == center[1] < 0 &&
- data[4] < center[0] == center[0] < data[0] &&
- data[5] < center[1] == center[1] < data[1]
- );
-}
-
-/**
- * Computes lines equations by two points and returns their intersection point.
- *
- * @type {(coords: number[]) => undefined | Point}
- */
-function getIntersection(coords) {
- // Prev line equation parameters.
- var a1 = coords[1] - coords[3], // y1 - y2
- b1 = coords[2] - coords[0], // x2 - x1
- c1 = coords[0] * coords[3] - coords[2] * coords[1], // x1 * y2 - x2 * y1
- // Next line equation parameters
- a2 = coords[5] - coords[7], // y1 - y2
- b2 = coords[6] - coords[4], // x2 - x1
- c2 = coords[4] * coords[7] - coords[5] * coords[6], // x1 * y2 - x2 * y1
- denom = a1 * b2 - a2 * b1;
-
- if (!denom) return; // parallel lines haven't an intersection
-
- /**
- * @type {Point}
- */
- var cross = [(b1 * c2 - b2 * c1) / denom, (a1 * c2 - a2 * c1) / -denom];
- if (
- !isNaN(cross[0]) &&
- !isNaN(cross[1]) &&
- isFinite(cross[0]) &&
- isFinite(cross[1])
- ) {
- return cross;
- }
-}
-
-/**
- * Decrease accuracy of floating-point numbers
- * in path data keeping a specified number of decimals.
- * Smart rounds values like 2.3491 to 2.35 instead of 2.349.
- * Doesn't apply "smartness" if the number precision fits already.
- *
- * @type {(data: number[]) => number[]}
- */
-function strongRound(data) {
- const precisionNum = precision || 0;
- for (let i = data.length; i-- > 0; ) {
- const fixed = toFixed(data[i], precisionNum);
- if (fixed !== data[i]) {
- const rounded = toFixed(data[i], precisionNum - 1);
- data[i] =
- toFixed(Math.abs(rounded - data[i]), precisionNum + 1) >= error
- ? fixed
- : rounded;
- }
- }
- return data;
-}
-
-/**
- * Simple rounding function if precision is 0.
- *
- * @type {(data: number[]) => number[]}
- */
-function round(data) {
- for (var i = data.length; i-- > 0; ) {
- data[i] = Math.round(data[i]);
- }
- return data;
-}
-
-/**
- * Checks if a curve is a straight line by measuring distance
- * from middle points to the line formed by end points.
- *
- * @type {(data: number[]) => boolean}
- */
-function isCurveStraightLine(data) {
- // Get line equation a·x + b·y + c = 0 coefficients a, b (c = 0) by start and end points.
- var i = data.length - 2,
- a = -data[i + 1], // y1 − y2 (y1 = 0)
- b = data[i], // x2 − x1 (x1 = 0)
- d = 1 / (a * a + b * b); // same part for all points
-
- if (i <= 1 || !isFinite(d)) return false; // curve that ends at start point isn't the case
-
- // Distance from point (x0, y0) to the line is sqrt((c − a·x0 − b·y0)² / (a² + b²))
- while ((i -= 2) >= 0) {
- if (Math.sqrt(Math.pow(a * data[i] + b * data[i + 1], 2) * d) > error)
- return false;
- }
-
- return true;
-}
-
-/**
- * Calculates the sagitta of an arc if possible.
- *
- * @type {(data: number[]) => number | undefined}
- * @see https://wikipedia.org/wiki/Sagitta_(geometry)#Formulas
- */
-function calculateSagitta(data) {
- if (data[3] === 1) return undefined;
- const [rx, ry] = data;
- if (Math.abs(rx - ry) > error) return undefined;
- const chord = Math.sqrt(data[5] ** 2 + data[6] ** 2);
- if (chord > rx * 2) return undefined;
- return rx - Math.sqrt(rx ** 2 - 0.25 * chord ** 2);
-}
-
-/**
- * Converts next curve from shorthand to full form using the current curve data.
- *
- * @type {(item: PathDataItem, data: number[]) => PathDataItem}
- */
-function makeLonghand(item, data) {
- switch (item.command) {
- case 's':
- item.command = 'c';
- break;
- case 't':
- item.command = 'q';
- break;
- }
- item.args.unshift(
- data[data.length - 2] - data[data.length - 4],
- data[data.length - 1] - data[data.length - 3],
- );
- return item;
-}
-
-/**
- * Returns distance between two points
- *
- * @type {(point1: Point, point2: Point) => number}
- */
-function getDistance(point1, point2) {
- return Math.sqrt((point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2);
-}
-
-/**
- * Reflects point across another point.
- *
- * @param {Point} controlPoint
- * @param {Point} base
- * @returns {Point}
- */
-function reflectPoint(controlPoint, base) {
- return [2 * base[0] - controlPoint[0], 2 * base[1] - controlPoint[1]];
-}
-
-/**
- * Returns coordinates of the curve point corresponding to the certain t
- * a·(1 - t)³·p1 + b·(1 - t)²·t·p2 + c·(1 - t)·t²·p3 + d·t³·p4,
- * where pN are control points and p1 is zero due to relative coordinates.
- *
- * @type {(curve: number[], t: number) => Point}
- */
-function getCubicBezierPoint(curve, t) {
- var sqrT = t * t,
- cubT = sqrT * t,
- mt = 1 - t,
- sqrMt = mt * mt;
-
- return [
- 3 * sqrMt * t * curve[0] + 3 * mt * sqrT * curve[2] + cubT * curve[4],
- 3 * sqrMt * t * curve[1] + 3 * mt * sqrT * curve[3] + cubT * curve[5],
- ];
-}
-
-/**
- * Finds circle by 3 points of the curve and checks if the curve fits the found circle.
- *
- * @type {(curve: number[]) => undefined | Circle}
- */
-function findCircle(curve) {
- var midPoint = getCubicBezierPoint(curve, 1 / 2),
- m1 = [midPoint[0] / 2, midPoint[1] / 2],
- m2 = [(midPoint[0] + curve[4]) / 2, (midPoint[1] + curve[5]) / 2],
- center = getIntersection([
- m1[0],
- m1[1],
- m1[0] + m1[1],
- m1[1] - m1[0],
- m2[0],
- m2[1],
- m2[0] + (m2[1] - midPoint[1]),
- m2[1] - (m2[0] - midPoint[0]),
- ]),
- radius = center && getDistance([0, 0], center),
- // @ts-ignore
- tolerance = Math.min(arcThreshold * error, (arcTolerance * radius) / 100);
-
- if (
- center &&
- // @ts-ignore
- radius < 1e15 &&
- [1 / 4, 3 / 4].every(function (point) {
- return (
- Math.abs(
- // @ts-ignore
- getDistance(getCubicBezierPoint(curve, point), center) - radius,
- ) <= tolerance
- );
- })
- )
- // @ts-ignore
- return { center: center, radius: radius };
-}
-
-/**
- * Checks if a curve fits the given circle.
- *
- * @type {(curve: number[], circle: Circle) => boolean}
- */
-function isArc(curve, circle) {
- var tolerance = Math.min(
- arcThreshold * error,
- (arcTolerance * circle.radius) / 100,
- );
-
- return [0, 1 / 4, 1 / 2, 3 / 4, 1].every(function (point) {
- return (
- Math.abs(
- getDistance(getCubicBezierPoint(curve, point), circle.center) -
- circle.radius,
- ) <= tolerance
- );
- });
-}
-
-/**
- * Checks if a previous curve fits the given circle.
- *
- * @type {(curve: number[], circle: Circle) => boolean}
- */
-function isArcPrev(curve, circle) {
- return isArc(curve, {
- center: [circle.center[0] + curve[4], circle.center[1] + curve[5]],
- radius: circle.radius,
- });
-}
-
-/**
- * Finds angle of a curve fitting the given arc.
-
- * @type {(curve: number[], relCircle: Circle) => number}
- */
-function findArcAngle(curve, relCircle) {
- var x1 = -relCircle.center[0],
- y1 = -relCircle.center[1],
- x2 = curve[4] - relCircle.center[0],
- y2 = curve[5] - relCircle.center[1];
-
- return Math.acos(
- (x1 * x2 + y1 * y2) / Math.sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2)),
- );
-}
-
-/**
- * Converts given path data to string.
- *
- * @type {(params: InternalParams, pathData: PathDataItem[]) => string}
- */
-function data2Path(params, pathData) {
- return pathData.reduce(function (pathString, item) {
- var strData = '';
- if (item.args) {
- strData = cleanupOutData(roundData(item.args.slice()), params);
- }
- return pathString + item.command + strData;
- }, '');
-}
diff --git a/node_modules/svgo/plugins/convertShapeToPath.js b/node_modules/svgo/plugins/convertShapeToPath.js
deleted file mode 100644
index f0ba0fd8..00000000
--- a/node_modules/svgo/plugins/convertShapeToPath.js
+++ /dev/null
@@ -1,170 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types').PathDataItem} PathDataItem
- */
-
-const { stringifyPathData } = require('../lib/path.js');
-const { detachNodeFromParent } = require('../lib/xast.js');
-
-exports.name = 'convertShapeToPath';
-exports.description = 'converts basic shapes to more compact path form';
-
-const regNumber = /[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/g;
-
-/**
- * Converts basic shape to more compact path.
- * It also allows further optimizations like
- * combining paths with similar attributes.
- *
- * @see https://www.w3.org/TR/SVG11/shapes.html
- *
- * @author Lev Solntsev
- *
- * @type {import('./plugins-types').Plugin<'convertShapeToPath'>}
- */
-exports.fn = (root, params) => {
- const { convertArcs = false, floatPrecision: precision } = params;
-
- return {
- element: {
- enter: (node, parentNode) => {
- // convert rect to path
- if (
- node.name === 'rect' &&
- node.attributes.width != null &&
- node.attributes.height != null &&
- node.attributes.rx == null &&
- node.attributes.ry == null
- ) {
- const x = Number(node.attributes.x || '0');
- const y = Number(node.attributes.y || '0');
- const width = Number(node.attributes.width);
- const height = Number(node.attributes.height);
- // Values like '100%' compute to NaN, thus running after
- // cleanupNumericValues when 'px' units has already been removed.
- // TODO: Calculate sizes from % and non-px units if possible.
- if (Number.isNaN(x - y + width - height)) return;
- /**
- * @type {PathDataItem[]}
- */
- const pathData = [
- { command: 'M', args: [x, y] },
- { command: 'H', args: [x + width] },
- { command: 'V', args: [y + height] },
- { command: 'H', args: [x] },
- { command: 'z', args: [] },
- ];
- node.name = 'path';
- node.attributes.d = stringifyPathData({ pathData, precision });
- delete node.attributes.x;
- delete node.attributes.y;
- delete node.attributes.width;
- delete node.attributes.height;
- }
-
- // convert line to path
- if (node.name === 'line') {
- const x1 = Number(node.attributes.x1 || '0');
- const y1 = Number(node.attributes.y1 || '0');
- const x2 = Number(node.attributes.x2 || '0');
- const y2 = Number(node.attributes.y2 || '0');
- if (Number.isNaN(x1 - y1 + x2 - y2)) return;
- /**
- * @type {PathDataItem[]}
- */
- const pathData = [
- { command: 'M', args: [x1, y1] },
- { command: 'L', args: [x2, y2] },
- ];
- node.name = 'path';
- node.attributes.d = stringifyPathData({ pathData, precision });
- delete node.attributes.x1;
- delete node.attributes.y1;
- delete node.attributes.x2;
- delete node.attributes.y2;
- }
-
- // convert polyline and polygon to path
- if (
- (node.name === 'polyline' || node.name === 'polygon') &&
- node.attributes.points != null
- ) {
- const coords = (node.attributes.points.match(regNumber) || []).map(
- Number,
- );
- if (coords.length < 4) {
- detachNodeFromParent(node, parentNode);
- return;
- }
- /**
- * @type {PathDataItem[]}
- */
- const pathData = [];
- for (let i = 0; i < coords.length; i += 2) {
- pathData.push({
- command: i === 0 ? 'M' : 'L',
- args: coords.slice(i, i + 2),
- });
- }
- if (node.name === 'polygon') {
- pathData.push({ command: 'z', args: [] });
- }
- node.name = 'path';
- node.attributes.d = stringifyPathData({ pathData, precision });
- delete node.attributes.points;
- }
-
- // optionally convert circle
- if (node.name === 'circle' && convertArcs) {
- const cx = Number(node.attributes.cx || '0');
- const cy = Number(node.attributes.cy || '0');
- const r = Number(node.attributes.r || '0');
- if (Number.isNaN(cx - cy + r)) {
- return;
- }
- /**
- * @type {PathDataItem[]}
- */
- const pathData = [
- { command: 'M', args: [cx, cy - r] },
- { command: 'A', args: [r, r, 0, 1, 0, cx, cy + r] },
- { command: 'A', args: [r, r, 0, 1, 0, cx, cy - r] },
- { command: 'z', args: [] },
- ];
- node.name = 'path';
- node.attributes.d = stringifyPathData({ pathData, precision });
- delete node.attributes.cx;
- delete node.attributes.cy;
- delete node.attributes.r;
- }
-
- // optionally convert ellipse
- if (node.name === 'ellipse' && convertArcs) {
- const ecx = Number(node.attributes.cx || '0');
- const ecy = Number(node.attributes.cy || '0');
- const rx = Number(node.attributes.rx || '0');
- const ry = Number(node.attributes.ry || '0');
- if (Number.isNaN(ecx - ecy + rx - ry)) {
- return;
- }
- /**
- * @type {PathDataItem[]}
- */
- const pathData = [
- { command: 'M', args: [ecx, ecy - ry] },
- { command: 'A', args: [rx, ry, 0, 1, 0, ecx, ecy + ry] },
- { command: 'A', args: [rx, ry, 0, 1, 0, ecx, ecy - ry] },
- { command: 'z', args: [] },
- ];
- node.name = 'path';
- node.attributes.d = stringifyPathData({ pathData, precision });
- delete node.attributes.cx;
- delete node.attributes.cy;
- delete node.attributes.rx;
- delete node.attributes.ry;
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/convertStyleToAttrs.js b/node_modules/svgo/plugins/convertStyleToAttrs.js
deleted file mode 100644
index a9305fc4..00000000
--- a/node_modules/svgo/plugins/convertStyleToAttrs.js
+++ /dev/null
@@ -1,136 +0,0 @@
-'use strict';
-
-const { attrsGroups } = require('./_collections');
-
-exports.name = 'convertStyleToAttrs';
-exports.description = 'converts style to attributes';
-
-/**
- * @type {(...args: string[]) => string}
- */
-const g = (...args) => {
- return '(?:' + args.join('|') + ')';
-};
-
-const stylingProps = attrsGroups.presentation;
-const rEscape = '\\\\(?:[0-9a-f]{1,6}\\s?|\\r\\n|.)'; // Like \" or \2051. Code points consume one space.
-const rAttr = '\\s*(' + g('[^:;\\\\]', rEscape) + '*?)\\s*'; // attribute name like ‘fill’
-const rSingleQuotes = "'(?:[^'\\n\\r\\\\]|" + rEscape + ")*?(?:'|$)"; // string in single quotes: 'smth'
-const rQuotes = '"(?:[^"\\n\\r\\\\]|' + rEscape + ')*?(?:"|$)'; // string in double quotes: "smth"
-const rQuotedString = new RegExp('^' + g(rSingleQuotes, rQuotes) + '$');
-// Parentheses, E.g.: url(data:image/png;base64,iVBO...).
-// ':' and ';' inside of it should be treated as is. (Just like in strings.)
-const rParenthesis =
- '\\(' + g('[^\'"()\\\\]+', rEscape, rSingleQuotes, rQuotes) + '*?' + '\\)';
-// The value. It can have strings and parentheses (see above). Fallbacks to anything in case of unexpected input.
-const rValue =
- '\\s*(' +
- g(
- '[^!\'"();\\\\]+?',
- rEscape,
- rSingleQuotes,
- rQuotes,
- rParenthesis,
- '[^;]*?',
- ) +
- '*?' +
- ')';
-// End of declaration. Spaces outside of capturing groups help to do natural trimming.
-const rDeclEnd = '\\s*(?:;\\s*|$)';
-// Important rule
-const rImportant = '(\\s*!important(?![-(\\w]))?';
-// Final RegExp to parse CSS declarations.
-const regDeclarationBlock = new RegExp(
- rAttr + ':' + rValue + rImportant + rDeclEnd,
- 'ig',
-);
-// Comments expression. Honors escape sequences and strings.
-const regStripComments = new RegExp(
- g(rEscape, rSingleQuotes, rQuotes, '/\\*[^]*?\\*/'),
- 'ig',
-);
-
-/**
- * Convert style in attributes. Cleanups comments and illegal declarations (without colon) as a side effect.
- *
- * @example
- * <g style="fill:#000; color: #fff;">
- * ⬇
- * <g fill="#000" color="#fff">
- *
- * @example
- * <g style="fill:#000; color: #fff; -webkit-blah: blah">
- * ⬇
- * <g fill="#000" color="#fff" style="-webkit-blah: blah">
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'convertStyleToAttrs'>}
- */
-exports.fn = (_root, params) => {
- const { keepImportant = false } = params;
- return {
- element: {
- enter: (node) => {
- if (node.attributes.style != null) {
- // ['opacity: 1', 'color: #000']
- let styles = [];
- /**
- * @type {Record<string, string>}
- */
- const newAttributes = {};
-
- // Strip CSS comments preserving escape sequences and strings.
- const styleValue = node.attributes.style.replace(
- regStripComments,
- (match) => {
- return match[0] == '/'
- ? ''
- : match[0] == '\\' && /[-g-z]/i.test(match[1])
- ? match[1]
- : match;
- },
- );
-
- regDeclarationBlock.lastIndex = 0;
- for (var rule; (rule = regDeclarationBlock.exec(styleValue)); ) {
- if (!keepImportant || !rule[3]) {
- styles.push([rule[1], rule[2]]);
- }
- }
-
- if (styles.length) {
- styles = styles.filter(function (style) {
- if (style[0]) {
- var prop = style[0].toLowerCase(),
- val = style[1];
-
- if (rQuotedString.test(val)) {
- val = val.slice(1, -1);
- }
-
- if (stylingProps.has(prop)) {
- newAttributes[prop] = val;
-
- return false;
- }
- }
-
- return true;
- });
-
- Object.assign(node.attributes, newAttributes);
-
- if (styles.length) {
- node.attributes.style = styles
- .map((declaration) => declaration.join(':'))
- .join(';');
- } else {
- delete node.attributes.style;
- }
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/convertTransform.js b/node_modules/svgo/plugins/convertTransform.js
deleted file mode 100644
index 6f399078..00000000
--- a/node_modules/svgo/plugins/convertTransform.js
+++ /dev/null
@@ -1,418 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types').XastChild} XastChild
- * @typedef {import('../lib/types').XastElement} XastElement
- * @typedef {import('../lib/types').XastParent} XastParent
- */
-
-const { cleanupOutData, toFixed } = require('../lib/svgo/tools.js');
-const {
- transform2js,
- transformsMultiply,
- matrixToTransform,
-} = require('./_transforms.js');
-
-exports.name = 'convertTransform';
-exports.description = 'collapses multiple transformations and optimizes it';
-
-/**
- * Convert matrices to the short aliases,
- * convert long translate, scale or rotate transform notations to the shorts ones,
- * convert transforms to the matrices and multiply them all into one,
- * remove useless transforms.
- *
- * @see https://www.w3.org/TR/SVG11/coords.html#TransformMatrixDefined
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'convertTransform'>}
- */
-exports.fn = (_root, params) => {
- const {
- convertToShorts = true,
- // degPrecision = 3, // transformPrecision (or matrix precision) - 2 by default
- degPrecision,
- floatPrecision = 3,
- transformPrecision = 5,
- matrixToTransform = true,
- shortTranslate = true,
- shortScale = true,
- shortRotate = true,
- removeUseless = true,
- collapseIntoOne = true,
- leadingZero = true,
- negativeExtraSpace = false,
- } = params;
- const newParams = {
- convertToShorts,
- degPrecision,
- floatPrecision,
- transformPrecision,
- matrixToTransform,
- shortTranslate,
- shortScale,
- shortRotate,
- removeUseless,
- collapseIntoOne,
- leadingZero,
- negativeExtraSpace,
- };
- return {
- element: {
- enter: (node) => {
- if (node.attributes.transform != null) {
- convertTransform(node, 'transform', newParams);
- }
-
- if (node.attributes.gradientTransform != null) {
- convertTransform(node, 'gradientTransform', newParams);
- }
-
- if (node.attributes.patternTransform != null) {
- convertTransform(node, 'patternTransform', newParams);
- }
- },
- },
- };
-};
-
-/**
- * @typedef {{
- * convertToShorts: boolean,
- * degPrecision?: number,
- * floatPrecision: number,
- * transformPrecision: number,
- * matrixToTransform: boolean,
- * shortTranslate: boolean,
- * shortScale: boolean,
- * shortRotate: boolean,
- * removeUseless: boolean,
- * collapseIntoOne: boolean,
- * leadingZero: boolean,
- * negativeExtraSpace: boolean,
- * }} TransformParams
- */
-
-/**
- * @typedef {{ name: string, data: number[] }} TransformItem
- */
-
-/**
- * @param {XastElement} item
- * @param {string} attrName
- * @param {TransformParams} params
- */
-const convertTransform = (item, attrName, params) => {
- let data = transform2js(item.attributes[attrName]);
- params = definePrecision(data, params);
-
- if (params.collapseIntoOne && data.length > 1) {
- data = [transformsMultiply(data)];
- }
-
- if (params.convertToShorts) {
- data = convertToShorts(data, params);
- } else {
- data.forEach((item) => roundTransform(item, params));
- }
-
- if (params.removeUseless) {
- data = removeUseless(data);
- }
-
- if (data.length) {
- item.attributes[attrName] = js2transform(data, params);
- } else {
- delete item.attributes[attrName];
- }
-};
-
-/**
- * Defines precision to work with certain parts.
- * transformPrecision - for scale and four first matrix parameters (needs a better precision due to multiplying),
- * floatPrecision - for translate including two last matrix and rotate parameters,
- * degPrecision - for rotate and skew. By default it's equal to (roughly)
- * transformPrecision - 2 or floatPrecision whichever is lower. Can be set in params.
- *
- * @type {(data: TransformItem[], params: TransformParams) => TransformParams}
- *
- * clone params so it don't affect other elements transformations.
- */
-const definePrecision = (data, { ...newParams }) => {
- const matrixData = [];
- for (const item of data) {
- if (item.name == 'matrix') {
- matrixData.push(...item.data.slice(0, 4));
- }
- }
- let numberOfDigits = newParams.transformPrecision;
- // Limit transform precision with matrix one. Calculating with larger precision doesn't add any value.
- if (matrixData.length) {
- newParams.transformPrecision = Math.min(
- newParams.transformPrecision,
- Math.max.apply(Math, matrixData.map(floatDigits)) ||
- newParams.transformPrecision,
- );
- numberOfDigits = Math.max.apply(
- Math,
- matrixData.map(
- (n) => n.toString().replace(/\D+/g, '').length, // Number of digits in a number. 123.45 → 5
- ),
- );
- }
- // No sense in angle precision more then number of significant digits in matrix.
- if (newParams.degPrecision == null) {
- newParams.degPrecision = Math.max(
- 0,
- Math.min(newParams.floatPrecision, numberOfDigits - 2),
- );
- }
- return newParams;
-};
-
-/**
- * @type {(data: number[], params: TransformParams) => number[]}
- */
-const degRound = (data, params) => {
- if (
- params.degPrecision != null &&
- params.degPrecision >= 1 &&
- params.floatPrecision < 20
- ) {
- return smartRound(params.degPrecision, data);
- } else {
- return round(data);
- }
-};
-/**
- * @type {(data: number[], params: TransformParams) => number[]}
- */
-const floatRound = (data, params) => {
- if (params.floatPrecision >= 1 && params.floatPrecision < 20) {
- return smartRound(params.floatPrecision, data);
- } else {
- return round(data);
- }
-};
-
-/**
- * @type {(data: number[], params: TransformParams) => number[]}
- */
-const transformRound = (data, params) => {
- if (params.transformPrecision >= 1 && params.floatPrecision < 20) {
- return smartRound(params.transformPrecision, data);
- } else {
- return round(data);
- }
-};
-
-/**
- * Returns number of digits after the point. 0.125 → 3
- *
- * @type {(n: number) => number}
- */
-const floatDigits = (n) => {
- const str = n.toString();
- return str.slice(str.indexOf('.')).length - 1;
-};
-
-/**
- * Convert transforms to the shorthand alternatives.
- *
- * @param {TransformItem[]} transforms
- * @param {TransformParams} params
- * @returns {TransformItem[]}
- */
-const convertToShorts = (transforms, params) => {
- for (var i = 0; i < transforms.length; i++) {
- let transform = transforms[i];
-
- // convert matrix to the short aliases
- if (params.matrixToTransform && transform.name === 'matrix') {
- var decomposed = matrixToTransform(transform, params);
- if (
- js2transform(decomposed, params).length <=
- js2transform([transform], params).length
- ) {
- transforms.splice(i, 1, ...decomposed);
- }
- transform = transforms[i];
- }
-
- // fixed-point numbers
- // 12.754997 → 12.755
- roundTransform(transform, params);
-
- // convert long translate transform notation to the shorts one
- // translate(10 0) → translate(10)
- if (
- params.shortTranslate &&
- transform.name === 'translate' &&
- transform.data.length === 2 &&
- !transform.data[1]
- ) {
- transform.data.pop();
- }
-
- // convert long scale transform notation to the shorts one
- // scale(2 2) → scale(2)
- if (
- params.shortScale &&
- transform.name === 'scale' &&
- transform.data.length === 2 &&
- transform.data[0] === transform.data[1]
- ) {
- transform.data.pop();
- }
-
- // convert long rotate transform notation to the short one
- // translate(cx cy) rotate(a) translate(-cx -cy) → rotate(a cx cy)
- if (
- params.shortRotate &&
- transforms[i - 2]?.name === 'translate' &&
- transforms[i - 1].name === 'rotate' &&
- transforms[i].name === 'translate' &&
- transforms[i - 2].data[0] === -transforms[i].data[0] &&
- transforms[i - 2].data[1] === -transforms[i].data[1]
- ) {
- transforms.splice(i - 2, 3, {
- name: 'rotate',
- data: [
- transforms[i - 1].data[0],
- transforms[i - 2].data[0],
- transforms[i - 2].data[1],
- ],
- });
-
- // splice compensation
- i -= 2;
- }
- }
-
- return transforms;
-};
-
-/**
- * Remove useless transforms.
- *
- * @type {(transforms: TransformItem[]) => TransformItem[]}
- */
-const removeUseless = (transforms) => {
- return transforms.filter((transform) => {
- // translate(0), rotate(0[, cx, cy]), skewX(0), skewY(0)
- if (
- (['translate', 'rotate', 'skewX', 'skewY'].indexOf(transform.name) > -1 &&
- (transform.data.length == 1 || transform.name == 'rotate') &&
- !transform.data[0]) ||
- // translate(0, 0)
- (transform.name == 'translate' &&
- !transform.data[0] &&
- !transform.data[1]) ||
- // scale(1)
- (transform.name == 'scale' &&
- transform.data[0] == 1 &&
- (transform.data.length < 2 || transform.data[1] == 1)) ||
- // matrix(1 0 0 1 0 0)
- (transform.name == 'matrix' &&
- transform.data[0] == 1 &&
- transform.data[3] == 1 &&
- !(
- transform.data[1] ||
- transform.data[2] ||
- transform.data[4] ||
- transform.data[5]
- ))
- ) {
- return false;
- }
-
- return true;
- });
-};
-
-/**
- * Convert transforms JS representation to string.
- *
- * @param {TransformItem[]} transformJS
- * @param {TransformParams} params
- * @returns {string}
- */
-const js2transform = (transformJS, params) => {
- const transformString = transformJS
- .map((transform) => {
- roundTransform(transform, params);
- return `${transform.name}(${cleanupOutData(transform.data, params)})`;
- })
- .join('');
-
- return transformString;
-};
-
-/**
- * @type {(transform: TransformItem, params: TransformParams) => TransformItem}
- */
-const roundTransform = (transform, params) => {
- switch (transform.name) {
- case 'translate':
- transform.data = floatRound(transform.data, params);
- break;
- case 'rotate':
- transform.data = [
- ...degRound(transform.data.slice(0, 1), params),
- ...floatRound(transform.data.slice(1), params),
- ];
- break;
- case 'skewX':
- case 'skewY':
- transform.data = degRound(transform.data, params);
- break;
- case 'scale':
- transform.data = transformRound(transform.data, params);
- break;
- case 'matrix':
- transform.data = [
- ...transformRound(transform.data.slice(0, 4), params),
- ...floatRound(transform.data.slice(4), params),
- ];
- break;
- }
- return transform;
-};
-
-/**
- * Rounds numbers in array.
- *
- * @type {(data: number[]) => number[]}
- */
-const round = (data) => {
- return data.map(Math.round);
-};
-
-/**
- * Decrease accuracy of floating-point numbers
- * in transforms keeping a specified number of decimals.
- * Smart rounds values like 2.349 to 2.35.
- *
- * @param {number} precision
- * @param {number[]} data
- * @returns {number[]}
- */
-const smartRound = (precision, data) => {
- for (
- var i = data.length,
- tolerance = +Math.pow(0.1, precision).toFixed(precision);
- i--;
-
- ) {
- if (toFixed(data[i], precision) !== data[i]) {
- var rounded = +data[i].toFixed(precision - 1);
- data[i] =
- +Math.abs(rounded - data[i]).toFixed(precision + 1) >= tolerance
- ? +data[i].toFixed(precision)
- : rounded;
- }
- }
-
- return data;
-};
diff --git a/node_modules/svgo/plugins/inlineStyles.js b/node_modules/svgo/plugins/inlineStyles.js
deleted file mode 100644
index e09988de..00000000
--- a/node_modules/svgo/plugins/inlineStyles.js
+++ /dev/null
@@ -1,390 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types').XastElement} XastElement
- * @typedef {import('../lib/types').XastParent} XastParent
- */
-
-const csstree = require('css-tree');
-const {
- syntax: { specificity },
-} = require('csso');
-const {
- visitSkip,
- querySelectorAll,
- detachNodeFromParent,
-} = require('../lib/xast.js');
-const { compareSpecificity, includesAttrSelector } = require('../lib/style');
-const { attrsGroups, pseudoClasses } = require('./_collections');
-
-exports.name = 'inlineStyles';
-exports.description = 'inline styles (additional options)';
-
-/**
- * Some pseudo-classes can only be calculated by clients, like :visited,
- * :future, or :hover, but there are other pseudo-classes that we can evaluate
- * during optimization.
- *
- * The list of pseudo-classes that we can evaluate during optimization, and so
- * shouldn't be toggled conditionally through the `usePseudos` parameter.
- *
- * @see https://developer.mozilla.org/docs/Web/CSS/Pseudo-classes
- */
-const preservedPseudos = [
- ...pseudoClasses.functional,
- ...pseudoClasses.treeStructural,
-];
-
-/**
- * Merges styles from style nodes into inline styles.
- *
- * @type {import('./plugins-types').Plugin<'inlineStyles'>}
- * @author strarsis <strarsis@gmail.com>
- */
-exports.fn = (root, params) => {
- const {
- onlyMatchedOnce = true,
- removeMatchedSelectors = true,
- useMqs = ['', 'screen'],
- usePseudos = [''],
- } = params;
-
- /**
- * @type {{ node: XastElement, parentNode: XastParent, cssAst: csstree.StyleSheet }[]}
- */
- const styles = [];
- /**
- * @type {{
- * node: csstree.Selector,
- * item: csstree.ListItem<csstree.CssNode>,
- * rule: csstree.Rule,
- * matchedElements?: XastElement[]
- * }[]}
- */
- let selectors = [];
-
- return {
- element: {
- enter: (node, parentNode) => {
- if (node.name === 'foreignObject') {
- return visitSkip;
- }
- if (node.name !== 'style' || node.children.length === 0) {
- return;
- }
- if (
- node.attributes.type != null &&
- node.attributes.type !== '' &&
- node.attributes.type !== 'text/css'
- ) {
- return;
- }
-
- const cssText = node.children
- .filter((child) => child.type === 'text' || child.type === 'cdata')
- // @ts-ignore
- .map((child) => child.value)
- .join('');
-
- /** @type {?csstree.CssNode} */
- let cssAst = null;
- try {
- cssAst = csstree.parse(cssText, {
- parseValue: false,
- parseCustomProperty: false,
- });
- } catch {
- return;
- }
- if (cssAst.type === 'StyleSheet') {
- styles.push({ node, parentNode, cssAst });
- }
-
- // collect selectors
- csstree.walk(cssAst, {
- visit: 'Rule',
- enter(node) {
- const atrule = this.atrule;
-
- // skip media queries not included into useMqs param
- let mediaQuery = '';
- if (atrule != null) {
- mediaQuery = atrule.name;
- if (atrule.prelude != null) {
- mediaQuery += ` ${csstree.generate(atrule.prelude)}`;
- }
- }
- if (!useMqs.includes(mediaQuery)) {
- return;
- }
-
- if (node.prelude.type === 'SelectorList') {
- node.prelude.children.forEach((childNode, item) => {
- if (childNode.type === 'Selector') {
- /**
- * @type {{
- * item: csstree.ListItem<csstree.CssNode>,
- * list: csstree.List<csstree.CssNode>
- * }[]}
- */
- const pseudos = [];
-
- childNode.children.forEach(
- (grandchildNode, grandchildItem, grandchildList) => {
- const isPseudo =
- grandchildNode.type === 'PseudoClassSelector' ||
- grandchildNode.type === 'PseudoElementSelector';
-
- if (
- isPseudo &&
- !preservedPseudos.includes(grandchildNode.name)
- ) {
- pseudos.push({
- item: grandchildItem,
- list: grandchildList,
- });
- }
- },
- );
-
- const pseudoSelectors = csstree.generate({
- type: 'Selector',
- children: new csstree.List().fromArray(
- pseudos.map((pseudo) => pseudo.item.data),
- ),
- });
-
- if (usePseudos.includes(pseudoSelectors)) {
- for (const pseudo of pseudos) {
- pseudo.list.remove(pseudo.item);
- }
- }
-
- selectors.push({ node: childNode, rule: node, item: item });
- }
- });
- }
- },
- });
- },
- },
-
- root: {
- exit: () => {
- if (styles.length === 0) {
- return;
- }
- const sortedSelectors = selectors
- .slice()
- .sort((a, b) => {
- const aSpecificity = specificity(a.item.data);
- const bSpecificity = specificity(b.item.data);
- return compareSpecificity(aSpecificity, bSpecificity);
- })
- .reverse();
-
- for (const selector of sortedSelectors) {
- // match selectors
- const selectorText = csstree.generate(selector.item.data);
- /** @type {XastElement[]} */
- const matchedElements = [];
- try {
- for (const node of querySelectorAll(root, selectorText)) {
- if (node.type === 'element') {
- matchedElements.push(node);
- }
- }
- } catch (selectError) {
- continue;
- }
- // nothing selected
- if (matchedElements.length === 0) {
- continue;
- }
-
- // apply styles to matched elements
- // skip selectors that match more than once if option onlyMatchedOnce is enabled
- if (onlyMatchedOnce && matchedElements.length > 1) {
- continue;
- }
-
- // apply <style/> to matched elements
- for (const selectedEl of matchedElements) {
- const styleDeclarationList = csstree.parse(
- selectedEl.attributes.style ?? '',
- {
- context: 'declarationList',
- parseValue: false,
- },
- );
- if (styleDeclarationList.type !== 'DeclarationList') {
- continue;
- }
- const styleDeclarationItems = new Map();
-
- /** @type {csstree.ListItem<csstree.CssNode>} */
- let firstListItem;
-
- csstree.walk(styleDeclarationList, {
- visit: 'Declaration',
- enter(node, item) {
- if (firstListItem == null) {
- firstListItem = item;
- }
-
- styleDeclarationItems.set(node.property.toLowerCase(), item);
- },
- });
- // merge declarations
- csstree.walk(selector.rule, {
- visit: 'Declaration',
- enter(ruleDeclaration) {
- // existing inline styles have higher priority
- // no inline styles, external styles, external styles used
- // inline styles, external styles same priority as inline styles, inline styles used
- // inline styles, external styles higher priority than inline styles, external styles used
- const property = ruleDeclaration.property;
-
- if (
- attrsGroups.presentation.has(property) &&
- !selectors.some((selector) =>
- includesAttrSelector(selector.item, property),
- )
- ) {
- delete selectedEl.attributes[property];
- }
-
- const matchedItem = styleDeclarationItems.get(property);
- const ruleDeclarationItem =
- styleDeclarationList.children.createItem(ruleDeclaration);
- if (matchedItem == null) {
- styleDeclarationList.children.insert(
- ruleDeclarationItem,
- firstListItem,
- );
- } else if (
- matchedItem.data.important !== true &&
- ruleDeclaration.important === true
- ) {
- styleDeclarationList.children.replace(
- matchedItem,
- ruleDeclarationItem,
- );
- styleDeclarationItems.set(property, ruleDeclarationItem);
- }
- },
- });
-
- const newStyles = csstree.generate(styleDeclarationList);
- if (newStyles.length !== 0) {
- selectedEl.attributes.style = newStyles;
- }
- }
-
- if (
- removeMatchedSelectors &&
- matchedElements.length !== 0 &&
- selector.rule.prelude.type === 'SelectorList'
- ) {
- // clean up matching simple selectors if option removeMatchedSelectors is enabled
- selector.rule.prelude.children.remove(selector.item);
- }
- selector.matchedElements = matchedElements;
- }
-
- // no further processing required
- if (!removeMatchedSelectors) {
- return;
- }
-
- // clean up matched class + ID attribute values
- for (const selector of sortedSelectors) {
- if (selector.matchedElements == null) {
- continue;
- }
-
- if (onlyMatchedOnce && selector.matchedElements.length > 1) {
- // skip selectors that match more than once if option onlyMatchedOnce is enabled
- continue;
- }
-
- for (const selectedEl of selector.matchedElements) {
- // class
- const classList = new Set(
- selectedEl.attributes.class == null
- ? null
- : selectedEl.attributes.class.split(' '),
- );
-
- for (const child of selector.node.children) {
- if (
- child.type === 'ClassSelector' &&
- !selectors.some((selector) =>
- includesAttrSelector(
- selector.item,
- 'class',
- child.name,
- true,
- ),
- )
- ) {
- classList.delete(child.name);
- }
- }
-
- if (classList.size === 0) {
- delete selectedEl.attributes.class;
- } else {
- selectedEl.attributes.class = Array.from(classList).join(' ');
- }
-
- // ID
- const firstSubSelector = selector.node.children.first;
- if (
- firstSubSelector?.type === 'IdSelector' &&
- selectedEl.attributes.id === firstSubSelector.name &&
- !selectors.some((selector) =>
- includesAttrSelector(
- selector.item,
- 'id',
- firstSubSelector.name,
- true,
- ),
- )
- ) {
- delete selectedEl.attributes.id;
- }
- }
- }
-
- for (const style of styles) {
- csstree.walk(style.cssAst, {
- visit: 'Rule',
- enter: function (node, item, list) {
- // clean up <style/> rulesets without any css selectors left
- if (
- node.type === 'Rule' &&
- node.prelude.type === 'SelectorList' &&
- node.prelude.children.isEmpty
- ) {
- list.remove(item);
- }
- },
- });
-
- // csstree v2 changed this type
- if (style.cssAst.children.isEmpty) {
- // remove empty style element
- detachNodeFromParent(style.node, style.parentNode);
- } else {
- // update style element if any styles left
- const firstChild = style.node.children[0];
- if (firstChild.type === 'text' || firstChild.type === 'cdata') {
- firstChild.value = csstree.generate(style.cssAst);
- }
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/mergePaths.js b/node_modules/svgo/plugins/mergePaths.js
deleted file mode 100644
index fe982c13..00000000
--- a/node_modules/svgo/plugins/mergePaths.js
+++ /dev/null
@@ -1,148 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import("../lib/types").PathDataItem} PathDataItem
- * @typedef {import('../lib/types').XastChild} XastChild
- * @typedef {import('../lib/types').XastElement} XastElement
- */
-
-const { collectStylesheet, computeStyle } = require('../lib/style.js');
-const { path2js, js2path, intersects } = require('./_path.js');
-
-exports.name = 'mergePaths';
-exports.description = 'merges multiple paths in one if possible';
-
-/**
- * Merge multiple Paths into one.
- *
- * @author Kir Belevich, Lev Solntsev
- *
- * @type {import('./plugins-types').Plugin<'mergePaths'>}
- */
-exports.fn = (root, params) => {
- const {
- force = false,
- floatPrecision,
- noSpaceAfterFlags = false, // a20 60 45 0 1 30 20 → a20 60 45 0130 20
- } = params;
- const stylesheet = collectStylesheet(root);
-
- return {
- element: {
- enter: (node) => {
- if (node.children.length <= 1) {
- return;
- }
-
- /** @type {XastChild[]} */
- const elementsToRemove = [];
- let prevChild = node.children[0];
- let prevPathData = null;
-
- /**
- * @param {XastElement} child
- * @param {PathDataItem[]} pathData
- */
- const updatePreviousPath = (child, pathData) => {
- js2path(child, pathData, {
- floatPrecision,
- noSpaceAfterFlags,
- });
- prevPathData = null;
- };
-
- for (let i = 1; i < node.children.length; i++) {
- const child = node.children[i];
-
- if (
- prevChild.type !== 'element' ||
- prevChild.name !== 'path' ||
- prevChild.children.length !== 0 ||
- prevChild.attributes.d == null
- ) {
- if (prevPathData && prevChild.type === 'element') {
- updatePreviousPath(prevChild, prevPathData);
- }
- prevChild = child;
- continue;
- }
-
- if (
- child.type !== 'element' ||
- child.name !== 'path' ||
- child.children.length !== 0 ||
- child.attributes.d == null
- ) {
- if (prevPathData) {
- updatePreviousPath(prevChild, prevPathData);
- }
- prevChild = child;
- continue;
- }
-
- const computedStyle = computeStyle(stylesheet, child);
- if (
- computedStyle['marker-start'] ||
- computedStyle['marker-mid'] ||
- computedStyle['marker-end']
- ) {
- if (prevPathData) {
- updatePreviousPath(prevChild, prevPathData);
- }
- prevChild = child;
- continue;
- }
- const childAttrs = Object.keys(child.attributes);
- if (childAttrs.length !== Object.keys(prevChild.attributes).length) {
- if (prevPathData) {
- updatePreviousPath(prevChild, prevPathData);
- }
- prevChild = child;
- continue;
- }
-
- const areAttrsEqual = childAttrs.some((attr) => {
- return (
- attr !== 'd' &&
- prevChild.type === 'element' &&
- prevChild.attributes[attr] !== child.attributes[attr]
- );
- });
-
- if (areAttrsEqual) {
- if (prevPathData) {
- updatePreviousPath(prevChild, prevPathData);
- }
- prevChild = child;
- continue;
- }
-
- const hasPrevPath = prevPathData != null;
- const currentPathData = path2js(child);
- prevPathData = prevPathData ?? path2js(prevChild);
-
- if (force || !intersects(prevPathData, currentPathData)) {
- prevPathData.push(...currentPathData);
- elementsToRemove.push(child);
- continue;
- }
-
- if (hasPrevPath) {
- updatePreviousPath(prevChild, prevPathData);
- }
-
- prevChild = child;
- prevPathData = null;
- }
-
- if (prevPathData && prevChild.type === 'element') {
- updatePreviousPath(prevChild, prevPathData);
- }
-
- node.children = node.children.filter(
- (child) => !elementsToRemove.includes(child),
- );
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/mergeStyles.js b/node_modules/svgo/plugins/mergeStyles.js
deleted file mode 100644
index 764d0194..00000000
--- a/node_modules/svgo/plugins/mergeStyles.js
+++ /dev/null
@@ -1,98 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types').XastElement} XastElement
- * @typedef {import('../lib/types').XastChild} XastChild
- */
-
-const { visitSkip, detachNodeFromParent } = require('../lib/xast.js');
-
-exports.name = 'mergeStyles';
-exports.description = 'merge multiple style elements into one';
-
-/**
- * Merge multiple style elements into one.
- *
- * @author strarsis <strarsis@gmail.com>
- *
- * @type {import('./plugins-types').Plugin<'mergeStyles'>}
- */
-exports.fn = () => {
- /**
- * @type {?XastElement}
- */
- let firstStyleElement = null;
- let collectedStyles = '';
- /**
- * @type {'text' | 'cdata'}
- */
- let styleContentType = 'text';
-
- return {
- element: {
- enter: (node, parentNode) => {
- // skip <foreignObject> content
- if (node.name === 'foreignObject') {
- return visitSkip;
- }
-
- // collect style elements
- if (node.name !== 'style') {
- return;
- }
-
- // skip <style> with invalid type attribute
- if (
- node.attributes.type != null &&
- node.attributes.type !== '' &&
- node.attributes.type !== 'text/css'
- ) {
- return;
- }
-
- // extract style element content
- let css = '';
- for (const child of node.children) {
- if (child.type === 'text') {
- css += child.value;
- }
- if (child.type === 'cdata') {
- styleContentType = 'cdata';
- css += child.value;
- }
- }
-
- // remove empty style elements
- if (css.trim().length === 0) {
- detachNodeFromParent(node, parentNode);
- return;
- }
-
- // collect css and wrap with media query if present in attribute
- if (node.attributes.media == null) {
- collectedStyles += css;
- } else {
- collectedStyles += `@media ${node.attributes.media}{${css}}`;
- delete node.attributes.media;
- }
-
- // combine collected styles in the first style element
- if (firstStyleElement == null) {
- firstStyleElement = node;
- } else {
- detachNodeFromParent(node, parentNode);
- /**
- * @type {XastChild}
- */
- const child = { type: styleContentType, value: collectedStyles };
- // TODO remove legacy parentNode in v4
- Object.defineProperty(child, 'parentNode', {
- writable: true,
- value: firstStyleElement,
- });
- firstStyleElement.children = [child];
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/minifyStyles.js b/node_modules/svgo/plugins/minifyStyles.js
deleted file mode 100644
index ade441b3..00000000
--- a/node_modules/svgo/plugins/minifyStyles.js
+++ /dev/null
@@ -1,141 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types').XastElement} XastElement
- * @typedef {import('../lib/types').XastParent} XastParent
- */
-
-const csso = require('csso');
-const { detachNodeFromParent } = require('../lib/xast');
-const { hasScripts } = require('../lib/svgo/tools');
-
-exports.name = 'minifyStyles';
-exports.description = 'minifies styles and removes unused styles';
-
-/**
- * Minifies styles (<style> element + style attribute) using CSSO.
- *
- * @author strarsis <strarsis@gmail.com>
- * @type {import('./plugins-types').Plugin<'minifyStyles'>}
- */
-exports.fn = (_root, { usage, ...params }) => {
- /** @type {Map<XastElement, XastParent>} */
- const styleElements = new Map();
-
- /** @type {XastElement[]} */
- const elementsWithStyleAttributes = [];
-
- /** @type {Set<string>} */
- const tagsUsage = new Set();
-
- /** @type {Set<string>} */
- const idsUsage = new Set();
-
- /** @type {Set<string>} */
- const classesUsage = new Set();
-
- let enableTagsUsage = true;
- let enableIdsUsage = true;
- let enableClassesUsage = true;
-
- /**
- * Force to use usage data even if it unsafe. For example, the document
- * contains scripts or in attributes..
- */
- let forceUsageDeoptimized = false;
-
- if (typeof usage === 'boolean') {
- enableTagsUsage = usage;
- enableIdsUsage = usage;
- enableClassesUsage = usage;
- } else if (usage) {
- enableTagsUsage = usage.tags == null ? true : usage.tags;
- enableIdsUsage = usage.ids == null ? true : usage.ids;
- enableClassesUsage = usage.classes == null ? true : usage.classes;
- forceUsageDeoptimized = usage.force == null ? false : usage.force;
- }
-
- let deoptimized = false;
-
- return {
- element: {
- enter: (node, parentNode) => {
- // detect deoptimisations
- if (hasScripts(node)) {
- deoptimized = true;
- }
-
- // collect tags, ids and classes usage
- tagsUsage.add(node.name);
- if (node.attributes.id != null) {
- idsUsage.add(node.attributes.id);
- }
- if (node.attributes.class != null) {
- for (const className of node.attributes.class.split(/\s+/)) {
- classesUsage.add(className);
- }
- }
- // collect style elements or elements with style attribute
- if (node.name === 'style' && node.children.length !== 0) {
- styleElements.set(node, parentNode);
- } else if (node.attributes.style != null) {
- elementsWithStyleAttributes.push(node);
- }
- },
- },
-
- root: {
- exit: () => {
- /** @type {csso.Usage} */
- const cssoUsage = {};
- if (!deoptimized || forceUsageDeoptimized) {
- if (enableTagsUsage) {
- cssoUsage.tags = Array.from(tagsUsage);
- }
- if (enableIdsUsage) {
- cssoUsage.ids = Array.from(idsUsage);
- }
- if (enableClassesUsage) {
- cssoUsage.classes = Array.from(classesUsage);
- }
- }
- // minify style elements
- for (const [styleNode, styleNodeParent] of styleElements.entries()) {
- if (
- styleNode.children[0].type === 'text' ||
- styleNode.children[0].type === 'cdata'
- ) {
- const cssText = styleNode.children[0].value;
- const minified = csso.minify(cssText, {
- ...params,
- usage: cssoUsage,
- }).css;
-
- if (minified.length === 0) {
- detachNodeFromParent(styleNode, styleNodeParent);
- continue;
- }
-
- // preserve cdata if necessary
- // TODO split cdata -> text optimisation into separate plugin
- if (cssText.indexOf('>') >= 0 || cssText.indexOf('<') >= 0) {
- styleNode.children[0].type = 'cdata';
- styleNode.children[0].value = minified;
- } else {
- styleNode.children[0].type = 'text';
- styleNode.children[0].value = minified;
- }
- }
- }
- // minify style attributes
- for (const node of elementsWithStyleAttributes) {
- // style attribute
- const elemStyle = node.attributes.style;
- node.attributes.style = csso.minifyBlock(elemStyle, {
- ...params,
- }).css;
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/moveElemsAttrsToGroup.js b/node_modules/svgo/plugins/moveElemsAttrsToGroup.js
deleted file mode 100644
index 633f4439..00000000
--- a/node_modules/svgo/plugins/moveElemsAttrsToGroup.js
+++ /dev/null
@@ -1,128 +0,0 @@
-'use strict';
-
-const { visit } = require('../lib/xast.js');
-const { inheritableAttrs, pathElems } = require('./_collections.js');
-
-exports.name = 'moveElemsAttrsToGroup';
-exports.description = 'Move common attributes of group children to the group';
-
-/**
- * Move common attributes of group children to the group
- *
- * @example
- * <g attr1="val1">
- * <g attr2="val2">
- * text
- * </g>
- * <circle attr2="val2" attr3="val3"/>
- * </g>
- * ⬇
- * <g attr1="val1" attr2="val2">
- * <g>
- * text
- * </g>
- * <circle attr3="val3"/>
- * </g>
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'moveElemsAttrsToGroup'>}
- */
-exports.fn = (root) => {
- // find if any style element is present
- let deoptimizedWithStyles = false;
- visit(root, {
- element: {
- enter: (node) => {
- if (node.name === 'style') {
- deoptimizedWithStyles = true;
- }
- },
- },
- });
-
- return {
- element: {
- exit: (node) => {
- // process only groups with more than 1 children
- if (node.name !== 'g' || node.children.length <= 1) {
- return;
- }
-
- // deoptimize the plugin when style elements are present
- // selectors may rely on id, classes or tag names
- if (deoptimizedWithStyles) {
- return;
- }
-
- /**
- * find common attributes in group children
- * @type {Map<string, string>}
- */
- const commonAttributes = new Map();
- let initial = true;
- let everyChildIsPath = true;
- for (const child of node.children) {
- if (child.type === 'element') {
- if (!pathElems.has(child.name)) {
- everyChildIsPath = false;
- }
- if (initial) {
- initial = false;
- // collect all inheritable attributes from first child element
- for (const [name, value] of Object.entries(child.attributes)) {
- // consider only inheritable attributes
- if (inheritableAttrs.has(name)) {
- commonAttributes.set(name, value);
- }
- }
- } else {
- // exclude uncommon attributes from initial list
- for (const [name, value] of commonAttributes) {
- if (child.attributes[name] !== value) {
- commonAttributes.delete(name);
- }
- }
- }
- }
- }
-
- // preserve transform on children when group has clip-path or mask
- if (
- node.attributes['clip-path'] != null ||
- node.attributes.mask != null
- ) {
- commonAttributes.delete('transform');
- }
-
- // preserve transform when all children are paths
- // so the transform could be applied to path data by other plugins
- if (everyChildIsPath) {
- commonAttributes.delete('transform');
- }
-
- // add common children attributes to group
- for (const [name, value] of commonAttributes) {
- if (name === 'transform') {
- if (node.attributes.transform != null) {
- node.attributes.transform = `${node.attributes.transform} ${value}`;
- } else {
- node.attributes.transform = value;
- }
- } else {
- node.attributes[name] = value;
- }
- }
-
- // delete common attributes from children
- for (const child of node.children) {
- if (child.type === 'element') {
- for (const [name] of commonAttributes) {
- delete child.attributes[name];
- }
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/moveGroupAttrsToElems.js b/node_modules/svgo/plugins/moveGroupAttrsToElems.js
deleted file mode 100644
index 450fb265..00000000
--- a/node_modules/svgo/plugins/moveGroupAttrsToElems.js
+++ /dev/null
@@ -1,65 +0,0 @@
-'use strict';
-
-const { pathElems, referencesProps } = require('./_collections.js');
-const { includesUrlReference } = require('../lib/svgo/tools.js');
-
-exports.name = 'moveGroupAttrsToElems';
-exports.description = 'moves some group attributes to the content elements';
-
-const pathElemsWithGroupsAndText = [...pathElems, 'g', 'text'];
-
-/**
- * Move group attrs to the content elements.
- *
- * @example
- * <g transform="scale(2)">
- * <path transform="rotate(45)" d="M0,0 L10,20"/>
- * <path transform="translate(10, 20)" d="M0,10 L20,30"/>
- * </g>
- * ⬇
- * <g>
- * <path transform="scale(2) rotate(45)" d="M0,0 L10,20"/>
- * <path transform="scale(2) translate(10, 20)" d="M0,10 L20,30"/>
- * </g>
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'moveGroupAttrsToElems'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node) => {
- // move group transform attr to content's pathElems
- if (
- node.name === 'g' &&
- node.children.length !== 0 &&
- node.attributes.transform != null &&
- Object.entries(node.attributes).some(
- ([name, value]) =>
- referencesProps.has(name) && includesUrlReference(value),
- ) === false &&
- node.children.every(
- (child) =>
- child.type === 'element' &&
- pathElemsWithGroupsAndText.includes(child.name) &&
- child.attributes.id == null,
- )
- ) {
- for (const child of node.children) {
- const value = node.attributes.transform;
- if (child.type === 'element') {
- if (child.attributes.transform != null) {
- child.attributes.transform = `${value} ${child.attributes.transform}`;
- } else {
- child.attributes.transform = value;
- }
- }
- }
-
- delete node.attributes.transform;
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/plugins-types.d.ts b/node_modules/svgo/plugins/plugins-types.d.ts
deleted file mode 100644
index e94e7137..00000000
--- a/node_modules/svgo/plugins/plugins-types.d.ts
+++ /dev/null
@@ -1,291 +0,0 @@
-import type {
- Plugin as PluginDef,
- PluginInfo,
- XastElement,
-} from '../lib/types';
-
-type DefaultPlugins = {
- cleanupAttrs: {
- newlines?: boolean;
- trim?: boolean;
- spaces?: boolean;
- };
- cleanupEnableBackground: void;
- cleanupIds: {
- remove?: boolean;
- minify?: boolean;
- preserve?: string[];
- preservePrefixes?: string[];
- force?: boolean;
- };
- cleanupNumericValues: {
- floatPrecision?: number;
- leadingZero?: boolean;
- defaultPx?: boolean;
- convertToPx?: boolean;
- };
- collapseGroups: void;
- convertColors: {
- currentColor?: boolean | string | RegExp;
- names2hex?: boolean;
- rgb2hex?: boolean;
- shorthex?: boolean;
- shortname?: boolean;
- };
- convertEllipseToCircle: void;
- convertPathData: {
- applyTransforms?: boolean;
- applyTransformsStroked?: boolean;
- makeArcs?: {
- threshold: number;
- tolerance: number;
- };
- straightCurves?: boolean;
- convertToQ?: boolean;
- lineShorthands?: boolean;
- convertToZ?: boolean;
- curveSmoothShorthands?: boolean;
- floatPrecision?: number | false;
- transformPrecision?: number;
- smartArcRounding?: boolean;
- removeUseless?: boolean;
- collapseRepeated?: boolean;
- utilizeAbsolute?: boolean;
- leadingZero?: boolean;
- negativeExtraSpace?: boolean;
- noSpaceAfterFlags?: boolean;
- forceAbsolutePath?: boolean;
- };
- convertShapeToPath: {
- convertArcs?: boolean;
- floatPrecision?: number;
- };
- convertTransform: {
- convertToShorts?: boolean;
- degPrecision?: number;
- floatPrecision?: number;
- transformPrecision?: number;
- matrixToTransform?: boolean;
- shortTranslate?: boolean;
- shortScale?: boolean;
- shortRotate?: boolean;
- removeUseless?: boolean;
- collapseIntoOne?: boolean;
- leadingZero?: boolean;
- negativeExtraSpace?: boolean;
- };
- mergeStyles: void;
- inlineStyles: {
- /**
- * Inlines selectors that match once only.
- *
- * @default true
- */
- onlyMatchedOnce?: boolean;
- /**
- * Clean up matched selectors. Unused selects are left as-is.
- *
- * @default true
- */
- removeMatchedSelectors?: boolean;
- /**
- * Media queries to use. An empty string indicates all selectors outside of
- * media queries.
- */
- useMqs?: string[];
- /**
- * Pseudo-classes and elements to use. An empty string indicates all
- * all non-pseudo-classes and elements.
- */
- usePseudos?: string[];
- };
- mergePaths: {
- force?: boolean;
- floatPrecision?: number;
- noSpaceAfterFlags?: boolean;
- };
-
- minifyStyles: {
- /**
- * Disable or enable a structure optimisations.
- * @default true
- */
- restructure?: boolean;
- /**
- * Enables merging of @media rules with the same media query split by other rules.
- * The optimisation is unsafe in general, but should work fine in most cases. Use it on your own risk.
- * @default false
- */
- forceMediaMerge?: boolean;
- /**
- * Specify what comments to leave:
- * - 'exclamation' or true – leave all exclamation comments
- * - 'first-exclamation' – remove every comment except first one
- * - false – remove all comments
- * @default true
- */
- comments?: string | boolean;
- /**
- * Advanced optimizations
- */
- usage?:
- | boolean
- | {
- force?: boolean;
- ids?: boolean;
- classes?: boolean;
- tags?: boolean;
- };
- };
-
- moveElemsAttrsToGroup: void;
- moveGroupAttrsToElems: void;
- removeComments: {
- preservePatterns: Array<RegExp | string> | false;
- };
- removeDesc: {
- removeAny?: boolean;
- };
- removeDoctype: void;
- removeEditorsNSData: {
- additionalNamespaces?: string[];
- };
- removeEmptyAttrs: void;
- removeEmptyContainers: void;
- removeEmptyText: {
- text?: boolean;
- tspan?: boolean;
- tref?: boolean;
- };
- removeHiddenElems: {
- isHidden?: boolean;
- displayNone?: boolean;
- opacity0?: boolean;
- circleR0?: boolean;
- ellipseRX0?: boolean;
- ellipseRY0?: boolean;
- rectWidth0?: boolean;
- rectHeight0?: boolean;
- patternWidth0?: boolean;
- patternHeight0?: boolean;
- imageWidth0?: boolean;
- imageHeight0?: boolean;
- pathEmptyD?: boolean;
- polylineEmptyPoints?: boolean;
- polygonEmptyPoints?: boolean;
- };
- removeMetadata: void;
- removeNonInheritableGroupAttrs: void;
- removeTitle: void;
- removeUnknownsAndDefaults: {
- unknownContent?: boolean;
- unknownAttrs?: boolean;
- defaultAttrs?: boolean;
- /**
- * If to remove XML declarations that are assigned their default value. XML
- * declarations are the properties in the `<?xml … ?>` block at the top of
- * the document.
- */
- defaultMarkupDeclarations?: boolean;
- uselessOverrides?: boolean;
- keepDataAttrs?: boolean;
- keepAriaAttrs?: boolean;
- keepRoleAttr?: boolean;
- };
- removeUnusedNS: void;
- removeUselessDefs: void;
- removeUselessStrokeAndFill: {
- stroke?: boolean;
- fill?: boolean;
- removeNone?: boolean;
- };
- removeViewBox: void;
- removeXMLProcInst: void;
- sortAttrs: {
- order?: string[];
- xmlnsOrder?: 'front' | 'alphabetical';
- };
- sortDefsChildren: void;
-};
-
-type PresetDefaultOverrides = {
- [Name in keyof DefaultPlugins]?: DefaultPlugins[Name] | false;
-};
-
-export type BuiltinsWithOptionalParams = DefaultPlugins & {
- 'preset-default': {
- floatPrecision?: number;
- /**
- * All default plugins can be customized or disabled here
- * for example
- * {
- * sortAttrs: { xmlnsOrder: "alphabetical" },
- * cleanupAttrs: false,
- * }
- */
- overrides?: PresetDefaultOverrides;
- };
- cleanupListOfValues: {
- floatPrecision?: number;
- leadingZero?: boolean;
- defaultPx?: boolean;
- convertToPx?: boolean;
- };
- convertOneStopGradients: void;
- convertStyleToAttrs: {
- keepImportant?: boolean;
- };
- prefixIds: {
- prefix?:
- | boolean
- | string
- | ((node: XastElement, info: PluginInfo) => string);
- delim?: string;
- prefixIds?: boolean;
- prefixClassNames?: boolean;
- };
- removeDimensions: void;
- removeOffCanvasPaths: void;
- removeRasterImages: void;
- removeScriptElement: void;
- removeStyleElement: void;
- removeXlink: {
- /**
- * By default this plugin ignores legacy elements that were deprecated or
- * removed in SVG 2. Set to true to force performing operations on those
- * too.
- *
- * @default false
- */
- includeLegacy: boolean;
- };
- removeXMLNS: void;
- reusePaths: void;
-};
-
-export type BuiltinsWithRequiredParams = {
- addAttributesToSVGElement: {
- attribute?: string | Record<string, null | string>;
- attributes?: Array<string | Record<string, null | string>>;
- };
- addClassesToSVGElement: {
- className?: string;
- classNames?: string[];
- };
- removeAttributesBySelector: any;
- removeAttrs: {
- elemSeparator?: string;
- preserveCurrentColor?: boolean;
- attrs: string | string[];
- };
- removeElementsByAttr: {
- id?: string | string[];
- class?: string | string[];
- };
-};
-
-type PluginsParams = BuiltinsWithOptionalParams & BuiltinsWithRequiredParams;
-
-export type Plugin<Name extends keyof PluginsParams> = PluginDef<
- PluginsParams[Name]
->;
diff --git a/node_modules/svgo/plugins/prefixIds.js b/node_modules/svgo/plugins/prefixIds.js
deleted file mode 100644
index ec305c6b..00000000
--- a/node_modules/svgo/plugins/prefixIds.js
+++ /dev/null
@@ -1,268 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types.js').PluginInfo} PluginInfo
- * @typedef {import('../lib/types').XastElement} XastElement
- */
-
-const csstree = require('css-tree');
-const { referencesProps } = require('./_collections.js');
-
-exports.name = 'prefixIds';
-exports.description = 'prefix IDs';
-
-/**
- * extract basename from path
- * @type {(path: string) => string}
- */
-const getBasename = (path) => {
- // extract everything after latest slash or backslash
- const matched = /[/\\]?([^/\\]+)$/.exec(path);
- if (matched) {
- return matched[1];
- }
- return '';
-};
-
-/**
- * escapes a string for being used as ID
- * @type {(string: string) => string}
- */
-const escapeIdentifierName = (str) => {
- return str.replace(/[. ]/g, '_');
-};
-
-/**
- * @type {(string: string) => string}
- */
-const unquote = (string) => {
- if (
- (string.startsWith('"') && string.endsWith('"')) ||
- (string.startsWith("'") && string.endsWith("'"))
- ) {
- return string.slice(1, -1);
- }
- return string;
-};
-
-/**
- * Prefix the given string, unless it already starts with the generated prefix.
- *
- * @param {(id: string) => string} prefixGenerator Function to generate a prefix.
- * @param {string} body An arbitrary string.
- * @returns {string} The given string with a prefix prepended to it.
- */
-const prefixId = (prefixGenerator, body) => {
- const prefix = prefixGenerator(body);
- if (body.startsWith(prefix)) {
- return body;
- }
- return prefix + body;
-};
-
-/**
- * Insert the prefix in a reference string. A reference string is already
- * prefixed with #, so the prefix is inserted after the first character.
- *
- * @param {(id: string) => string} prefixGenerator Function to generate a prefix.
- * @param {string} reference An arbitrary string, should start with "#".
- * @returns {?string} The given string with a prefix inserted, or null if the string did not start with "#".
- */
-const prefixReference = (prefixGenerator, reference) => {
- if (reference.startsWith('#')) {
- return '#' + prefixId(prefixGenerator, reference.slice(1));
- }
- return null;
-};
-
-/**
- * Generates a prefix for the given string.
- *
- * @param {string} body An arbitrary string.
- * @param {XastElement} node XML node that the identifier belongs to.
- * @param {PluginInfo} info
- * @param {((node: XastElement, info: PluginInfo) => string)|string|boolean|undefined} prefixGenerator Some way of obtaining a prefix.
- * @param {string} delim Content to insert between the prefix and original value.
- * @param {Map<string, string>} history Map of previously generated prefixes to IDs.
- * @returns {string} A generated prefix.
- */
-const generatePrefix = (body, node, info, prefixGenerator, delim, history) => {
- if (typeof prefixGenerator === 'function') {
- let prefix = history.get(body);
-
- if (prefix != null) {
- return prefix;
- }
-
- prefix = prefixGenerator(node, info) + delim;
- history.set(body, prefix);
- return prefix;
- }
-
- if (typeof prefixGenerator === 'string') {
- return prefixGenerator + delim;
- }
-
- if (prefixGenerator === false) {
- return '';
- }
-
- if (info.path != null && info.path.length > 0) {
- return escapeIdentifierName(getBasename(info.path)) + delim;
- }
-
- return 'prefix' + delim;
-};
-
-/**
- * Prefixes identifiers
- *
- * @author strarsis <strarsis@gmail.com>
- * @type {import('./plugins-types').Plugin<'prefixIds'>}
- */
-exports.fn = (_root, params, info) => {
- const {
- delim = '__',
- prefix,
- prefixIds = true,
- prefixClassNames = true,
- } = params;
-
- /** @type {Map<string, string>} */
- const prefixMap = new Map();
-
- return {
- element: {
- enter: (node) => {
- /**
- * @param {string} id A node identifier or class.
- * @returns {string} Given string with a prefix inserted, or null if the string did not start with "#".
- */
- const prefixGenerator = (id) =>
- generatePrefix(id, node, info, prefix, delim, prefixMap);
-
- // prefix id/class selectors and url() references in styles
- if (node.name === 'style') {
- // skip empty <style/> elements
- if (node.children.length === 0) {
- return;
- }
-
- for (const child of node.children) {
- if (child.type !== 'text' && child.type !== 'cdata') {
- continue;
- }
-
- const cssText = child.value;
- /** @type {?csstree.CssNode} */
- let cssAst = null;
- try {
- cssAst = csstree.parse(cssText, {
- parseValue: true,
- parseCustomProperty: false,
- });
- } catch {
- return;
- }
-
- csstree.walk(cssAst, (node) => {
- if (
- (prefixIds && node.type === 'IdSelector') ||
- (prefixClassNames && node.type === 'ClassSelector')
- ) {
- node.name = prefixId(prefixGenerator, node.name);
- return;
- }
- if (node.type === 'Url' && node.value.length > 0) {
- const prefixed = prefixReference(
- prefixGenerator,
- unquote(node.value),
- );
- if (prefixed != null) {
- node.value = prefixed;
- }
- }
- });
-
- child.value = csstree.generate(cssAst);
- return;
- }
- }
-
- // prefix an ID attribute value
- if (
- prefixIds &&
- node.attributes.id != null &&
- node.attributes.id.length !== 0
- ) {
- node.attributes.id = prefixId(prefixGenerator, node.attributes.id);
- }
-
- // prefix a class attribute value
- if (
- prefixClassNames &&
- node.attributes.class != null &&
- node.attributes.class.length !== 0
- ) {
- node.attributes.class = node.attributes.class
- .split(/\s+/)
- .map((name) => prefixId(prefixGenerator, name))
- .join(' ');
- }
-
- // prefix a href attribute value
- // xlink:href is deprecated, must be still supported
- for (const name of ['href', 'xlink:href']) {
- if (
- node.attributes[name] != null &&
- node.attributes[name].length !== 0
- ) {
- const prefixed = prefixReference(
- prefixGenerator,
- node.attributes[name],
- );
- if (prefixed != null) {
- node.attributes[name] = prefixed;
- }
- }
- }
-
- // prefix a URL attribute value
- for (const name of referencesProps) {
- if (
- node.attributes[name] != null &&
- node.attributes[name].length !== 0
- ) {
- node.attributes[name] = node.attributes[name].replace(
- /\burl\((["'])?(#.+?)\1\)/gi,
- (match, _, url) => {
- const prefixed = prefixReference(prefixGenerator, url);
- if (prefixed == null) {
- return match;
- }
- return `url(${prefixed})`;
- },
- );
- }
- }
-
- // prefix begin/end attribute value
- for (const name of ['begin', 'end']) {
- if (
- node.attributes[name] != null &&
- node.attributes[name].length !== 0
- ) {
- const parts = node.attributes[name].split(/\s*;\s+/).map((val) => {
- if (val.endsWith('.end') || val.endsWith('.start')) {
- const [id, postfix] = val.split('.');
- return `${prefixId(prefixGenerator, id)}.${postfix}`;
- }
- return val;
- });
- node.attributes[name] = parts.join('; ');
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/preset-default.js b/node_modules/svgo/plugins/preset-default.js
deleted file mode 100644
index 86516fd7..00000000
--- a/node_modules/svgo/plugins/preset-default.js
+++ /dev/null
@@ -1,82 +0,0 @@
-'use strict';
-
-const { createPreset } = require('../lib/svgo/plugins.js');
-
-const removeDoctype = require('./removeDoctype.js');
-const removeXMLProcInst = require('./removeXMLProcInst.js');
-const removeComments = require('./removeComments.js');
-const removeMetadata = require('./removeMetadata.js');
-const removeEditorsNSData = require('./removeEditorsNSData.js');
-const cleanupAttrs = require('./cleanupAttrs.js');
-const mergeStyles = require('./mergeStyles.js');
-const inlineStyles = require('./inlineStyles.js');
-const minifyStyles = require('./minifyStyles.js');
-const cleanupIds = require('./cleanupIds.js');
-const removeUselessDefs = require('./removeUselessDefs.js');
-const cleanupNumericValues = require('./cleanupNumericValues.js');
-const convertColors = require('./convertColors.js');
-const removeUnknownsAndDefaults = require('./removeUnknownsAndDefaults.js');
-const removeNonInheritableGroupAttrs = require('./removeNonInheritableGroupAttrs.js');
-const removeUselessStrokeAndFill = require('./removeUselessStrokeAndFill.js');
-const removeViewBox = require('./removeViewBox.js');
-const cleanupEnableBackground = require('./cleanupEnableBackground.js');
-const removeHiddenElems = require('./removeHiddenElems.js');
-const removeEmptyText = require('./removeEmptyText.js');
-const convertShapeToPath = require('./convertShapeToPath.js');
-const convertEllipseToCircle = require('./convertEllipseToCircle.js');
-const moveElemsAttrsToGroup = require('./moveElemsAttrsToGroup.js');
-const moveGroupAttrsToElems = require('./moveGroupAttrsToElems.js');
-const collapseGroups = require('./collapseGroups.js');
-const convertPathData = require('./convertPathData.js');
-const convertTransform = require('./convertTransform.js');
-const removeEmptyAttrs = require('./removeEmptyAttrs.js');
-const removeEmptyContainers = require('./removeEmptyContainers.js');
-const mergePaths = require('./mergePaths.js');
-const removeUnusedNS = require('./removeUnusedNS.js');
-const sortAttrs = require('./sortAttrs.js');
-const sortDefsChildren = require('./sortDefsChildren.js');
-const removeTitle = require('./removeTitle.js');
-const removeDesc = require('./removeDesc.js');
-
-const presetDefault = createPreset({
- name: 'preset-default',
- plugins: [
- removeDoctype,
- removeXMLProcInst,
- removeComments,
- removeMetadata,
- removeEditorsNSData,
- cleanupAttrs,
- mergeStyles,
- inlineStyles,
- minifyStyles,
- cleanupIds,
- removeUselessDefs,
- cleanupNumericValues,
- convertColors,
- removeUnknownsAndDefaults,
- removeNonInheritableGroupAttrs,
- removeUselessStrokeAndFill,
- removeViewBox,
- cleanupEnableBackground,
- removeHiddenElems,
- removeEmptyText,
- convertShapeToPath,
- convertEllipseToCircle,
- moveElemsAttrsToGroup,
- moveGroupAttrsToElems,
- collapseGroups,
- convertPathData,
- convertTransform,
- removeEmptyAttrs,
- removeEmptyContainers,
- mergePaths,
- removeUnusedNS,
- sortAttrs,
- sortDefsChildren,
- removeTitle,
- removeDesc,
- ],
-});
-
-module.exports = presetDefault;
diff --git a/node_modules/svgo/plugins/removeAttributesBySelector.js b/node_modules/svgo/plugins/removeAttributesBySelector.js
deleted file mode 100644
index 12630c2a..00000000
--- a/node_modules/svgo/plugins/removeAttributesBySelector.js
+++ /dev/null
@@ -1,97 +0,0 @@
-'use strict';
-
-const { querySelectorAll } = require('../lib/xast.js');
-
-exports.name = 'removeAttributesBySelector';
-exports.description =
- 'removes attributes of elements that match a css selector';
-
-/**
- * Removes attributes of elements that match a css selector.
- *
- * @example
- * <caption>A selector removing a single attribute</caption>
- * plugins: [
- * {
- * name: "removeAttributesBySelector",
- * params: {
- * selector: "[fill='#00ff00']"
- * attributes: "fill"
- * }
- * }
- * ]
- *
- * <rect x="0" y="0" width="100" height="100" fill="#00ff00" stroke="#00ff00"/>
- * ↓
- * <rect x="0" y="0" width="100" height="100" stroke="#00ff00"/>
- *
- * <caption>A selector removing multiple attributes</caption>
- * plugins: [
- * {
- * name: "removeAttributesBySelector",
- * params: {
- * selector: "[fill='#00ff00']",
- * attributes: [
- * "fill",
- * "stroke"
- * ]
- * }
- * }
- * ]
- *
- * <rect x="0" y="0" width="100" height="100" fill="#00ff00" stroke="#00ff00"/>
- * ↓
- * <rect x="0" y="0" width="100" height="100"/>
- *
- * <caption>Multiple selectors removing attributes</caption>
- * plugins: [
- * {
- * name: "removeAttributesBySelector",
- * params: {
- * selectors: [
- * {
- * selector: "[fill='#00ff00']",
- * attributes: "fill"
- * },
- * {
- * selector: "#remove",
- * attributes: [
- * "stroke",
- * "id"
- * ]
- * }
- * ]
- * }
- * }
- * ]
- *
- * <rect x="0" y="0" width="100" height="100" fill="#00ff00" stroke="#00ff00"/>
- * ↓
- * <rect x="0" y="0" width="100" height="100"/>
- *
- * @link https://developer.mozilla.org/docs/Web/CSS/CSS_Selectors|MDN CSS Selectors
- *
- * @author Bradley Mease
- *
- * @type {import('./plugins-types').Plugin<'removeAttributesBySelector'>}
- */
-exports.fn = (root, params) => {
- const selectors = Array.isArray(params.selectors)
- ? params.selectors
- : [params];
- for (const { selector, attributes } of selectors) {
- const nodes = querySelectorAll(root, selector);
- for (const node of nodes) {
- if (node.type === 'element') {
- if (Array.isArray(attributes)) {
- for (const name of attributes) {
- delete node.attributes[name];
- }
- } else {
- delete node.attributes[attributes];
- }
- }
- }
- }
- return {};
-};
diff --git a/node_modules/svgo/plugins/removeAttrs.js b/node_modules/svgo/plugins/removeAttrs.js
deleted file mode 100644
index dc1224bd..00000000
--- a/node_modules/svgo/plugins/removeAttrs.js
+++ /dev/null
@@ -1,151 +0,0 @@
-'use strict';
-
-exports.name = 'removeAttrs';
-exports.description = 'removes specified attributes';
-
-const DEFAULT_SEPARATOR = ':';
-const ENOATTRS = `Warning: The plugin "removeAttrs" requires the "attrs" parameter.
-It should have a pattern to remove, otherwise the plugin is a noop.
-Config example:
-
-plugins: [
- {
- name: "removeAttrs",
- params: {
- attrs: "(fill|stroke)"
- }
- }
-]
-`;
-
-/**
- * Remove attributes
- *
- * @example elemSeparator
- * format: string
- *
- * @example preserveCurrentColor
- * format: boolean
- *
- * @example attrs:
- *
- * format: [ element* : attribute* : value* ]
- *
- * element : regexp (wrapped into ^...$), single * or omitted > all elements (must be present when value is used)
- * attribute : regexp (wrapped into ^...$)
- * value : regexp (wrapped into ^...$), single * or omitted > all values
- *
- * examples:
- *
- * > basic: remove fill attribute
- * ---
- * removeAttrs:
- * attrs: 'fill'
- *
- * > remove fill attribute on path element
- * ---
- * attrs: 'path:fill'
- *
- * > remove fill attribute on path element where value is none
- * ---
- * attrs: 'path:fill:none'
- *
- *
- * > remove all fill and stroke attribute
- * ---
- * attrs:
- * - 'fill'
- * - 'stroke'
- *
- * [is same as]
- *
- * attrs: '(fill|stroke)'
- *
- * [is same as]
- *
- * attrs: '*:(fill|stroke)'
- *
- * [is same as]
- *
- * attrs: '.*:(fill|stroke)'
- *
- * [is same as]
- *
- * attrs: '.*:(fill|stroke):.*'
- *
- *
- * > remove all stroke related attributes
- * ----
- * attrs: 'stroke.*'
- *
- *
- * @author Benny Schudel
- *
- * @type {import('./plugins-types').Plugin<'removeAttrs'>}
- */
-exports.fn = (root, params) => {
- if (typeof params.attrs == 'undefined') {
- console.warn(ENOATTRS);
- return null;
- }
-
- const elemSeparator =
- typeof params.elemSeparator == 'string'
- ? params.elemSeparator
- : DEFAULT_SEPARATOR;
- const preserveCurrentColor =
- typeof params.preserveCurrentColor == 'boolean'
- ? params.preserveCurrentColor
- : false;
- const attrs = Array.isArray(params.attrs) ? params.attrs : [params.attrs];
-
- return {
- element: {
- enter: (node) => {
- for (let pattern of attrs) {
- // if no element separators (:), assume it's attribute name, and apply to all elements *regardless of value*
- if (!pattern.includes(elemSeparator)) {
- pattern = ['.*', pattern, '.*'].join(elemSeparator);
- // if only 1 separator, assume it's element and attribute name, and apply regardless of attribute value
- } else if (pattern.split(elemSeparator).length < 3) {
- pattern = [pattern, '.*'].join(elemSeparator);
- }
-
- // create regexps for element, attribute name, and attribute value
- const list = pattern.split(elemSeparator).map((value) => {
- // adjust single * to match anything
- if (value === '*') {
- value = '.*';
- }
- return new RegExp(['^', value, '$'].join(''), 'i');
- });
-
- // matches element
- if (list[0].test(node.name)) {
- // loop attributes
- for (const [name, value] of Object.entries(node.attributes)) {
- const isFillCurrentColor =
- preserveCurrentColor &&
- name == 'fill' &&
- value == 'currentColor';
- const isStrokeCurrentColor =
- preserveCurrentColor &&
- name == 'stroke' &&
- value == 'currentColor';
- if (
- !isFillCurrentColor &&
- !isStrokeCurrentColor &&
- // matches attribute name
- list[1].test(name) &&
- // matches attribute value
- list[2].test(value)
- ) {
- delete node.attributes[name];
- }
- }
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeComments.js b/node_modules/svgo/plugins/removeComments.js
deleted file mode 100644
index 46a32590..00000000
--- a/node_modules/svgo/plugins/removeComments.js
+++ /dev/null
@@ -1,51 +0,0 @@
-'use strict';
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-
-exports.name = 'removeComments';
-exports.description = 'removes comments';
-
-/**
- * If a comment matches one of the following patterns, it will be
- * preserved by default. Particularly for copyright/license information.
- */
-const DEFAULT_PRESERVE_PATTERNS = [/^!/];
-
-/**
- * Remove comments.
- *
- * @example
- * <!-- Generator: Adobe Illustrator 15.0.0, SVG Export
- * Plug-In . SVG Version: 6.00 Build 0) -->
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeComments'>}
- */
-exports.fn = (_root, params) => {
- const { preservePatterns = DEFAULT_PRESERVE_PATTERNS } = params;
-
- return {
- comment: {
- enter: (node, parentNode) => {
- if (preservePatterns) {
- if (!Array.isArray(preservePatterns)) {
- throw Error(
- `Expected array in removeComments preservePatterns parameter but received ${preservePatterns}`,
- );
- }
-
- const matches = preservePatterns.some((pattern) => {
- return new RegExp(pattern).test(node.value);
- });
-
- if (matches) {
- return;
- }
- }
-
- detachNodeFromParent(node, parentNode);
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeDesc.js b/node_modules/svgo/plugins/removeDesc.js
deleted file mode 100644
index f766350e..00000000
--- a/node_modules/svgo/plugins/removeDesc.js
+++ /dev/null
@@ -1,39 +0,0 @@
-'use strict';
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-
-exports.name = 'removeDesc';
-exports.description = 'removes <desc>';
-
-const standardDescs = /^(Created with|Created using)/;
-
-/**
- * Removes <desc>.
- * Removes only standard editors content or empty elements 'cause it can be used for accessibility.
- * Enable parameter 'removeAny' to remove any description.
- *
- * https://developer.mozilla.org/docs/Web/SVG/Element/desc
- *
- * @author Daniel Wabyick
- *
- * @type {import('./plugins-types').Plugin<'removeDesc'>}
- */
-exports.fn = (root, params) => {
- const { removeAny = false } = params;
- return {
- element: {
- enter: (node, parentNode) => {
- if (node.name === 'desc') {
- if (
- removeAny ||
- node.children.length === 0 ||
- (node.children[0].type === 'text' &&
- standardDescs.test(node.children[0].value))
- ) {
- detachNodeFromParent(node, parentNode);
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeDimensions.js b/node_modules/svgo/plugins/removeDimensions.js
deleted file mode 100644
index 4f4f3984..00000000
--- a/node_modules/svgo/plugins/removeDimensions.js
+++ /dev/null
@@ -1,43 +0,0 @@
-'use strict';
-
-exports.name = 'removeDimensions';
-exports.description =
- 'removes width and height in presence of viewBox (opposite to removeViewBox, disable it first)';
-
-/**
- * Remove width/height attributes and add the viewBox attribute if it's missing
- *
- * @example
- * <svg width="100" height="50" />
- * ↓
- * <svg viewBox="0 0 100 50" />
- *
- * @author Benny Schudel
- *
- * @type {import('./plugins-types').Plugin<'removeDimensions'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node) => {
- if (node.name === 'svg') {
- if (node.attributes.viewBox != null) {
- delete node.attributes.width;
- delete node.attributes.height;
- } else if (
- node.attributes.width != null &&
- node.attributes.height != null &&
- Number.isNaN(Number(node.attributes.width)) === false &&
- Number.isNaN(Number(node.attributes.height)) === false
- ) {
- const width = Number(node.attributes.width);
- const height = Number(node.attributes.height);
- node.attributes.viewBox = `0 0 ${width} ${height}`;
- delete node.attributes.width;
- delete node.attributes.height;
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeDoctype.js b/node_modules/svgo/plugins/removeDoctype.js
deleted file mode 100644
index cbdcd013..00000000
--- a/node_modules/svgo/plugins/removeDoctype.js
+++ /dev/null
@@ -1,40 +0,0 @@
-'use strict';
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-
-exports.name = 'removeDoctype';
-exports.description = 'removes doctype declaration';
-
-/**
- * Remove DOCTYPE declaration.
- *
- * "Unfortunately the SVG DTDs are a source of so many
- * issues that the SVG WG has decided not to write one
- * for the upcoming SVG 1.2 standard. In fact SVG WG
- * members are even telling people not to use a DOCTYPE
- * declaration in SVG 1.0 and 1.1 documents"
- * https://jwatt.org/svg/authoring/#doctype-declaration
- *
- * @example
- * <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- * q"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
- *
- * @example
- * <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- * "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [
- * <!-- an internal subset can be embedded here -->
- * ]>
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeDoctype'>}
- */
-exports.fn = () => {
- return {
- doctype: {
- enter: (node, parentNode) => {
- detachNodeFromParent(node, parentNode);
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeEditorsNSData.js b/node_modules/svgo/plugins/removeEditorsNSData.js
deleted file mode 100644
index 852681bf..00000000
--- a/node_modules/svgo/plugins/removeEditorsNSData.js
+++ /dev/null
@@ -1,64 +0,0 @@
-'use strict';
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-const { editorNamespaces } = require('./_collections.js');
-
-exports.name = 'removeEditorsNSData';
-exports.description = 'removes editors namespaces, elements and attributes';
-
-/**
- * Remove editors namespaces, elements and attributes.
- *
- * @example
- * <svg xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd">
- * <sodipodi:namedview/>
- * <path sodipodi:nodetypes="cccc"/>
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeEditorsNSData'>}
- */
-exports.fn = (_root, params) => {
- let namespaces = [...editorNamespaces];
- if (Array.isArray(params.additionalNamespaces)) {
- namespaces = [...editorNamespaces, ...params.additionalNamespaces];
- }
- /**
- * @type {string[]}
- */
- const prefixes = [];
- return {
- element: {
- enter: (node, parentNode) => {
- // collect namespace prefixes from svg element
- if (node.name === 'svg') {
- for (const [name, value] of Object.entries(node.attributes)) {
- if (name.startsWith('xmlns:') && namespaces.includes(value)) {
- prefixes.push(name.slice('xmlns:'.length));
- // <svg xmlns:sodipodi="">
- delete node.attributes[name];
- }
- }
- }
- // remove editor attributes, for example
- // <* sodipodi:*="">
- for (const name of Object.keys(node.attributes)) {
- if (name.includes(':')) {
- const [prefix] = name.split(':');
- if (prefixes.includes(prefix)) {
- delete node.attributes[name];
- }
- }
- }
- // remove editor elements, for example
- // <sodipodi:*>
- if (node.name.includes(':')) {
- const [prefix] = node.name.split(':');
- if (prefixes.includes(prefix)) {
- detachNodeFromParent(node, parentNode);
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeElementsByAttr.js b/node_modules/svgo/plugins/removeElementsByAttr.js
deleted file mode 100644
index 9c9915f0..00000000
--- a/node_modules/svgo/plugins/removeElementsByAttr.js
+++ /dev/null
@@ -1,73 +0,0 @@
-'use strict';
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-
-exports.name = 'removeElementsByAttr';
-exports.description =
- 'removes arbitrary elements by ID or className (disabled by default)';
-
-/**
- * Remove arbitrary SVG elements by ID or className.
- *
- * @example id
- * > single: remove element with ID of `elementID`
- * ---
- * removeElementsByAttr:
- * id: 'elementID'
- *
- * > list: remove multiple elements by ID
- * ---
- * removeElementsByAttr:
- * id:
- * - 'elementID'
- * - 'anotherID'
- *
- * @example class
- * > single: remove all elements with class of `elementClass`
- * ---
- * removeElementsByAttr:
- * class: 'elementClass'
- *
- * > list: remove all elements with class of `elementClass` or `anotherClass`
- * ---
- * removeElementsByAttr:
- * class:
- * - 'elementClass'
- * - 'anotherClass'
- *
- * @author Eli Dupuis (@elidupuis)
- *
- * @type {import('./plugins-types').Plugin<'removeElementsByAttr'>}
- */
-exports.fn = (root, params) => {
- const ids =
- params.id == null ? [] : Array.isArray(params.id) ? params.id : [params.id];
- const classes =
- params.class == null
- ? []
- : Array.isArray(params.class)
- ? params.class
- : [params.class];
- return {
- element: {
- enter: (node, parentNode) => {
- // remove element if it's `id` matches configured `id` params
- if (node.attributes.id != null && ids.length !== 0) {
- if (ids.includes(node.attributes.id)) {
- detachNodeFromParent(node, parentNode);
- }
- }
- // remove element if it's `class` contains any of the configured `class` params
- if (node.attributes.class && classes.length !== 0) {
- const classList = node.attributes.class.split(' ');
- for (const item of classes) {
- if (classList.includes(item)) {
- detachNodeFromParent(node, parentNode);
- break;
- }
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeEmptyAttrs.js b/node_modules/svgo/plugins/removeEmptyAttrs.js
deleted file mode 100644
index 194d27b8..00000000
--- a/node_modules/svgo/plugins/removeEmptyAttrs.js
+++ /dev/null
@@ -1,31 +0,0 @@
-'use strict';
-
-const { attrsGroups } = require('./_collections.js');
-
-exports.name = 'removeEmptyAttrs';
-exports.description = 'removes empty attributes';
-
-/**
- * Remove attributes with empty values.
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeEmptyAttrs'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node) => {
- for (const [name, value] of Object.entries(node.attributes)) {
- if (
- value === '' &&
- // empty conditional processing attributes prevents elements from rendering
- !attrsGroups.conditionalProcessing.has(name)
- ) {
- delete node.attributes[name];
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeEmptyContainers.js b/node_modules/svgo/plugins/removeEmptyContainers.js
deleted file mode 100644
index 03907344..00000000
--- a/node_modules/svgo/plugins/removeEmptyContainers.js
+++ /dev/null
@@ -1,59 +0,0 @@
-'use strict';
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-const { elemsGroups } = require('./_collections.js');
-
-exports.name = 'removeEmptyContainers';
-exports.description = 'removes empty container elements';
-
-/**
- * Remove empty containers.
- *
- * @see https://www.w3.org/TR/SVG11/intro.html#TermContainerElement
- *
- * @example
- * <defs/>
- *
- * @example
- * <g><marker><a/></marker></g>
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeEmptyContainers'>}
- */
-exports.fn = () => {
- return {
- element: {
- exit: (node, parentNode) => {
- // remove only empty non-svg containers
- if (
- node.name === 'svg' ||
- !elemsGroups.container.has(node.name) ||
- node.children.length !== 0
- ) {
- return;
- }
- // empty patterns may contain reusable configuration
- if (
- node.name === 'pattern' &&
- Object.keys(node.attributes).length !== 0
- ) {
- return;
- }
- // The <g> may not have content, but the filter may cause a rectangle
- // to be created and filled with pattern.
- if (node.name === 'g' && node.attributes.filter != null) {
- return;
- }
- // empty <mask> hides masked element
- if (node.name === 'mask' && node.attributes.id != null) {
- return;
- }
- if (parentNode.type === 'element' && parentNode.name === 'switch') {
- return;
- }
- detachNodeFromParent(node, parentNode);
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeEmptyText.js b/node_modules/svgo/plugins/removeEmptyText.js
deleted file mode 100644
index 5f6db3d3..00000000
--- a/node_modules/svgo/plugins/removeEmptyText.js
+++ /dev/null
@@ -1,51 +0,0 @@
-'use strict';
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-
-exports.name = 'removeEmptyText';
-exports.description = 'removes empty <text> elements';
-
-/**
- * Remove empty Text elements.
- *
- * @see https://www.w3.org/TR/SVG11/text.html
- *
- * @example
- * Remove empty text element:
- * <text/>
- *
- * Remove empty tspan element:
- * <tspan/>
- *
- * Remove tref with empty xlink:href attribute:
- * <tref xlink:href=""/>
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeEmptyText'>}
- */
-exports.fn = (root, params) => {
- const { text = true, tspan = true, tref = true } = params;
- return {
- element: {
- enter: (node, parentNode) => {
- // Remove empty text element
- if (text && node.name === 'text' && node.children.length === 0) {
- detachNodeFromParent(node, parentNode);
- }
- // Remove empty tspan element
- if (tspan && node.name === 'tspan' && node.children.length === 0) {
- detachNodeFromParent(node, parentNode);
- }
- // Remove tref with empty xlink:href attribute
- if (
- tref &&
- node.name === 'tref' &&
- node.attributes['xlink:href'] == null
- ) {
- detachNodeFromParent(node, parentNode);
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeHiddenElems.js b/node_modules/svgo/plugins/removeHiddenElems.js
deleted file mode 100644
index 75720a06..00000000
--- a/node_modules/svgo/plugins/removeHiddenElems.js
+++ /dev/null
@@ -1,440 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types').XastChild} XastChild
- * @typedef {import('../lib/types').XastElement} XastElement
- * @typedef {import('../lib/types').XastParent} XastParent
- */
-
-const { elemsGroups } = require('./_collections.js');
-const {
- visit,
- visitSkip,
- querySelector,
- detachNodeFromParent,
-} = require('../lib/xast.js');
-const { collectStylesheet, computeStyle } = require('../lib/style.js');
-const { parsePathData } = require('../lib/path.js');
-const { hasScripts, findReferences } = require('../lib/svgo/tools.js');
-
-const nonRendering = elemsGroups.nonRendering;
-
-exports.name = 'removeHiddenElems';
-exports.description =
- 'removes hidden elements (zero sized, with absent attributes)';
-
-/**
- * Remove hidden elements with disabled rendering:
- * - display="none"
- * - opacity="0"
- * - circle with zero radius
- * - ellipse with zero x-axis or y-axis radius
- * - rectangle with zero width or height
- * - pattern with zero width or height
- * - image with zero width or height
- * - path with empty data
- * - polyline with empty points
- * - polygon with empty points
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeHiddenElems'>}
- */
-exports.fn = (root, params) => {
- const {
- isHidden = true,
- displayNone = true,
- opacity0 = true,
- circleR0 = true,
- ellipseRX0 = true,
- ellipseRY0 = true,
- rectWidth0 = true,
- rectHeight0 = true,
- patternWidth0 = true,
- patternHeight0 = true,
- imageWidth0 = true,
- imageHeight0 = true,
- pathEmptyD = true,
- polylineEmptyPoints = true,
- polygonEmptyPoints = true,
- } = params;
- const stylesheet = collectStylesheet(root);
-
- /**
- * Skip non-rendered nodes initially, and only detach if they have no ID, or
- * their ID is not referenced by another node.
- *
- * @type {Map<XastElement, XastParent>}
- */
- const nonRenderedNodes = new Map();
-
- /**
- * IDs for removed hidden definitions.
- *
- * @type {Set<string>}
- */
- const removedDefIds = new Set();
-
- /**
- * @type {Map<XastElement, XastParent>}
- */
- const allDefs = new Map();
-
- /** @type {Set<string>} */
- const allReferences = new Set();
-
- /**
- * @type {Map<string, Array<{ node: XastElement, parentNode: XastParent }>>}
- */
- const referencesById = new Map();
-
- /**
- * If styles are present, we can't be sure if a definition is unused or not
- */
- let deoptimized = false;
-
- /**
- * @param {XastChild} node
- * @param {XastParent} parentNode
- */
- function removeElement(node, parentNode) {
- if (
- node.type === 'element' &&
- node.attributes.id != null &&
- parentNode.type === 'element' &&
- parentNode.name === 'defs'
- ) {
- removedDefIds.add(node.attributes.id);
- }
-
- detachNodeFromParent(node, parentNode);
- }
-
- visit(root, {
- element: {
- enter: (node, parentNode) => {
- // transparent non-rendering elements still apply where referenced
- if (nonRendering.has(node.name)) {
- if (node.attributes.id == null) {
- detachNodeFromParent(node, parentNode);
- return visitSkip;
- }
-
- nonRenderedNodes.set(node, parentNode);
- return visitSkip;
- }
- const computedStyle = computeStyle(stylesheet, node);
- // opacity="0"
- //
- // https://www.w3.org/TR/SVG11/masking.html#ObjectAndGroupOpacityProperties
- if (
- opacity0 &&
- computedStyle.opacity &&
- computedStyle.opacity.type === 'static' &&
- computedStyle.opacity.value === '0'
- ) {
- removeElement(node, parentNode);
- }
- },
- },
- });
-
- return {
- element: {
- enter: (node, parentNode) => {
- if (
- (node.name === 'style' && node.children.length !== 0) ||
- hasScripts(node)
- ) {
- deoptimized = true;
- return;
- }
-
- if (node.name === 'defs') {
- allDefs.set(node, parentNode);
- }
-
- if (node.name === 'use') {
- for (const attr of Object.keys(node.attributes)) {
- if (attr !== 'href' && !attr.endsWith(':href')) continue;
- const value = node.attributes[attr];
- const id = value.slice(1);
-
- let refs = referencesById.get(id);
- if (!refs) {
- refs = [];
- referencesById.set(id, refs);
- }
- refs.push({ node, parentNode });
- }
- }
-
- // Removes hidden elements
- // https://www.w3schools.com/cssref/pr_class_visibility.asp
- const computedStyle = computeStyle(stylesheet, node);
- if (
- isHidden &&
- computedStyle.visibility &&
- computedStyle.visibility.type === 'static' &&
- computedStyle.visibility.value === 'hidden' &&
- // keep if any descendant enables visibility
- querySelector(node, '[visibility=visible]') == null
- ) {
- removeElement(node, parentNode);
- return;
- }
-
- // display="none"
- //
- // https://www.w3.org/TR/SVG11/painting.html#DisplayProperty
- // "A value of display: none indicates that the given element
- // and its children shall not be rendered directly"
- if (
- displayNone &&
- computedStyle.display &&
- computedStyle.display.type === 'static' &&
- computedStyle.display.value === 'none' &&
- // markers with display: none still rendered
- node.name !== 'marker'
- ) {
- removeElement(node, parentNode);
- return;
- }
-
- // Circles with zero radius
- //
- // https://www.w3.org/TR/SVG11/shapes.html#CircleElementRAttribute
- // "A value of zero disables rendering of the element"
- //
- // <circle r="0">
- if (
- circleR0 &&
- node.name === 'circle' &&
- node.children.length === 0 &&
- node.attributes.r === '0'
- ) {
- removeElement(node, parentNode);
- return;
- }
-
- // Ellipse with zero x-axis radius
- //
- // https://www.w3.org/TR/SVG11/shapes.html#EllipseElementRXAttribute
- // "A value of zero disables rendering of the element"
- //
- // <ellipse rx="0">
- if (
- ellipseRX0 &&
- node.name === 'ellipse' &&
- node.children.length === 0 &&
- node.attributes.rx === '0'
- ) {
- removeElement(node, parentNode);
- return;
- }
-
- // Ellipse with zero y-axis radius
- //
- // https://www.w3.org/TR/SVG11/shapes.html#EllipseElementRYAttribute
- // "A value of zero disables rendering of the element"
- //
- // <ellipse ry="0">
- if (
- ellipseRY0 &&
- node.name === 'ellipse' &&
- node.children.length === 0 &&
- node.attributes.ry === '0'
- ) {
- removeElement(node, parentNode);
- return;
- }
-
- // Rectangle with zero width
- //
- // https://www.w3.org/TR/SVG11/shapes.html#RectElementWidthAttribute
- // "A value of zero disables rendering of the element"
- //
- // <rect width="0">
- if (
- rectWidth0 &&
- node.name === 'rect' &&
- node.children.length === 0 &&
- node.attributes.width === '0'
- ) {
- removeElement(node, parentNode);
- return;
- }
-
- // Rectangle with zero height
- //
- // https://www.w3.org/TR/SVG11/shapes.html#RectElementHeightAttribute
- // "A value of zero disables rendering of the element"
- //
- // <rect height="0">
- if (
- rectHeight0 &&
- rectWidth0 &&
- node.name === 'rect' &&
- node.children.length === 0 &&
- node.attributes.height === '0'
- ) {
- removeElement(node, parentNode);
- return;
- }
-
- // Pattern with zero width
- //
- // https://www.w3.org/TR/SVG11/pservers.html#PatternElementWidthAttribute
- // "A value of zero disables rendering of the element (i.e., no paint is applied)"
- //
- // <pattern width="0">
- if (
- patternWidth0 &&
- node.name === 'pattern' &&
- node.attributes.width === '0'
- ) {
- removeElement(node, parentNode);
- return;
- }
-
- // Pattern with zero height
- //
- // https://www.w3.org/TR/SVG11/pservers.html#PatternElementHeightAttribute
- // "A value of zero disables rendering of the element (i.e., no paint is applied)"
- //
- // <pattern height="0">
- if (
- patternHeight0 &&
- node.name === 'pattern' &&
- node.attributes.height === '0'
- ) {
- removeElement(node, parentNode);
- return;
- }
-
- // Image with zero width
- //
- // https://www.w3.org/TR/SVG11/struct.html#ImageElementWidthAttribute
- // "A value of zero disables rendering of the element"
- //
- // <image width="0">
- if (
- imageWidth0 &&
- node.name === 'image' &&
- node.attributes.width === '0'
- ) {
- removeElement(node, parentNode);
- return;
- }
-
- // Image with zero height
- //
- // https://www.w3.org/TR/SVG11/struct.html#ImageElementHeightAttribute
- // "A value of zero disables rendering of the element"
- //
- // <image height="0">
- if (
- imageHeight0 &&
- node.name === 'image' &&
- node.attributes.height === '0'
- ) {
- removeElement(node, parentNode);
- return;
- }
-
- // Path with empty data
- //
- // https://www.w3.org/TR/SVG11/paths.html#DAttribute
- //
- // <path d=""/>
- if (pathEmptyD && node.name === 'path') {
- if (node.attributes.d == null) {
- removeElement(node, parentNode);
- return;
- }
- const pathData = parsePathData(node.attributes.d);
- if (pathData.length === 0) {
- removeElement(node, parentNode);
- return;
- }
- // keep single point paths for markers
- if (
- pathData.length === 1 &&
- computedStyle['marker-start'] == null &&
- computedStyle['marker-end'] == null
- ) {
- removeElement(node, parentNode);
- return;
- }
- }
-
- // Polyline with empty points
- //
- // https://www.w3.org/TR/SVG11/shapes.html#PolylineElementPointsAttribute
- //
- // <polyline points="">
- if (
- polylineEmptyPoints &&
- node.name === 'polyline' &&
- node.attributes.points == null
- ) {
- removeElement(node, parentNode);
- return;
- }
-
- // Polygon with empty points
- //
- // https://www.w3.org/TR/SVG11/shapes.html#PolygonElementPointsAttribute
- //
- // <polygon points="">
- if (
- polygonEmptyPoints &&
- node.name === 'polygon' &&
- node.attributes.points == null
- ) {
- removeElement(node, parentNode);
- return;
- }
-
- for (const [name, value] of Object.entries(node.attributes)) {
- const ids = findReferences(name, value);
-
- for (const id of ids) {
- allReferences.add(id);
- }
- }
- },
- },
- root: {
- exit: () => {
- for (const id of removedDefIds) {
- const refs = referencesById.get(id);
- if (refs) {
- for (const { node, parentNode } of refs) {
- detachNodeFromParent(node, parentNode);
- }
- }
- }
-
- if (!deoptimized) {
- for (const [
- nonRenderedNode,
- nonRenderedParent,
- ] of nonRenderedNodes.entries()) {
- const id = nonRenderedNode.attributes.id;
-
- if (!allReferences.has(id)) {
- detachNodeFromParent(nonRenderedNode, nonRenderedParent);
- }
- }
- }
-
- for (const [node, parentNode] of allDefs.entries()) {
- if (node.children.length === 0) {
- detachNodeFromParent(node, parentNode);
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeMetadata.js b/node_modules/svgo/plugins/removeMetadata.js
deleted file mode 100644
index 8c9de27e..00000000
--- a/node_modules/svgo/plugins/removeMetadata.js
+++ /dev/null
@@ -1,27 +0,0 @@
-'use strict';
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-
-exports.name = 'removeMetadata';
-exports.description = 'removes <metadata>';
-
-/**
- * Remove <metadata>.
- *
- * https://www.w3.org/TR/SVG11/metadata.html
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeMetadata'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node, parentNode) => {
- if (node.name === 'metadata') {
- detachNodeFromParent(node, parentNode);
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeNonInheritableGroupAttrs.js b/node_modules/svgo/plugins/removeNonInheritableGroupAttrs.js
deleted file mode 100644
index 73e6bcda..00000000
--- a/node_modules/svgo/plugins/removeNonInheritableGroupAttrs.js
+++ /dev/null
@@ -1,38 +0,0 @@
-'use strict';
-
-const {
- inheritableAttrs,
- attrsGroups,
- presentationNonInheritableGroupAttrs,
-} = require('./_collections');
-
-exports.name = 'removeNonInheritableGroupAttrs';
-exports.description =
- 'removes non-inheritable group’s presentational attributes';
-
-/**
- * Remove non-inheritable group's "presentation" attributes.
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeNonInheritableGroupAttrs'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node) => {
- if (node.name === 'g') {
- for (const name of Object.keys(node.attributes)) {
- if (
- attrsGroups.presentation.has(name) &&
- !inheritableAttrs.has(name) &&
- !presentationNonInheritableGroupAttrs.has(name)
- ) {
- delete node.attributes[name];
- }
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeOffCanvasPaths.js b/node_modules/svgo/plugins/removeOffCanvasPaths.js
deleted file mode 100644
index 60a69fb1..00000000
--- a/node_modules/svgo/plugins/removeOffCanvasPaths.js
+++ /dev/null
@@ -1,136 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types').PathDataItem} PathDataItem
- */
-
-const { visitSkip, detachNodeFromParent } = require('../lib/xast.js');
-const { parsePathData } = require('../lib/path.js');
-const { intersects } = require('./_path.js');
-
-exports.name = 'removeOffCanvasPaths';
-exports.description =
- 'removes elements that are drawn outside of the viewbox (disabled by default)';
-
-/**
- * Remove elements that are drawn outside of the viewbox.
- *
- * @author JoshyPHP
- *
- * @type {import('./plugins-types').Plugin<'removeOffCanvasPaths'>}
- */
-exports.fn = () => {
- /**
- * @type {?{
- * top: number,
- * right: number,
- * bottom: number,
- * left: number,
- * width: number,
- * height: number
- * }}
- */
- let viewBoxData = null;
-
- return {
- element: {
- enter: (node, parentNode) => {
- if (node.name === 'svg' && parentNode.type === 'root') {
- let viewBox = '';
- // find viewbox
- if (node.attributes.viewBox != null) {
- // remove commas and plus signs, normalize and trim whitespace
- viewBox = node.attributes.viewBox;
- } else if (
- node.attributes.height != null &&
- node.attributes.width != null
- ) {
- viewBox = `0 0 ${node.attributes.width} ${node.attributes.height}`;
- }
-
- // parse viewbox
- // remove commas and plus signs, normalize and trim whitespace
- viewBox = viewBox
- .replace(/[,+]|px/g, ' ')
- .replace(/\s+/g, ' ')
- .replace(/^\s*|\s*$/g, '');
- // ensure that the dimensions are 4 values separated by space
- const m =
- /^(-?\d*\.?\d+) (-?\d*\.?\d+) (\d*\.?\d+) (\d*\.?\d+)$/.exec(
- viewBox,
- );
- if (m == null) {
- return;
- }
- const left = Number.parseFloat(m[1]);
- const top = Number.parseFloat(m[2]);
- const width = Number.parseFloat(m[3]);
- const height = Number.parseFloat(m[4]);
-
- // store the viewBox boundaries
- viewBoxData = {
- left,
- top,
- right: left + width,
- bottom: top + height,
- width,
- height,
- };
- }
-
- // consider that any item with a transform attribute is visible
- if (node.attributes.transform != null) {
- return visitSkip;
- }
-
- if (
- node.name === 'path' &&
- node.attributes.d != null &&
- viewBoxData != null
- ) {
- const pathData = parsePathData(node.attributes.d);
-
- // consider that a M command within the viewBox is visible
- let visible = false;
- for (const pathDataItem of pathData) {
- if (pathDataItem.command === 'M') {
- const [x, y] = pathDataItem.args;
- if (
- x >= viewBoxData.left &&
- x <= viewBoxData.right &&
- y >= viewBoxData.top &&
- y <= viewBoxData.bottom
- ) {
- visible = true;
- }
- }
- }
- if (visible) {
- return;
- }
-
- if (pathData.length === 2) {
- // close the path too short for intersects()
- pathData.push({ command: 'z', args: [] });
- }
-
- const { left, top, width, height } = viewBoxData;
- /**
- * @type {PathDataItem[]}
- */
- const viewBoxPathData = [
- { command: 'M', args: [left, top] },
- { command: 'h', args: [width] },
- { command: 'v', args: [height] },
- { command: 'H', args: [left] },
- { command: 'z', args: [] },
- ];
-
- if (intersects(viewBoxPathData, pathData) === false) {
- detachNodeFromParent(node, parentNode);
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeRasterImages.js b/node_modules/svgo/plugins/removeRasterImages.js
deleted file mode 100644
index 1a4a4a12..00000000
--- a/node_modules/svgo/plugins/removeRasterImages.js
+++ /dev/null
@@ -1,31 +0,0 @@
-'use strict';
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-
-exports.name = 'removeRasterImages';
-exports.description = 'removes raster images (disabled by default)';
-
-/**
- * Remove raster images references in <image>.
- *
- * @see https://bugs.webkit.org/show_bug.cgi?id=63548
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeRasterImages'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node, parentNode) => {
- if (
- node.name === 'image' &&
- node.attributes['xlink:href'] != null &&
- /(\.|image\/)(jpe?g|png|gif)/.test(node.attributes['xlink:href'])
- ) {
- detachNodeFromParent(node, parentNode);
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeScriptElement.js b/node_modules/svgo/plugins/removeScriptElement.js
deleted file mode 100644
index 80fcea3b..00000000
--- a/node_modules/svgo/plugins/removeScriptElement.js
+++ /dev/null
@@ -1,70 +0,0 @@
-'use strict';
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-const { attrsGroups } = require('./_collections.js');
-
-exports.name = 'removeScriptElement';
-exports.description = 'removes scripts (disabled by default)';
-
-/** Union of all event attributes. */
-const eventAttrs = [
- ...attrsGroups.animationEvent,
- ...attrsGroups.documentEvent,
- ...attrsGroups.documentElementEvent,
- ...attrsGroups.globalEvent,
- ...attrsGroups.graphicalEvent,
-];
-
-/**
- * Remove scripts.
- *
- * https://www.w3.org/TR/SVG11/script.html
- *
- * @author Patrick Klingemann
- * @type {import('./plugins-types').Plugin<'removeScriptElement'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node, parentNode) => {
- if (node.name === 'script') {
- detachNodeFromParent(node, parentNode);
- return;
- }
-
- for (const attr of eventAttrs) {
- if (node.attributes[attr] != null) {
- delete node.attributes[attr];
- }
- }
- },
- exit: (node, parentNode) => {
- if (node.name !== 'a') {
- return;
- }
-
- for (const attr of Object.keys(node.attributes)) {
- if (attr === 'href' || attr.endsWith(':href')) {
- if (
- node.attributes[attr] == null ||
- !node.attributes[attr].trimStart().startsWith('javascript:')
- ) {
- continue;
- }
-
- const index = parentNode.children.indexOf(node);
- parentNode.children.splice(index, 1, ...node.children);
-
- // TODO remove legacy parentNode in v4
- for (const child of node.children) {
- Object.defineProperty(child, 'parentNode', {
- writable: true,
- value: parentNode,
- });
- }
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeStyleElement.js b/node_modules/svgo/plugins/removeStyleElement.js
deleted file mode 100644
index d869a50a..00000000
--- a/node_modules/svgo/plugins/removeStyleElement.js
+++ /dev/null
@@ -1,27 +0,0 @@
-'use strict';
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-
-exports.name = 'removeStyleElement';
-exports.description = 'removes <style> element (disabled by default)';
-
-/**
- * Remove <style>.
- *
- * https://www.w3.org/TR/SVG11/styling.html#StyleElement
- *
- * @author Betsy Dupuis
- *
- * @type {import('./plugins-types').Plugin<'removeStyleElement'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node, parentNode) => {
- if (node.name === 'style') {
- detachNodeFromParent(node, parentNode);
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeTitle.js b/node_modules/svgo/plugins/removeTitle.js
deleted file mode 100644
index 906dd3c2..00000000
--- a/node_modules/svgo/plugins/removeTitle.js
+++ /dev/null
@@ -1,27 +0,0 @@
-'use strict';
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-
-exports.name = 'removeTitle';
-exports.description = 'removes <title>';
-
-/**
- * Remove <title>.
- *
- * https://developer.mozilla.org/docs/Web/SVG/Element/title
- *
- * @author Igor Kalashnikov
- *
- * @type {import('./plugins-types').Plugin<'removeTitle'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node, parentNode) => {
- if (node.name === 'title') {
- detachNodeFromParent(node, parentNode);
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeUnknownsAndDefaults.js b/node_modules/svgo/plugins/removeUnknownsAndDefaults.js
deleted file mode 100644
index e76e4e5f..00000000
--- a/node_modules/svgo/plugins/removeUnknownsAndDefaults.js
+++ /dev/null
@@ -1,212 +0,0 @@
-'use strict';
-
-const { visitSkip, detachNodeFromParent } = require('../lib/xast.js');
-const { collectStylesheet, computeStyle } = require('../lib/style.js');
-const {
- elems,
- attrsGroups,
- elemsGroups,
- attrsGroupsDefaults,
- presentationNonInheritableGroupAttrs,
-} = require('./_collections');
-
-exports.name = 'removeUnknownsAndDefaults';
-exports.description =
- 'removes unknown elements content and attributes, removes attrs with default values';
-
-// resolve all groups references
-
-/**
- * @type {Map<string, Set<string>>}
- */
-const allowedChildrenPerElement = new Map();
-/**
- * @type {Map<string, Set<string>>}
- */
-const allowedAttributesPerElement = new Map();
-/**
- * @type {Map<string, Map<string, string>>}
- */
-const attributesDefaultsPerElement = new Map();
-
-for (const [name, config] of Object.entries(elems)) {
- /**
- * @type {Set<string>}
- */
- const allowedChildren = new Set();
- if (config.content) {
- for (const elementName of config.content) {
- allowedChildren.add(elementName);
- }
- }
- if (config.contentGroups) {
- for (const contentGroupName of config.contentGroups) {
- const elemsGroup = elemsGroups[contentGroupName];
- if (elemsGroup) {
- for (const elementName of elemsGroup) {
- allowedChildren.add(elementName);
- }
- }
- }
- }
- /**
- * @type {Set<string>}
- */
- const allowedAttributes = new Set();
- if (config.attrs) {
- for (const attrName of config.attrs) {
- allowedAttributes.add(attrName);
- }
- }
- /**
- * @type {Map<string, string>}
- */
- const attributesDefaults = new Map();
- if (config.defaults) {
- for (const [attrName, defaultValue] of Object.entries(config.defaults)) {
- attributesDefaults.set(attrName, defaultValue);
- }
- }
- for (const attrsGroupName of config.attrsGroups) {
- const attrsGroup = attrsGroups[attrsGroupName];
- if (attrsGroup) {
- for (const attrName of attrsGroup) {
- allowedAttributes.add(attrName);
- }
- }
- const groupDefaults = attrsGroupsDefaults[attrsGroupName];
- if (groupDefaults) {
- for (const [attrName, defaultValue] of Object.entries(groupDefaults)) {
- attributesDefaults.set(attrName, defaultValue);
- }
- }
- }
- allowedChildrenPerElement.set(name, allowedChildren);
- allowedAttributesPerElement.set(name, allowedAttributes);
- attributesDefaultsPerElement.set(name, attributesDefaults);
-}
-
-/**
- * Remove unknown elements content and attributes,
- * remove attributes with default values.
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeUnknownsAndDefaults'>}
- */
-exports.fn = (root, params) => {
- const {
- unknownContent = true,
- unknownAttrs = true,
- defaultAttrs = true,
- defaultMarkupDeclarations = true,
- uselessOverrides = true,
- keepDataAttrs = true,
- keepAriaAttrs = true,
- keepRoleAttr = false,
- } = params;
- const stylesheet = collectStylesheet(root);
-
- return {
- instruction: {
- enter: (node) => {
- if (defaultMarkupDeclarations) {
- node.value = node.value.replace(/\s*standalone\s*=\s*(["'])no\1/, '');
- }
- },
- },
- element: {
- enter: (node, parentNode) => {
- // skip namespaced elements
- if (node.name.includes(':')) {
- return;
- }
- // skip visiting foreignObject subtree
- if (node.name === 'foreignObject') {
- return visitSkip;
- }
-
- // remove unknown element's content
- if (unknownContent && parentNode.type === 'element') {
- const allowedChildren = allowedChildrenPerElement.get(
- parentNode.name,
- );
- if (allowedChildren == null || allowedChildren.size === 0) {
- // remove unknown elements
- if (allowedChildrenPerElement.get(node.name) == null) {
- detachNodeFromParent(node, parentNode);
- return;
- }
- } else {
- // remove not allowed children
- if (allowedChildren.has(node.name) === false) {
- detachNodeFromParent(node, parentNode);
- return;
- }
- }
- }
-
- const allowedAttributes = allowedAttributesPerElement.get(node.name);
- const attributesDefaults = attributesDefaultsPerElement.get(node.name);
- const computedParentStyle =
- parentNode.type === 'element'
- ? computeStyle(stylesheet, parentNode)
- : null;
-
- // remove element's unknown attrs and attrs with default values
- for (const [name, value] of Object.entries(node.attributes)) {
- if (keepDataAttrs && name.startsWith('data-')) {
- continue;
- }
- if (keepAriaAttrs && name.startsWith('aria-')) {
- continue;
- }
- if (keepRoleAttr && name === 'role') {
- continue;
- }
- // skip xmlns attribute
- if (name === 'xmlns') {
- continue;
- }
- // skip namespaced attributes except xml:* and xlink:*
- if (name.includes(':')) {
- const [prefix] = name.split(':');
- if (prefix !== 'xml' && prefix !== 'xlink') {
- continue;
- }
- }
-
- if (
- unknownAttrs &&
- allowedAttributes &&
- allowedAttributes.has(name) === false
- ) {
- delete node.attributes[name];
- }
- if (
- defaultAttrs &&
- node.attributes.id == null &&
- attributesDefaults &&
- attributesDefaults.get(name) === value
- ) {
- // keep defaults if parent has own or inherited style
- if (computedParentStyle?.[name] == null) {
- delete node.attributes[name];
- }
- }
- if (uselessOverrides && node.attributes.id == null) {
- const style = computedParentStyle?.[name];
- if (
- presentationNonInheritableGroupAttrs.has(name) === false &&
- style != null &&
- style.type === 'static' &&
- style.value === value
- ) {
- delete node.attributes[name];
- }
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeUnusedNS.js b/node_modules/svgo/plugins/removeUnusedNS.js
deleted file mode 100644
index ac81eeaf..00000000
--- a/node_modules/svgo/plugins/removeUnusedNS.js
+++ /dev/null
@@ -1,59 +0,0 @@
-'use strict';
-
-exports.name = 'removeUnusedNS';
-exports.description = 'removes unused namespaces declaration';
-
-/**
- * Remove unused namespaces declaration from svg element
- * which are not used in elements or attributes
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeUnusedNS'>}
- */
-exports.fn = () => {
- /**
- * @type {Set<string>}
- */
- const unusedNamespaces = new Set();
- return {
- element: {
- enter: (node, parentNode) => {
- // collect all namespaces from svg element
- // (such as xmlns:xlink="http://www.w3.org/1999/xlink")
- if (node.name === 'svg' && parentNode.type === 'root') {
- for (const name of Object.keys(node.attributes)) {
- if (name.startsWith('xmlns:')) {
- const local = name.slice('xmlns:'.length);
- unusedNamespaces.add(local);
- }
- }
- }
- if (unusedNamespaces.size !== 0) {
- // preserve namespace used in nested elements names
- if (node.name.includes(':')) {
- const [ns] = node.name.split(':');
- if (unusedNamespaces.has(ns)) {
- unusedNamespaces.delete(ns);
- }
- }
- // preserve namespace used in nested elements attributes
- for (const name of Object.keys(node.attributes)) {
- if (name.includes(':')) {
- const [ns] = name.split(':');
- unusedNamespaces.delete(ns);
- }
- }
- }
- },
- exit: (node, parentNode) => {
- // remove unused namespace attributes from svg element
- if (node.name === 'svg' && parentNode.type === 'root') {
- for (const name of unusedNamespaces) {
- delete node.attributes[`xmlns:${name}`];
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeUselessDefs.js b/node_modules/svgo/plugins/removeUselessDefs.js
deleted file mode 100644
index 5d19810e..00000000
--- a/node_modules/svgo/plugins/removeUselessDefs.js
+++ /dev/null
@@ -1,65 +0,0 @@
-'use strict';
-
-/**
- * @typedef {import('../lib/types').XastElement} XastElement
- */
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-const { elemsGroups } = require('./_collections.js');
-
-exports.name = 'removeUselessDefs';
-exports.description = 'removes elements in <defs> without id';
-
-/**
- * Removes content of defs and properties that aren't rendered directly without ids.
- *
- * @author Lev Solntsev
- *
- * @type {import('./plugins-types').Plugin<'removeUselessDefs'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node, parentNode) => {
- if (node.name === 'defs') {
- /**
- * @type {XastElement[]}
- */
- const usefulNodes = [];
- collectUsefulNodes(node, usefulNodes);
- if (usefulNodes.length === 0) {
- detachNodeFromParent(node, parentNode);
- }
- // TODO remove legacy parentNode in v4
- for (const usefulNode of usefulNodes) {
- Object.defineProperty(usefulNode, 'parentNode', {
- writable: true,
- value: node,
- });
- }
- node.children = usefulNodes;
- } else if (
- elemsGroups.nonRendering.has(node.name) &&
- node.attributes.id == null
- ) {
- detachNodeFromParent(node, parentNode);
- }
- },
- },
- };
-};
-
-/**
- * @type {(node: XastElement, usefulNodes: XastElement[]) => void}
- */
-const collectUsefulNodes = (node, usefulNodes) => {
- for (const child of node.children) {
- if (child.type === 'element') {
- if (child.attributes.id != null || child.name === 'style') {
- usefulNodes.push(child);
- } else {
- collectUsefulNodes(child, usefulNodes);
- }
- }
- }
-};
diff --git a/node_modules/svgo/plugins/removeUselessStrokeAndFill.js b/node_modules/svgo/plugins/removeUselessStrokeAndFill.js
deleted file mode 100644
index 95193fa6..00000000
--- a/node_modules/svgo/plugins/removeUselessStrokeAndFill.js
+++ /dev/null
@@ -1,139 +0,0 @@
-'use strict';
-
-const { visit, visitSkip, detachNodeFromParent } = require('../lib/xast.js');
-const { collectStylesheet, computeStyle } = require('../lib/style.js');
-const { hasScripts } = require('../lib/svgo/tools.js');
-const { elemsGroups } = require('./_collections.js');
-
-exports.name = 'removeUselessStrokeAndFill';
-exports.description = 'removes useless stroke and fill attributes';
-
-/**
- * Remove useless stroke and fill attrs.
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeUselessStrokeAndFill'>}
- */
-exports.fn = (root, params) => {
- const {
- stroke: removeStroke = true,
- fill: removeFill = true,
- removeNone = false,
- } = params;
-
- // style and script elements deoptimise this plugin
- let hasStyleOrScript = false;
- visit(root, {
- element: {
- enter: (node) => {
- if (node.name === 'style' || hasScripts(node)) {
- hasStyleOrScript = true;
- }
- },
- },
- });
- if (hasStyleOrScript) {
- return null;
- }
-
- const stylesheet = collectStylesheet(root);
-
- return {
- element: {
- enter: (node, parentNode) => {
- // id attribute deoptimise the whole subtree
- if (node.attributes.id != null) {
- return visitSkip;
- }
- if (!elemsGroups.shape.has(node.name)) {
- return;
- }
- const computedStyle = computeStyle(stylesheet, node);
- const stroke = computedStyle.stroke;
- const strokeOpacity = computedStyle['stroke-opacity'];
- const strokeWidth = computedStyle['stroke-width'];
- const markerEnd = computedStyle['marker-end'];
- const fill = computedStyle.fill;
- const fillOpacity = computedStyle['fill-opacity'];
- const computedParentStyle =
- parentNode.type === 'element'
- ? computeStyle(stylesheet, parentNode)
- : null;
- const parentStroke =
- computedParentStyle == null ? null : computedParentStyle.stroke;
-
- // remove stroke*
- if (removeStroke) {
- if (
- stroke == null ||
- (stroke.type === 'static' && stroke.value == 'none') ||
- (strokeOpacity != null &&
- strokeOpacity.type === 'static' &&
- strokeOpacity.value === '0') ||
- (strokeWidth != null &&
- strokeWidth.type === 'static' &&
- strokeWidth.value === '0')
- ) {
- // stroke-width may affect the size of marker-end
- // marker is not visible when stroke-width is 0
- if (
- (strokeWidth != null &&
- strokeWidth.type === 'static' &&
- strokeWidth.value === '0') ||
- markerEnd == null
- ) {
- for (const name of Object.keys(node.attributes)) {
- if (name.startsWith('stroke')) {
- delete node.attributes[name];
- }
- }
- // set explicit none to not inherit from parent
- if (
- parentStroke != null &&
- parentStroke.type === 'static' &&
- parentStroke.value !== 'none'
- ) {
- node.attributes.stroke = 'none';
- }
- }
- }
- }
-
- // remove fill*
- if (removeFill) {
- if (
- (fill != null && fill.type === 'static' && fill.value === 'none') ||
- (fillOpacity != null &&
- fillOpacity.type === 'static' &&
- fillOpacity.value === '0')
- ) {
- for (const name of Object.keys(node.attributes)) {
- if (name.startsWith('fill-')) {
- delete node.attributes[name];
- }
- }
- if (
- fill == null ||
- (fill.type === 'static' && fill.value !== 'none')
- ) {
- node.attributes.fill = 'none';
- }
- }
- }
-
- if (removeNone) {
- if (
- (stroke == null || node.attributes.stroke === 'none') &&
- ((fill != null &&
- fill.type === 'static' &&
- fill.value === 'none') ||
- node.attributes.fill === 'none')
- ) {
- detachNodeFromParent(node, parentNode);
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeViewBox.js b/node_modules/svgo/plugins/removeViewBox.js
deleted file mode 100644
index c0f23de2..00000000
--- a/node_modules/svgo/plugins/removeViewBox.js
+++ /dev/null
@@ -1,49 +0,0 @@
-'use strict';
-
-exports.name = 'removeViewBox';
-exports.description = 'removes viewBox attribute when possible';
-
-const viewBoxElems = new Set(['pattern', 'svg', 'symbol']);
-
-/**
- * Remove viewBox attr which coincides with a width/height box.
- *
- * @see https://www.w3.org/TR/SVG11/coords.html#ViewBoxAttribute
- *
- * @example
- * <svg width="100" height="50" viewBox="0 0 100 50">
- * ⬇
- * <svg width="100" height="50">
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeViewBox'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node, parentNode) => {
- if (
- viewBoxElems.has(node.name) &&
- node.attributes.viewBox != null &&
- node.attributes.width != null &&
- node.attributes.height != null
- ) {
- // TODO remove width/height for such case instead
- if (node.name === 'svg' && parentNode.type !== 'root') {
- return;
- }
- const nums = node.attributes.viewBox.split(/[ ,]+/g);
- if (
- nums[0] === '0' &&
- nums[1] === '0' &&
- node.attributes.width.replace(/px$/, '') === nums[2] && // could use parseFloat too
- node.attributes.height.replace(/px$/, '') === nums[3]
- ) {
- delete node.attributes.viewBox;
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeXMLNS.js b/node_modules/svgo/plugins/removeXMLNS.js
deleted file mode 100644
index b7ec69a1..00000000
--- a/node_modules/svgo/plugins/removeXMLNS.js
+++ /dev/null
@@ -1,29 +0,0 @@
-'use strict';
-
-exports.name = 'removeXMLNS';
-exports.description =
- 'removes xmlns attribute (for inline svg, disabled by default)';
-
-/**
- * Remove the xmlns attribute when present.
- *
- * @example
- * <svg viewBox="0 0 100 50" xmlns="http://www.w3.org/2000/svg">
- * ↓
- * <svg viewBox="0 0 100 50">
- *
- * @author Ricardo Tomasi
- *
- * @type {import('./plugins-types').Plugin<'removeXMLNS'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node) => {
- if (node.name === 'svg') {
- delete node.attributes.xmlns;
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeXMLProcInst.js b/node_modules/svgo/plugins/removeXMLProcInst.js
deleted file mode 100644
index 73ec2335..00000000
--- a/node_modules/svgo/plugins/removeXMLProcInst.js
+++ /dev/null
@@ -1,28 +0,0 @@
-'use strict';
-
-const { detachNodeFromParent } = require('../lib/xast.js');
-
-exports.name = 'removeXMLProcInst';
-exports.description = 'removes XML processing instructions';
-
-/**
- * Remove XML Processing Instruction.
- *
- * @example
- * <?xml version="1.0" encoding="utf-8"?>
- *
- * @author Kir Belevich
- *
- * @type {import('./plugins-types').Plugin<'removeXMLProcInst'>}
- */
-exports.fn = () => {
- return {
- instruction: {
- enter: (node, parentNode) => {
- if (node.name === 'xml') {
- detachNodeFromParent(node, parentNode);
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/removeXlink.js b/node_modules/svgo/plugins/removeXlink.js
deleted file mode 100644
index 0411cc14..00000000
--- a/node_modules/svgo/plugins/removeXlink.js
+++ /dev/null
@@ -1,226 +0,0 @@
-'use strict';
-
-const { elems } = require('./_collections');
-
-/**
- * @typedef {import('../lib/types').XastElement} XastElement
- */
-
-exports.name = 'removeXlink';
-exports.description =
- 'remove xlink namespace and replaces attributes with the SVG 2 equivalent where applicable';
-
-/** URI indicating the Xlink namespace. */
-const XLINK_NAMESPACE = 'http://www.w3.org/1999/xlink';
-
-/**
- * Map of `xlink:show` values to the SVG 2 `target` attribute values.
- *
- * @type {Record<string, string>}
- * @see https://developer.mozilla.org/docs/Web/SVG/Attribute/xlink:show#usage_notes
- */
-const SHOW_TO_TARGET = {
- new: '_blank',
- replace: '_self',
-};
-
-/**
- * Elements that use xlink:href, but were deprecated in SVG 2 and therefore
- * don't support the SVG 2 href attribute.
- *
- * @type {Set<string>}
- * @see https://developer.mozilla.org/docs/Web/SVG/Attribute/xlink:href
- * @see https://developer.mozilla.org/docs/Web/SVG/Attribute/href
- */
-const LEGACY_ELEMENTS = new Set([
- 'cursor',
- 'filter',
- 'font-face-uri',
- 'glyphRef',
- 'tref',
-]);
-
-/**
- * @param {XastElement} node
- * @param {string[]} prefixes
- * @param {string} attr
- * @returns {string[]}
- */
-const findPrefixedAttrs = (node, prefixes, attr) => {
- return prefixes
- .map((prefix) => `${prefix}:${attr}`)
- .filter((attr) => node.attributes[attr] != null);
-};
-
-/**
- * Removes XLink namespace prefixes and converts references to XLink attributes
- * to the native SVG equivalent.
- *
- * The XLink namespace is deprecated in SVG 2.
- *
- * @type {import('./plugins-types').Plugin<'removeXlink'>}
- * @see https://developer.mozilla.org/docs/Web/SVG/Attribute/xlink:href
- */
-exports.fn = (_, params) => {
- const { includeLegacy } = params;
-
- /**
- * XLink namespace prefixes that are currently in the stack.
- *
- * @type {string[]}
- */
- const xlinkPrefixes = [];
-
- /**
- * Namespace prefixes that exist in {@link xlinkPrefixes} but were overridden
- * in a child element to point to another namespace, and so is not treated as
- * an XLink attribute.
- *
- * @type {string[]}
- */
- const overriddenPrefixes = [];
-
- /**
- * Namespace prefixes that were used in one of the {@link LEGACY_ELEMENTS}.
- *
- * @type {string[]}
- */
- const usedInLegacyElement = [];
-
- return {
- element: {
- enter: (node) => {
- for (const [key, value] of Object.entries(node.attributes)) {
- if (key.startsWith('xmlns:')) {
- const prefix = key.split(':', 2)[1];
-
- if (value === XLINK_NAMESPACE) {
- xlinkPrefixes.push(prefix);
- continue;
- }
-
- if (xlinkPrefixes.includes(prefix)) {
- overriddenPrefixes.push(prefix);
- }
- }
- }
-
- if (
- overriddenPrefixes.some((prefix) => xlinkPrefixes.includes(prefix))
- ) {
- return;
- }
-
- const showAttrs = findPrefixedAttrs(node, xlinkPrefixes, 'show');
- let showHandled = node.attributes.target != null;
- for (let i = showAttrs.length - 1; i >= 0; i--) {
- const attr = showAttrs[i];
- const value = node.attributes[attr];
- const mapping = SHOW_TO_TARGET[value];
-
- if (showHandled || mapping == null) {
- delete node.attributes[attr];
- continue;
- }
-
- if (mapping !== elems[node.name]?.defaults?.target) {
- node.attributes.target = mapping;
- }
-
- delete node.attributes[attr];
- showHandled = true;
- }
-
- const titleAttrs = findPrefixedAttrs(node, xlinkPrefixes, 'title');
- for (let i = titleAttrs.length - 1; i >= 0; i--) {
- const attr = titleAttrs[i];
- const value = node.attributes[attr];
- const hasTitle = node.children.filter(
- (child) => child.type === 'element' && child.name === 'title',
- );
-
- if (hasTitle.length > 0) {
- delete node.attributes[attr];
- continue;
- }
-
- /** @type {XastElement} */
- const titleTag = {
- type: 'element',
- name: 'title',
- attributes: {},
- children: [
- {
- type: 'text',
- value,
- },
- ],
- };
-
- Object.defineProperty(titleTag, 'parentNode', {
- writable: true,
- value: node,
- });
-
- node.children.unshift(titleTag);
- delete node.attributes[attr];
- }
-
- const hrefAttrs = findPrefixedAttrs(node, xlinkPrefixes, 'href');
-
- if (
- hrefAttrs.length > 0 &&
- LEGACY_ELEMENTS.has(node.name) &&
- !includeLegacy
- ) {
- hrefAttrs
- .map((attr) => attr.split(':', 1)[0])
- .forEach((prefix) => usedInLegacyElement.push(prefix));
- return;
- }
-
- for (let i = hrefAttrs.length - 1; i >= 0; i--) {
- const attr = hrefAttrs[i];
- const value = node.attributes[attr];
-
- if (node.attributes.href != null) {
- delete node.attributes[attr];
- continue;
- }
-
- node.attributes.href = value;
- delete node.attributes[attr];
- }
- },
- exit: (node) => {
- for (const [key, value] of Object.entries(node.attributes)) {
- const [prefix, attr] = key.split(':', 2);
-
- if (
- xlinkPrefixes.includes(prefix) &&
- !overriddenPrefixes.includes(prefix) &&
- !usedInLegacyElement.includes(prefix) &&
- !includeLegacy
- ) {
- delete node.attributes[key];
- continue;
- }
-
- if (key.startsWith('xmlns:') && !usedInLegacyElement.includes(attr)) {
- if (value === XLINK_NAMESPACE) {
- const index = xlinkPrefixes.indexOf(attr);
- xlinkPrefixes.splice(index, 1);
- delete node.attributes[key];
- continue;
- }
-
- if (overriddenPrefixes.includes(prefix)) {
- const index = overriddenPrefixes.indexOf(attr);
- overriddenPrefixes.splice(index, 1);
- }
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/reusePaths.js b/node_modules/svgo/plugins/reusePaths.js
deleted file mode 100644
index 8c2ddf0d..00000000
--- a/node_modules/svgo/plugins/reusePaths.js
+++ /dev/null
@@ -1,195 +0,0 @@
-'use strict';
-
-const { collectStylesheet } = require('../lib/style');
-const { detachNodeFromParent, querySelectorAll } = require('../lib/xast');
-
-/**
- * @typedef {import('../lib/types').XastElement} XastElement
- * @typedef {import('../lib/types').XastParent} XastParent
- * @typedef {import('../lib/types').XastNode} XastNode
- */
-
-exports.name = 'reusePaths';
-exports.description =
- 'Finds <path> elements with the same d, fill, and ' +
- 'stroke, and converts them to <use> elements ' +
- 'referencing a single <path> def.';
-
-/**
- * Finds <path> elements with the same d, fill, and stroke, and converts them to
- * <use> elements referencing a single <path> def.
- *
- * @author Jacob Howcroft
- *
- * @type {import('./plugins-types').Plugin<'reusePaths'>}
- */
-exports.fn = (root) => {
- const stylesheet = collectStylesheet(root);
-
- /**
- * @type {Map<string, XastElement[]>}
- */
- const paths = new Map();
-
- /**
- * Reference to the first defs element that is a direct child of the svg
- * element if one exists.
- *
- * @type {XastElement}
- * @see https://developer.mozilla.org/docs/Web/SVG/Element/defs
- */
- let svgDefs;
-
- /**
- * Set of hrefs that reference the id of another node.
- *
- * @type {Set<string>}
- */
- const hrefs = new Set();
-
- return {
- element: {
- enter: (node, parentNode) => {
- if (node.name === 'path' && node.attributes.d != null) {
- const d = node.attributes.d;
- const fill = node.attributes.fill || '';
- const stroke = node.attributes.stroke || '';
- const key = d + ';s:' + stroke + ';f:' + fill;
- let list = paths.get(key);
- if (list == null) {
- list = [];
- paths.set(key, list);
- }
- list.push(node);
- }
-
- if (
- svgDefs == null &&
- node.name === 'defs' &&
- parentNode.type === 'element' &&
- parentNode.name === 'svg'
- ) {
- svgDefs = node;
- }
-
- if (node.name === 'use') {
- for (const name of ['href', 'xlink:href']) {
- const href = node.attributes[name];
-
- if (href != null && href.startsWith('#') && href.length > 1) {
- hrefs.add(href.slice(1));
- }
- }
- }
- },
-
- exit: (node, parentNode) => {
- if (node.name === 'svg' && parentNode.type === 'root') {
- let defsTag = svgDefs;
-
- if (defsTag == null) {
- defsTag = {
- type: 'element',
- name: 'defs',
- attributes: {},
- children: [],
- };
- // TODO remove legacy parentNode in v4
- Object.defineProperty(defsTag, 'parentNode', {
- writable: true,
- value: node,
- });
- }
-
- let index = 0;
- for (const list of paths.values()) {
- if (list.length > 1) {
- /** @type {XastElement} */
- const reusablePath = {
- type: 'element',
- name: 'path',
- attributes: {},
- children: [],
- };
-
- for (const attr of ['fill', 'stroke', 'd']) {
- if (list[0].attributes[attr] != null) {
- reusablePath.attributes[attr] = list[0].attributes[attr];
- }
- }
-
- const originalId = list[0].attributes.id;
- if (
- originalId == null ||
- hrefs.has(originalId) ||
- stylesheet.rules.some(
- (rule) => rule.selector === `#${originalId}`,
- )
- ) {
- reusablePath.attributes.id = 'reuse-' + index++;
- } else {
- reusablePath.attributes.id = originalId;
- delete list[0].attributes.id;
- }
- // TODO remove legacy parentNode in v4
- Object.defineProperty(reusablePath, 'parentNode', {
- writable: true,
- value: defsTag,
- });
- defsTag.children.push(reusablePath);
- // convert paths to <use>
- for (const pathNode of list) {
- delete pathNode.attributes.d;
- delete pathNode.attributes.stroke;
- delete pathNode.attributes.fill;
-
- if (
- defsTag.children.includes(pathNode) &&
- pathNode.children.length === 0
- ) {
- if (Object.keys(pathNode.attributes).length === 0) {
- detachNodeFromParent(pathNode, defsTag);
- continue;
- }
-
- if (
- Object.keys(pathNode.attributes).length === 1 &&
- pathNode.attributes.id != null
- ) {
- detachNodeFromParent(pathNode, defsTag);
- const selector = `[xlink\\:href=#${pathNode.attributes.id}], [href=#${pathNode.attributes.id}]`;
- for (const child of querySelectorAll(node, selector)) {
- if (child.type !== 'element') {
- continue;
- }
- for (const name of ['href', 'xlink:href']) {
- if (child.attributes[name] != null) {
- child.attributes[name] =
- '#' + reusablePath.attributes.id;
- }
- }
- }
- continue;
- }
- }
-
- pathNode.name = 'use';
- pathNode.attributes['xlink:href'] =
- '#' + reusablePath.attributes.id;
- }
- }
- }
- if (defsTag.children.length !== 0) {
- if (node.attributes['xmlns:xlink'] == null) {
- node.attributes['xmlns:xlink'] = 'http://www.w3.org/1999/xlink';
- }
-
- if (svgDefs == null) {
- node.children.unshift(defsTag);
- }
- }
- }
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/sortAttrs.js b/node_modules/svgo/plugins/sortAttrs.js
deleted file mode 100644
index 6347f65e..00000000
--- a/node_modules/svgo/plugins/sortAttrs.js
+++ /dev/null
@@ -1,108 +0,0 @@
-'use strict';
-
-exports.name = 'sortAttrs';
-exports.description = 'Sort element attributes for better compression';
-
-/**
- * Sort element attributes for better compression
- *
- * @author Nikolay Frantsev
- *
- * @type {import('./plugins-types').Plugin<'sortAttrs'>}
- */
-exports.fn = (_root, params) => {
- const {
- order = [
- 'id',
- 'width',
- 'height',
- 'x',
- 'x1',
- 'x2',
- 'y',
- 'y1',
- 'y2',
- 'cx',
- 'cy',
- 'r',
- 'fill',
- 'stroke',
- 'marker',
- 'd',
- 'points',
- ],
- xmlnsOrder = 'front',
- } = params;
-
- /**
- * @type {(name: string) => number}
- */
- const getNsPriority = (name) => {
- if (xmlnsOrder === 'front') {
- // put xmlns first
- if (name === 'xmlns') {
- return 3;
- }
- // xmlns:* attributes second
- if (name.startsWith('xmlns:')) {
- return 2;
- }
- }
- // other namespaces after and sort them alphabetically
- if (name.includes(':')) {
- return 1;
- }
- // other attributes
- return 0;
- };
-
- /**
- * @type {(a: [string, string], b: [string, string]) => number}
- */
- const compareAttrs = ([aName], [bName]) => {
- // sort namespaces
- const aPriority = getNsPriority(aName);
- const bPriority = getNsPriority(bName);
- const priorityNs = bPriority - aPriority;
- if (priorityNs !== 0) {
- return priorityNs;
- }
- // extract the first part from attributes
- // for example "fill" from "fill" and "fill-opacity"
- const [aPart] = aName.split('-');
- const [bPart] = bName.split('-');
- // rely on alphabetical sort when the first part is the same
- if (aPart !== bPart) {
- const aInOrderFlag = order.includes(aPart) ? 1 : 0;
- const bInOrderFlag = order.includes(bPart) ? 1 : 0;
- // sort by position in order param
- if (aInOrderFlag === 1 && bInOrderFlag === 1) {
- return order.indexOf(aPart) - order.indexOf(bPart);
- }
- // put attributes from order param before others
- const priorityOrder = bInOrderFlag - aInOrderFlag;
- if (priorityOrder !== 0) {
- return priorityOrder;
- }
- }
- // sort alphabetically
- return aName < bName ? -1 : 1;
- };
-
- return {
- element: {
- enter: (node) => {
- const attrs = Object.entries(node.attributes);
- attrs.sort(compareAttrs);
- /**
- * @type {Record<string, string>}
- */
- const sortedAttributes = {};
- for (const [name, value] of attrs) {
- sortedAttributes[name] = value;
- }
- node.attributes = sortedAttributes;
- },
- },
- };
-};
diff --git a/node_modules/svgo/plugins/sortDefsChildren.js b/node_modules/svgo/plugins/sortDefsChildren.js
deleted file mode 100644
index 6ae5d421..00000000
--- a/node_modules/svgo/plugins/sortDefsChildren.js
+++ /dev/null
@@ -1,58 +0,0 @@
-'use strict';
-
-exports.name = 'sortDefsChildren';
-exports.description = 'Sorts children of <defs> to improve compression';
-
-/**
- * Sorts children of defs in order to improve compression.
- * Sorted first by frequency then by element name length then by element name (to ensure grouping).
- *
- * @author David Leston
- *
- * @type {import('./plugins-types').Plugin<'sortDefsChildren'>}
- */
-exports.fn = () => {
- return {
- element: {
- enter: (node) => {
- if (node.name === 'defs') {
- /**
- * @type {Map<string, number>}
- */
- const frequencies = new Map();
- for (const child of node.children) {
- if (child.type === 'element') {
- const frequency = frequencies.get(child.name);
- if (frequency == null) {
- frequencies.set(child.name, 1);
- } else {
- frequencies.set(child.name, frequency + 1);
- }
- }
- }
- node.children.sort((a, b) => {
- if (a.type !== 'element' || b.type !== 'element') {
- return 0;
- }
- const aFrequency = frequencies.get(a.name);
- const bFrequency = frequencies.get(b.name);
- if (aFrequency != null && bFrequency != null) {
- const frequencyComparison = bFrequency - aFrequency;
- if (frequencyComparison !== 0) {
- return frequencyComparison;
- }
- }
- const lengthComparison = b.name.length - a.name.length;
- if (lengthComparison !== 0) {
- return lengthComparison;
- }
- if (a.name !== b.name) {
- return a.name > b.name ? -1 : 1;
- }
- return 0;
- });
- }
- },
- },
- };
-};