Socket
Socket
Sign inDemoInstall

level-codec

Package Overview
Dependencies
Maintainers
3
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

level-codec - npm Package Compare versions

Comparing version 8.0.0 to 9.0.0

143

index.js

@@ -1,106 +0,107 @@

var encodings = require('./lib/encodings');
var encodings = require('./lib/encodings')
module.exports = Codec;
module.exports = Codec
function Codec(opts){
this.opts = opts || {};
this.encodings = encodings;
function Codec (opts) {
if (!(this instanceof Codec)) {
return new Codec(opts)
}
this.opts = opts || {}
this.encodings = encodings
}
Codec.prototype._encoding = function(encoding){
if (typeof encoding == 'string') encoding = encodings[encoding];
if (!encoding) encoding = encodings.id;
return encoding;
};
Codec.prototype._encoding = function (encoding) {
if (typeof encoding === 'string') encoding = encodings[encoding]
if (!encoding) encoding = encodings.id
return encoding
}
Codec.prototype._keyEncoding = function(opts, batchOpts){
return this._encoding(batchOpts && batchOpts.keyEncoding
|| opts && opts.keyEncoding
|| this.opts.keyEncoding);
};
Codec.prototype._keyEncoding = function (opts, batchOpts) {
return this._encoding((batchOpts && batchOpts.keyEncoding) ||
(opts && opts.keyEncoding) ||
this.opts.keyEncoding)
}
Codec.prototype._valueEncoding = function(opts, batchOpts){
return this._encoding(
batchOpts && (batchOpts.valueEncoding || batchOpts.encoding)
|| opts && (opts.valueEncoding || opts.encoding)
|| (this.opts.valueEncoding || this.opts.encoding));
};
Codec.prototype._valueEncoding = function (opts, batchOpts) {
return this._encoding((batchOpts && (batchOpts.valueEncoding || batchOpts.encoding)) ||
(opts && (opts.valueEncoding || opts.encoding)) ||
(this.opts.valueEncoding || this.opts.encoding))
}
Codec.prototype.encodeKey = function(key, opts, batchOpts){
return this._keyEncoding(opts, batchOpts).encode(key);
};
Codec.prototype.encodeKey = function (key, opts, batchOpts) {
return this._keyEncoding(opts, batchOpts).encode(key)
}
Codec.prototype.encodeValue = function(value, opts, batchOpts){
return this._valueEncoding(opts, batchOpts).encode(value);
};
Codec.prototype.encodeValue = function (value, opts, batchOpts) {
return this._valueEncoding(opts, batchOpts).encode(value)
}
Codec.prototype.decodeKey = function(key, opts){
return this._keyEncoding(opts).decode(key);
};
Codec.prototype.decodeKey = function (key, opts) {
return this._keyEncoding(opts).decode(key)
}
Codec.prototype.decodeValue = function(value, opts){
return this._valueEncoding(opts).decode(value);
};
Codec.prototype.decodeValue = function (value, opts) {
return this._valueEncoding(opts).decode(value)
}
Codec.prototype.encodeBatch = function(ops, opts){
var self = this;
Codec.prototype.encodeBatch = function (ops, opts) {
var self = this
return ops.map(function(_op){
return ops.map(function (_op) {
var op = {
type: _op.type,
key: self.encodeKey(_op.key, opts, _op)
};
if (self.keyAsBuffer(opts, _op)) op.keyEncoding = 'binary';
if (_op.prefix) op.prefix = _op.prefix;
}
if (self.keyAsBuffer(opts, _op)) op.keyEncoding = 'binary'
if (_op.prefix) op.prefix = _op.prefix
if ('value' in _op) {
op.value = self.encodeValue(_op.value, opts, _op);
if (self.valueAsBuffer(opts, _op)) op.valueEncoding = 'binary';
op.value = self.encodeValue(_op.value, opts, _op)
if (self.valueAsBuffer(opts, _op)) op.valueEncoding = 'binary'
}
return op;
});
};
return op
})
}
var ltgtKeys = ['lt', 'gt', 'lte', 'gte', 'start', 'end'];
var ltgtKeys = ['lt', 'gt', 'lte', 'gte', 'start', 'end']
Codec.prototype.encodeLtgt = function(ltgt){
var self = this;
var ret = {};
Object.keys(ltgt).forEach(function(key){
Codec.prototype.encodeLtgt = function (ltgt) {
var self = this
var ret = {}
Object.keys(ltgt).forEach(function (key) {
ret[key] = ltgtKeys.indexOf(key) > -1
? self.encodeKey(ltgt[key], ltgt)
: ltgt[key]
});
return ret;
};
})
return ret
}
Codec.prototype.createStreamDecoder = function(opts){
var self = this;
Codec.prototype.createStreamDecoder = function (opts) {
var self = this
if (opts.keys && opts.values) {
return function(key, value){
return function (key, value) {
return {
key: self.decodeKey(key, opts),
value: self.decodeValue(value, opts)
};
};
}
}
} else if (opts.keys) {
return function(key) {
return self.decodeKey(key, opts);
};
return function (key) {
return self.decodeKey(key, opts)
}
} else if (opts.values) {
return function(_, value){
return self.decodeValue(value, opts);
return function (_, value) {
return self.decodeValue(value, opts)
}
} else {
return function(){};
return function () {}
}
};
}
Codec.prototype.keyAsBuffer = function(opts){
return this._keyEncoding(opts).buffer;
};
Codec.prototype.keyAsBuffer = function (opts) {
return this._keyEncoding(opts).buffer
}
Codec.prototype.valueAsBuffer = function(opts){
return this._valueEncoding(opts).buffer;
};
Codec.prototype.valueAsBuffer = function (opts) {
return this._valueEncoding(opts).buffer
}
exports.utf8 = exports['utf-8'] = {
encode: function(data){
return isBinary(data)
? data
: String(data);
encode: function (data) {
return isBinary(data) ? data : String(data)
},

@@ -10,3 +8,3 @@ decode: identity,

type: 'utf8'
};
}

@@ -18,9 +16,7 @@ exports.json = {

type: 'json'
};
}
exports.binary = {
encode: function(data){
return isBinary(data)
? data
: new Buffer(data);
encode: function (data) {
return isBinary(data) ? data : Buffer.from(data)
},

@@ -30,3 +26,3 @@ decode: identity,

type: 'binary'
};
}

@@ -38,5 +34,5 @@ exports.none = {

type: 'id'
};
}
exports.id = exports.none;
exports.id = exports.none

@@ -51,27 +47,23 @@ var bufferEncodings = [

'utf-16le'
];
]
bufferEncodings.forEach(function(type){
bufferEncodings.forEach(function (type) {
exports[type] = {
encode: function(data){
return isBinary(data)
? data
: new Buffer(data, type);
encode: function (data) {
return isBinary(data) ? data : Buffer.from(data, type)
},
decode: function(buffer){
return buffer.toString(type);
decode: function (buffer) {
return buffer.toString(type)
},
buffer: true,
type: type
};
});
}
})
function identity(value){
return value;
function identity (value) {
return value
}
function isBinary(data){
return data === undefined
|| data === null
|| Buffer.isBuffer(data);
function isBinary (data) {
return data === undefined || data === null || Buffer.isBuffer(data)
}
{
"name": "level-codec",
"repository": "Level/codec",
"version": "8.0.0",
"version": "9.0.0",
"description": "Levelup's encoding logic",
"license": "MIT",
"devDependencies": {
"standard": "^11.0.1",
"tape": "^4.3.0"

@@ -13,5 +14,8 @@ },

"scripts": {
"test": "make test"
"test": "tape test/*.js && standard"
},
"engines": {
"node": ">=6"
},
"dependencies": {}
}

@@ -7,57 +7,63 @@ # level-codec

[![npm](https://img.shields.io/npm/v/level-codec.svg)](https://www.npmjs.com/package/level-codec)
![Node version](https://img.shields.io/node/v/level-codec.svg)
[![Travis](https://travis-ci.org/Level/codec.svg?branch=master)](https://travis-ci.org/Level/codec)
[![david](https://david-dm.org/Level/codec.svg)](https://david-dm.org/level/codec)
[![npm](https://img.shields.io/npm/dm/level-codec.svg)](https://www.npmjs.com/package/level-codec)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
## API
## Usage
### Codec([opts])
```js
const Codec = require('level-codec')
const codec = Codec({ keyEncoding: 'json' })
const key = codec.encodeKey({ foo: 'bar' })
console.log(key) // -> '{"foo":"bar"}'
console.log(codec.decodeKey(key)) // -> { foo: 'bar' }
```
Create a new codec, with a global options object.
## API
This could be something like
### `codec = Codec([opts])`
```js
var codec = new Codec(db.options);
```
Create a new codec, with a global options object.
### #encodeKey(key[, opts])
### `codec.encodeKey(key[, opts])`
Encode `key` with given `opts`.
Encode `key` with given `opts`.
### #encodeValue(value[, opts])
### `codec.encodeValue(value[, opts])`
Encode `value` with given `opts`.
Encode `value` with given `opts`.
### #encodeBatch(batch[, opts])
### `codec.encodeBatch(batch[, opts])`
Encode `batch` ops with given `opts`.
Encode `batch` ops with given `opts`.
### #encodeLtgt(ltgt)
### `codec.encodeLtgt(ltgt)`
Encode the ltgt values of option object `ltgt`.
Encode the ltgt values of option object `ltgt`.
### #decodeKey(key[, opts])
### `codec.decodeKey(key[, opts])`
Decode `key` with given `opts`.
Decode `key` with given `opts`.
### #decodeValue(value[, opts])
### `codec.decodeValue(value[, opts])`
Decode `value` with given `opts`.
Decode `value` with given `opts`.
### #createStreamDecoder([opts])
### `codec.createStreamDecoder([opts])`
Create a function with signature `(key, value)`, that for each key/value pair returned from a levelup read stream returns the decoded value to be emitted.
Create a function with signature `(key, value)`, that for each key-value pair returned from a levelup read stream returns the decoded value to be emitted.
### #keyAsBuffer([opts])
### `codec.keyAsBuffer([opts])`
Check whether `opts` and the global `opts` call for a binary key encoding.
Check whether `opts` and the global `opts` call for a binary key encoding.
### #valueAsBuffer([opts])
### `codec.valueAsBuffer([opts])`
Check whether `opts` and the global `opts` call for a binary value encoding.
Check whether `opts` and the global `opts` call for a binary value encoding.
### #encodings
### `codec.encodings`
The builtin encodings as object of form
The builtin encodings as object of form

@@ -72,3 +78,3 @@ ```js

## Builtin encodings
## Builtin Encodings

@@ -85,3 +91,3 @@ | Type | Input | Stored as | Output

## Encoding format
## Encoding Format

@@ -111,13 +117,8 @@ An encoding is an object of the form:

## Publishers
## License
* [@juliangruber](https://github.com/juliangruber)
* [@ralphtheninja](https://github.com/ralphtheninja)
Copyright (c) 2012-2018 `level-codec` contributors.
## License & copyright
`level-codec` is licensed under the MIT license. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE.md file for more details.
Copyright (c) 2012-2017 `levelup` contributors.
`levelup` is licensed under the MIT license. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE.md file for more details.
[level-badge]: http://leveldb.org/img/badge.svg

@@ -124,0 +125,0 @@ [`encoding-down`]: https://github.com/level/encoding-down

@@ -1,19 +0,18 @@

var test = require('tape');
var Codec = require('..');
var test = require('tape')
var Codec = require('..')
test('key as buffer', function(t){
var codec = new Codec({ keyEncoding: 'hex' });
t.ok(codec.keyAsBuffer({}));
t.ok(codec.keyAsBuffer());
t.notOk(codec.keyAsBuffer({ keyEncoding: 'utf8' }));
t.end();
});
test('key as buffer', function (t) {
var codec = new Codec({ keyEncoding: 'hex' })
t.ok(codec.keyAsBuffer({}))
t.ok(codec.keyAsBuffer())
t.notOk(codec.keyAsBuffer({ keyEncoding: 'utf8' }))
t.end()
})
test('value as buffer', function(t){
var codec = new Codec({ valueEncoding: 'hex' });
t.ok(codec.valueAsBuffer({}));
t.ok(codec.valueAsBuffer());
t.notOk(codec.valueAsBuffer({ valueEncoding: 'utf8' }));
t.end();
});
test('value as buffer', function (t) {
var codec = new Codec({ valueEncoding: 'hex' })
t.ok(codec.valueAsBuffer({}))
t.ok(codec.valueAsBuffer())
t.notOk(codec.valueAsBuffer({ valueEncoding: 'utf8' }))
t.end()
})

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

var test = require('tape');
var Codec = require('..');
var test = require('tape')
var Codec = require('..')
test('batch', function(t){
var codec = new Codec({});
test('batch', function (t) {
var codec = new Codec({})
var ops = [
{ type: 'put', key: 'string', value: 'string', valueEncoding: 'utf8' },
{ type: 'put', key: 'json', value: {} }
];
var opsSerialized = JSON.stringify(ops);
]
var opsSerialized = JSON.stringify(ops)
var encoded = codec.encodeBatch(ops, { valueEncoding: 'json' });
var encoded = codec.encodeBatch(ops, { valueEncoding: 'json' })
t.equal(opsSerialized, JSON.stringify(ops), 'ops not changed');
t.equal(opsSerialized, JSON.stringify(ops), 'ops not changed')

@@ -19,25 +19,24 @@ t.deepEqual(encoded, [

{ type: 'put', key: 'json', value: '{}' }
]);
])
encoded = codec.encodeBatch(ops);
encoded = codec.encodeBatch(ops)
t.deepEqual(encoded, [
{ type: 'put', key: 'string', value: 'string' },
{ type: 'put', key: 'json', value: {} }
]);
])
t.end();
});
t.end()
})
test('batch - legacy', function(t){
var codec = new Codec({});
test('batch - legacy', function (t) {
var codec = new Codec({})
var ops = [
{ type: 'put', key: 'string', value: 'string', encoding: 'utf8' },
{ type: 'put', key: 'json', value: {} }
];
var opsSerialized = JSON.stringify(ops);
]
var opsSerialized = JSON.stringify(ops)
var encoded = codec.encodeBatch(ops, { encoding: 'json' });
var encoded = codec.encodeBatch(ops, { encoding: 'json' })
t.equal(opsSerialized, JSON.stringify(ops), 'ops not changed');
t.equal(opsSerialized, JSON.stringify(ops), 'ops not changed')

@@ -47,12 +46,11 @@ t.deepEqual(encoded, [

{ type: 'put', key: 'json', value: '{}' }
]);
])
encoded = codec.encodeBatch(ops);
encoded = codec.encodeBatch(ops)
t.deepEqual(encoded, [
{ type: 'put', key: 'string', value: 'string' },
{ type: 'put', key: 'json', value: {} }
]);
])
t.end();
});
t.end()
})

@@ -1,11 +0,18 @@

var test = require('tape');
var Codec = require('..');
var test = require('tape')
var Codec = require('..')
test('codec', function(t){
var codec = new Codec({ keyEncoding: 'hex' });
t.ok(codec.keyAsBuffer());
var codec = new Codec();
t.notOk(codec.keyAsBuffer());
t.end();
});
test('codec', function (t) {
var codec = new Codec({ keyEncoding: 'hex' })
t.ok(codec.keyAsBuffer())
codec = new Codec()
t.notOk(codec.keyAsBuffer())
t.end()
})
test('codec, new not needed', function (t) {
var codec = Codec({ keyEncoding: 'hex' })
t.ok(codec.keyAsBuffer())
codec = Codec()
t.notOk(codec.keyAsBuffer())
t.end()
})

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

var test = require('tape');
var Codec = require('..');
var test = require('tape')
var Codec = require('..')
test('createStreamDecoder', function(t){
var codec = new Codec({ keyEncoding: 'hex' });
test('createStreamDecoder', function (t) {
var codec = new Codec({ keyEncoding: 'hex' })
t.test('keys and values', function(t){
t.test('keys and values', function (t) {
var decoder = codec.createStreamDecoder({

@@ -12,32 +12,32 @@ valueEncoding: 'json',

values: true
});
t.deepEqual(decoder(new Buffer('hey'), '"you"'), {
})
t.deepEqual(decoder(Buffer.from('hey'), '"you"'), {
key: '686579',
value: 'you'
});
t.end();
});
})
t.end()
})
t.test('keys', function(t){
t.test('keys', function (t) {
var decoder = codec.createStreamDecoder({
keys: true
});
t.equal(decoder(new Buffer('hey')), '686579');
t.end();
});
})
t.equal(decoder(Buffer.from('hey')), '686579')
t.end()
})
t.test('values', function(t){
t.test('values', function (t) {
var decoder = codec.createStreamDecoder({
valueEncoding: 'hex',
values: true
});
t.equal(decoder(null, new Buffer('hey')), '686579');
t.end();
});
});
})
t.equal(decoder(null, Buffer.from('hey')), '686579')
t.end()
})
})
test('createStreamDecoder - legacy', function(t){
var codec = new Codec({ keyEncoding: 'hex' });
test('createStreamDecoder - legacy', function (t) {
var codec = new Codec({ keyEncoding: 'hex' })
t.test('keys and values', function(t){
t.test('keys and values', function (t) {
var decoder = codec.createStreamDecoder({

@@ -47,26 +47,26 @@ encoding: 'json',

values: true
});
t.deepEqual(decoder(new Buffer('hey'), '"you"'), {
})
t.deepEqual(decoder(Buffer.from('hey'), '"you"'), {
key: '686579',
value: 'you'
});
t.end();
});
})
t.end()
})
t.test('keys', function(t){
t.test('keys', function (t) {
var decoder = codec.createStreamDecoder({
keys: true
});
t.equal(decoder(new Buffer('hey')), '686579');
t.end();
});
})
t.equal(decoder(Buffer.from('hey')), '686579')
t.end()
})
t.test('values', function(t){
t.test('values', function (t) {
var decoder = codec.createStreamDecoder({
encoding: 'hex',
values: true
});
t.equal(decoder(null, new Buffer('hey')), '686579');
t.end();
});
});
})
t.equal(decoder(null, Buffer.from('hey')), '686579')
t.end()
})
})

@@ -1,110 +0,109 @@

var test = require('tape');
var Codec = require('..');
var test = require('tape')
var Codec = require('..')
test('encode key', function(t){
var codec = new Codec({ keyEncoding: 'hex' });
test('encode key', function (t) {
var codec = new Codec({ keyEncoding: 'hex' })
var buf = codec.encodeKey('686579', {});
t.equal(buf.toString(), 'hey');
var buf = codec.encodeKey('686579', {})
t.equal(buf.toString(), 'hey')
buf = codec.encodeKey('686579');
t.equal(buf.toString(), 'hey');
buf = codec.encodeKey('686579')
t.equal(buf.toString(), 'hey')
buf = codec.encodeKey('686579', {
keyEncoding: 'binary'
});
t.equal(buf.toString(), '686579');
})
t.equal(buf.toString(), '686579')
buf = codec.encodeKey({ foo: 'bar' }, {
keyEncoding: 'none'
});
t.deepEqual(buf, { foo: 'bar' });
})
t.deepEqual(buf, { foo: 'bar' })
t.end();
});
t.end()
})
test('encode value', function(t){
var codec = new Codec({ valueEncoding: 'hex' });
test('encode value', function (t) {
var codec = new Codec({ valueEncoding: 'hex' })
var buf = codec.encodeValue('686579', {});
t.equal(buf.toString(), 'hey');
var buf = codec.encodeValue('686579', {})
t.equal(buf.toString(), 'hey')
buf = codec.encodeValue('686579');
t.equal(buf.toString(), 'hey');
buf = codec.encodeValue('686579')
t.equal(buf.toString(), 'hey')
buf = codec.encodeValue('686579', {
valueEncoding: 'binary'
});
t.equal(buf.toString(), '686579');
})
t.equal(buf.toString(), '686579')
t.end();
});
t.end()
})
test('decode key', function(t){
var codec = new Codec({ keyEncoding: 'hex' });
test('decode key', function (t) {
var codec = new Codec({ keyEncoding: 'hex' })
var buf = codec.decodeKey(new Buffer('hey'), {});
t.equal(buf, '686579');
var buf = codec.decodeKey(Buffer.from('hey'), {})
t.equal(buf, '686579')
buf = codec.decodeKey(new Buffer('hey'));
t.equal(buf, '686579');
buf = codec.decodeKey(Buffer.from('hey'))
t.equal(buf, '686579')
buf = codec.decodeKey(new Buffer('hey'), {
buf = codec.decodeKey(Buffer.from('hey'), {
keyEncoding: 'binary'
});
t.equal(buf.toString(), 'hey');
})
t.equal(buf.toString(), 'hey')
t.end();
});
t.end()
})
test('decode value', function(t){
var codec = new Codec({ valueEncoding: 'hex' });
test('decode value', function (t) {
var codec = new Codec({ valueEncoding: 'hex' })
var buf = codec.decodeValue(new Buffer('hey'), {});
t.equal(buf, '686579');
var buf = codec.decodeValue(Buffer.from('hey'), {})
t.equal(buf, '686579')
buf = codec.decodeValue(new Buffer('hey'));
t.equal(buf, '686579');
buf = codec.decodeValue(Buffer.from('hey'))
t.equal(buf, '686579')
buf = codec.decodeValue(new Buffer('hey'), {
buf = codec.decodeValue(Buffer.from('hey'), {
valueEncoding: 'binary'
});
t.equal(buf.toString(), 'hey');
})
t.equal(buf.toString(), 'hey')
t.end();
});
t.end()
})
test('encode value - legacy', function(t){
var codec = new Codec({ encoding: 'hex' });
test('encode value - legacy', function (t) {
var codec = new Codec({ encoding: 'hex' })
var buf = codec.encodeValue('686579', {});
t.equal(buf.toString(), 'hey');
var buf = codec.encodeValue('686579', {})
t.equal(buf.toString(), 'hey')
buf = codec.encodeValue('686579');
t.equal(buf.toString(), 'hey');
buf = codec.encodeValue('686579')
t.equal(buf.toString(), 'hey')
buf = codec.encodeValue('686579', {
encoding: 'binary'
});
t.equal(buf.toString(), '686579');
})
t.equal(buf.toString(), '686579')
t.end();
});
t.end()
})
test('decode value - legacy', function(t){
var codec = new Codec({ encoding: 'hex' });
test('decode value - legacy', function (t) {
var codec = new Codec({ encoding: 'hex' })
var buf = codec.decodeValue(new Buffer('hey'), {});
t.equal(buf, '686579');
var buf = codec.decodeValue(Buffer.from('hey'), {})
t.equal(buf, '686579')
buf = codec.decodeValue(new Buffer('hey'));
t.equal(buf, '686579');
buf = codec.decodeValue(Buffer.from('hey'))
t.equal(buf, '686579')
buf = codec.decodeValue(new Buffer('hey'), {
buf = codec.decodeValue(Buffer.from('hey'), {
encoding: 'binary'
});
t.equal(buf.toString(), 'hey');
})
t.equal(buf.toString(), 'hey')
t.end();
});
t.end()
})

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

var test = require('tape');
var Codec = require('..');
var test = require('tape')
var Codec = require('..')
test('encode ltgt', function(t){
var codec = new Codec({ keyEncoding: 'hex' });
test('encode ltgt', function (t) {
var codec = new Codec({ keyEncoding: 'hex' })

@@ -10,6 +10,6 @@ var ltgt = {

lte: '686579'
};
var encoded = codec.encodeLtgt(ltgt);
t.equal(encoded.start.toString(), 'hey');
t.equal(encoded.lte.toString(), 'hey');
}
var encoded = codec.encodeLtgt(ltgt)
t.equal(encoded.start.toString(), 'hey')
t.equal(encoded.lte.toString(), 'hey')

@@ -20,9 +20,8 @@ ltgt = {

keyEncoding: 'json'
};
encoded = codec.encodeLtgt(ltgt);
t.equal(encoded.start, '"686579"');
t.equal(encoded.lte, '"686579"');
}
encoded = codec.encodeLtgt(ltgt)
t.equal(encoded.start, '"686579"')
t.equal(encoded.lte, '"686579"')
t.end();
});
t.end()
})

Sorry, the diff of this file is not supported yet

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