Socket
Socket
Sign inDemoInstall

@tensorflow/tfjs-layers

Package Overview
Dependencies
Maintainers
11
Versions
157
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tensorflow/tfjs-layers - npm Package Compare versions

Comparing version 0.6.6 to 0.6.7

dist/tf-layers.esm.js

2

dist/engine/topology.d.ts

@@ -111,2 +111,4 @@ import { DataType, Scalar, serialization, Tensor } from '@tensorflow/tfjs-core';

apply(inputs: Tensor | Tensor[] | SymbolicTensor | SymbolicTensor[], kwargs?: Kwargs): Tensor | Tensor[] | SymbolicTensor | SymbolicTensor[];
readonly outputShape: Shape | Shape[];
countParams(): number;
build(inputShape: Shape | Shape[]): void;

@@ -113,0 +115,0 @@ getWeights(trainableOnly?: boolean): Tensor[];

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

import * as tfc from '@tensorflow/tfjs-core';
import { io, ModelPredictConfig, Optimizer, Scalar, Tensor, Tensor1D } from '@tensorflow/tfjs-core';

@@ -59,3 +60,3 @@ import { Callback, CustomCallbackConfig, History } from '../callbacks';

}
export declare class Model extends Container {
export declare class Model extends Container implements tfc.InferenceModel {
static className: string;

@@ -81,2 +82,3 @@ optimizer: Optimizer;

constructor(config: ContainerConfig);
summary(lineLength?: number, positions?: number[], printFn?: (message?: any, ...optionalParams: any[]) => void): void;
compile(config: ModelCompileConfig): void;

@@ -86,2 +88,4 @@ private checkTrainableWeightsConsistency();

private checkNumSamples(ins, batchSize?, steps?, stepsName?);
execute(inputs: Tensor | Tensor[] | NamedTensorMap, outputs: string | string[]): Tensor | Tensor[];
private retrieveSymbolicTensors(symbolicTensorNames);
private predictLoop(ins, batchSize?, verbose?);

@@ -88,0 +92,0 @@ predict(x: Tensor | Tensor[], config?: ModelPredictConfig): Tensor | Tensor[];

@@ -63,2 +63,3 @@ "use strict";

var generic_utils_1 = require("../utils/generic_utils");
var layer_utils_1 = require("../utils/layer_utils");
var math_utils_1 = require("../utils/math_utils");

@@ -354,2 +355,11 @@ var executor_1 = require("./executor");

}
Model.prototype.summary = function (lineLength, positions, printFn) {
if (printFn === void 0) { printFn = console.log; }
if (!this.built) {
throw new errors_1.ValueError("This model has never been called, thus its weights have not been " +
"created yet. So no summary can be displayed. Build the model " +
"first (e.g., by calling it on some test data).");
}
layer_utils_1.printSummary(this, lineLength, positions, printFn);
};
Model.prototype.compile = function (config) {

@@ -559,2 +569,72 @@ var _this = this;

};
Model.prototype.execute = function (inputs, outputs) {
if (Array.isArray(outputs) && outputs.length === 0) {
throw new errors_1.ValueError('`outputs` is an empty Array, which is not allowed.');
}
var outputsIsArray = Array.isArray(outputs);
var outputNames = (outputsIsArray ? outputs :
[outputs]);
var outputSymbolicTensors = this.retrieveSymbolicTensors(outputNames);
var feedDict = new executor_1.FeedDict();
if (inputs instanceof tfjs_core_1.Tensor) {
inputs = [inputs];
}
if (Array.isArray(inputs)) {
if (inputs.length !== this.inputs.length) {
throw new errors_1.ValueError("The number of inputs provided (" + inputs.length + ") " +
"does not match the number of inputs of this model " +
("(" + this.inputs.length + ")."));
}
for (var i = 0; i < this.inputs.length; ++i) {
feedDict.add(this.inputs[i], inputs[i]);
}
}
else {
for (var _i = 0, _a = this.inputs; _i < _a.length; _i++) {
var input = _a[_i];
var tensorValue = inputs[input.name];
if (tensorValue == null) {
throw new errors_1.ValueError("No value is provided for the model's input " + input.name);
}
feedDict.add(input, tensorValue);
}
}
var executeOutputs = executor_1.execute(outputSymbolicTensors, feedDict);
return outputsIsArray ? executeOutputs : executeOutputs[0];
};
Model.prototype.retrieveSymbolicTensors = function (symbolicTensorNames) {
var outputSymbolicTensors = generic_utils_1.pyListRepeat(null, symbolicTensorNames.length);
var outputsRemaining = symbolicTensorNames.length;
for (var _i = 0, _a = this.layers; _i < _a.length; _i++) {
var layer = _a[_i];
var layerOutputs = Array.isArray(layer.output) ?
layer.output :
[layer.output];
var layerOutputNames = layerOutputs.map(function (output) { return output.name; });
for (var i = 0; i < symbolicTensorNames.length; ++i) {
var index = layerOutputNames.indexOf(symbolicTensorNames[i]);
if (index !== -1) {
outputSymbolicTensors[i] = layerOutputs[index];
outputsRemaining--;
}
if (outputsRemaining === 0) {
break;
}
}
if (outputsRemaining === 0) {
break;
}
}
if (outputsRemaining > 0) {
var remainingNames_1 = [];
outputSymbolicTensors.forEach(function (tensor, i) {
if (tensor == null) {
remainingNames_1.push(symbolicTensorNames[i]);
}
});
throw new errors_1.ValueError("Cannot find SymbolicTensors for output name(s): " +
("" + JSON.stringify(remainingNames_1)));
}
return outputSymbolicTensors;
};
Model.prototype.predictLoop = function (ins, batchSize, verbose) {

@@ -1076,2 +1156,5 @@ var _this = this;

__decorate([
tfjs_core_1.doc({ heading: 'Models', subheading: 'Classes' })
], Model.prototype, "summary", null);
__decorate([
tfjs_core_1.doc({ heading: 'Models', subheading: 'Classes', configParamIndices: [0] })

@@ -1091,2 +1174,5 @@ ], Model.prototype, "compile", null);

], Model.prototype, "fit", null);
__decorate([
tfjs_core_1.doc({ heading: 'Models', subheading: 'Classes', configParamIndices: [1] })
], Model.prototype, "save", null);
Model = __decorate([

@@ -1093,0 +1179,0 @@ tfjs_core_1.doc({ heading: 'Models', subheading: 'Classes' })

4

dist/layers/convolutional_depthwise.d.ts

@@ -7,3 +7,3 @@ import { Tensor } from '@tensorflow/tfjs-core';

import { Kwargs, Shape } from '../types';
import { BaseConvLayerConfig, Conv2D } from './convolutional';
import { BaseConv, BaseConvLayerConfig } from './convolutional';
export declare function depthwiseConv2d(x: Tensor, depthwiseKernel: Tensor, strides?: [number, number], padding?: string, dataFormat?: DataFormat, dilationRate?: [number, number]): Tensor;

@@ -17,3 +17,3 @@ export interface DepthwiseConv2DLayerConfig extends BaseConvLayerConfig {

}
export declare class DepthwiseConv2D extends Conv2D {
export declare class DepthwiseConv2D extends BaseConv {
static className: string;

@@ -20,0 +20,0 @@ private readonly depthMultiplier;

@@ -53,3 +53,3 @@ "use strict";

function DepthwiseConv2D(config) {
var _this = _super.call(this, config) || this;
var _this = _super.call(this, 2, config) || this;
_this.depthwiseKernel = null;

@@ -119,5 +119,5 @@ _this.depthMultiplier =

return DepthwiseConv2D;
}(convolutional_1.Conv2D));
}(convolutional_1.BaseConv));
exports.DepthwiseConv2D = DepthwiseConv2D;
tfjs_core_1.serialization.SerializationMap.register(DepthwiseConv2D);
//# sourceMappingURL=convolutional_depthwise.js.map

@@ -34,5 +34,4 @@ import { serialization, Tensor } from '@tensorflow/tfjs-core';

}
export declare abstract class Conv extends Layer {
export declare abstract class BaseConv extends Layer {
protected readonly rank: number;
protected readonly filters: number;
protected readonly kernelSize: number[];

@@ -42,15 +41,20 @@ protected readonly strides: number[];

protected readonly dataFormat: DataFormat;
protected readonly dilationRate: number | [number] | [number, number];
protected readonly activation: Activation;
protected readonly useBias: boolean;
protected readonly kernelInitializer?: Initializer;
protected readonly dilationRate: number | [number] | [number, number];
protected readonly biasInitializer?: Initializer;
protected readonly kernelConstraint?: Constraint;
protected readonly biasConstraint?: Constraint;
protected readonly kernelRegularizer?: Regularizer;
protected readonly biasRegularizer?: Regularizer;
protected kernel: LayerVariable;
protected bias: LayerVariable;
readonly DEFAULT_KERNEL_INITIALIZER: InitializerIdentifier;
readonly DEFAULT_BIAS_INITIALIZER: InitializerIdentifier;
constructor(rank: number, config: BaseConvLayerConfig);
protected static verifyConfig(config: BaseConvLayerConfig): void;
}
export declare abstract class Conv extends BaseConv {
protected readonly filters: number;
protected kernel: LayerVariable;
protected readonly kernelInitializer?: Initializer;
protected readonly kernelConstraint?: Constraint;
protected readonly kernelRegularizer?: Regularizer;
constructor(rank: number, config: ConvLayerConfig);

@@ -61,2 +65,3 @@ build(inputShape: Shape | Shape[]): void;

getConfig(): serialization.ConfigDict;
protected static verifyConfig(config: ConvLayerConfig): void;
}

@@ -67,2 +72,3 @@ export declare class Conv2D extends Conv {

getConfig(): serialization.ConfigDict;
protected static verifyConfig(config: ConvLayerConfig): void;
}

@@ -113,2 +119,3 @@ export declare class Conv2DTranspose extends Conv2D {

getConfig(): serialization.ConfigDict;
static verifyConfig(config: ConvLayerConfig): void;
}

@@ -115,0 +122,0 @@ export interface Cropping2DLayerConfig extends LayerConfig {

@@ -125,10 +125,10 @@ "use strict";

exports.conv2dWithBias = conv2dWithBias;
var Conv = (function (_super) {
__extends(Conv, _super);
function Conv(rank, config) {
var BaseConv = (function (_super) {
__extends(BaseConv, _super);
function BaseConv(rank, config) {
var _this = _super.call(this, config) || this;
_this.kernel = null;
_this.bias = null;
_this.DEFAULT_KERNEL_INITIALIZER = 'glorotNormal';
_this.DEFAULT_BIAS_INITIALIZER = 'zeros';
BaseConv.verifyConfig(config);
_this.rank = rank;

@@ -139,3 +139,2 @@ if (_this.rank !== 1 && _this.rank !== 2) {

}
_this.filters = config.filters;
_this.kernelSize = conv_utils_1.normalizeArray(config.kernelSize, rank, 'kernelSize');

@@ -148,2 +147,9 @@ _this.strides = conv_utils_1.normalizeArray(config.strides == null ? 1 : config.strides, rank, 'strides');

common_2.checkDataFormat(_this.dataFormat);
_this.activation = activations_1.getActivation(config.activation);
_this.useBias = config.useBias == null ? true : config.useBias;
_this.biasInitializer =
initializers_1.getInitializer(config.biasInitializer || _this.DEFAULT_BIAS_INITIALIZER);
_this.biasConstraint = constraints_1.getConstraint(config.biasConstraint);
_this.biasRegularizer = regularizers_1.getRegularizer(config.biasRegularizer);
_this.activityRegularizer = regularizers_1.getRegularizer(config.activityRegularizer);
_this.dilationRate = config.dilationRate == null ? 1 : config.dilationRate;

@@ -166,12 +172,24 @@ if (_this.rank === 1 &&

}
_this.activation = activations_1.getActivation(config.activation);
_this.useBias = config.useBias == null ? true : config.useBias;
return _this;
}
BaseConv.verifyConfig = function (config) {
generic_utils.assert('kernelSize' in config, "required key 'kernelSize' not in config");
if (typeof config.kernelSize !== 'number' &&
!generic_utils.checkArrayTypeAndLength(config.kernelSize, 'number', 1, 2))
throw new errors_1.ValueError("BaseConv expects config.kernelSize to be number or number[] with " +
("length 1 or 2, but received " + JSON.stringify(config.kernelSize) + "."));
};
return BaseConv;
}(topology_1.Layer));
exports.BaseConv = BaseConv;
var Conv = (function (_super) {
__extends(Conv, _super);
function Conv(rank, config) {
var _this = _super.call(this, rank, config) || this;
_this.kernel = null;
Conv.verifyConfig(config);
_this.filters = config.filters;
_this.kernelInitializer = initializers_1.getInitializer(config.kernelInitializer || _this.DEFAULT_KERNEL_INITIALIZER);
_this.biasInitializer =
initializers_1.getInitializer(config.biasInitializer || _this.DEFAULT_BIAS_INITIALIZER);
_this.kernelConstraint = constraints_1.getConstraint(config.kernelConstraint);
_this.biasConstraint = constraints_1.getConstraint(config.biasConstraint);
_this.kernelRegularizer = regularizers_1.getRegularizer(config.kernelRegularizer);
_this.biasRegularizer = regularizers_1.getRegularizer(config.biasRegularizer);
_this.activityRegularizer = regularizers_1.getRegularizer(config.activityRegularizer);
return _this;

@@ -262,4 +280,11 @@ }

};
Conv.verifyConfig = function (config) {
if (!('filters' in config) || typeof config.filters !== 'number' ||
config.filters < 1) {
throw new errors_1.ValueError("Convolution layer expected config.filters to be a 'number' > 0 " +
("but got " + JSON.stringify(config.filters)));
}
};
return Conv;
}(topology_1.Layer));
}(BaseConv));
exports.Conv = Conv;

@@ -269,3 +294,5 @@ var Conv2D = (function (_super) {

function Conv2D(config) {
return _super.call(this, 2, config) || this;
var _this = _super.call(this, 2, config) || this;
Conv2D.verifyConfig(config);
return _this;
}

@@ -277,2 +304,8 @@ Conv2D.prototype.getConfig = function () {

};
Conv2D.verifyConfig = function (config) {
if ((typeof config.kernelSize !== 'number') &&
!generic_utils.checkArrayTypeAndLength(config.kernelSize, 'number', 1, 2))
throw new errors_1.ValueError("Conv2D expects config.kernelSize to be number or number[] with " +
("length 1 or 2, but received " + JSON.stringify(config.kernelSize) + "."));
};
Conv2D.className = 'Conv2D';

@@ -530,2 +563,3 @@ return Conv2D;

var _this = _super.call(this, 1, config) || this;
Conv1D.verifyConfig(config);
_this.inputSpec = [{ ndim: 3 }];

@@ -540,2 +574,8 @@ return _this;

};
Conv1D.verifyConfig = function (config) {
if (typeof config.kernelSize !== 'number' &&
!generic_utils.checkArrayTypeAndLength(config.kernelSize, 'number', 1, 1))
throw new errors_1.ValueError("Conv1D expects config.kernelSize to be number or number[] with " +
("length 1, but received " + JSON.stringify(config.kernelSize) + "."));
};
Conv1D.className = 'Conv1D';

@@ -542,0 +582,0 @@ return Conv1D;

@@ -33,3 +33,3 @@ import { serialization, Tensor } from '@tensorflow/tfjs-core';

poolSize?: number | [number, number];
strides?: [number, number];
strides?: number | [number, number];
padding?: PaddingMode;

@@ -36,0 +36,0 @@ dataFormat?: DataFormat;

@@ -169,3 +169,16 @@ "use strict";

[config.poolSize, config.poolSize];
_this.strides = config.strides == null ? _this.poolSize : config.strides;
if (config.strides == null) {
_this.strides = _this.poolSize;
}
else if (Array.isArray(config.strides)) {
if (config.strides.length !== 2) {
throw new errors_1.ValueError("If the strides property of a 2D pooling layer is an Array, " +
"it is expected to have a length of 2, but received length " +
(config.strides.length + "."));
}
_this.strides = config.strides;
}
else {
_this.strides = [config.strides, config.strides];
}
_this.padding = config.padding == null ? 'valid' : config.padding;

@@ -172,0 +185,0 @@ _this.dataFormat =

@@ -175,2 +175,3 @@ import * as tfc from '@tensorflow/tfjs-core';

export interface GRULayerConfig extends SimpleRNNLayerConfig {
recurrentActivation?: string;
implementation?: number;

@@ -184,2 +185,3 @@ }

readonly activation: Activation;
readonly recurrentActivation: Activation;
readonly useBias: boolean;

@@ -240,2 +242,3 @@ readonly kernelInitializer: Initializer;

export interface LSTMLayerConfig extends SimpleRNNLayerConfig {
recurrentActivation?: string;
unitForgetBias?: boolean;

@@ -250,2 +253,3 @@ implementation?: 1 | 2;

readonly activation: Activation;
readonly recurrentActivation: Activation;
readonly useBias: boolean;

@@ -252,0 +256,0 @@ readonly kernelInitializer: Initializer;

@@ -32,2 +32,4 @@ import { io, Scalar, serialization, Tensor } from '@tensorflow/tfjs-core';

build(inputShape?: Shape | Shape[]): void;
countParams(): number;
summary(lineLength?: number, positions?: number[], printFn?: (message?: any, ...optionalParams: any[]) => void): void;
setWeights(weights: Tensor[]): void;

@@ -34,0 +36,0 @@ updatable: boolean;

@@ -216,2 +216,3 @@ "use strict";

}
this.inboundNodes = [];
new topology_1.Node({

@@ -295,2 +296,15 @@ outboundLayer: this,

};
Sequential.prototype.countParams = function () {
if (!this.built) {
this.build();
}
return _super.prototype.countParams.call(this);
};
Sequential.prototype.summary = function (lineLength, positions, printFn) {
if (printFn === void 0) { printFn = console.log; }
if (!this.built) {
this.build();
}
_super.prototype.summary.call(this, lineLength, positions, printFn);
};
Sequential.prototype.setWeights = function (weights) {

@@ -390,2 +404,5 @@ if (this.model == null) {

__decorate([
tfjs_core_1.doc({ heading: 'Models', subheading: 'Classes' })
], Sequential.prototype, "summary", null);
__decorate([
tfjs_core_1.doc({ heading: 'Models', subheading: 'Classes', configParamIndices: [2] })

@@ -392,0 +409,0 @@ ], Sequential.prototype, "evaluate", null);

@@ -9,3 +9,5 @@ "use strict";

'Adagrad': function () { return tfjs_core_1.train.adagrad(.01); },
'Adadelta': function () { return tfjs_core_1.train.adadelta(1.0, 0.95, K.epsilon()); },
'Adam': function () { return tfjs_core_1.train.adam(.001, .9, .999, K.epsilon()); },
'Adamax': function () { return tfjs_core_1.train.adamax(0.002, .9, .999, K.epsilon(), 0.0); },
'RMSProp': function () { return tfjs_core_1.train.rmsprop(.001, .9, null, K.epsilon()); },

@@ -15,3 +17,5 @@ 'SGD': function () { return tfjs_core_1.train.sgd(.01); }

optimizerMap['adagrad'] = optimizerMap['Adagrad'];
optimizerMap['adadelta'] = optimizerMap['Adadelta'];
optimizerMap['adam'] = optimizerMap['Adam'];
optimizerMap['adamax'] = optimizerMap['Adamax'];
optimizerMap['rmsprop'] = optimizerMap['RMSProp'];

@@ -18,0 +22,0 @@ optimizerMap['sgd'] = optimizerMap['SGD'];

@@ -13,3 +13,3 @@ import { DataType, Scalar, Tensor } from '@tensorflow/tfjs-core';

readonly id: number;
readonly name?: string;
readonly name: string;
readonly originalName?: string;

@@ -16,0 +16,0 @@ readonly rank: number;

import { DataType, serialization, Tensor } from '@tensorflow/tfjs-core';
import { Shape } from '../types';
import { LayerVariable } from '../variables';
export declare function pyListRepeat(value: any, numValues: number): any[];

@@ -28,1 +29,3 @@ export declare function assert(val: boolean, message?: string): void;

export declare function checkStringTypeUnionValue(values: string[], label: string, value: string): void;
export declare function checkArrayTypeAndLength(x: any, expectedType: string, minLength?: number, maxLength?: number): boolean;
export declare function countParamsInWeights(weights: LayerVariable[]): number;

@@ -288,2 +288,25 @@ "use strict";

exports.checkStringTypeUnionValue = checkStringTypeUnionValue;
function checkArrayTypeAndLength(x, expectedType, minLength, maxLength) {
if (minLength === void 0) { minLength = 0; }
if (maxLength === void 0) { maxLength = Infinity; }
assert(minLength >= 0);
assert(maxLength >= minLength);
return (Array.isArray(x) && x.length >= minLength && x.length <= maxLength &&
x.every(function (e) { return typeof e === expectedType; }));
}
exports.checkArrayTypeAndLength = checkArrayTypeAndLength;
function countParamsInWeights(weights) {
var count = 0;
for (var _i = 0, weights_1 = weights; _i < weights_1.length; _i++) {
var weight = weights_1[_i];
if (weight.shape.length === 0) {
count += 1;
}
else {
count += weight.shape.reduce(function (a, b) { return a * b; });
}
}
return count;
}
exports.countParamsInWeights = countParamsInWeights;
//# sourceMappingURL=generic_utils.js.map

@@ -25,3 +25,3 @@ "use strict";

function describeMathCPUAndGPU(testName, tests) {
jasmine_util_1.describeWithFlags(testName, {}, function () {
jasmine_util_1.describeWithFlags(testName, tfjs_core_1.test_util.ALL_ENVS, function () {
beforeEach(function () {

@@ -28,0 +28,0 @@ tfjs_backend_1.disposeScalarCache();

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

declare const version = "0.6.6";
declare const version = "0.6.7";
export { version };
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var version = '0.6.6';
var version = '0.6.7';
exports.version = version;
//# sourceMappingURL=version.js.map
{
"name": "@tensorflow/tfjs-layers",
"version": "0.6.6",
"version": "0.6.7",
"description": "TensorFlow layers API in JavaScript",

@@ -8,10 +8,10 @@ "private": false,

"types": "dist/index.d.ts",
"jsnext:main": "dist-es6/index.js",
"module": "dist-es6/index.js",
"jsnext:main": "dist/tf-layers.esm.js",
"module": "dist/tf-layers.esm.js",
"jsdelivr": "dist/tf-layers.min.js",
"unpkg": "dist/tf-layers.min.js",
"devDependencies": {
"@tensorflow/tfjs-core": "~0.11.6",
"@tensorflow/tfjs-core": "~0.11.9",
"@types/jasmine": "~2.5.53",
"browserify": "~16.1.0",
"clang-format": "~1.2.2",
"cross-spawn": "~5.1.0",
"http-server": "~0.10.0",

@@ -25,5 +25,2 @@ "jasmine-core": "~3.1.0",

"karma-typescript": "^3.0.12",
"karma-typescript-es6-transform": "~1.0.4",
"minimist": "~1.2.0",
"opn": "~5.1.0",
"rimraf": "~2.6.2",

@@ -34,12 +31,9 @@ "rollup": "^0.58.2",

"rollup-plugin-typescript2": "0.13.0",
"rollup-plugin-uglify": "^4.0.0",
"tsify": "~3.0.1",
"rollup-plugin-uglify": "~3.0.0",
"tslint": "~5.6.0",
"typedoc": "~0.8.0",
"typescript": "2.8.3",
"watchify": "~3.9.0",
"yalc": "~1.0.0-pre.21"
},
"scripts": {
"build": "tsc --project tsconfig-es5.json && tsc",
"build": "tsc",
"build-npm": "./scripts/build-npm.sh",

@@ -56,4 +50,4 @@ "format": "./tools/clang_format_ts.sh",

"peerDependencies": {
"@tensorflow/tfjs-core": "~0.11.6"
"@tensorflow/tfjs-core": "~0.11.9"
}
}
{
"compilerOptions": {
"module": "ES2015",
"module": "commonjs",
"moduleResolution": "node",

@@ -12,3 +12,3 @@ "noImplicitAny": true,

"lib": ["es2015", "dom"],
"outDir": "./dist-es6",
"outDir": "./dist",
"noUnusedLocals": true,

@@ -15,0 +15,0 @@ "noImplicitReturns": true,

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

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