Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

camera-2d-simple

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

camera-2d-simple - npm Package Compare versions

Comparing version 2.2.1 to 3.0.0

117

dist/camera-2d.esm.js

@@ -8,3 +8,10 @@ import { mat4, vec4 } from 'gl-matrix';

initViewCenter = [0, 0],
initScaleBounds = [0, Infinity]
initScaleBounds = [
[0, Infinity],
[0, Infinity],
],
initTranslationBounds = [
[-Infinity, Infinity],
[-Infinity, Infinity],
]
) => {

@@ -19,12 +26,41 @@ // Scratch variables

const scaleBounds = [...initScaleBounds];
const scaleXBounds = Array.isArray(initScaleBounds[0])
? [...initScaleBounds[0]]
: [...initScaleBounds];
const scaleYBounds = Array.isArray(initScaleBounds[0])
? [...initScaleBounds[1]]
: [...initScaleBounds];
const getRotation = () => Math.acos(view[0] / getScaling());
const translationXBounds = Array.isArray(initTranslationBounds[0])
? [...initTranslationBounds[0]]
: [...initTranslationBounds];
const translationYBounds = Array.isArray(initTranslationBounds[0])
? [...initTranslationBounds[1]]
: [...initTranslationBounds];
const getScaling = () => mat4.getScaling(scratch0, view)[0];
const getScaling = () => mat4.getScaling(scratch0, view).slice(0, 2);
const getMinScaling = () => {
const scaling = getScaling();
return Math.min(scaling[0], scaling[1]);
};
const getMaxScaling = () => {
const scaling = getScaling();
return Math.max(scaling[0], scaling[1]);
};
const getScaleBounds = () => [...scaleBounds];
const getRotation = () => Math.acos(view[0] / getMaxScaling());
const getDistance = () => 1 / getScaling();
const getScaleBounds = () => [[...scaleXBounds], [...scaleYBounds]];
const getTranslationBounds = () => [
[...translationXBounds],
[...translationYBounds],
];
const getDistance = () => {
const scaling = getScaling();
return [1 / scaling[0], 1 / scaling[1]];
};
const getMinDistance = () => 1 / getMinScaling();
const getMaxDistance = () => 1 / getMaxScaling();
const getTranslation = () => mat4.getTranslation(scratch0, view).slice(0, 2);

@@ -63,13 +99,23 @@

const scale = (d, mousePos) => {
if (d <= 0) return;
const isArray = Array.isArray(d);
let dx = isArray ? d[0] : d;
let dy = isArray ? d[1] : d;
const scale = getScaling();
const newScale = scale * d;
if (dx <= 0 || dy <= 0 || (dx === 1 && dy === 1)) return;
d = Math.max(scaleBounds[0], Math.min(newScale, scaleBounds[1])) / scale;
const scaling = getScaling();
const newXScale = scaling[0] * dx;
const newYScale = scaling[1] * dy;
if (d === 1) return; // There is nothing to do
dx =
Math.max(scaleXBounds[0], Math.min(newXScale, scaleXBounds[1])) /
scaling[0];
dy =
Math.max(scaleYBounds[0], Math.min(newYScale, scaleYBounds[1])) /
scaling[1];
scratch0[0] = d;
scratch0[1] = d;
if (dx === 1 && dy === 1) return; // There is nothing to do
scratch0[0] = dx;
scratch0[1] = dy;
scratch0[2] = 1;

@@ -95,3 +141,3 @@

const rotate = rad => {
const rotate = (rad) => {
const r = mat4.create();

@@ -105,8 +151,19 @@ mat4.fromRotation(r, rad, [0, 0, 1]);

const setScaleBounds = newBounds => {
scaleBounds[0] = newBounds[0];
scaleBounds[1] = newBounds[1];
const setScaleBounds = (newBounds) => {
const isArray = Array.isArray(newBounds[0]);
scaleXBounds[0] = isArray ? newBounds[0][0] : newBounds[0];
scaleXBounds[1] = isArray ? newBounds[0][1] : newBounds[1];
scaleYBounds[0] = isArray ? newBounds[1][0] : newBounds[0];
scaleYBounds[1] = isArray ? newBounds[1][1] : newBounds[1];
};
const setView = newView => {
const setTranslationBounds = (newBounds) => {
const isArray = Array.isArray(newBounds[0]);
translationXBounds[0] = isArray ? newBounds[0][0] : newBounds[0];
translationXBounds[1] = isArray ? newBounds[0][1] : newBounds[1];
translationYBounds[0] = isArray ? newBounds[1][0] : newBounds[0];
translationYBounds[1] = isArray ? newBounds[1][1] : newBounds[1];
};
const setView = (newView) => {
if (!newView || newView.length < 16) return;

@@ -116,3 +173,3 @@ view = newView;

const setViewCenter = newViewCenter => {
const setViewCenter = (newViewCenter) => {
viewCenter = [...newViewCenter.slice(0, 2), 0, 1];

@@ -138,8 +195,23 @@ };

},
get minScaling() {
return getMinScaling();
},
get maxScaling() {
return getMaxScaling();
},
get scaleBounds() {
return getScaleBounds();
},
get translationBounds() {
return getTranslationBounds();
},
get distance() {
return getDistance();
},
get minDistance() {
return getMinDistance();
},
get maxDistance() {
return getMaxDistance();
},
get rotation() {

@@ -162,11 +234,12 @@ return getRotation();

set: (...args) => {
console.warn("`set()` is deprecated. Please use `setView()` instead.");
console.warn('`set()` is deprecated. Please use `setView()` instead.');
return setView(...args);
},
setScaleBounds,
setTranslationBounds,
setView,
setViewCenter
setViewCenter,
};
};
export default createCamera;
export { createCamera as default };
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('gl-matrix')) :
typeof define === 'function' && define.amd ? define(['gl-matrix'], factory) :
(global = global || self, global.createCamera2d = factory(global.glMatrix));
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.createCamera2d = factory(global.glMatrix));
}(this, (function (glMatrix) { 'use strict';

@@ -12,3 +12,4 @@

initViewCenter,
initScaleBounds
initScaleBounds,
initTranslationBounds
) {

@@ -19,3 +20,8 @@ if ( initTarget === void 0 ) initTarget = [0, 0];

if ( initViewCenter === void 0 ) initViewCenter = [0, 0];
if ( initScaleBounds === void 0 ) initScaleBounds = [0, Infinity];
if ( initScaleBounds === void 0 ) initScaleBounds = [
[0, Infinity],
[0, Infinity] ];
if ( initTranslationBounds === void 0 ) initTranslationBounds = [
[-Infinity, Infinity],
[-Infinity, Infinity] ];

@@ -30,12 +36,40 @@ // Scratch variables

var scaleBounds = [].concat( initScaleBounds );
var scaleXBounds = Array.isArray(initScaleBounds[0])
? [].concat( initScaleBounds[0] )
: [].concat( initScaleBounds );
var scaleYBounds = Array.isArray(initScaleBounds[0])
? [].concat( initScaleBounds[1] )
: [].concat( initScaleBounds );
var getRotation = function () { return Math.acos(view[0] / getScaling()); };
var translationXBounds = Array.isArray(initTranslationBounds[0])
? [].concat( initTranslationBounds[0] )
: [].concat( initTranslationBounds );
var translationYBounds = Array.isArray(initTranslationBounds[0])
? [].concat( initTranslationBounds[1] )
: [].concat( initTranslationBounds );
var getScaling = function () { return glMatrix.mat4.getScaling(scratch0, view)[0]; };
var getScaling = function () { return glMatrix.mat4.getScaling(scratch0, view).slice(0, 2); };
var getMinScaling = function () {
var scaling = getScaling();
return Math.min(scaling[0], scaling[1]);
};
var getMaxScaling = function () {
var scaling = getScaling();
return Math.max(scaling[0], scaling[1]);
};
var getScaleBounds = function () { return [].concat( scaleBounds ); };
var getRotation = function () { return Math.acos(view[0] / getMaxScaling()); };
var getDistance = function () { return 1 / getScaling(); };
var getScaleBounds = function () { return [[].concat( scaleXBounds ), [].concat( scaleYBounds )]; };
var getTranslationBounds = function () { return [
[].concat( translationXBounds ),
[].concat( translationYBounds ) ]; };
var getDistance = function () {
var scaling = getScaling();
return [1 / scaling[0], 1 / scaling[1]];
};
var getMinDistance = function () { return 1 / getMinScaling(); };
var getMaxDistance = function () { return 1 / getMaxScaling(); };
var getTranslation = function () { return glMatrix.mat4.getTranslation(scratch0, view).slice(0, 2); };

@@ -83,13 +117,23 @@

var scale = function (d, mousePos) {
if (d <= 0) { return; }
var isArray = Array.isArray(d);
var dx = isArray ? d[0] : d;
var dy = isArray ? d[1] : d;
var scale = getScaling();
var newScale = scale * d;
if (dx <= 0 || dy <= 0 || (dx === 1 && dy === 1)) { return; }
d = Math.max(scaleBounds[0], Math.min(newScale, scaleBounds[1])) / scale;
var scaling = getScaling();
var newXScale = scaling[0] * dx;
var newYScale = scaling[1] * dy;
if (d === 1) { return; } // There is nothing to do
dx =
Math.max(scaleXBounds[0], Math.min(newXScale, scaleXBounds[1])) /
scaling[0];
dy =
Math.max(scaleYBounds[0], Math.min(newYScale, scaleYBounds[1])) /
scaling[1];
scratch0[0] = d;
scratch0[1] = d;
if (dx === 1 && dy === 1) { return; } // There is nothing to do
scratch0[0] = dx;
scratch0[1] = dy;
scratch0[2] = 1;

@@ -125,6 +169,17 @@

var setScaleBounds = function (newBounds) {
scaleBounds[0] = newBounds[0];
scaleBounds[1] = newBounds[1];
var isArray = Array.isArray(newBounds[0]);
scaleXBounds[0] = isArray ? newBounds[0][0] : newBounds[0];
scaleXBounds[1] = isArray ? newBounds[0][1] : newBounds[1];
scaleYBounds[0] = isArray ? newBounds[1][0] : newBounds[0];
scaleYBounds[1] = isArray ? newBounds[1][1] : newBounds[1];
};
var setTranslationBounds = function (newBounds) {
var isArray = Array.isArray(newBounds[0]);
translationXBounds[0] = isArray ? newBounds[0][0] : newBounds[0];
translationXBounds[1] = isArray ? newBounds[0][1] : newBounds[1];
translationYBounds[0] = isArray ? newBounds[1][0] : newBounds[0];
translationYBounds[1] = isArray ? newBounds[1][1] : newBounds[1];
};
var setView = function (newView) {

@@ -156,8 +211,23 @@ if (!newView || newView.length < 16) { return; }

},
get minScaling() {
return getMinScaling();
},
get maxScaling() {
return getMaxScaling();
},
get scaleBounds() {
return getScaleBounds();
},
get translationBounds() {
return getTranslationBounds();
},
get distance() {
return getDistance();
},
get minDistance() {
return getMinDistance();
},
get maxDistance() {
return getMaxDistance();
},
get rotation() {

@@ -183,8 +253,9 @@ return getRotation();

console.warn("`set()` is deprecated. Please use `setView()` instead.");
console.warn('`set()` is deprecated. Please use `setView()` instead.');
return setView.apply(void 0, args);
},
setScaleBounds: setScaleBounds,
setTranslationBounds: setTranslationBounds,
setView: setView,
setViewCenter: setViewCenter
setViewCenter: setViewCenter,
};

@@ -191,0 +262,0 @@ };

2

dist/camera-2d.min.js

@@ -1,1 +0,1 @@

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("gl-matrix")):"function"==typeof define&&define.amd?define(["gl-matrix"],e):(t=t||self).createCamera2d=e(t.glMatrix)}(this,(function(t){"use strict";return function(e,n,a,r,i){void 0===e&&(e=[0,0]),void 0===n&&(n=1),void 0===a&&(a=0),void 0===r&&(r=[0,0]),void 0===i&&(i=[0,1/0]);var o=new Float32Array(16),c=new Float32Array(16),l=new Float32Array(16),u=t.mat4.create(),s=r.slice(0,2).concat([0],[1]),m=[].concat(i),f=function(){return t.mat4.getScaling(o,u)[0]},d=function(e,n,a){void 0===e&&(e=[]);var r=e[0];void 0===r&&(r=0);var i=e[1];void 0===i&&(i=0),void 0===n&&(n=1),void 0===a&&(a=0),u=t.mat4.create(),v([-r,-i]),p(a),g(1/n)},v=function(e){void 0===e&&(e=[]);var n=e[0];void 0===n&&(n=0);var a=e[1];void 0===a&&(a=0),o[0]=n,o[1]=a,o[2]=0;var r=t.mat4.fromTranslation(c,o);t.mat4.multiply(u,r,u)},g=function(e,n){if(!(e<=0)){var a=f(),r=a*e;if(1!==(e=Math.max(m[0],Math.min(r,m[1]))/a)){o[0]=e,o[1]=e,o[2]=1;var i=t.mat4.fromScaling(c,o),d=n?n.concat([0]):s,v=t.mat4.fromTranslation(o,d);t.mat4.multiply(u,v,t.mat4.multiply(u,i,t.mat4.multiply(u,t.mat4.invert(l,v),u)))}}},p=function(e){var n=t.mat4.create();t.mat4.fromRotation(n,e,[0,0,1]),t.mat4.multiply(u,n,u)},y=function(t){!t||t.length<16||(u=t)};return d(e,n,a),{get translation(){return t.mat4.getTranslation(o,u).slice(0,2)},get target(){return t.vec4.transformMat4(o,s,t.mat4.invert(l,u)).slice(0,2)},get scaling(){return f()},get scaleBounds(){return[].concat(m)},get distance(){return 1/f()},get rotation(){return Math.acos(u[0]/f())},get view(){return u},get viewCenter(){return s.slice(0,2)},lookAt:d,translate:v,pan:v,rotate:p,scale:g,zoom:g,reset:function(){d(e,n,a)},set:function(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];return console.warn("`set()` is deprecated. Please use `setView()` instead."),y.apply(void 0,t)},setScaleBounds:function(t){m[0]=t[0],m[1]=t[1]},setView:y,setViewCenter:function(t){s=t.slice(0,2).concat([0],[1])}}}}));
!function(t,a){"object"==typeof exports&&"undefined"!=typeof module?module.exports=a(require("gl-matrix")):"function"==typeof define&&define.amd?define(["gl-matrix"],a):(t="undefined"!=typeof globalThis?globalThis:t||self).createCamera2d=a(t.glMatrix)}(this,(function(t){"use strict";return function(a,r,n,e,i,o){void 0===a&&(a=[0,0]),void 0===r&&(r=1),void 0===n&&(n=0),void 0===e&&(e=[0,0]),void 0===i&&(i=[[0,1/0],[0,1/0]]),void 0===o&&(o=[[-1/0,1/0],[-1/0,1/0]]);var c=new Float32Array(16),s=new Float32Array(16),u=new Float32Array(16),l=t.mat4.create(),m=e.slice(0,2).concat([0],[1]),v=Array.isArray(i[0])?[].concat(i[0]):[].concat(i),f=Array.isArray(i[0])?[].concat(i[1]):[].concat(i),d=Array.isArray(o[0])?[].concat(o[0]):[].concat(o),g=Array.isArray(o[0])?[].concat(o[1]):[].concat(o),y=function(){return t.mat4.getScaling(c,l).slice(0,2)},A=function(){var t=y();return Math.min(t[0],t[1])},p=function(){var t=y();return Math.max(t[0],t[1])},h=function(a,r,n){void 0===a&&(a=[]);var e=a[0];void 0===e&&(e=0);var i=a[1];void 0===i&&(i=0),void 0===r&&(r=1),void 0===n&&(n=0),l=t.mat4.create(),x([-e,-i]),M(n),w(1/r)},x=function(a){void 0===a&&(a=[]);var r=a[0];void 0===r&&(r=0);var n=a[1];void 0===n&&(n=0),c[0]=r,c[1]=n,c[2]=0;var e=t.mat4.fromTranslation(s,c);t.mat4.multiply(l,e,l)},w=function(a,r){var n=Array.isArray(a),e=n?a[0]:a,i=n?a[1]:a;if(!(e<=0||i<=0||1===e&&1===i)){var o=y(),d=o[0]*e,g=o[1]*i;if(e=Math.max(v[0],Math.min(d,v[1]))/o[0],i=Math.max(f[0],Math.min(g,f[1]))/o[1],1!==e||1!==i){c[0]=e,c[1]=i,c[2]=1;var A=t.mat4.fromScaling(s,c),p=r?r.concat([0]):m,h=t.mat4.fromTranslation(c,p);t.mat4.multiply(l,h,t.mat4.multiply(l,A,t.mat4.multiply(l,t.mat4.invert(u,h),l)))}}},M=function(a){var r=t.mat4.create();t.mat4.fromRotation(r,a,[0,0,1]),t.mat4.multiply(l,r,l)},T=function(t){!t||t.length<16||(l=t)};return h(a,r,n),{get translation(){return t.mat4.getTranslation(c,l).slice(0,2)},get target(){return t.vec4.transformMat4(c,m,t.mat4.invert(u,l)).slice(0,2)},get scaling(){return y()},get minScaling(){return A()},get maxScaling(){return p()},get scaleBounds(){return[[].concat(v),[].concat(f)]},get translationBounds(){return[[].concat(d),[].concat(g)]},get distance(){return[1/(t=y())[0],1/t[1]];var t},get minDistance(){return 1/A()},get maxDistance(){return 1/p()},get rotation(){return Math.acos(l[0]/p())},get view(){return l},get viewCenter(){return m.slice(0,2)},lookAt:h,translate:x,pan:x,rotate:M,scale:w,zoom:w,reset:function(){h(a,r,n)},set:function(){for(var t=[],a=arguments.length;a--;)t[a]=arguments[a];return console.warn("`set()` is deprecated. Please use `setView()` instead."),T.apply(void 0,t)},setScaleBounds:function(t){var a=Array.isArray(t[0]);v[0]=a?t[0][0]:t[0],v[1]=a?t[0][1]:t[1],f[0]=a?t[1][0]:t[0],f[1]=a?t[1][1]:t[1]},setTranslationBounds:function(t){var a=Array.isArray(t[0]);d[0]=a?t[0][0]:t[0],d[1]=a?t[0][1]:t[1],g[0]=a?t[1][0]:t[0],g[1]=a?t[1][1]:t[1]},setView:T,setViewCenter:function(t){m=t.slice(0,2).concat([0],[1])}}}}));
{
"name": "camera-2d-simple",
"version": "2.2.1",
"version": "3.0.0",
"description": "2D camera for WebGL",

@@ -20,21 +20,21 @@ "author": "Fritz Lekschas",

"dependencies": {
"gl-matrix": "~3.1.0"
"gl-matrix": "~3.3.0"
},
"peerDependencies": {
"gl-matrix": "~3.1.0"
"gl-matrix": "~3.3.0"
},
"devDependencies": {
"@rollup/plugin-buble": "^0.21.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^v6.10.0",
"@rollup/plugin-buble": "^0.21.3",
"eslint": "^7.32.0",
"eslint-config-prettier": "^v8.3.0",
"esm": "^3.2.25",
"husky": "^4.2.1",
"prettier": "^1.19.1",
"pretty-quick": "^2.0.1",
"rollup": "^1.31.0",
"rollup-plugin-filesize": "^6.2.1",
"rollup-plugin-terser": "^5.2.0",
"rollup-plugin-visualizer": "^3.3.1",
"prettier": "^2.3.2",
"pretty-quick": "^3.1.1",
"rollup": "^2.55.1",
"rollup-plugin-filesize": "^9.1.1",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-visualizer": "^5.5.2",
"tap-spec": "^5.0.0",
"tape": "^4.13.0"
"zora": "^4.1.0"
},

@@ -41,0 +41,0 @@ "scripts": {

# 2D Camera
[![npm version](https://img.shields.io/npm/v/camera-2d-simple.svg)](https://www.npmjs.com/package/camera-2d-simple)
[![stability experimental](https://img.shields.io/badge/stability-experimental-orange.svg)](https://nodejs.org/api/documentation.html#documentation_stability_index)
[![build status](https://travis-ci.org/flekschas/camera-2d.svg?branch=master)](https://travis-ci.org/flekschas/camera-2d)
[![gzipped size](https://img.shields.io/badge/gzipped%20size-0.8%20KB-6ae3c7.svg)](https://unpkg.com/camera-2d-simple)
[![code style prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
[![demo](https://img.shields.io/badge/demo-online-6ae3c7.svg)](https://flekschas.github.io/regl-scatterplot/)
[![npm version](https://img.shields.io/npm/v/camera-2d-simple.svg?color=1a8cff&style=flat-square)](https://www.npmjs.com/package/camera-2d-simple)
[![build status](https://img.shields.io/github/workflow/status/flekschas/camera-2d/build?color=139ce9&style=flat-square)](https://github.com/flekschas/camera-2d/actions?query=workflow%3Abuild)
[![file size](http://img.badgesize.io/https://unpkg.com/camera-2d-simple@2.2.1/dist/camera-2d.min.js?compression=gzip&color=0dacd4&style=flat-square)](https://bundlephobia.com/result?p=camera-2d-simple)
[![code style prettier](https://img.shields.io/badge/code_style-prettier-06bcbe.svg?style=flat-square)](https://github.com/prettier/prettier)
[![demo](https://img.shields.io/badge/demo-online-00cca9.svg?style=flat-square)](https://flekschas.github.io/regl-scatterplot/)

@@ -20,9 +19,11 @@ > Simple camera built on top of gl-matrix for 2D scenes. Heavily inspired by [Mikola's Orbit Camera](https://github.com/mikolalysenko/orbit-camera).

```
npm install camera-2d-simple
npm install camera-2d-simple gl-matrix
```
Note, `gl-matrix` is a required dependency but it's not prebundled!
## API
```javascript
import createCamera from "camera-2d-simple";
import createCamera from 'camera-2d-simple';
```

@@ -32,3 +33,3 @@

<a name="createCamera" href="#createCamera">#</a> <b>createCamera</b>(<i>target = [0,0]</i>, <i>distance = 1</i>, <i>rotation = 0</i>, <i>viewCenter = [0,0]</i>, <i>scaleBounds = [0,Infinity]</i>)
<a name="createCamera" href="#createCamera">#</a> <b>createCamera</b>(<i>target = [0,0]</i>, <i>distance = 1</i>, <i>rotation = 0</i>, <i>viewCenter = [0,0]</i>, <i>scaleBounds = [[0, Infinity], [0, Infinity]]</i>, <i>translationBounds = [[-Infinity, Infinity], [-Infinity, Infinity]]</i>)

@@ -41,3 +42,4 @@ Creates a 2d camera looking at `target` from a certain `distance`.

- `viewCenter` is the center point of the canvas w.r.t the view coordinates. When operating in normalized-device coordinates this must be `[0,0]` but the center can differ when operating in pixel coordinates.
- `scaleBounds` are the min and max allowed scalings.
- `scaleBounds` are the min and max allowed scalings in the x and y direction.
- `translationBounds` are the min and max allowed translation in the x and y direction.

@@ -98,2 +100,4 @@ **Returns** A new 2d camera object

For x and y specific scaling, you can specify a tuple as detla (`[xDelta, yDelta]`).
<a name="camera.zoom" href="#camera.zoom">#</a> camera.<b>zoom</b>(<i>delta</i>, <i>scaleCenter</i>)

@@ -111,2 +115,4 @@

For x and y specific scale bound, you can specify a tuple of tuple (`[[xScaleMin, xScaleMax], [yScaleMin, yScaleMax]]`). Make sure to take special care when using `scale()` in this scenario as the scale can get out of sync.
<a name="camera.setView" href="#camera.setView">#</a> camera.<b>setView</b>(<i>view</i>)

@@ -113,0 +119,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc