imagetracerjs
Advanced tools
Comparing version 1.2.3 to 1.2.4
@@ -8,3 +8,3 @@ { | ||
}, | ||
"main": "imagetracer_v1.2.3.js", | ||
"main": "imagetracer_v1.2.4.js", | ||
"keywords": [ | ||
@@ -11,0 +11,0 @@ "image", |
@@ -5,3 +5,3 @@ "use strict"; | ||
var ImageTracer = require( __dirname + '/../imagetracer_v1.2.3' ); | ||
var ImageTracer = require( __dirname + '/../imagetracer_v1.2.4' ); | ||
@@ -20,3 +20,7 @@ // This example uses https://github.com/arian/pngjs | ||
// Output file name | ||
if(thisargname === 'outfilename' || thisargname === '-outfilename'){ outfilename = process.argv[i+1]; } | ||
// Tracing | ||
if(thisargname === 'corsenabled' || thisargname === '-corsenabled'){ options.corsenabled = (process.argv[i+1].toLowerCase() === 'true'); } | ||
if(thisargname === 'ltres' || thisargname === '-ltres'){ options.ltres = parseFloat(process.argv[i+1]); } | ||
@@ -26,2 +30,4 @@ if(thisargname === 'qtres' || thisargname === '-qtres'){ options.qtres = parseFloat(process.argv[i+1]); } | ||
if(thisargname === 'rightangleenhance' || thisargname === '-rightangleenhance'){ options.rightangleenhance = (process.argv[i+1].toLowerCase() === 'true'); } | ||
// Color quantization | ||
if(thisargname === 'colorsampling' || thisargname === '-colorsampling'){ options.colorsampling = parseInt(process.argv[i+1]); } | ||
@@ -31,4 +37,7 @@ if(thisargname === 'numberofcolors' || thisargname === '-numberofcolors'){ options.numberofcolors = parseInt(process.argv[i+1]); } | ||
if(thisargname === 'colorquantcycles' || thisargname === '-colorquantcycles'){ options.colorquantcycles = parseInt(process.argv[i+1]); } | ||
if(thisargname === 'blurradius' || thisargname === '-blurradius'){ options.blurradius = parseInt(process.argv[i+1]); } | ||
if(thisargname === 'blurdelta' || thisargname === '-blurdelta'){ options.blurdelta = parseInt(process.argv[i+1]); } | ||
// Layering method | ||
if(thisargname === 'layering' || thisargname === '-layering'){ options.layering = process.argv[i+1]; } | ||
// SVG rendering | ||
if(thisargname === 'strokewidth' || thisargname === '-strokewidth'){ options.strokewidth = parseFloat(process.argv[i+1]); } | ||
@@ -42,3 +51,6 @@ if(thisargname === 'linefilter' || thisargname === '-linefilter'){ options.linefilter = (process.argv[i+1].toLowerCase() === 'true'); } | ||
if(thisargname === 'qcpr' || thisargname === '-qcpr'){ options.qcpr = parseFloat(process.argv[i+1]); } | ||
if(thisargname === 'corsenabled' || thisargname === '-corsenabled'){ options.corsenabled = (process.argv[i+1].toLowerCase() === 'true'); } | ||
// Blur | ||
if(thisargname === 'blurradius' || thisargname === '-blurradius'){ options.blurradius = parseInt(process.argv[i+1]); } | ||
if(thisargname === 'blurdelta' || thisargname === '-blurdelta'){ options.blurdelta = parseInt(process.argv[i+1]); } | ||
@@ -45,0 +57,0 @@ }// End of argv loop |
{ | ||
"name": "imagetracerjs", | ||
"version": "1.2.3", | ||
"version": "1.2.4", | ||
"description": "raster image tracer and vectorizer, bitmap to SVG converter", | ||
"main": "imagetracer_v1.2.3.js", | ||
"main": "imagetracer_v1.2.4.js", | ||
"scripts": { | ||
@@ -7,0 +7,0 @@ "test": "node ./nodetest/nodetest.js" |
### Process overview | ||
#### 1. Color quantization | ||
The **colorquantization** function creates an indexed image (https://en.wikipedia.org/wiki/Indexed_color) | ||
The **colorquantization** function creates an indexed image (https://en.wikipedia.org/wiki/Indexed_color) using a variant of the https://en.wikipedia.org/wiki/K-means_clustering or https://en.wikipedia.org/wiki/K-medians_clustering algorithm. | ||
@@ -8,3 +8,3 @@ ![alt Original image (20x scale)](docimages/s2.png) | ||
#### 2. Layer separation and edge detection | ||
The **layering** function creates arrays for every color, and calculates edge node types. These are at the center of every 4 pixels, shown here as dots. | ||
The **layering** function creates arrays for every color, and calculates edge node types. These are at the center of every 4 pixels, shown here as dots. This, **pathscan** and **interpolation** are a reinvented variant of the https://en.wikipedia.org/wiki/Marching_squares algorithm. | ||
@@ -41,3 +41,3 @@ ![alt layer 0: black](docimages/s3.png) | ||
If the **fitseq** function can not fit a straight line or a quadratic spline to the sequence with the given error tresholds, then it will split the sequence in two and recursively call **fitseq** on each part. | ||
If the **fitseq** function can not fit a straight line or a quadratic spline to the sequence with the given error tresholds, then it will split the sequence in two and recursively call **fitseq** on each part (https://en.wikipedia.org/wiki/Divide_and_conquer_algorithm). | ||
@@ -48,7 +48,8 @@ #### 6. SVG rendering | ||
### Ideas for improvement | ||
- | ||
- Error handling: there's very little error handling now, Out of memory can happen easily with big images or many layers. | ||
- Color quantization: other algorithms? | ||
- Color quantization: other algorithms e.g. https://en.wikipedia.org/wiki/Octree ? | ||
- Color quantization: colors with few pixels are randomized, but probably the most distant colors should be found instead. | ||
- Tracing: 5.1. finding more suitable sequences. | ||
- Tracing: 5.5. Set splitpoint = (fitting point + errorpoint)/2 ; this is just a guess, there might be a better splitpoint. | ||
- Tracing: 5.5. splitpoint = fitpoint ; this is just a guess, there might be a better splitpoint. | ||
- Tracing: 5.7. If splitpoint-endpoint is a spline, try to add new points from the next sequence; this is not implemented. | ||
@@ -58,1 +59,3 @@ - Tracing: cubic splines or other curves? | ||
- Output: [PDF](https://en.wikipedia.org/wiki/Portable_Document_Format), [DXF](https://en.wikipedia.org/wiki/AutoCAD_DXF), [G-code](https://en.wikipedia.org/wiki/G-code) or other output? | ||
- comparing and integrating ideas from https://en.wikipedia.org/wiki/Potrace | ||
- Pathomit with background hole path shrinking |
288
README.md
@@ -6,54 +6,120 @@ # imagetracerjs | ||
### 1.2.3 | ||
--- | ||
- Node.js Command line interface (Enhancement Issue #13) | ||
- FIXED: Pathomit problem thanks to EusthEnoptEron (Issue #14) | ||
- options.corsenabled for [CORS Image loading](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image) thanks to neel-radica (Issue #12) | ||
## Table of contents | ||
- [Getting started](#getting-started) | ||
- [News](#news) | ||
- [API](#api) | ||
- [Options](#options) | ||
- [Examples](#examples) | ||
- [Process overview](#process-overview) | ||
- [License](#license) | ||
### 1.2.2 | ||
--- | ||
- FIXED: missing hole in path because of incorrect bounding box (Issue #11) | ||
- Posterized3 option preset | ||
- Changed svgpathstring() arguments to simplify getsvgstring() | ||
## Getting started | ||
### 1.2.1 | ||
### Using in the Browser | ||
Include the script: | ||
```javascript | ||
<script src="imagetracer_v1.2.4.js"></script> | ||
``` | ||
Then: | ||
```javascript | ||
// Loading an image, tracing with the 'posterized2' option preset, and appending the SVG to an element with id="svgcontainer" | ||
ImageTracer.imageToSVG( | ||
- FIXED: Gaussian blur preprocessing is now independent of DOM and canvas, thus working directly with Node.js (Issue #9) | ||
'panda.png', /* input filename / URL */ | ||
function(svgstr){ ImageTracer.appendSVGString( svgstr, 'svgcontainer' ); }, /* callback function to run on SVG string result */ | ||
'posterized2' /* Option preset */ | ||
); | ||
``` | ||
### 1.2.0 | ||
### Using with Node.js | ||
This is a major update, changing some internal logic and option default values. The API is compatible, so it should work out of the box. | ||
Node.js Command line interface example: | ||
- FIXED: transparent holes are now possible. ( Issue #7 and #8 ) | ||
- Deterministic output by default: ```options.colorsampling = 2``` ; ```options.mincolorratio = 0``` are deterministic and the defaults now. | ||
- Right angle enhancing: ```options.rightangleenhance``` ( default : true ) | ||
- Option presets (see below) | ||
- Custom strokewidth with ```options.strokewidth``` ( default : 1 ) | ||
- Line filter with ```options.linefilter``` ( default : false ) | ||
- Simplified ```getsvgstring()```; ```options.desc = false``` by default; splitpoint = fitpoint in fitseq(); small bugfixes and optimizations | ||
``` | ||
imagetracerjs/nodecli>node nodecli ../panda.png outfilename panda.svg scale 10 | ||
``` | ||
Version history and README for the old 1.1.2 version is [here.](README_v1.1.2.md) | ||
Expected result: | ||
### Option presets | ||
Are you confused by the many parameters and their meaning in the options object? Just use a preset like this: | ||
```javascript | ||
// This uses the 'Posterized2' option preset and appends the SVG to an element with id="svgcontainer" | ||
ImageTracer.imageToSVG( | ||
'panda.png', // Input filename | ||
function(svgstr){ ImageTracer.appendSVGString( svgstr, 'svgcontainer' ); }, // callback function to append the SVG to the svgcontainer div | ||
'Posterized2' // Option preset | ||
); | ||
``` | ||
imagetracerjs/nodecli/panda.svg was saved! | ||
``` | ||
--- | ||
## News | ||
### 1.2.4 | ||
- ```options.layering``` : default 0 = sequential, new method ; 1 = parallel, old method. (Enhancement Issue #17) | ||
- case insensitive option preset names | ||
- README.md reorganizing | ||
[Version history](https://github.com/jankovicsandras/imagetracerjs/blob/master/version_history.md) | ||
--- | ||
## API | ||
|Function name|Arguments|Returns|Run type| | ||
|-------------|---------|-------|--------| | ||
|```imageToSVG```|```image_url /*string*/ , callback /*function*/ , options /*optional object or preset name*/```|Nothing, ```callback(svgstring)``` will be executed|Asynchronous, Browser only| | ||
|```imagedataToSVG```|```imagedata /*object*/ , options /*optional object or preset name*/```|```svgstring /*string*/```|Synchronous, Browser & Node.js| | ||
|```imageToTracedata```|```image_url /*string*/ , callback /*function*/ , options /*optional object or preset name*/```|Nothing, ```callback(tracedata)``` will be executed|Asynchronous, Browser only| | ||
|```imagedataToTracedata```|```imagedata /*object*/ , options /*optional object or preset name*/```|```tracedata /*object*/```|Synchronous, Browser & Node.js| | ||
```imagedata``` is standard [ImageData](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) here, ```canvas``` is [canvas](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) . | ||
### Helper Functions (Browser only) | ||
|Function name|Arguments|Returns|Run type| | ||
|-------------|---------|-------|--------| | ||
|```appendSVGString```|```svgstring /*string*/, parentid /*string*/```|Nothing, an SVG will be appended to the container DOM element with id=parentid.|Synchronous, Browser only| | ||
|```loadImage```|```url /*string*/, callback /*function*/```|Nothing, loading an image from a URL, then executing ```callback(canvas)```|Asynchronous, Browser only| | ||
|```getImgdata```|```canvas /*object*/```|```imagedata /*object*/```|Synchronous, Browser only| | ||
```imagedata``` is standard [ImageData](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) here, ```canvas``` is [canvas](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) . | ||
There are more functions for advanced users, read the source if you are interested. :) | ||
"Browser only" means that Node.js doesn't have built-in canvas and DOM support as of 2018, so loading an image to an ImageData object needs an external library. | ||
--- | ||
## Options | ||
You can use an option preset name (string) or an [options object](https://github.com/jankovicsandras/imagetracerjs/blob/master/options.md) to control the tracing and rendering process. | ||
![Option presets gallery](docimages/option_presets_small.png) | ||
These strings can be passed instead of the options object: 'Default', 'Posterized1', 'Posterized2', 'Posterized3', 'Curvy', 'Sharp', 'Detailed', 'Smoothed', 'Grayscale', 'Fixedpalette', 'Randomsampling1', 'Randomsampling2', 'Artistic1', 'Artistic2', 'Artistic3', 'Artistic4' . | ||
These strings can be passed instead of the options object: | ||
```'default'``` | ||
```'posterized1'``` | ||
```'posterized2'``` | ||
```'posterized3'``` | ||
```'curvy'``` | ||
```'sharp'``` | ||
```'detailed'``` | ||
```'smoothed'``` | ||
```'grayscale'``` | ||
```'fixedpalette'``` | ||
```'randomsampling1'``` | ||
```'randomsampling2'``` | ||
```'artistic1'``` | ||
```'artistic2'``` | ||
```'artistic3'``` | ||
```'artistic4'``` | ||
Check out [imagetracer_options_gallery.html](https://github.com/jankovicsandras/imagetracerjs/blob/master/imagetracer_options_gallery.html) or a [bigger image](docimages/option_presets.png). | ||
[Read more about options.](https://github.com/jankovicsandras/imagetracerjs/blob/master/options.md) | ||
### Using in the browser | ||
--- | ||
## Examples | ||
### Using in the Browser | ||
Include the script: | ||
```javascript | ||
<script src="imagetracer_v1.2.3.js"></script> | ||
<script src="imagetracer_v1.2.4.js"></script> | ||
``` | ||
@@ -64,6 +130,4 @@ Then | ||
ImageTracer.imageToSVG( 'smiley.png', alert ); | ||
``` | ||
More examples: | ||
```javascript | ||
// Almost the same with options, and the ImageTracer.appendSVGString callback will append the SVG | ||
@@ -73,7 +137,7 @@ ImageTracer.imageToSVG( 'smiley.png', ImageTracer.appendSVGString, { ltres:0.1, qtres:1, scale:10, strokewidth:5 } ); | ||
// This uses the 'Posterized2' option preset and appends the SVG to an element with id="svgcontainer" | ||
// This uses the 'posterized2' option preset and appends the SVG to an element with id="svgcontainer" | ||
ImageTracer.imageToSVG( | ||
'panda.png', | ||
function(svgstr){ ImageTracer.appendSVGString( svgstr, 'svgcontainer' ); }, | ||
'Posterized2' | ||
'posterized2' | ||
); | ||
@@ -133,10 +197,8 @@ | ||
### Using with Node.js | ||
### Using with Node.js CLI | ||
Please read nodecli/nodecli.js | ||
Node.js Command line interface example: | ||
``` | ||
imagetracerjs/nodecli>node nodecli ../panda.png outfilename panda.svg -scale 10 | ||
imagetracerjs/nodecli>node nodecli ../panda.png outfilename panda.svg scale 10 | ||
``` | ||
@@ -150,105 +212,67 @@ | ||
#### Supported CLI arguments: | ||
CLI parameter names are supported both with and without trailing dash: ```-scale 10``` and ```scale 10``` are both correct. | ||
Almost all options are supported, except ```pal``` and ```layercontainerid```. | ||
<input file name must be the first argument REQUIRED> | ||
outfilename or -outfilename REQUIRED | ||
ltres or -ltres | ||
qtres or -qtres | ||
pathomit or -pathomit | ||
rightangleenhance or -rightangleenhance | ||
colorsampling or -colorsampling | ||
numberofcolors or -numberofcolors | ||
mincolorratio or -mincolorratio | ||
colorquantcycles or -colorquantcycles | ||
blurradius or -blurradius | ||
blurdelta or -blurdelta | ||
strokewidth or -strokewidth | ||
linefilter or -linefilter | ||
scale or -scale | ||
roundcoords or -roundcoords | ||
viewbox or -viewbox | ||
desc or -desc | ||
lcpr or -lcpr | ||
qcpr or -qcpr | ||
corsenabled or -corsenabled | ||
### Simple Node.js converting example | ||
### Deterministic output | ||
ImageTracer version >= 1.2.0 is deterministic by default, but randomization can be turned back on. | ||
```javascript | ||
"use strict"; | ||
This is relevant to versions < 1.2.0 : [options for deterministic tracing](https://github.com/jankovicsandras/imagetracerjs/blob/master/deterministic.md) | ||
var fs = require('fs'); | ||
### Main Functions | ||
|Function name|Arguments|Returns|Run type| | ||
|-------------|---------|-------|--------| | ||
|```imageToSVG```|```image_url /*string*/ , callback /*function*/ , options /*optional object*/```|Nothing, ```callback(svgstring)``` will be executed|Asynchronous| | ||
|```imagedataToSVG```|```imagedata /*object*/ , options /*optional object*/```|```svgstring /*string*/```|Synchronous| | ||
|```imageToTracedata```|```image_url /*string*/ , callback /*function*/ , options /*optional object*/```|Nothing, ```callback(tracedata)``` will be executed|Asynchronous| | ||
|```imagedataToTracedata```|```imagedata /*object*/ , options /*optional object*/```|```tracedata /*object*/```|Synchronous| | ||
var ImageTracer = require( __dirname + '/../imagetracer_v1.2.4' ); | ||
```imagedata``` is standard [ImageData](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) here, ```canvas``` is [canvas](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) . | ||
// This example uses https://github.com/arian/pngjs | ||
// , but other libraries can be used to load an image file to an ImageData object. | ||
var PNGReader = require( __dirname + '/PNGReader' ); | ||
#### Helper Functions | ||
|Function name|Arguments|Returns|Run type| | ||
|-------------|---------|-------|--------| | ||
|```appendSVGString```|```svgstring /*string*/, parentid /*string*/```|Nothing, an SVG will be appended to the container div with id=parentid.|Synchronous| | ||
|```loadImage```|```url /*string*/, callback /*function*/```|Nothing, loading an image from a URL, then executing ```callback(canvas)```|Asynchronous| | ||
|```getImgdata```|```canvas /*object*/```|```imagedata /*object*/```|Synchronous| | ||
// Input and output filepaths / URLs | ||
var infilepath = __dirname + '/' + 'panda.png'; | ||
var outfilepath = __dirname + '/' + 'panda.svg'; | ||
```imagedata``` is standard [ImageData](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) here, ```canvas``` is [canvas](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) . | ||
There are more functions for advanced users, read the source if you are interested. :) | ||
fs.readFile( | ||
infilepath, | ||
### Options | ||
|Option name|Default value|Meaning| | ||
|-----------|-------------|-------| | ||
|```ltres```|```1```|Error treshold for straight lines.| | ||
|```qtres```|```1```|Error treshold for quadratic splines.| | ||
|```pathomit```|```8```|Edge node paths shorter than this will be discarded for noise reduction.| | ||
|```rightangleenhance```|```true```|Enhance right angle corners.| | ||
|```pal```|No default value|Custom palette, an array of color objects: ```[ {r:0,g:0,b:0,a:255}, ... ]```| | ||
|```colorsampling```|```2```|0: disabled, generating a palette; 1: random sampling; 2: deterministic sampling| | ||
|```numberofcolors```|```16```|Number of colors to use on palette if pal object is not defined.| | ||
|```mincolorratio```|```0```|Color quantization will randomize a color if fewer pixels than (total pixels*mincolorratio) has it.| | ||
|```colorquantcycles```|```3```|Color quantization will be repeated this many times.| | ||
|```blurradius```|```0```|Set this to 1..5 for selective Gaussian blur preprocessing.| | ||
|```blurdelta```|```20```|RGBA delta treshold for selective Gaussian blur preprocessing.| | ||
|```strokewidth```|```1```|[SVG stroke-width](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-width)| | ||
|```linefilter```|```false```|Enable or disable line filter for noise reduction.| | ||
|```scale```|```1```|Every coordinate will be multiplied with this, to scale the SVG.| | ||
|```roundcoords```|```1```|rounding coordinates to a given decimal place. 1 means rounded to 1 decimal place like 7.3 ; 3 means rounded to 3 places, like 7.356| | ||
|```viewbox```|```false```|Enable or disable SVG viewBox.| | ||
|```desc```|```false```|Enable or disable SVG descriptions.| | ||
|```corsenabled```|```false```|Enable or disable [CORS Image loading](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image)| | ||
|```lcpr```|```0```|Straight line control point radius, if this is greater than zero, small circles will be drawn in the SVG. Do not use this for big/complex images.| | ||
|```qcpr```|```0```|Quadratic spline control point radius, if this is greater than zero, small circles and lines will be drawn in the SVG. Do not use this for big/complex images.| | ||
|```layercontainerid```|No default value|Edge node layers can be visualized if a container div's id is defined.| | ||
The almost complete options object: | ||
```javascript | ||
var options = {ltres:1, qtres:1, pathomit:8, rightangleenhance:true, colorsampling:2, numberofcolors:16, mincolorratio:0, colorquantcycles:3, blurradius:0, blurdelta:20, strokewidth:1, linefilter:false, scale:1, roundcoords:1, lcpr:0, qcpr:0, desc:false, viewbox:false, corsenabled:false }; | ||
function( err, bytes ){ // fs.readFile callback | ||
if(err){ console.log(err); throw err; } | ||
var reader = new PNGReader(bytes); | ||
reader.parse( function( err, png ){ // PNGReader callback | ||
if(err){ console.log(err); throw err; } | ||
// creating an ImageData object | ||
var myImageData = { width:png.width, height:png.height, data:png.pixels }; | ||
// tracing to SVG string | ||
var options = { scale: 5 }; // options object; option preset string can be used also | ||
var svgstring = ImageTracer.imagedataToSVG( myImageData, options ); | ||
// writing to file | ||
fs.writeFile( | ||
outfilepath, | ||
svgstring, | ||
function(err){ if(err){ console.log(err); throw err; } console.log( outfilepath + ' was saved!' ); } | ||
); | ||
});// End of reader.parse() | ||
}// End of readFile callback() | ||
);// End of fs.readFile() | ||
``` | ||
Adding custom palette. This will override numberofcolors. | ||
```javascript | ||
options.pal = [{r:0,g:0,b:0,a:255}, {r:0,g:0,b:255,a:255}, {r:255,g:255,b:0,a:255}]; | ||
``` | ||
### Legacy 1.1.2 version | ||
--- | ||
The 1.1.2 version can be used like this: *ImageTracer112*.imageToSVG() | ||
## Process overview | ||
See [Process overview and Ideas for improvement](https://github.com/jankovicsandras/imagetracerjs/blob/master/process_overview.md) | ||
Include the script: | ||
```javascript | ||
<script src="imagetracer_v1.1.2.js"></script> | ||
``` | ||
Then | ||
```javascript | ||
// Loading smiley.png, tracing and calling alert callback on the SVG string result | ||
ImageTracer112.imageToSVG( 'smiley.png', alert ); | ||
``` | ||
--- | ||
### Process overview | ||
See [Process overview and Ideas for improvement](https://github.com/jankovicsandras/imagetracerjs/blob/master/process_overview.md) | ||
## License | ||
### The Unlicense / PUBLIC DOMAIN | ||
### License | ||
#### The Unlicense / PUBLIC DOMAIN | ||
This is free and unencumbered software released into the public domain. | ||
@@ -255,0 +279,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
297
3175370
56
1568