svgo
Advanced tools
Comparing version 0.4.5 to 0.5.0
@@ -0,1 +1,19 @@ | ||
### [ [>](https://github.com/svg/svgo/tree/v0.4.5) ] 0.5.0 / 05.11.2014 | ||
* added ``--multipass`` command line option which repeatedly applies optimizations like collapsing groups (by @dfilatov) | ||
* exposed JSAPI as a factory method (by @mistakster) | ||
* added removeDesc plugin (by @dwabyick), disabled by default | ||
* [removeUselessStrokeAndFill](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill) plugin is disabled by default since it's unable to check inherited properties | ||
* transformations now apply to paths with arcs in [plugins/convertPathData](https://github.com/svg/svgo/blob/master/plugins/convertPathData.js) | ||
* a lot of bug fixes mostly related to transformations | ||
### [ [>](https://github.com/svg/svgo/tree/v0.4.5) ] 0.4.5 / 02.08.2014 | ||
* significally improved plugin [plugins/convertPathData](https://github.com/svg/svgo/blob/master/plugins/convertPathData.js): | ||
- Now data is being written relative or absolute whichever is shorter. You can turn it off by setting ``utilizeAbsolute`` to ``false``. | ||
- Smarter rounding: values like 2.499 now rounds to 2.5. Rounding now takes in account accumulutive error meaning that points will not be misplaced due to rounding more than it neccessary. | ||
- Fixed couple bugs. | ||
* ``--output`` option now can be a folder along with ``--folder``, thanks to @mako-taco. | ||
* [plugins/cleanupIDs](https://github.com/svg/svgo/blob/master/plugins/cleanupIDs.js) now have ``prefix`` option in case you want to combine multiple svg later (by @DanielMazurkiewicz). | ||
* Quotes now being escaped in attributes (by @ditesh). | ||
* Minor bugfixes. | ||
### [ [>](https://github.com/svg/svgo/tree/v0.4.4) ] 0.4.4 / 14.01.2014 | ||
@@ -2,0 +20,0 @@ * new plugin [plugins/removeTitle](https://github.com/svg/svgo/blob/master/plugins/removeTitle.js) (disabled by default, close [#159](https://github.com/svg/svgo/issues/159)) |
@@ -6,7 +6,7 @@ 'use strict'; | ||
* | ||
* @see http://deepsweet.github.com/svgo/ | ||
* @see https://github.com/svg/svgo | ||
* | ||
* @author Kir Belevich <kir@soulshine.in> (https://github.com/deepsweet) | ||
* @copyright © 2012 Kir Belevich | ||
* @license MIT https://raw.github.com/deepsweet/svgo/master/LICENSE | ||
* @license MIT https://raw.githubusercontent.com/svg/svgo/master/LICENSE | ||
*/ | ||
@@ -17,2 +17,3 @@ | ||
PLUGINS = require('./svgo/plugins'), | ||
JSAPI = require('./svgo/jsAPI.js'), | ||
JS2SVG = require('./svgo/js2svg'); | ||
@@ -37,8 +38,30 @@ | ||
svgjs = PLUGINS(svgjs, config.plugins); | ||
var svg = { data : null }, | ||
maxIterationCount = config.multipass ? 10 : 1, | ||
counter = 0, | ||
prevResult; | ||
callback(JS2SVG(svgjs, config.js2svg)); | ||
do { | ||
prevResult = svg; | ||
svgjs = PLUGINS(svgjs, config.plugins); | ||
svg = JS2SVG(svgjs, config.js2svg); | ||
} while(++counter < maxIterationCount && prevResult.data !== svg.data); | ||
callback(svg); | ||
}); | ||
}; | ||
/** | ||
* The factory that creates a content item with the helper methods. | ||
* | ||
* @param {Object} data which passed to jsAPI constructor | ||
* @returns {JSAPI} content item | ||
*/ | ||
SVGO.prototype.createContentItem = function(data) { | ||
return new JSAPI(data); | ||
}; |
'use strict'; | ||
require('colors'); | ||
require('js-yaml'); | ||
@@ -10,2 +9,3 @@ var FS = require('fs'), | ||
SVGO = require('../svgo'), | ||
YAML = require('js-yaml'), | ||
PKG = require('../../package.json'), | ||
@@ -90,2 +90,7 @@ encodeSVGDatauri = require('./tools').encodeSVGDatauri, | ||
.opt() | ||
.name('multipass').title('Enable multipass') | ||
.long('multipass') | ||
.flag() | ||
.end() | ||
.opt() | ||
.name('pretty').title('Make SVG pretty printed') | ||
@@ -105,3 +110,3 @@ .long('pretty') | ||
output = args && args.output ? args.output : opts.output, | ||
config, | ||
config = {}, | ||
configFull; | ||
@@ -127,3 +132,7 @@ | ||
} else { | ||
config = require(PATH.resolve(opts.config)); | ||
try { | ||
config = require(PATH.resolve(opts.config)); | ||
} catch (e) { | ||
config = YAML.safeLoad(FS.readFileSync(PATH.resolve(opts.config), 'utf8')); | ||
} | ||
} | ||
@@ -143,2 +152,10 @@ | ||
// --multipass | ||
if (opts.multipass) { | ||
config = config || {}; | ||
config.multipass = true; | ||
} | ||
// --pretty | ||
@@ -434,3 +451,3 @@ if (opts.pretty) { | ||
else if (++i < files.length) { | ||
optimizeFile(files[i]); | ||
optimizeFile(files[i]); | ||
} | ||
@@ -437,0 +454,0 @@ |
'use strict'; | ||
require('js-yaml'); | ||
var FS = require('fs'); | ||
var yaml = require('js-yaml'); | ||
@@ -27,5 +28,7 @@ var EXTEND = require('whet.extend'); | ||
defaults.multipass = config.multipass; | ||
} else { | ||
defaults = EXTEND({}, require('../../.svgo.yml')); | ||
defaults = EXTEND({}, yaml.safeLoad(FS.readFileSync(__dirname + '/../../.svgo.yml', 'utf8'))); | ||
@@ -36,2 +39,3 @@ defaults.plugins = preparePluginsArray(defaults.plugins); | ||
defaults = extendConfig(defaults, config); | ||
defaults.multipass = config.multipass; | ||
} | ||
@@ -38,0 +42,0 @@ |
@@ -140,1 +140,20 @@ 'use strict'; | ||
}; | ||
/** | ||
* Tests whether some attribute passes the test. | ||
* | ||
* @param {Function} callback callback | ||
* @param {Object} [context] callback context | ||
* @return {Boolean} false if there are no any attributes | ||
*/ | ||
JSAPI.prototype.someAttr = function(callback, context) { | ||
if (!this.hasAttr()) return false; | ||
for (var name in this.attrs) { | ||
if (callback.call(context, this.attrs[name])) return true; | ||
} | ||
return false; | ||
}; |
{ | ||
"name": "svgo", | ||
"version": "0.4.5", | ||
"version": "0.5.0", | ||
"description": "Nodejs-based tool for optimizing SVG vector graphics files", | ||
@@ -43,13 +43,13 @@ "keywords": [ "svgo", "svg", "optimize", "minify" ], | ||
"sax": "~0.6.0", | ||
"coa": "~0.4.0", | ||
"js-yaml": "~2.1.0", | ||
"colors": "~0.6.0", | ||
"coa": "~0.4.1", | ||
"js-yaml": "~3.2.2", | ||
"colors": "~1.0.3", | ||
"whet.extend": "~0.9.9" | ||
}, | ||
"devDependencies": { | ||
"mocha": "~1.14.0", | ||
"should": "~2.1.0", | ||
"istanbul": "~0.2.0", | ||
"mocha": "~2.0.1", | ||
"should": "~4.1.0", | ||
"istanbul": "~0.3.2", | ||
"mocha-istanbul": "~0.2.0", | ||
"coveralls": "~2.11.1" | ||
"coveralls": "~2.11.2" | ||
}, | ||
@@ -56,0 +56,0 @@ "engines": { |
@@ -5,5 +5,7 @@ 'use strict'; | ||
regPathData = /[\-+]?\d*\.?\d+([eE][\-+]?\d+)?/g, | ||
regValue = /[+-]?\d+(?:e[+-]?\d+)?|[+-]?\d*\.\d+(?:e[+-]?\d+)?/i, | ||
transform2js = require('./_transforms').transform2js, | ||
transformsMultiply = require('./_transforms').transformsMultiply, | ||
cleanupOutData = require('../lib/svgo/tools').cleanupOutData; | ||
cleanupOutData = require('../lib/svgo/tools').cleanupOutData, | ||
removeLeadingZero = require('../lib/svgo/tools').removeLeadingZero; | ||
@@ -189,11 +191,11 @@ /** | ||
exports.applyTransforms = function(elem, path, applyTransformsStroked, floatPrecision) { | ||
// if there are no 'stroke' attr and 'a' segments | ||
if ( | ||
!elem.hasAttr('transform') || | ||
!path.every(function(i) { return i.instruction !== 'a'; }) | ||
) { | ||
return path; | ||
} | ||
// if there are no 'stroke' attr and references to other objects such as | ||
// gradiends or clip-path which are also subjects to transform. | ||
if (!elem.hasAttr('transform') || | ||
elem.someAttr(function(attr) { return ~attr.value.indexOf('url(') })) | ||
return path; | ||
var matrix = transformsMultiply(transform2js(elem.attr('transform').value)), | ||
newPoint, sx, sy, strokeWidth; | ||
splittedMatrix = matrix.splitted || splitMatrix(matrix.data), | ||
newPoint, sx, sy, strokeWidth; | ||
@@ -220,3 +222,4 @@ if (elem.hasAttr('stroke') || elem.hasAttr('stroke-width')){ | ||
if (elem.hasAttr('stroke-width')){ | ||
elem.attrs['stroke-width'].value = elem.attrs['stroke-width'].value * sx; | ||
elem.attrs['stroke-width'].value = elem.attrs['stroke-width'].value | ||
.replace(regValue, function(num) { return removeLeadingZero(num * sx) }); | ||
} else { | ||
@@ -233,2 +236,28 @@ elem.addAttr({ | ||
// If an 'a' command can't be transformed directly, convert path to curves. | ||
if (!splittedMatrix.isSimple && path.some(function(i) { return i.instruction == 'a' })) { | ||
var prev; | ||
path = path.reduce(function(newPath, item){ | ||
if (item.instruction == 'a') { | ||
var curves = a2c.apply(0, [0, 0].concat(item.data)), | ||
curveData; | ||
while ((curveData = curves.splice(0,6)).length) { | ||
item = { | ||
instruction: 'c', | ||
data: curveData, | ||
base: prev.coords | ||
}; | ||
item.coords = [item.base[0] + item.data[4], item.base[1] + item.data[5]]; | ||
prev = item; | ||
newPath.push(item); | ||
} | ||
} else { | ||
newPath.push(item); | ||
if (prev) item.base = prev.coords; | ||
prev = item; | ||
} | ||
return newPath; | ||
}, []); | ||
} | ||
path.forEach(function(pathItem) { | ||
@@ -270,6 +299,18 @@ | ||
for (var i = 0; i < pathItem.data.length; i += 2) { | ||
newPoint = transformPoint(matrix.data, pathItem.data[i], pathItem.data[i + 1]); | ||
pathItem.data[i] = newPoint[0]; | ||
pathItem.data[i + 1] = newPoint[1]; | ||
if (pathItem.instruction == 'a') { | ||
pathItem.data[0] *= splittedMatrix.scalex; | ||
pathItem.data[1] *= splittedMatrix.scaley; | ||
pathItem.data[2] += splittedMatrix.rotate; | ||
newPoint = transformPoint(matrix.data, pathItem.data[5], pathItem.data[6]); | ||
pathItem.data[5] = newPoint[0]; | ||
pathItem.data[6] = newPoint[1]; | ||
} else { | ||
for (var i = 0; i < pathItem.data.length; i += 2) { | ||
newPoint = transformPoint(matrix.data, pathItem.data[i], pathItem.data[i + 1]); | ||
pathItem.data[i] = newPoint[0]; | ||
pathItem.data[i + 1] = newPoint[1]; | ||
} | ||
} | ||
@@ -526,1 +567,149 @@ | ||
}; | ||
/* Based on code from Snap.svg (Apache 2 license). http://snapsvg.io/ | ||
* Thanks to Dmitry Baranovskiy for his great work! | ||
*/ | ||
function norm(a) { | ||
return a[0] * a[0] + a[1] * a[1]; | ||
} | ||
function normalize(a) { | ||
var mag = Math.sqrt(norm(a)); | ||
if (a[0]) a[0] /= mag; | ||
if (a[1]) a[1] /= mag; | ||
} | ||
function deg(rad) { | ||
return rad * 180 / Math.PI % 360; | ||
} | ||
function determinant(matrix) { | ||
return matrix[0] * matrix[3] - matrix[1] * matrix[2]; | ||
}; | ||
/* Splits matrix into primitive transformations | ||
= (object) in format: | ||
o dx (number) translation by x | ||
o dy (number) translation by y | ||
o scalex (number) scale by x | ||
o scaley (number) scale by y | ||
o shear (number) shear | ||
o rotate (number) rotation in deg | ||
o isSimple (boolean) could it be represented via simple transformations | ||
*/ | ||
function splitMatrix(matrix) { | ||
var out = {}; | ||
// translation | ||
out.dx = matrix[4]; | ||
out.dy = matrix[5]; | ||
// scale and shear | ||
var row = [[matrix[0] , matrix[2] ], [matrix[1] , matrix[3]]]; | ||
out.scalex = Math.sqrt(norm(row[0])); | ||
normalize(row[0]); | ||
out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1]; | ||
row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear]; | ||
out.scaley = Math.sqrt(norm(row[1])); | ||
normalize(row[1]); | ||
out.shear /= out.scaley; | ||
if (determinant(matrix) < 0) { | ||
out.scalex = -out.scalex; | ||
} | ||
// rotation | ||
var sin = -row[0][1], | ||
cos = row[1][1]; | ||
if (cos < 0) { | ||
out.rotate = deg(Math.acos(cos)); | ||
if (sin < 0) { | ||
out.rotate = 360 - out.rotate; | ||
} | ||
} else { | ||
out.rotate = deg(Math.asin(sin)); | ||
} | ||
out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate); | ||
return out; | ||
}; | ||
function a2c(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { | ||
// for more information of where this Math came from visit: | ||
// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes | ||
var _120 = Math.PI * 120 / 180, | ||
rad = Math.PI / 180 * (+angle || 0), | ||
res = [], | ||
rotateX = function(x, y, rad) { return x * Math.cos(rad) - y * Math.sin(rad) }, | ||
rotateY = function(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 cos = Math.cos(Math.PI / 180 * angle), | ||
sin = Math.sin(Math.PI / 180 * angle), | ||
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, | ||
ry2 = ry * ry, | ||
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))), | ||
cx = k * rx * y / ry + (x1 + x2) / 2, | ||
cy = k * -ry * x / rx + (y1 + y2) / 2, | ||
f1 = Math.asin(((y1 - cy) / ry).toFixed(9)), | ||
f2 = Math.asin(((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; | ||
} | ||
}; |
@@ -54,7 +54,27 @@ 'use strict'; | ||
var simple = true, | ||
scalex = 1, | ||
scaley = 1, | ||
rotate = 0; | ||
// convert transforms objects to the matrices | ||
transforms = transforms.map(function(transform) { | ||
return transform.name === 'martix' ? | ||
transform : | ||
transformToMatrix(transform); | ||
if (transform.name === 'matrix') { | ||
simple = false; | ||
return transform.data; | ||
} else if (simple) { | ||
if (transform.name == 'scale') { | ||
scalex *= transform.data[0]; | ||
scaley *= transform.data[1]; | ||
} else if (transform.name == 'rotate') { | ||
if (scalex.toFixed(9) == scaley.toFixed(9)) { | ||
rotate += transform.data[0]; | ||
} else { | ||
simple = false; | ||
} | ||
} else if (transform.name != 'translate') { | ||
simple = false; | ||
} | ||
} | ||
return transformToMatrix(transform); | ||
}); | ||
@@ -68,4 +88,13 @@ | ||
}) | ||
}; | ||
} | ||
if (simple) { | ||
transforms.splitted = { | ||
scalex: scalex, | ||
scaley: scaley, | ||
rotate: rotate, | ||
isSimple: true | ||
} | ||
} | ||
return transforms; | ||
@@ -72,0 +101,0 @@ |
@@ -45,6 +45,9 @@ 'use strict'; | ||
// move group attibutes to the single content element | ||
if (g.attrs && g.content.length === 1) { | ||
if (g.hasAttr() && g.content.length === 1) { | ||
var inner = g.content[0]; | ||
if (inner.elem && !(g.hasAttr('transform') && g.hasAttr('clip-path') && inner.hasAttr('transform'))) { | ||
if (inner.isElem() && !inner.hasAttr('id') && | ||
!(g.hasAttr('clip-path') && | ||
(g.hasAttr('transform') || inner.hasAttr('transform'))) | ||
) { | ||
g.eachAttr(function(attr) { | ||
@@ -62,3 +65,3 @@ if (!inner.hasAttr(attr.name)) { | ||
// collapse groups without attributes | ||
if (!g.attrs) { | ||
if (!g.hasAttr()) { | ||
unflatten = true; | ||
@@ -65,0 +68,0 @@ |
@@ -94,3 +94,4 @@ 'use strict'; | ||
subpathPoint = [0, 0], | ||
mM = false; | ||
mM = false, | ||
baseItem; | ||
@@ -121,2 +122,3 @@ path.forEach(function(item, index) { | ||
subpathPoint = point.slice(-2); | ||
baseItem = item; | ||
} | ||
@@ -151,2 +153,3 @@ | ||
subpathPoint = point.slice(-2); | ||
baseItem = item; | ||
@@ -245,3 +248,3 @@ } | ||
else { | ||
item.coords = subpathPoint.slice(0); | ||
item.coords = baseItem.coords; | ||
point = subpathPoint; | ||
@@ -272,3 +275,3 @@ mM = false; | ||
path = path.filter(function(item) { | ||
path = path.filter(function(item, index) { | ||
@@ -501,2 +504,3 @@ var instruction = item.instruction, | ||
) { | ||
path[index] = prev; | ||
return false; | ||
@@ -511,2 +515,3 @@ } | ||
) { | ||
path[index] = prev; | ||
return false; | ||
@@ -596,2 +601,4 @@ } | ||
prev.data = prev.data.concat(adata); | ||
prev.coords = item.coords; | ||
path[index] = prev; | ||
return false; | ||
@@ -601,2 +608,4 @@ } | ||
prev.data = prev.data.concat(data); | ||
prev.coords = item.coords; | ||
path[index] = prev; | ||
return false; | ||
@@ -632,3 +641,3 @@ } | ||
( | ||
!item.data || | ||
'Mmz'.indexOf(item.instruction) > -1 || | ||
'hv'.indexOf(item.instruction) > -1 && (prev.data[0] >= 0) == (item.data[0] >= 0) || | ||
@@ -641,2 +650,5 @@ !params.utilizeAbsolute | ||
prev.data[0] += item.data[0]; | ||
} else if (item.instruction.toLowerCase() === 'm') { | ||
prev.data[0] += item.data[0]; | ||
prev.data[1] += item.data[1]; | ||
// concat previous data with current if it is not z | ||
@@ -646,2 +658,3 @@ } else if (item.data) { | ||
} | ||
prev.coords = item.coords; | ||
@@ -648,0 +661,0 @@ // filter out current item |
@@ -38,2 +38,3 @@ 'use strict'; | ||
!item.isEmpty() && | ||
!item.someAttr(function(attr) { return ~attr.value.indexOf('url(') }) && | ||
item.content.every(function(inner) { | ||
@@ -40,0 +41,0 @@ return inner.isElem(pathElems); |
@@ -5,3 +5,3 @@ 'use strict'; | ||
exports.active = true; | ||
exports.active = false; | ||
@@ -8,0 +8,0 @@ exports.params = { |
@@ -40,3 +40,3 @@ **english** | [русский](https://github.com/svg/svgo/blob/master/README.ru.md) | ||
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeNonInheritableGroupAttrs.js) ] remove non-inheritable group's "presentation" attributes | ||
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill.js) ] remove useless stroke and fill attrs. | ||
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill.js) ] remove useless stroke and fill attrs (disabled by default) | ||
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeUnusedNS.js) ] remove unused namespaces declaration | ||
@@ -43,0 +43,0 @@ * [ [>](https://github.com/svg/svgo/blob/master/plugins/cleanupIDs.js) ] remove unused and minify used IDs |
@@ -26,3 +26,4 @@ [english](https://github.com/svg/svgo/blob/master/README.md) | **русский** | ||
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeMetadata.js) ] удаление `<metadata>` | ||
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeTitle.js) ] удаление `<title>` | ||
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeTitle.js) ] удаление `<title>` (отключена по умолчанию) | ||
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeDesc.js) ] удаление `<desc>` (отключена по умолчанию) | ||
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeEditorsNSData.js) ] удаление пространств имён различных редакторов, их элементов и атрибутов | ||
@@ -41,2 +42,3 @@ * [ [>](https://github.com/svg/svgo/blob/master/plugins/removeEmptyAttrs.js) ] удаление пустых атрибутов | ||
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeNonInheritableGroupAttrs.js) ] удаление ненаследуемых "презентационных" атрибутов групп | ||
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill.js) ] удаление неиспользуемых атрибутов stroke-* и fill-* (выключено по умолчанию) | ||
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeUnusedNS.js) ] удаление деклараций неиспользуемых пространств имён | ||
@@ -43,0 +45,0 @@ * [ [>](https://github.com/svg/svgo/blob/master/plugins/cleanupIDs.js) ] удаление неиспользуемых и сокращение используемых ID |
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
387605
60
8664
6
9
+ Addedargparse@1.0.10(transitive)
+ Addedcolors@1.0.3(transitive)
+ Addedesprima@2.0.0(transitive)
+ Addedjs-yaml@3.2.7(transitive)
+ Addedsprintf-js@1.0.3(transitive)
- Removedargparse@0.1.16(transitive)
- Removedcolors@0.6.2(transitive)
- Removedesprima@1.0.4(transitive)
- Removedjs-yaml@2.1.3(transitive)
- Removedunderscore@1.7.0(transitive)
- Removedunderscore.string@2.4.0(transitive)
Updatedcoa@~0.4.1
Updatedcolors@~1.0.3
Updatedjs-yaml@~3.2.2