This commit is contained in:
thewesker
2016-06-18 17:22:45 -04:00
parent f8c72a5a29
commit 11a88b601c
1631 changed files with 55 additions and 164199 deletions

54
id_rsa_pagoda Normal file
View File

@@ -0,0 +1,54 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,A907E1F0C46F90328FEB773DA16BB035
g1ofaAVOuVlwN9PKWmZu8+pcJ+Mv/SjdVva1O1yyD7J+E8HGMK2aHax16SbApBBy
7I8IFnk7RhIuDBo2n4YiXRkbiLW7zLPhhsYv+6aEUUUHiZweOewpW37z+AYD5wvV
Gv8/ynqEc/V4mwouQ19cB/2T9oOLRXYAZKKYiqV+93mqWsxQ8jDOR8AyZbZgsyl1
ZC03eaoth/UqYEwqyiuLrHQPYou3SnI1fdNTspr8z0MYKr5nonvao5G3udK5zq+d
RyZYMSIMeMqtkYA/jNiXbavOI2UNbgw6IVixwNfWuBG8Y5ErdN4OFyFuB8tHxQVs
DW7sDsDzZHlX5+5YzRf8W9HO4Z3E7KZ74DfHP4zyBnpptO3vILFSxREpXF2D2U//
FDgoFdB60kSKFFcJ1h0mqGaBxHavH3m5ME7CWRy5BDwPeEDYMOpNVSqTDl28Rsv8
l8ktgJS+aMT/fQMgf/VtoyRENtrJMk8jb3vLYPOhA+k+USvx0ybmC/VjEsrU9Z1X
9fgwNYi7tP7RgCKa1opiie8ibYz1BMdiql0iZWh6OvA9o6vKFQNhOB5/NDBeZ2NO
0cLaEyyTcJE281i9qw3kFg8fCRF6JI9VkKUJad0L0XBQj3NMle4gukb/Dm9o2Tpu
4SIr8MTdXFebQWQNEa3d0BmmPcOXEkNfPj7AmRpCmEP5EsLsBjJ5ao2NcK4489ut
hE6xMuHmiH34EWoADYlgmJ1B+Bi0kBBU4A75vaP2ygVY1LWEpWLaSNM7FGZq/Erf
w4R+1lB1AuSqWVX8TshArusHhbXUzt/mLswSV0c9/L+oQgMsPegsb1OiO1kp6CZ2
4u3j0bRwWf8u2q6ci6nAAZQuhtqupLphGPqGzr97HxjFN6puQq8wYgTB402jvAtv
PM3oIN8+Wsg+K9NoZij2a0Qtz0bn+G+vcmVBlmPrjLo7dtrBRbH8Q1cwBDbfmw0F
eqeC0HfqGjWsSGDNMQZWjMD7DYU9878HKDjosPpIdsYNRpMDoY1onCLF7WeP4+2L
Y/cWO0IHJ97ACiHBz6Pbv0cZFKdGY3WkHGvNO+Tq1bgdYqujvG/olgKcRzdDE4MO
61wGyOswNahtC2f+bHw/gIgDRrEujj0O8DGIUP4j80UbVSqXmaL9W595q9IEPKSZ
ZMAIGPwGyHLKNjSV0i9Q78HnPkngzEkD3uj+yHjnzYY2YWiut50bhX6LUAOxKFpU
YsjNb5ph+Cv35eP2Dr7ZUElAc+hJx/d6KgYIpX+I+aDh/OwUjTiXs9hVa425Nyap
NTYFiOno0L7PYYFHDd4TSo/kJbenYCR3wJlCa3TabwSV6z82MPlZJ6GBznL6aAVx
ExqI8NWoL1LyLCF9l2Drkmm9lnUFv8KBhslVs1jj8M9H3HJcqYrRqOwcFCFQlDeH
Vt3jDHa9VwA8jpLmcdmBtD9GQZXqHWB/d8OLVjBg9De0cQeRQTiYyEXoP9m9qC+C
B9jB9EkBIMzuLRuHyRteSg/gjC7VfrLwxL97PPTmAQOf9O0zSQ78jSy3pdKfgyzJ
8gzd65m97fEoOn7MedKLUlYCq9u4tV058baFNzs+sle7CLsiEhrIYNo+3A/5NpbE
QoFENMwYWkfI8pk0MaQeKkGVIrvw/fTVLClXLGGVbgxey0GrmGWCLmPdeAl6L5db
MQ5yx4ruMncXMlLE+9ZUj9X82V+Ok9uGoTmhAWdhePCmJs5fc2w+2koH3dlxj3dw
1cJSkA0JBz559whv1/fyJkhblVWS56hwebSx3I4Bfz3ud00lERNDVgYt8CNkqROq
YqrxZXpHeQf5t5Q2KszIXenY36Yqszn3Z/kG6X58Pxnw8TwoCaXjULmLm2yZ9HYV
BhmzTztoEC6nGU3b0DbEeHLvuHn4JXvVpg7Mh+OSAH5kDIXA/No6N4I7s7ECfKqU
aCbS6/dvM/TfC8BK0S39wnEaTqi+PSqSJ7gmZNZWggl1CHMW9uD2fwR1waF7Xg8e
1O2IuVeN0HBRQ9oNUs3pXbQyCMhz4GIkKZvkuRqi8SGzABhrIWGoub5b5uElSeBV
mboEX9c3VDnPifI6yOp8uzlBT1eyfbj3pkbO0xu4YZHJvnjJE6g0KD0oUKhljhcA
pIX+nM9LFZbrl93dpcofjbxxO4IfyPAmuMOrpHUaOdAce3PTChMqQ9vTSKQchbAx
kFjJhaBpZKE1PlR9/6KDq5beJoKlLQ50zIy7S9dbcJ4u8nPe+hIwSG5HydMJdiZj
6L3MjQVN90gypxi/XyxctyNP+kLXxR9f4KAM25pCU97qTM/znsSawmKphIo9tmwN
BkKQ1Xp1nayWLoT8eDXzLAWbXMUYODY+TrgrZtq6IkrwyI0Hsaif3EKICarCBatx
EEAGG/w6XcXHWmvcYdPxyBBZJmlWi5IzKupA0kryw8awYZG8HRw667bp2SHJqR+X
+OPQh38a90ZjmwC1ZB+zjw1wJ4fPuKqd4gibM6vnZdLuTFHUQkS+0VLGdZpdU2Ox
vGuJ8xCXvF20VxtQZQgkoQbjZwywHqPsyIoYwGkwxecpzlsR2I9zo+vfpzpBP5YM
rbBb+ARimM3a5mkJ2s0AS9TpJZhjhuFhYeYIa+ZtVdSfZ//RwUw98undeMyBnWut
nnu9e3d8Agg1EKNqV60ThqpjdiO/udIvTsxzIPVtlrtMf2DQltYWKMkZjR++U2TU
ipqwIXXLNTqo1C7T11TffxBPC1rRFZGvSHx6VWzLGplVbcxJr1u2lgEiPeBrJsEh
5eZ8ymwOQCaqqt/w+JKHLj6rvAj2LbT4+IFiHTeyeqtJXKW9BPH8tJ4h5vjBF7wg
/u2TK9IjqMuXLaFJfF+Qr2/iqQIKwbbzkR+Rk17u6BsmWanWrOlk2HP2juWx81H3
HDYuGCh5WLxJShj2mo9rKjWI8iEFFcRM5bsNimbQlQuqKjt4N73GuAm439hRBmkG
P4xZBvGGJRC2ORIAZXE6XN3ISp0qvsamHtyjsyS3nFIkCJ6SFjPbWpIm7/yehgV/
+GgxlRjBdzvSFO1/173FRmdVvbMs0lAR8aZSn6uPCaNvdICCpaC52jONmY9RUkRN
IAxkjoBBgvWauT4wcj8F3bmn7ujUoMtdBfzvbUPRbnA0NlCoZneYezjI+aXki4HP
-----END RSA PRIVATE KEY-----

1
id_rsa_pagoda.pub Normal file
View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDL4DS4icbVaQTeL5MhF8n7At/N0NGVHZZHl0Yzlltnf4NBm3NDHa/y7XpHCpQH9qe8f+VgJ0c7DdbP9/6vaYSog7VWcRw2eyY9WqpUBQH62TwanhZEo//sHPPv+XYQVvjerrVZPtvY13s6ZjMu7HoTo8l6/TW8QGHN+luipW0GG+w/2KrfBvPpYOEm9AaS1zb3QmEmjmNqcLD5DTf/xg+gbwW7rVhDOlgbBfohDdm6Kippcn3YP4Vw1+0K9vxaqL0A39R4G+q+9wsliFG3jybTqtcO4QLp7Orb6IBQ5PGQ2f8hu6rzp5dC5r4VZpl+eiIhnvjPvUgei0j/oSafrNaGX/ZhD22AEKL/4ab9j2Wj2Sq1JIbG+2PHSL7RnL6MG++4TtYQA2NbBdFOqB2wdpZq/7555ET4ftGOUI8G3qIAS1jiKftMa2ejTK5Xbcx1IqF+IZsyGP0FMgnHijGe6p8ME9CAbS9rIzdC7p6VE9m0Nk3ESmSnWPGn/6fbeWDoKoGy3CnviZqncZJO/IPS1/D2rP/NLX4PEFd3h/YthQE3SMY2ojY+EDysXIGltbPig9qpUU4zULDESwDPEUfJxUCw1+PPCEGQenEeOBD/lQgpEen9B2JaTNAWJwqAV5DTAUl4BGnkpR8rSH7canHtU87ndpZNffUS/tWM1kbCsyDQmQ== talorb@outlook.com

1
node_modules/fs/index.js generated vendored
View File

@@ -1 +0,0 @@
console.log("I'm `fs` modules");

32
node_modules/fs/package.json generated vendored
View File

@@ -1,32 +0,0 @@
{
"name": "fs",
"version": "0.0.2",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "MIT",
"_id": "fs@0.0.2",
"_shasum": "e1f244ef3933c1b2a64bd4799136060d0f5914f8",
"_from": "fs@>=0.0.2 <0.0.3",
"_npmVersion": "1.4.14",
"_npmUser": {
"name": "alsotang",
"email": "alsotang@gmail.com"
},
"maintainers": [
{
"name": "alsotang",
"email": "alsotang@gmail.com"
}
],
"dist": {
"shasum": "e1f244ef3933c1b2a64bd4799136060d0f5914f8",
"tarball": "https://registry.npmjs.org/fs/-/fs-0.0.2.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/fs/-/fs-0.0.2.tgz",
"readme": "ERROR: No README data found!"
}

6
node_modules/lowdb/.babelrc generated vendored
View File

@@ -1,6 +0,0 @@
{
"presets": [
"es2015",
"stage-3"
]
}

3
node_modules/lowdb/.npmignore generated vendored
View File

@@ -1,3 +0,0 @@
.travis.yml
src
test

20
node_modules/lowdb/LICENSE generated vendored
View File

@@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright (c) 2014 typicode
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

404
node_modules/lowdb/README.md generated vendored
View File

@@ -1,404 +0,0 @@
# lowdb [![NPM version](https://badge.fury.io/js/lowdb.svg)](http://badge.fury.io/js/lowdb) [![Build Status](https://travis-ci.org/typicode/lowdb.svg?branch=master)](https://travis-ci.org/typicode/lowdb)
> Need a quick way to get a local database for a CLI, an Electron app, a small server or the browser?
## Example
```js
const low = require('lowdb')
const storage = require('lowdb/file-sync')
const db = low('db.json', { storage })
db('posts').push({ title: 'lowdb is awesome'})
```
Database is __automatically__ saved to `db.json`.
```js
{
"posts": [
{ "title": "lowdb is awesome" }
]
}
```
You can query and manipulate it using __any__ [lodash](https://lodash.com/docs) __method__.
```js
db('posts').find({ title: 'lowdb is awesome' })
```
And access underlying database object any time.
```js
db.object.posts
```
__[Click here to try lowdb in the browser.](http://typicode.github.io/lowdb/)__
## ES2015
Examples use ES2015 syntax for convenience, but you can use ES5 syntax too. For example:
```js
var db = low('db.json', { storage: storage })
```
Please note also that lowdb can only be run in one instance of Node, it doesn't support Cluster.
## Installation
Using npm:
```bash
npm install lowdb --save
```
A standalone UMD build is also available on [npmcdn](https://npmcdn.com/):
```html
<script src="http://npmcdn.com/lowdb@^0.12.4/dist/lowdb.min.js"></script>
<script>
var db = low() // in-memory
var db = low('db', { storage: low.localStorage }) // localStorage
</script>
```
## Features
* Very small (~100 lines for core)
* lodash API
* Extendable:
* __Custom storage__ (file, browser, in-memory, ...)
* __Custom format__ (JSON, BSON, YAML, ...)
* __Mixins__ (id support, ...)
* __Encryption__
Lowdb is also very easy to learn since it has __only a few methods and properties__.
_lowdb powers [json-server](https://github.com/typicode/json-server) package, [jsonplaceholder](http://jsonplaceholder.typicode.com/) website and [many other great projects](https://www.npmjs.com/browse/depended/lowdb)._
## Usage examples
Depending on the context, you can use different storages and formats.
Lowdb comes bundled with `file-sync`, `file-async` and `browser` storages, but you can also write your own if needed.
### CLI
For CLIs, it's easier to use `lowdb/file-sync` synchronous file storage .
```js
const low = require('lowdb')
const storage = require('lowdb/file-sync')
const db = low('db.json', { storage })
db('users').push({ name: 'typicode' })
const user = db('users').find({ name: 'typicode' })
```
### Server
For servers, it's better to avoid blocking requests. Use `lowdb/file-async` asynchronous file storage.
__Important__
* When you modify the database, a Promise is returned.
* When you read from the database, the result is immediately returned.
```js
const low = require('lowdb').
const storage = require('lowdb/file-async')
const db = low('db.json', { storage })
app.get('/posts/:id', (req, res) => {
// Returns a post
const post = db('posts').find({ id: req.params.id })
res.send(post)
})
app.post('/posts', (req, res) => {
// Returns a Promise that resolves to a post
db('posts')
.push(req.body)
.then(post => res.send(post))
})
```
### Browser
In the browser, `lowdb/browser` will add `localStorage` support.
```js
const low = require('lowdb')
const storage = require('lowdb/browser')
const db = low('db', { storage })
db('users').push({ name: 'typicode' })
const user = db('users').find({ name: 'typicode' })
```
### In-memory
For the best performance, use lowdb in-memory storage.
```js
const low = require('lowdb')
const db = low()
db('users').push({ name: 'typicode' })
const user = db('users').find({ name: 'typicode' })
```
Please note that, as an alternative, you can also disable `writeOnChange` if you want to control when data is written.
## API
__low([filename, [storage, [writeOnChange = true]]])__
Creates a new database instance. Here are some examples:
```js
low() // in-memory
low('db.json', { storage: /* */ }) // persisted
low('db.json', { storage: /* */ }, false) // auto write disabled
// To create read-only or write-only database,
// set only storage.read or storage.write
const fileSync = require('lowdb/file-sync')
// write-only
low('db.json', {
storage: { write: fileSync.write }
})
// read-only
low('db.json', {
storage: { read: fileSync.read }
})
```
You can also define custom storages and formats:
```js
const myStorage = {
read: (source, deserialize) => // obj or a Promise
write: (dest, obj, serialize) => // undefined or a Promise
}
const myFormat = {
format: {
deserialize: (data) => // obj
serialize: (obj) => // data
}
}
low(source, { storage: myStorage, format: myFormat }, writeOnChange)
```
__db.___
Database lodash instance. Use it to add your own utility functions or third-party mixins like [underscore-contrib](https://github.com/documentcloud/underscore-contrib) or [underscore-db](https://github.com/typicode/underscore-db).
```js
db._.mixin({
second: function(array) {
return array[1]
}
})
const post1 = db('posts').first()
const post2 = db('posts').second()
```
__db.object__
Use whenever you want to access or modify the underlying database object.
```js
db.object // { posts: [ ... ] }
```
If you directly modify the content of the database object, you will need to manually call `write` to persist changes.
```js
// Delete an array
delete db.object.posts
db.write()
// Drop database
db.object = {}
db.write()
```
__db.write([source])__
Persists database using `storage.write` method. Depending on the storage, it may return a promise.
Note: by default, lowdb automatically calls it when database changes.
```js
const db = low('db.json', { storage })
db.write() // writes to db.json
db.write('copy.json') // writes to copy.json
```
__db.read([source])__
Reads source using `storage.read` method. Depending on the storage, it may return a promise.
```js
const db = low('db.json', { storage })
db.read() // re-reads db.json
db.read('copy.json') // reads copy.json
```
## Guide
### How to query
With lowdb, you get access to the entire [lodash API](http://lodash.com/), so there is many ways to query and manipulate data. Here are a few examples to get you started.
Please note that data is returned by reference, this means that modifications to returned objects may change the database. To avoid such behaviour, you need to use `.cloneDeep()`.
Also, the execution of chained methods is lazy, that is, execution is deferred until `.value()` is called.
#### Examples
Sort the top five posts.
```js
db('posts')
.chain()
.filter({published: true})
.sortBy('views')
.take(5)
.value()
```
Retrieve post titles.
```js
db('posts').map('title')
```
Get the number of posts.
```js
db('posts').size()
```
Make a deep clone of posts.
```js
db('posts').cloneDeep()
```
Update a post.
```js
db('posts')
.chain()
.find({ title: 'low!' })
.assign({ title: 'hi!'})
.value()
```
Remove posts.
```js
db('posts').remove({ title: 'low!' })
```
### How to use id based resources
Being able to retrieve data using an id can be quite useful, particularly in servers. To add id-based resources support to lowdb, you have 2 options.
[underscore-db](https://github.com/typicode/underscore-db) provides a set of helpers for creating and manipulating id-based resources.
```js
const db = low('db.json')
db._.mixin(require('underscore-db'))
const postId = db('posts').insert({ title: 'low!' }).id
const post = db('posts').getById(postId)
```
[uuid](https://github.com/broofa/node-uuid) is more minimalist and returns a unique id that you can use when creating resources.
```js
const uuid = require('uuid')
const postId = db('posts').push({ id: uuid(), title: 'low!' }).id
const post = db('posts').find({ id: postId })
```
### How to use custom format
By default, lowdb storages will use `JSON` to `parse` and `stringify` database object.
But it's also possible to specify custom `format.serializer` and `format.deserializer` methods that will be passed by lowdb to `storage.read` and `storage.write` methods.
For example, if you want to store database in `.bson` files ([MongoDB file format](https://github.com/mongodb/js-bson)):
```js
const low = require('lowdb')
const storage = require('lowdb/file-sync')
const bson = require('bson')
const BSON = new bson.BSONPure.BSON()
low('db.bson', { storage, format: {
serialize: BSON.serialize,
deserialize: BSON.deserialize
}})
// Alternative ES2015 short syntax
const bson = require('bson')
const format = new bson.BSONPure.BSON()
low('db.bson', { storage, format })
```
### How to encrypt data
Simply `encrypt` and `decrypt` data in `format.serialize` and `format.deserialize` methods.
For example, using [cryptr](https://github.com/MauriceButler/cryptr):
```js
const Cryptr = require("./cryptr"),
const cryptr = new Cryptr('my secret key')
const db = low('db.json', {
format: {
deserialize: (str) => {
const decrypted = cryptr.decrypt(str)
const obj = JSON.parse(decrypted)
return obj
},
serialize: (obj) => {
const str = JSON.stringify(obj)
const encrypted = cryptr.encrypt(str)
return encrypted
}
}
})
```
## Changelog
See changes for each version in the [release notes](https://github.com/typicode/lowdb/releases).
## Limits
lowdb is a convenient method for storing data without setting up a database server. It is fast enough and safe to be used as an embedded database.
However, if you seek high performance and scalability more than simplicity, you should probably stick to traditional databases like MongoDB.
## License
MIT - [Typicode](https://github.com/typicode)

21
node_modules/lowdb/browser.js generated vendored
View File

@@ -1,21 +0,0 @@
'use strict';
/* global localStorage */
module.exports = {
read: function read(source) {
var deserialize = arguments.length <= 1 || arguments[1] === undefined ? JSON.parse : arguments[1];
var data = localStorage.getItem(source);
if (data) {
return deserialize(data);
} else {
localStorage.setItem(source, '{}');
return {};
}
},
write: function write(dest, obj) {
var serialize = arguments.length <= 2 || arguments[2] === undefined ? JSON.stringify : arguments[2];
return localStorage.setItem(dest, serialize(obj));
}
};

15173
node_modules/lowdb/dist/lowdb.js generated vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

24
node_modules/lowdb/file-async.js generated vendored
View File

@@ -1,24 +0,0 @@
'use strict';
var steno = require('steno');
var _require = require('./json');
var stringify = _require.stringify;
module.exports = {
read: require('./file-sync').read,
write: function write(dest, obj) {
var serialize = arguments.length <= 2 || arguments[2] === undefined ? stringify : arguments[2];
return new Promise(function (resolve, reject) {
var data = serialize(obj);
steno.writeFile(dest, data, function (err) {
if (err) return reject(err);
resolve();
});
});
}
};

39
node_modules/lowdb/file-sync.js generated vendored
View File

@@ -1,39 +0,0 @@
'use strict';
var fs = require('graceful-fs');
var _require = require('./json');
var parse = _require.parse;
var stringify = _require.stringify;
module.exports = {
read: function read(source) {
var deserialize = arguments.length <= 1 || arguments[1] === undefined ? parse : arguments[1];
if (fs.existsSync(source)) {
// Read database
var data = fs.readFileSync(source, 'utf-8').trim() || '{}';
try {
return deserialize(data);
} catch (e) {
if (e instanceof SyntaxError) {
e.message = 'Malformed JSON in file: ' + source + '\n' + e.message;
}
throw e;
}
} else {
// Initialize empty database
fs.writeFileSync(source, '{}');
return {};
}
},
write: function write(dest, obj) {
var serialize = arguments.length <= 2 || arguments[2] === undefined ? stringify : arguments[2];
var data = serialize(obj);
fs.writeFileSync(dest, data);
}
};

142
node_modules/lowdb/index.js generated vendored
View File

@@ -1,142 +0,0 @@
'use strict';
var lodash = require('lodash');
var isPromise = require('is-promise');
// Returns a lodash chain that calls .value()
// automatically after the first .method()
//
// It also returns a promise or value
//
// For example:
// lowChain(_, array, save).method()
//
// is the same as:
// _.chain(array).method().value()
function lowChain(_, array, save) {
var chain = _.chain(array);
_.functionsIn(chain).forEach(function (method) {
chain[method] = _.flow(chain[method], function (arg) {
var v = undefined;
if (arg) {
v = _.isFunction(arg.value) ? arg.value() : arg;
}
var s = save();
if (s) return s.then(function () {
return Promise.resolve(v);
});
return v;
});
});
return chain;
}
function low(source) {
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var writeOnChange = arguments.length <= 2 || arguments[2] === undefined ? true : arguments[2];
// Create a fresh copy of lodash
var _ = lodash.runInContext();
if (source) {
if (options.storage) {
(function () {
var storage = options.storage;
if (storage.read) {
db.read = function () {
var s = arguments.length <= 0 || arguments[0] === undefined ? source : arguments[0];
var res = storage.read(s, db.deserialize);
if (isPromise(res)) {
return res.then(function (obj) {
db.object = obj;
db._checksum = JSON.stringify(db.object);
return db;
});
}
db.object = res;
db._checksum = JSON.stringify(db.object);
return db;
};
}
if (storage.write) {
db.write = function () {
var dest = arguments.length <= 0 || arguments[0] === undefined ? source : arguments[0];
return storage.write(dest, db.object, db.serialize);
};
}
})();
}
if (options.format) {
var format = options.format;
db.serialize = format.serialize;
db.deserialize = format.deserialize;
}
}
// Modify value function to call save before returning result
_.prototype.value = _.wrap(_.prototype.value, function (value) {
var v = value.apply(this);
var s = _save();
if (s) return s.then(function () {
return Promise.resolve(v);
});
return v;
});
// Return a promise or nothing in sync mode or if the database hasn't changed
function _save() {
if (db.source && db.write && writeOnChange) {
var str = JSON.stringify(db.object);
if (str !== db._checksum) {
db._checksum = str;
return db.write(db.source, db.object);
}
}
}
function db(key) {
if (typeof db.object[key] === 'undefined') {
db.object[key] = [];
}
var array = db.object[key];
var short = lowChain(_, array, _save);
short.chain = function () {
return _.chain(array);
};
// Prevents db.write being called when just calling db('foo').value()
short.value = function () {
return db.object[key];
};
return short;
}
// Expose
db._ = _;
db.object = {};
db.source = source;
// Init
if (db.read) {
return db.read();
} else {
return db;
}
}
module.exports = low;

10
node_modules/lowdb/json.js generated vendored
View File

@@ -1,10 +0,0 @@
'use strict';
var jph = require('json-parse-helpfulerror');
module.exports = {
parse: jph.parse,
stringify: function stringify(obj) {
return JSON.stringify(obj, null, 2);
}
};

View File

@@ -1,15 +0,0 @@
The ISC License
Copyright (c) Isaac Z. Schlueter, Ben Noordhuis, and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@@ -1,133 +0,0 @@
# graceful-fs
graceful-fs functions as a drop-in replacement for the fs module,
making various improvements.
The improvements are meant to normalize behavior across different
platforms and environments, and to make filesystem access more
resilient to errors.
## Improvements over [fs module](http://api.nodejs.org/fs.html)
* Queues up `open` and `readdir` calls, and retries them once
something closes if there is an EMFILE error from too many file
descriptors.
* fixes `lchmod` for Node versions prior to 0.6.2.
* implements `fs.lutimes` if possible. Otherwise it becomes a noop.
* ignores `EINVAL` and `EPERM` errors in `chown`, `fchown` or
`lchown` if the user isn't root.
* makes `lchmod` and `lchown` become noops, if not available.
* retries reading a file if `read` results in EAGAIN error.
On Windows, it retries renaming a file for up to one second if `EACCESS`
or `EPERM` error occurs, likely because antivirus software has locked
the directory.
## USAGE
```javascript
// use just like fs
var fs = require('graceful-fs')
// now go and do stuff with it...
fs.readFileSync('some-file-or-whatever')
```
## Global Patching
If you want to patch the global fs module (or any other fs-like
module) you can do this:
```javascript
// Make sure to read the caveat below.
var realFs = require('fs')
var gracefulFs = require('graceful-fs')
gracefulFs.gracefulify(realFs)
```
This should only ever be done at the top-level application layer, in
order to delay on EMFILE errors from any fs-using dependencies. You
should **not** do this in a library, because it can cause unexpected
delays in other parts of the program.
## Changes
This module is fairly stable at this point, and used by a lot of
things. That being said, because it implements a subtle behavior
change in a core part of the node API, even modest changes can be
extremely breaking, and the versioning is thus biased towards
bumping the major when in doubt.
The main change between major versions has been switching between
providing a fully-patched `fs` module vs monkey-patching the node core
builtin, and the approach by which a non-monkey-patched `fs` was
created.
The goal is to trade `EMFILE` errors for slower fs operations. So, if
you try to open a zillion files, rather than crashing, `open`
operations will be queued up and wait for something else to `close`.
There are advantages to each approach. Monkey-patching the fs means
that no `EMFILE` errors can possibly occur anywhere in your
application, because everything is using the same core `fs` module,
which is patched. However, it can also obviously cause undesirable
side-effects, especially if the module is loaded multiple times.
Implementing a separate-but-identical patched `fs` module is more
surgical (and doesn't run the risk of patching multiple times), but
also imposes the challenge of keeping in sync with the core module.
The current approach loads the `fs` module, and then creates a
lookalike object that has all the same methods, except a few that are
patched. It is safe to use in all versions of Node from 0.8 through
7.0.
### v4
* Do not monkey-patch the fs module. This module may now be used as a
drop-in dep, and users can opt into monkey-patching the fs builtin
if their app requires it.
### v3
* Monkey-patch fs, because the eval approach no longer works on recent
node.
* fixed possible type-error throw if rename fails on windows
* verify that we *never* get EMFILE errors
* Ignore ENOSYS from chmod/chown
* clarify that graceful-fs must be used as a drop-in
### v2.1.0
* Use eval rather than monkey-patching fs.
* readdir: Always sort the results
* win32: requeue a file if error has an OK status
### v2.0
* A return to monkey patching
* wrap process.cwd
### v1.1
* wrap readFile
* Wrap fs.writeFile.
* readdir protection
* Don't clobber the fs builtin
* Handle fs.read EAGAIN errors by trying again
* Expose the curOpen counter
* No-op lchown/lchmod if not implemented
* fs.rename patch only for win32
* Patch fs.rename to handle AV software on Windows
* Close #4 Chown should not fail on einval or eperm if non-root
* Fix isaacs/fstream#1 Only wrap fs one time
* Fix #3 Start at 1024 max files, then back off on EMFILE
* lutimes that doens't blow up on Linux
* A full on-rewrite using a queue instead of just swallowing the EMFILE error
* Wrap Read/Write streams as well
### 1.0
* Update engines for node 0.6
* Be lstat-graceful on Windows
* first

View File

@@ -1,21 +0,0 @@
'use strict'
var fs = require('fs')
module.exports = clone(fs)
function clone (obj) {
if (obj === null || typeof obj !== 'object')
return obj
if (obj instanceof Object)
var copy = { __proto__: obj.__proto__ }
else
var copy = Object.create(null)
Object.getOwnPropertyNames(obj).forEach(function (key) {
Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key))
})
return copy
}

View File

@@ -1,253 +0,0 @@
var fs = require('fs')
var polyfills = require('./polyfills.js')
var legacy = require('./legacy-streams.js')
var queue = []
var util = require('util')
function noop () {}
var debug = noop
if (util.debuglog)
debug = util.debuglog('gfs4')
else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || ''))
debug = function() {
var m = util.format.apply(util, arguments)
m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ')
console.error(m)
}
if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) {
process.on('exit', function() {
debug(queue)
require('assert').equal(queue.length, 0)
})
}
module.exports = patch(require('./fs.js'))
if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) {
module.exports = patch(fs)
}
// Always patch fs.close/closeSync, because we want to
// retry() whenever a close happens *anywhere* in the program.
// This is essential when multiple graceful-fs instances are
// in play at the same time.
module.exports.close =
fs.close = (function (fs$close) { return function (fd, cb) {
return fs$close.call(fs, fd, function (err) {
if (!err)
retry()
if (typeof cb === 'function')
cb.apply(this, arguments)
})
}})(fs.close)
module.exports.closeSync =
fs.closeSync = (function (fs$closeSync) { return function (fd) {
// Note that graceful-fs also retries when fs.closeSync() fails.
// Looks like a bug to me, although it's probably a harmless one.
var rval = fs$closeSync.apply(fs, arguments)
retry()
return rval
}})(fs.closeSync)
function patch (fs) {
// Everything that references the open() function needs to be in here
polyfills(fs)
fs.gracefulify = patch
fs.FileReadStream = ReadStream; // Legacy name.
fs.FileWriteStream = WriteStream; // Legacy name.
fs.createReadStream = createReadStream
fs.createWriteStream = createWriteStream
var fs$readFile = fs.readFile
fs.readFile = readFile
function readFile (path, options, cb) {
if (typeof options === 'function')
cb = options, options = null
return go$readFile(path, options, cb)
function go$readFile (path, options, cb) {
return fs$readFile(path, options, function (err) {
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
enqueue([go$readFile, [path, options, cb]])
else {
if (typeof cb === 'function')
cb.apply(this, arguments)
retry()
}
})
}
}
var fs$writeFile = fs.writeFile
fs.writeFile = writeFile
function writeFile (path, data, options, cb) {
if (typeof options === 'function')
cb = options, options = null
return go$writeFile(path, data, options, cb)
function go$writeFile (path, data, options, cb) {
return fs$writeFile(path, data, options, function (err) {
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
enqueue([go$writeFile, [path, data, options, cb]])
else {
if (typeof cb === 'function')
cb.apply(this, arguments)
retry()
}
})
}
}
var fs$appendFile = fs.appendFile
if (fs$appendFile)
fs.appendFile = appendFile
function appendFile (path, data, options, cb) {
if (typeof options === 'function')
cb = options, options = null
return go$appendFile(path, data, options, cb)
function go$appendFile (path, data, options, cb) {
return fs$appendFile(path, data, options, function (err) {
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
enqueue([go$appendFile, [path, data, options, cb]])
else {
if (typeof cb === 'function')
cb.apply(this, arguments)
retry()
}
})
}
}
var fs$readdir = fs.readdir
fs.readdir = readdir
function readdir (path, cb) {
return go$readdir(path, cb)
function go$readdir () {
return fs$readdir(path, function (err, files) {
if (files && files.sort)
files.sort(); // Backwards compatibility with graceful-fs.
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
enqueue([go$readdir, [path, cb]])
else {
if (typeof cb === 'function')
cb.apply(this, arguments)
retry()
}
})
}
}
if (process.version.substr(0, 4) === 'v0.8') {
var legStreams = legacy(fs)
ReadStream = legStreams.ReadStream
WriteStream = legStreams.WriteStream
}
var fs$ReadStream = fs.ReadStream
ReadStream.prototype = Object.create(fs$ReadStream.prototype)
ReadStream.prototype.open = ReadStream$open
var fs$WriteStream = fs.WriteStream
WriteStream.prototype = Object.create(fs$WriteStream.prototype)
WriteStream.prototype.open = WriteStream$open
fs.ReadStream = ReadStream
fs.WriteStream = WriteStream
function ReadStream (path, options) {
if (this instanceof ReadStream)
return fs$ReadStream.apply(this, arguments), this
else
return ReadStream.apply(Object.create(ReadStream.prototype), arguments)
}
function ReadStream$open () {
var that = this
open(that.path, that.flags, that.mode, function (err, fd) {
if (err) {
if (that.autoClose)
that.destroy()
that.emit('error', err)
} else {
that.fd = fd
that.emit('open', fd)
that.read()
}
})
}
function WriteStream (path, options) {
if (this instanceof WriteStream)
return fs$WriteStream.apply(this, arguments), this
else
return WriteStream.apply(Object.create(WriteStream.prototype), arguments)
}
function WriteStream$open () {
var that = this
open(that.path, that.flags, that.mode, function (err, fd) {
if (err) {
that.destroy()
that.emit('error', err)
} else {
that.fd = fd
that.emit('open', fd)
}
})
}
function createReadStream (path, options) {
return new ReadStream(path, options)
}
function createWriteStream (path, options) {
return new WriteStream(path, options)
}
var fs$open = fs.open
fs.open = open
function open (path, flags, mode, cb) {
if (typeof mode === 'function')
cb = mode, mode = null
return go$open(path, flags, mode, cb)
function go$open (path, flags, mode, cb) {
return fs$open(path, flags, mode, function (err, fd) {
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
enqueue([go$open, [path, flags, mode, cb]])
else {
if (typeof cb === 'function')
cb.apply(this, arguments)
retry()
}
})
}
}
return fs
}
function enqueue (elem) {
debug('ENQUEUE', elem[0].name, elem[1])
queue.push(elem)
}
function retry () {
var elem = queue.shift()
if (elem) {
debug('RETRY', elem[0].name, elem[1])
elem[0].apply(null, elem[1])
}
}

View File

@@ -1,118 +0,0 @@
var Stream = require('stream').Stream
module.exports = legacy
function legacy (fs) {
return {
ReadStream: ReadStream,
WriteStream: WriteStream
}
function ReadStream (path, options) {
if (!(this instanceof ReadStream)) return new ReadStream(path, options);
Stream.call(this);
var self = this;
this.path = path;
this.fd = null;
this.readable = true;
this.paused = false;
this.flags = 'r';
this.mode = 438; /*=0666*/
this.bufferSize = 64 * 1024;
options = options || {};
// Mixin options into this
var keys = Object.keys(options);
for (var index = 0, length = keys.length; index < length; index++) {
var key = keys[index];
this[key] = options[key];
}
if (this.encoding) this.setEncoding(this.encoding);
if (this.start !== undefined) {
if ('number' !== typeof this.start) {
throw TypeError('start must be a Number');
}
if (this.end === undefined) {
this.end = Infinity;
} else if ('number' !== typeof this.end) {
throw TypeError('end must be a Number');
}
if (this.start > this.end) {
throw new Error('start must be <= end');
}
this.pos = this.start;
}
if (this.fd !== null) {
process.nextTick(function() {
self._read();
});
return;
}
fs.open(this.path, this.flags, this.mode, function (err, fd) {
if (err) {
self.emit('error', err);
self.readable = false;
return;
}
self.fd = fd;
self.emit('open', fd);
self._read();
})
}
function WriteStream (path, options) {
if (!(this instanceof WriteStream)) return new WriteStream(path, options);
Stream.call(this);
this.path = path;
this.fd = null;
this.writable = true;
this.flags = 'w';
this.encoding = 'binary';
this.mode = 438; /*=0666*/
this.bytesWritten = 0;
options = options || {};
// Mixin options into this
var keys = Object.keys(options);
for (var index = 0, length = keys.length; index < length; index++) {
var key = keys[index];
this[key] = options[key];
}
if (this.start !== undefined) {
if ('number' !== typeof this.start) {
throw TypeError('start must be a Number');
}
if (this.start < 0) {
throw new Error('start must be >= zero');
}
this.pos = this.start;
}
this.busy = false;
this._queue = [];
if (this.fd === null) {
this._open = fs.open;
this._queue.push([this._open, this.path, this.flags, this.mode, undefined]);
this.flush();
}
}
}

View File

@@ -1,77 +0,0 @@
{
"name": "graceful-fs",
"description": "A drop-in replacement for fs, making various improvements.",
"version": "4.1.4",
"repository": {
"type": "git",
"url": "git+https://github.com/isaacs/node-graceful-fs.git"
},
"main": "graceful-fs.js",
"engines": {
"node": ">=0.4.0"
},
"directories": {
"test": "test"
},
"scripts": {
"test": "node test.js | tap -"
},
"keywords": [
"fs",
"module",
"reading",
"retry",
"retries",
"queue",
"error",
"errors",
"handling",
"EMFILE",
"EAGAIN",
"EINVAL",
"EPERM",
"EACCESS"
],
"license": "ISC",
"devDependencies": {
"mkdirp": "^0.5.0",
"rimraf": "^2.2.8",
"tap": "^5.4.2"
},
"files": [
"fs.js",
"graceful-fs.js",
"legacy-streams.js",
"polyfills.js"
],
"gitHead": "fe8f05ccc2779d1dfa6db6173f3ed64f1e9aa72c",
"bugs": {
"url": "https://github.com/isaacs/node-graceful-fs/issues"
},
"homepage": "https://github.com/isaacs/node-graceful-fs#readme",
"_id": "graceful-fs@4.1.4",
"_shasum": "ef089d2880f033b011823ce5c8fae798da775dbd",
"_from": "graceful-fs@>=4.1.3 <5.0.0",
"_npmVersion": "3.8.9",
"_nodeVersion": "5.6.0",
"_npmUser": {
"name": "isaacs",
"email": "i@izs.me"
},
"dist": {
"shasum": "ef089d2880f033b011823ce5c8fae798da775dbd",
"tarball": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.4.tgz"
},
"maintainers": [
{
"name": "isaacs",
"email": "i@izs.me"
}
],
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/graceful-fs-4.1.4.tgz_1462474854900_0.9423982477746904"
},
"_resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.4.tgz",
"readme": "ERROR: No README data found!"
}

View File

@@ -1,252 +0,0 @@
var fs = require('./fs.js')
var constants = require('constants')
var origCwd = process.cwd
var cwd = null
process.cwd = function() {
if (!cwd)
cwd = origCwd.call(process)
return cwd
}
try {
process.cwd()
} catch (er) {}
var chdir = process.chdir
process.chdir = function(d) {
cwd = null
chdir.call(process, d)
}
module.exports = patch
function patch (fs) {
// (re-)implement some things that are known busted or missing.
// lchmod, broken prior to 0.6.2
// back-port the fix here.
if (constants.hasOwnProperty('O_SYMLINK') &&
process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
patchLchmod(fs)
}
// lutimes implementation, or no-op
if (!fs.lutimes) {
patchLutimes(fs)
}
// https://github.com/isaacs/node-graceful-fs/issues/4
// Chown should not fail on einval or eperm if non-root.
// It should not fail on enosys ever, as this just indicates
// that a fs doesn't support the intended operation.
fs.chown = chownFix(fs.chown)
fs.fchown = chownFix(fs.fchown)
fs.lchown = chownFix(fs.lchown)
fs.chmod = chownFix(fs.chmod)
fs.fchmod = chownFix(fs.fchmod)
fs.lchmod = chownFix(fs.lchmod)
fs.chownSync = chownFixSync(fs.chownSync)
fs.fchownSync = chownFixSync(fs.fchownSync)
fs.lchownSync = chownFixSync(fs.lchownSync)
fs.chmodSync = chownFix(fs.chmodSync)
fs.fchmodSync = chownFix(fs.fchmodSync)
fs.lchmodSync = chownFix(fs.lchmodSync)
// if lchmod/lchown do not exist, then make them no-ops
if (!fs.lchmod) {
fs.lchmod = function (path, mode, cb) {
process.nextTick(cb)
}
fs.lchmodSync = function () {}
}
if (!fs.lchown) {
fs.lchown = function (path, uid, gid, cb) {
process.nextTick(cb)
}
fs.lchownSync = function () {}
}
// on Windows, A/V software can lock the directory, causing this
// to fail with an EACCES or EPERM if the directory contains newly
// created files. Try again on failure, for up to 1 second.
if (process.platform === "win32") {
fs.rename = (function (fs$rename) { return function (from, to, cb) {
var start = Date.now()
fs$rename(from, to, function CB (er) {
if (er
&& (er.code === "EACCES" || er.code === "EPERM")
&& Date.now() - start < 1000) {
return fs$rename(from, to, CB)
}
if (cb) cb(er)
})
}})(fs.rename)
}
// if read() returns EAGAIN, then just try it again.
fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) {
var callback
if (callback_ && typeof callback_ === 'function') {
var eagCounter = 0
callback = function (er, _, __) {
if (er && er.code === 'EAGAIN' && eagCounter < 10) {
eagCounter ++
return fs$read.call(fs, fd, buffer, offset, length, position, callback)
}
callback_.apply(this, arguments)
}
}
return fs$read.call(fs, fd, buffer, offset, length, position, callback)
}})(fs.read)
fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) {
var eagCounter = 0
while (true) {
try {
return fs$readSync.call(fs, fd, buffer, offset, length, position)
} catch (er) {
if (er.code === 'EAGAIN' && eagCounter < 10) {
eagCounter ++
continue
}
throw er
}
}
}})(fs.readSync)
}
function patchLchmod (fs) {
fs.lchmod = function (path, mode, callback) {
callback = callback || noop
fs.open( path
, constants.O_WRONLY | constants.O_SYMLINK
, mode
, function (err, fd) {
if (err) {
callback(err)
return
}
// prefer to return the chmod error, if one occurs,
// but still try to close, and report closing errors if they occur.
fs.fchmod(fd, mode, function (err) {
fs.close(fd, function(err2) {
callback(err || err2)
})
})
})
}
fs.lchmodSync = function (path, mode) {
var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode)
// prefer to return the chmod error, if one occurs,
// but still try to close, and report closing errors if they occur.
var threw = true
var ret
try {
ret = fs.fchmodSync(fd, mode)
threw = false
} finally {
if (threw) {
try {
fs.closeSync(fd)
} catch (er) {}
} else {
fs.closeSync(fd)
}
}
return ret
}
}
function patchLutimes (fs) {
if (constants.hasOwnProperty("O_SYMLINK")) {
fs.lutimes = function (path, at, mt, cb) {
fs.open(path, constants.O_SYMLINK, function (er, fd) {
cb = cb || noop
if (er) return cb(er)
fs.futimes(fd, at, mt, function (er) {
fs.close(fd, function (er2) {
return cb(er || er2)
})
})
})
}
fs.lutimesSync = function (path, at, mt) {
var fd = fs.openSync(path, constants.O_SYMLINK)
var ret
var threw = true
try {
ret = fs.futimesSync(fd, at, mt)
threw = false
} finally {
if (threw) {
try {
fs.closeSync(fd)
} catch (er) {}
} else {
fs.closeSync(fd)
}
}
return ret
}
} else {
fs.lutimes = function (_a, _b, _c, cb) { process.nextTick(cb) }
fs.lutimesSync = function () {}
}
}
function chownFix (orig) {
if (!orig) return orig
return function (target, uid, gid, cb) {
return orig.call(fs, target, uid, gid, function (er, res) {
if (chownErOk(er)) er = null
cb(er, res)
})
}
}
function chownFixSync (orig) {
if (!orig) return orig
return function (target, uid, gid) {
try {
return orig.call(fs, target, uid, gid)
} catch (er) {
if (!chownErOk(er)) throw er
}
}
}
// ENOSYS means that the fs doesn't support the op. Just ignore
// that, because it doesn't matter.
//
// if there's no getuid, or if getuid() is something other
// than 0, and the error is EINVAL or EPERM, then just ignore
// it.
//
// This specific case is a silent failure in cp, install, tar,
// and most other unix tools that manage permissions.
//
// When running as root, or if other types of errors are
// encountered, then it's strict.
function chownErOk (er) {
if (!er)
return true
if (er.code === "ENOSYS")
return true
var nonroot = !process.getuid || process.getuid() !== 0
if (nonroot) {
if (er.code === "EINVAL" || er.code === "EPERM")
return true
}
return false
}

View File

@@ -1,6 +0,0 @@
component
build
node_modules
test.js
component.json
.gitignore

View File

@@ -1,3 +0,0 @@
language: node_js
node_js:
- "0.10"

View File

@@ -1,19 +0,0 @@
Copyright (c) 2014 Forbes Lindesay
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,5 +0,0 @@
module.exports = isPromise;
function isPromise(obj) {
return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
}

View File

@@ -1,48 +0,0 @@
{
"name": "is-promise",
"version": "2.1.0",
"description": "Test whether an object looks like a promises-a+ promise",
"main": "index.js",
"scripts": {
"test": "mocha -R spec"
},
"repository": {
"type": "git",
"url": "git+https://github.com/then/is-promise.git"
},
"author": {
"name": "ForbesLindesay"
},
"license": "MIT",
"devDependencies": {
"better-assert": "~0.1.0",
"mocha": "~1.7.4"
},
"gitHead": "056f8ac12eed91886ac4f0f7d872a176f6ed698f",
"bugs": {
"url": "https://github.com/then/is-promise/issues"
},
"homepage": "https://github.com/then/is-promise",
"_id": "is-promise@2.1.0",
"_shasum": "79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa",
"_from": "is-promise@>=2.1.0 <3.0.0",
"_npmVersion": "2.7.1",
"_nodeVersion": "1.6.2",
"_npmUser": {
"name": "forbeslindesay",
"email": "forbes@lindesay.co.uk"
},
"maintainers": [
{
"name": "forbeslindesay",
"email": "forbes@lindesay.co.uk"
}
],
"dist": {
"shasum": "79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa",
"tarball": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
"readme": "ERROR: No README data found!"
}

View File

@@ -1,29 +0,0 @@
<a href="http://promises-aplus.github.com/promises-spec"><img src="http://promises-aplus.github.com/promises-spec/assets/logo-small.png" align="right" /></a>
# is-promise
Test whether an object looks like a promises-a+ promise
[![Build Status](https://img.shields.io/travis/then/is-promise/master.svg)](https://travis-ci.org/then/is-promise)
[![Dependency Status](https://img.shields.io/gemnasium/then/is-promise.svg)](https://gemnasium.com/then/is-promise)
[![NPM version](https://img.shields.io/npm/v/is-promise.svg)](https://www.npmjs.org/package/is-promise)
## Installation
$ npm install is-promise
You can also use it client side via npm.
## API
```javascript
var isPromise = require('is-promise');
isPromise({then:function () {...}});//=>true
isPromise(null);//=>false
isPromise({});//=>false
isPromise({then: true})//=>false
```
## License
MIT

View File

@@ -1,14 +0,0 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.js, **/*.js]
indent_size = 4
indent_style = space
[{package.json,.travis.yml}]
indent_size = 2
indent_style = space

View File

@@ -1,14 +0,0 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.js, **/*.js]
indent_size = 4
indent_style = space
[{package.json,.travis.yml}]
indent_size = 2
indent_style = space

View File

@@ -1,28 +0,0 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# Commenting this out is preferred by some people, see
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
node_modules
# Users Environment Variables
.lock-wscript

View File

@@ -1,22 +0,0 @@
The MIT License (MIT)
Copyright (c) 2015 Sam Mikes
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,29 +0,0 @@
# json-parse-helpfulerror
A drop-in replacement for `JSON.parse` that uses
<https://npmjs.org/jju> to provide more useful error messages in the
event of a parse error.
# Example
## Installation
```
npm i -S json-parse-helpfulerror
```
## Use
```js
var jph = require('json-parse-helpfulerror');
var notJSON = "{'foo': 3}"; // keys must be double-quoted in JSON
JSON.parse(notJSON); // throws unhelpful error
jph.parse("{'foo': 3}") // throws more helpful error: "Unexpected token '\''..."
```
# License
MIT

View File

@@ -1,21 +0,0 @@
'use strict';
var jju = require('jju');
function parse(text, reviver) {
try {
return JSON.parse(text, reviver);
} catch (err) {
// we expect this to throw with a more informative message
jju.parse(text, {
mode: 'json',
reviver: reviver
});
// backup if jju is not as strict as JSON.parse; re-throw error
// data-dependent code path, I do not know how to cover it
throw err;
}
}
exports.parse = parse;

View File

@@ -1,20 +0,0 @@
'use strict';
var jju = require('jju');
function parse(text, reviver) {
try {
return JSON.parse(text, reviver);
} catch(err) {
// we expect this throw with a more informative message
jju.parse(text, {
mode: 'json',
reviver: reviver
});
// if it didn't throw, re-throw the original error
throw err;
}
}
module.exports = parse;

View File

@@ -1,9 +0,0 @@
package.json
node_modules
test
benchmark
docs
examples
/.editorconfig
/.eslint*
/.travis.yml

View File

@@ -1,14 +0,0 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

View File

@@ -1,243 +0,0 @@
`jju` - a set of utilities to work with JSON / JSON5 documents
[![npm version badge](https://img.shields.io/npm/v/jju.svg)](https://www.npmjs.org/package/jju)
[![travis badge](http://img.shields.io/travis/rlidwka/jju.svg)](https://travis-ci.org/rlidwka/jju)
[![downloads badge](http://img.shields.io/npm/dm/jju.svg)](https://www.npmjs.org/package/jju)
## Installation
```
npm install jju
```
## Usage
This module provides following functions:
1. [jju.parse()](#jjuparse-function) parses json/json5 text and returns a javascript value it corresponds to
2. [jju.stringify()](#jjustringify-function) converts javascript value to an appropriate json/json5 text
3. [jju.tokenize()](#jjutokenize-function) parses json/json5 text and returns an array of tokens it consists of ([see demo](http://rlidwka.github.io/jju/tokenizer.html))
4. [jju.analyze()](#jjuanalyze-function) parses json/json5 text and tries to guess indentation, quoting style, etc.
5. [jju.update()](#jjuupdate-function) changes json/json5 text, preserving original formatting as much as possible ([see demo](http://rlidwka.github.io/jju/editor.html))
All functions are able to work with a standard JSON documents. `jju.parse()` and `jju.stringify()` are better in some cases, but slower than native `JSON.parse()` and `JSON.stringify()` versions. Detailed description see below.
### jju.parse() function
```javascript
/*
* Main syntax:
*
* `text` - text to parse, type: String
* `options` - parser options, type: Object
*/
jju.parse(text[, options])
// compatibility syntax
jju.parse(text[, reviver])
```
Options:
- reserved\_keys - what to do with reserved keys (String, default="ignore")
- "ignore" - ignore reserved keys
- "throw" - throw SyntaxError in case of reserved keys
- "replace" - replace reserved keys, this is the default JSON.parse behaviour, unsafe
Reserved keys are keys that exist in an empty object (`hasOwnProperty`, `__proto__`, etc.).
```javascript
// 'ignore' will cause reserved keys to be ignored:
parse('{hasOwnProperty: 1}', {reserved_keys: 'ignore'}) == {}
parse('{hasOwnProperty: 1, x: 2}', {reserved_keys: 'ignore'}).hasOwnProperty('x') == true
// 'throw' will cause SyntaxError in these cases:
parse('{hasOwnProperty: 1}', {reserved_keys: 'throw'}) == SyntaxError
// 'replace' will replace reserved keys with new ones:
parse('{hasOwnProperty: 1}', {reserved_keys: 'throw'}) == {hasOwnProperty: 1}
parse('{hasOwnProperty: 1, x: 2}', {reserved_keys: 'ignore'}).hasOwnProperty('x') == TypeError
```
- null\_prototype - create object as Object.create(null) instead of '{}' (Boolean)
if `reserved_keys != 'replace'`, default is **false**
if `reserved_keys == 'replace'`, default is **true**
It is usually unsafe and not recommended to change this option to false in the last case.
- reviver - reviver function - Function
This function should follow JSON specification
- mode - operation mode, set it to 'json' if you want to throw on non-strict json files (String)
### jju.stringify() function
```javascript
/*
* Main syntax:
*
* `value` - value to serialize, type: *
* `options` - serializer options, type: Object
*/
jju.stringify(value[, options])
// compatibility syntax
jju.stringify(value[, replacer [, indent])
```
Options:
- ascii - output ascii only (Boolean, default=false)
If this option is enabled, output will not have any characters except of 0x20-0x7f.
- indent - indentation (String, Number or Boolean, default='\t')
This option follows JSON specification.
- quote - enquoting char (String, "'" or '"', default="'")
- quote\_keys - whether keys quoting in objects is required or not (String, default=false)
If you want `{"q": 1}` instead of `{q: 1}`, set it to true.
- sort\_keys - sort all keys while stringifying (Boolean or Function, default=false)
By default sort order will depend on implementation, with v8 it's insertion order. If set to `true`, all keys (but not arrays) will be sorted alphabetically. You can provide your own sorting function as well.
- replacer - replacer function or array (Function or Array)
This option follows JSON specification.
- no\_trailing\_comma = don't output trailing comma (Boolean, default=false)
If this option is set, arrays like this `[1,2,3,]` will never be generated. Otherwise they may be generated for pretty printing.
- mode - operation mode, set it to 'json' if you want correct json in the output (String)
Currently it's either 'json' or something else. If it is 'json', following options are implied:
- options.quote = '"'
- options.no\_trailing\_comma = true
- options.quote\_keys = true
- '\x' literals are not used
### jju.tokenize() function
```javascript
/*
* Main syntax:
*
* `text` - text to tokenize, type: String
* `options` - parser options, type: Object
*/
jju.tokenize(text[, options])
```
Options are the same as for the `jju.parse` function.
Return value is an array of tokens, where each token is an object:
- raw (String) - raw text of this token, if you join all raw's, you will get the original document
- type (String) - type of the token, can be `whitespace`, `comment`, `key`, `literal`, `separator` or `newline`
- stack (Array) - path to the current token in the syntax tree
- value - value of the token if token is a `key` or `literal`
You can check tokenizer for yourself using [this demo](http://rlidwka.github.io/jju/tokenizer.html).
### jju.analyze() function
```javascript
/*
* Main syntax:
*
* `text` - text to analyze, type: String
* `options` - parser options, type: Object
*/
jju.analyze(text[, options])
```
Options are the same as for the `jju.parse` function.
Return value is an object defining a programming style in which the document was written.
- indent (String) - preferred indentation
- newline (String) - preferred newline
- quote (String) - `"` or `'` depending on which quote is preferred
- quote\_keys (Boolean) - `true` if unquoted keys were used at least once
- has\_whitespace (Boolean) - `true` if input has a whitespace token
- has\_comments (Boolean) - `true` if input has a comment token
- has\_newlines (Boolean) - `true` if input has a newline token
- has\_trailing\_comma (Boolean) - `true` if input has at least one trailing comma
### jju.update() function
```javascript
/*
* Main syntax:
*
* `text` - original text, type: String
* `new_value` - new value you want to set
* `options` - parser or stringifier options, type: Object
*/
jju.update(text, new_value[, options])
```
If you want to update a JSON document, here is the general approach:
```javascript
// here is your original JSON document:
var input = '{"foo": "bar", "baz": 123}'
// you need to parse it first:
var json = jju.parse(input, {mode: 'json'})
// json is { foo: 'bar', baz: 123 }
// then you can change it as you like:
json.foo = 'quux'
json.hello = 'world'
// then you run an update function to change the original json:
var output = jju.update(input, json, {mode: 'json'})
// output is '{"foo": "quux", "baz": 123, "hello": "world"}'
```
Look at [this demo](http://rlidwka.github.io/jju/editor.html) to test various types of json.
## Advantages over existing JSON libraries
In a few cases it makes sense to use this module instead of built-in JSON methods.
Parser:
- better error reporting with source code and line numbers
In case of syntax error, JSON.parse does not return any good information to the user. This module does:
```
$ node -e 'require("jju").parse("[1,1,1,1,invalid]")'
SyntaxError: Unexpected token 'i' at 0:9
[1,1,1,1,invalid]
^
```
This module is about 5 times slower, so if user experience matters to you more than performance, use this module. If you're working with a lot of machine-generated data, use JSON.parse instead.
Stringifier:
- util.inspect-like pretty printing
This module behaves more smart when dealing with object and arrays, and does not always print newlines in them:
```
$ node -e 'console.log(require("./").stringify([[,,,],,,[,,,,]], {mode:"json"}))'
[
[null, null, null],
null,
null,
[null, null, null, null]
]
```
JSON.stringify will split this into 15 lines, and it's hard to read.
Yet again, this feature comes with a performance hit, so if user experience matters to you more than performance, use this module. If your JSON will be consumed by machines, use JSON.stringify instead.
As a rule of thumb, if you use "space" argument to indent your JSON, you'd better use this module instead.

View File

@@ -1,32 +0,0 @@
module.exports.__defineGetter__('parse', function() {
return require('./lib/parse').parse
})
module.exports.__defineGetter__('stringify', function() {
return require('./lib/stringify').stringify
})
module.exports.__defineGetter__('tokenize', function() {
return require('./lib/parse').tokenize
})
module.exports.__defineGetter__('update', function() {
return require('./lib/document').update
})
module.exports.__defineGetter__('analyze', function() {
return require('./lib/analyze').analyze
})
module.exports.__defineGetter__('utils', function() {
return require('./lib/utils')
})
/**package
{ "name": "jju",
"version": "0.0.0",
"dependencies": {"js-yaml": "*"},
"scripts": {"postinstall": "js-yaml package.yaml > package.json ; npm install"}
}
**/

View File

@@ -1,92 +0,0 @@
/*
* Author: Alex Kocharin <alex@kocharin.ru>
* GIT: https://github.com/rlidwka/jju
* License: WTFPL, grab your copy here: http://www.wtfpl.net/txt/copying/
*/
var tokenize = require('./parse').tokenize
module.exports.analyze = function analyzeJSON(input, options) {
if (options == null) options = {}
if (!Array.isArray(input)) {
input = tokenize(input, options)
}
var result = {
has_whitespace: false,
has_comments: false,
has_newlines: false,
has_trailing_comma: false,
indent: '',
newline: '\n',
quote: '"',
quote_keys: true,
}
var stats = {
indent: {},
newline: {},
quote: {},
}
for (var i=0; i<input.length; i++) {
if (input[i].type === 'newline') {
if (input[i+1] && input[i+1].type === 'whitespace') {
if (input[i+1].raw[0] === '\t') {
// if first is tab, then indent is tab
stats.indent['\t'] = (stats.indent['\t'] || 0) + 1
}
if (input[i+1].raw.match(/^\x20+$/)) {
// if all are spaces, then indent is space
// this can fail with mixed indent (4, 2 would display 3)
var ws_len = input[i+1].raw.length
var indent_len = input[i+1].stack.length + 1
if (ws_len % indent_len === 0) {
var t = Array(ws_len / indent_len + 1).join(' ')
stats.indent[t] = (stats.indent[t] || 0) + 1
}
}
}
stats.newline[input[i].raw] = (stats.newline[input[i].raw] || 0) + 1
}
if (input[i].type === 'newline') {
result.has_newlines = true
}
if (input[i].type === 'whitespace') {
result.has_whitespace = true
}
if (input[i].type === 'comment') {
result.has_comments = true
}
if (input[i].type === 'key') {
if (input[i].raw[0] !== '"' && input[i].raw[0] !== "'") result.quote_keys = false
}
if (input[i].type === 'key' || input[i].type === 'literal') {
if (input[i].raw[0] === '"' || input[i].raw[0] === "'") {
stats.quote[input[i].raw[0]] = (stats.quote[input[i].raw[0]] || 0) + 1
}
}
if (input[i].type === 'separator' && input[i].raw === ',') {
for (var j=i+1; j<input.length; j++) {
if (input[j].type === 'literal' || input[j].type === 'key') break
if (input[j].type === 'separator') result.has_trailing_comma = true
}
}
}
for (var k in stats) {
if (Object.keys(stats[k]).length) {
result[k] = Object.keys(stats[k]).reduce(function(a, b) {
return stats[k][a] > stats[k][b] ? a : b
})
}
}
return result
}

View File

@@ -1,485 +0,0 @@
/*
* Author: Alex Kocharin <alex@kocharin.ru>
* GIT: https://github.com/rlidwka/jju
* License: WTFPL, grab your copy here: http://www.wtfpl.net/txt/copying/
*/
var assert = require('assert')
var tokenize = require('./parse').tokenize
var stringify = require('./stringify').stringify
var analyze = require('./analyze').analyze
function isObject(x) {
return typeof(x) === 'object' && x !== null
}
function value_to_tokenlist(value, stack, options, is_key, indent) {
options = Object.create(options)
options._stringify_key = !!is_key
if (indent) {
options._prefix = indent.prefix.map(function(x) {
return x.raw
}).join('')
}
if (options._splitMin == null) options._splitMin = 0
if (options._splitMax == null) options._splitMax = 0
var stringified = stringify(value, options)
if (is_key) {
return [ { raw: stringified, type: 'key', stack: stack, value: value } ]
}
options._addstack = stack
var result = tokenize(stringified, {
_addstack: stack,
})
result.data = null
return result
}
// '1.2.3' -> ['1','2','3']
function arg_to_path(path) {
// array indexes
if (typeof(path) === 'number') path = String(path)
if (path === '') path = []
if (typeof(path) === 'string') path = path.split('.')
if (!Array.isArray(path)) throw Error('Invalid path type, string or array expected')
return path
}
// returns new [begin, end] or false if not found
//
// {x:3, xxx: 111, y: [111, {q: 1, e: 2} ,333] }
// f('y',0) returns this B^^^^^^^^^^^^^^^^^^^^^^^^E
// then f('1',1) would reduce it to B^^^^^^^^^^E
function find_element_in_tokenlist(element, lvl, tokens, begin, end) {
while(tokens[begin].stack[lvl] != element) {
if (begin++ >= end) return false
}
while(tokens[end].stack[lvl] != element) {
if (end-- < begin) return false
}
return [begin, end]
}
function is_whitespace(token_type) {
return token_type === 'whitespace'
|| token_type === 'newline'
|| token_type === 'comment'
}
function find_first_non_ws_token(tokens, begin, end) {
while(is_whitespace(tokens[begin].type)) {
if (begin++ >= end) return false
}
return begin
}
function find_last_non_ws_token(tokens, begin, end) {
while(is_whitespace(tokens[end].type)) {
if (end-- < begin) return false
}
return end
}
/*
* when appending a new element of an object/array, we are trying to
* figure out the style used on the previous element
*
* return {prefix, sep1, sep2, suffix}
*
* ' "key" : "element" \r\n'
* prefix^^^^ sep1^ ^^sep2 ^^^^^^^^suffix
*
* begin - the beginning of the object/array
* end - last token of the last element (value or comma usually)
*/
function detect_indent_style(tokens, is_array, begin, end, level) {
var result = {
sep1: [],
sep2: [],
suffix: [],
prefix: [],
newline: [],
}
if (tokens[end].type === 'separator' && tokens[end].stack.length !== level+1 && tokens[end].raw !== ',') {
// either a beginning of the array (no last element) or other weird situation
//
// just return defaults
return result
}
// ' "key" : "value" ,'
// skipping last separator, we're now here ^^
if (tokens[end].type === 'separator')
end = find_last_non_ws_token(tokens, begin, end - 1)
if (end === false) return result
// ' "key" : "value" ,'
// skipping value ^^^^^^^
while(tokens[end].stack.length > level) end--
if (!is_array) {
while(is_whitespace(tokens[end].type)) {
if (end < begin) return result
if (tokens[end].type === 'whitespace') {
result.sep2.unshift(tokens[end])
} else {
// newline, comment or other unrecognized codestyle
return result
}
end--
}
// ' "key" : "value" ,'
// skipping separator ^
assert.equal(tokens[end].type, 'separator')
assert.equal(tokens[end].raw, ':')
while(is_whitespace(tokens[--end].type)) {
if (end < begin) return result
if (tokens[end].type === 'whitespace') {
result.sep1.unshift(tokens[end])
} else {
// newline, comment or other unrecognized codestyle
return result
}
}
assert.equal(tokens[end].type, 'key')
end--
}
// ' "key" : "value" ,'
// skipping key ^^^^^
while(is_whitespace(tokens[end].type)) {
if (end < begin) return result
if (tokens[end].type === 'whitespace') {
result.prefix.unshift(tokens[end])
} else if (tokens[end].type === 'newline') {
result.newline.unshift(tokens[end])
return result
} else {
// comment or other unrecognized codestyle
return result
}
end--
}
return result
}
function Document(text, options) {
var self = Object.create(Document.prototype)
if (options == null) options = {}
//options._structure = true
var tokens = self._tokens = tokenize(text, options)
self._data = tokens.data
tokens.data = null
self._options = options
var stats = analyze(text, options)
if (options.indent == null) {
options.indent = stats.indent
}
if (options.quote == null) {
options.quote = stats.quote
}
if (options.quote_keys == null) {
options.quote_keys = stats.quote_keys
}
if (options.no_trailing_comma == null) {
options.no_trailing_comma = !stats.has_trailing_comma
}
return self
}
// return true if it's a proper object
// throw otherwise
function check_if_can_be_placed(key, object, is_unset) {
//if (object == null) return false
function error(add) {
return Error("You can't " + (is_unset ? 'unset' : 'set') + " key '" + key + "'" + add)
}
if (!isObject(object)) {
throw error(' of an non-object')
}
if (Array.isArray(object)) {
// array, check boundary
if (String(key).match(/^\d+$/)) {
key = Number(String(key))
if (object.length < key || (is_unset && object.length === key)) {
throw error(', out of bounds')
} else if (is_unset && object.length !== key+1) {
throw error(' in the middle of an array')
} else {
return true
}
} else {
throw error(' of an array')
}
} else {
// object
return true
}
}
// usage: document.set('path.to.something', 'value')
// or: document.set(['path','to','something'], 'value')
Document.prototype.set = function(path, value) {
path = arg_to_path(path)
// updating this._data and check for errors
if (path.length === 0) {
if (value === undefined) throw Error("can't remove root document")
this._data = value
var new_key = false
} else {
var data = this._data
for (var i=0; i<path.length-1; i++) {
check_if_can_be_placed(path[i], data, false)
data = data[path[i]]
}
if (i === path.length-1) {
check_if_can_be_placed(path[i], data, value === undefined)
}
var new_key = !(path[i] in data)
if (value === undefined) {
if (Array.isArray(data)) {
data.pop()
} else {
delete data[path[i]]
}
} else {
data[path[i]] = value
}
}
// for inserting document
if (!this._tokens.length)
this._tokens = [ { raw: '', type: 'literal', stack: [], value: undefined } ]
var position = [
find_first_non_ws_token(this._tokens, 0, this._tokens.length - 1),
find_last_non_ws_token(this._tokens, 0, this._tokens.length - 1),
]
for (var i=0; i<path.length-1; i++) {
position = find_element_in_tokenlist(path[i], i, this._tokens, position[0], position[1])
if (position == false) throw Error('internal error, please report this')
}
// assume that i == path.length-1 here
if (path.length === 0) {
var newtokens = value_to_tokenlist(value, path, this._options)
// all good
} else if (!new_key) {
// replace old value with a new one (or deleting something)
var pos_old = position
position = find_element_in_tokenlist(path[i], i, this._tokens, position[0], position[1])
if (value === undefined && position !== false) {
// deleting element (position !== false ensures there's something)
var newtokens = []
if (!Array.isArray(data)) {
// removing element from an object, `{x:1, key:CURRENT} -> {x:1}`
// removing sep, literal and optional sep
// ':'
var pos2 = find_last_non_ws_token(this._tokens, pos_old[0], position[0] - 1)
assert.equal(this._tokens[pos2].type, 'separator')
assert.equal(this._tokens[pos2].raw, ':')
position[0] = pos2
// key
var pos2 = find_last_non_ws_token(this._tokens, pos_old[0], position[0] - 1)
assert.equal(this._tokens[pos2].type, 'key')
assert.equal(this._tokens[pos2].value, path[path.length-1])
position[0] = pos2
}
// removing comma in arrays and objects
var pos2 = find_last_non_ws_token(this._tokens, pos_old[0], position[0] - 1)
assert.equal(this._tokens[pos2].type, 'separator')
if (this._tokens[pos2].raw === ',') {
position[0] = pos2
} else {
// beginning of the array/object, so we should remove trailing comma instead
pos2 = find_first_non_ws_token(this._tokens, position[1] + 1, pos_old[1])
assert.equal(this._tokens[pos2].type, 'separator')
if (this._tokens[pos2].raw === ',') {
position[1] = pos2
}
}
} else {
var indent = pos2 !== false
? detect_indent_style(this._tokens, Array.isArray(data), pos_old[0], position[1] - 1, i)
: {}
var newtokens = value_to_tokenlist(value, path, this._options, false, indent)
}
} else {
// insert new key, that's tricky
var path_1 = path.slice(0, i)
// find a last separator after which we're inserting it
var pos2 = find_last_non_ws_token(this._tokens, position[0] + 1, position[1] - 1)
assert(pos2 !== false)
var indent = pos2 !== false
? detect_indent_style(this._tokens, Array.isArray(data), position[0] + 1, pos2, i)
: {}
var newtokens = value_to_tokenlist(value, path, this._options, false, indent)
// adding leading whitespaces according to detected codestyle
var prefix = []
if (indent.newline && indent.newline.length)
prefix = prefix.concat(indent.newline)
if (indent.prefix && indent.prefix.length)
prefix = prefix.concat(indent.prefix)
// adding '"key":' (as in "key":"value") to object values
if (!Array.isArray(data)) {
prefix = prefix.concat(value_to_tokenlist(path[path.length-1], path_1, this._options, true))
if (indent.sep1 && indent.sep1.length)
prefix = prefix.concat(indent.sep1)
prefix.push({raw: ':', type: 'separator', stack: path_1})
if (indent.sep2 && indent.sep2.length)
prefix = prefix.concat(indent.sep2)
}
newtokens.unshift.apply(newtokens, prefix)
// check if prev token is a separator AND they're at the same level
if (this._tokens[pos2].type === 'separator' && this._tokens[pos2].stack.length === path.length-1) {
// previous token is either , or [ or {
if (this._tokens[pos2].raw === ',') {
// restore ending comma
newtokens.push({raw: ',', type: 'separator', stack: path_1})
}
} else {
// previous token isn't a separator, so need to insert one
newtokens.unshift({raw: ',', type: 'separator', stack: path_1})
}
if (indent.suffix && indent.suffix.length)
newtokens.push.apply(newtokens, indent.suffix)
assert.equal(this._tokens[position[1]].type, 'separator')
position[0] = pos2+1
position[1] = pos2
}
newtokens.unshift(position[1] - position[0] + 1)
newtokens.unshift(position[0])
this._tokens.splice.apply(this._tokens, newtokens)
return this
}
// convenience method
Document.prototype.unset = function(path) {
return this.set(path, undefined)
}
Document.prototype.get = function(path) {
path = arg_to_path(path)
var data = this._data
for (var i=0; i<path.length; i++) {
if (!isObject(data)) return undefined
data = data[path[i]]
}
return data
}
Document.prototype.has = function(path) {
path = arg_to_path(path)
var data = this._data
for (var i=0; i<path.length; i++) {
if (!isObject(data)) return false
data = data[path[i]]
}
return data !== undefined
}
// compare old object and new one, and change differences only
Document.prototype.update = function(value) {
var self = this
change([], self._data, value)
return self
function change(path, old_data, new_data) {
if (!isObject(new_data) || !isObject(old_data)) {
// if source or dest is primitive, just replace
if (new_data !== old_data)
self.set(path, new_data)
} else if (Array.isArray(new_data) != Array.isArray(old_data)) {
// old data is an array XOR new data is an array, replace as well
self.set(path, new_data)
} else if (Array.isArray(new_data)) {
// both values are arrays here
if (new_data.length > old_data.length) {
// adding new elements, so going forward
for (var i=0; i<new_data.length; i++) {
path.push(String(i))
change(path, old_data[i], new_data[i])
path.pop()
}
} else {
// removing something, so going backward
for (var i=old_data.length-1; i>=0; i--) {
path.push(String(i))
change(path, old_data[i], new_data[i])
path.pop()
}
}
} else {
// both values are objects here
for (var i in new_data) {
path.push(String(i))
change(path, old_data[i], new_data[i])
path.pop()
}
for (var i in old_data) {
if (i in new_data) continue
path.push(String(i))
change(path, old_data[i], new_data[i])
path.pop()
}
}
}
}
Document.prototype.toString = function() {
return this._tokens.map(function(x) {
return x.raw
}).join('')
}
module.exports.Document = Document
module.exports.update = function updateJSON(source, new_value, options) {
return Document(source, options).update(new_value).toString()
}

View File

@@ -1,765 +0,0 @@
/*
* Author: Alex Kocharin <alex@kocharin.ru>
* GIT: https://github.com/rlidwka/jju
* License: WTFPL, grab your copy here: http://www.wtfpl.net/txt/copying/
*/
// RTFM: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
var Uni = require('./unicode')
function isHexDigit(x) {
return (x >= '0' && x <= '9')
|| (x >= 'A' && x <= 'F')
|| (x >= 'a' && x <= 'f')
}
function isOctDigit(x) {
return x >= '0' && x <= '7'
}
function isDecDigit(x) {
return x >= '0' && x <= '9'
}
var unescapeMap = {
'\'': '\'',
'"' : '"',
'\\': '\\',
'b' : '\b',
'f' : '\f',
'n' : '\n',
'r' : '\r',
't' : '\t',
'v' : '\v',
'/' : '/',
}
function formatError(input, msg, position, lineno, column, json5) {
var result = msg + ' at ' + (lineno + 1) + ':' + (column + 1)
, tmppos = position - column - 1
, srcline = ''
, underline = ''
var isLineTerminator = json5 ? Uni.isLineTerminator : Uni.isLineTerminatorJSON
// output no more than 70 characters before the wrong ones
if (tmppos < position - 70) {
tmppos = position - 70
}
while (1) {
var chr = input[++tmppos]
if (isLineTerminator(chr) || tmppos === input.length) {
if (position >= tmppos) {
// ending line error, so show it after the last char
underline += '^'
}
break
}
srcline += chr
if (position === tmppos) {
underline += '^'
} else if (position > tmppos) {
underline += input[tmppos] === '\t' ? '\t' : ' '
}
// output no more than 78 characters on the string
if (srcline.length > 78) break
}
return result + '\n' + srcline + '\n' + underline
}
function parse(input, options) {
// parse as a standard JSON mode
var json5 = false;
var cjson = false;
if (options.legacy || options.mode === 'json') {
// use json
} else if (options.mode === 'cjson') {
cjson = true;
} else if (options.mode === 'json5') {
json5 = true;
} else {
// use it by default
json5 = true;
}
var isLineTerminator = json5 ? Uni.isLineTerminator : Uni.isLineTerminatorJSON
var isWhiteSpace = json5 ? Uni.isWhiteSpace : Uni.isWhiteSpaceJSON
var length = input.length
, lineno = 0
, linestart = 0
, position = 0
, stack = []
var tokenStart = function() {}
var tokenEnd = function(v) {return v}
/* tokenize({
raw: '...',
type: 'whitespace'|'comment'|'key'|'literal'|'separator'|'newline',
value: 'number'|'string'|'whatever',
path: [...],
})
*/
if (options._tokenize) {
;(function() {
var start = null
tokenStart = function() {
if (start !== null) throw Error('internal error, token overlap')
start = position
}
tokenEnd = function(v, type) {
if (start != position) {
var hash = {
raw: input.substr(start, position-start),
type: type,
stack: stack.slice(0),
}
if (v !== undefined) hash.value = v
options._tokenize.call(null, hash)
}
start = null
return v
}
})()
}
function fail(msg) {
var column = position - linestart
if (!msg) {
if (position < length) {
var token = '\'' +
JSON
.stringify(input[position])
.replace(/^"|"$/g, '')
.replace(/'/g, "\\'")
.replace(/\\"/g, '"')
+ '\''
if (!msg) msg = 'Unexpected token ' + token
} else {
if (!msg) msg = 'Unexpected end of input'
}
}
var error = SyntaxError(formatError(input, msg, position, lineno, column, json5))
error.row = lineno + 1
error.column = column + 1
throw error
}
function newline(chr) {
// account for <cr><lf>
if (chr === '\r' && input[position] === '\n') position++
linestart = position
lineno++
}
function parseGeneric() {
var result
while (position < length) {
tokenStart()
var chr = input[position++]
if (chr === '"' || (chr === '\'' && json5)) {
return tokenEnd(parseString(chr), 'literal')
} else if (chr === '{') {
tokenEnd(undefined, 'separator')
return parseObject()
} else if (chr === '[') {
tokenEnd(undefined, 'separator')
return parseArray()
} else if (chr === '-'
|| chr === '.'
|| isDecDigit(chr)
// + number Infinity NaN
|| (json5 && (chr === '+' || chr === 'I' || chr === 'N'))
) {
return tokenEnd(parseNumber(), 'literal')
} else if (chr === 'n') {
parseKeyword('null')
return tokenEnd(null, 'literal')
} else if (chr === 't') {
parseKeyword('true')
return tokenEnd(true, 'literal')
} else if (chr === 'f') {
parseKeyword('false')
return tokenEnd(false, 'literal')
} else {
position--
return tokenEnd(undefined)
}
}
}
function parseKey() {
var result
while (position < length) {
tokenStart()
var chr = input[position++]
if (chr === '"' || (chr === '\'' && json5)) {
return tokenEnd(parseString(chr), 'key')
} else if (chr === '{') {
tokenEnd(undefined, 'separator')
return parseObject()
} else if (chr === '[') {
tokenEnd(undefined, 'separator')
return parseArray()
} else if (chr === '.'
|| isDecDigit(chr)
) {
return tokenEnd(parseNumber(true), 'key')
} else if (json5
&& Uni.isIdentifierStart(chr) || (chr === '\\' && input[position] === 'u')) {
// unicode char or a unicode sequence
var rollback = position - 1
var result = parseIdentifier()
if (result === undefined) {
position = rollback
return tokenEnd(undefined)
} else {
return tokenEnd(result, 'key')
}
} else {
position--
return tokenEnd(undefined)
}
}
}
function skipWhiteSpace() {
tokenStart()
while (position < length) {
var chr = input[position++]
if (isLineTerminator(chr)) {
position--
tokenEnd(undefined, 'whitespace')
tokenStart()
position++
newline(chr)
tokenEnd(undefined, 'newline')
tokenStart()
} else if (isWhiteSpace(chr)) {
// nothing
} else if (chr === '/'
&& (json5 || cjson)
&& (input[position] === '/' || input[position] === '*')
) {
position--
tokenEnd(undefined, 'whitespace')
tokenStart()
position++
skipComment(input[position++] === '*')
tokenEnd(undefined, 'comment')
tokenStart()
} else {
position--
break
}
}
return tokenEnd(undefined, 'whitespace')
}
function skipComment(multi) {
while (position < length) {
var chr = input[position++]
if (isLineTerminator(chr)) {
// LineTerminator is an end of singleline comment
if (!multi) {
// let parent function deal with newline
position--
return
}
newline(chr)
} else if (chr === '*' && multi) {
// end of multiline comment
if (input[position] === '/') {
position++
return
}
} else {
// nothing
}
}
if (multi) {
fail('Unclosed multiline comment')
}
}
function parseKeyword(keyword) {
// keyword[0] is not checked because it should've checked earlier
var _pos = position
var len = keyword.length
for (var i=1; i<len; i++) {
if (position >= length || keyword[i] != input[position]) {
position = _pos-1
fail()
}
position++
}
}
function parseObject() {
var result = options.null_prototype ? Object.create(null) : {}
, empty_object = {}
, is_non_empty = false
while (position < length) {
skipWhiteSpace()
var item1 = parseKey()
skipWhiteSpace()
tokenStart()
var chr = input[position++]
tokenEnd(undefined, 'separator')
if (chr === '}' && item1 === undefined) {
if (!json5 && is_non_empty) {
position--
fail('Trailing comma in object')
}
return result
} else if (chr === ':' && item1 !== undefined) {
skipWhiteSpace()
stack.push(item1)
var item2 = parseGeneric()
stack.pop()
if (item2 === undefined) fail('No value found for key ' + item1)
if (typeof(item1) !== 'string') {
if (!json5 || typeof(item1) !== 'number') {
fail('Wrong key type: ' + item1)
}
}
if ((item1 in empty_object || empty_object[item1] != null) && options.reserved_keys !== 'replace') {
if (options.reserved_keys === 'throw') {
fail('Reserved key: ' + item1)
} else {
// silently ignore it
}
} else {
if (typeof(options.reviver) === 'function') {
item2 = options.reviver.call(null, item1, item2)
}
if (item2 !== undefined) {
is_non_empty = true
Object.defineProperty(result, item1, {
value: item2,
enumerable: true,
configurable: true,
writable: true,
})
}
}
skipWhiteSpace()
tokenStart()
var chr = input[position++]
tokenEnd(undefined, 'separator')
if (chr === ',') {
continue
} else if (chr === '}') {
return result
} else {
fail()
}
} else {
position--
fail()
}
}
fail()
}
function parseArray() {
var result = []
while (position < length) {
skipWhiteSpace()
stack.push(result.length)
var item = parseGeneric()
stack.pop()
skipWhiteSpace()
tokenStart()
var chr = input[position++]
tokenEnd(undefined, 'separator')
if (item !== undefined) {
if (typeof(options.reviver) === 'function') {
item = options.reviver.call(null, String(result.length), item)
}
if (item === undefined) {
result.length++
item = true // hack for check below, not included into result
} else {
result.push(item)
}
}
if (chr === ',') {
if (item === undefined) {
fail('Elisions are not supported')
}
} else if (chr === ']') {
if (!json5 && item === undefined && result.length) {
position--
fail('Trailing comma in array')
}
return result
} else {
position--
fail()
}
}
}
function parseNumber() {
// rewind because we don't know first char
position--
var start = position
, chr = input[position++]
, t
var to_num = function(is_octal) {
var str = input.substr(start, position - start)
if (is_octal) {
var result = parseInt(str.replace(/^0o?/, ''), 8)
} else {
var result = Number(str)
}
if (Number.isNaN(result)) {
position--
fail('Bad numeric literal - "' + input.substr(start, position - start + 1) + '"')
} else if (!json5 && !str.match(/^-?(0|[1-9][0-9]*)(\.[0-9]+)?(e[+-]?[0-9]+)?$/i)) {
// additional restrictions imposed by json
position--
fail('Non-json numeric literal - "' + input.substr(start, position - start + 1) + '"')
} else {
return result
}
}
// ex: -5982475.249875e+29384
// ^ skipping this
if (chr === '-' || (chr === '+' && json5)) chr = input[position++]
if (chr === 'N' && json5) {
parseKeyword('NaN')
return NaN
}
if (chr === 'I' && json5) {
parseKeyword('Infinity')
// returning +inf or -inf
return to_num()
}
if (chr >= '1' && chr <= '9') {
// ex: -5982475.249875e+29384
// ^^^ skipping these
while (position < length && isDecDigit(input[position])) position++
chr = input[position++]
}
// special case for leading zero: 0.123456
if (chr === '0') {
chr = input[position++]
// new syntax, "0o777" old syntax, "0777"
var is_octal = chr === 'o' || chr === 'O' || isOctDigit(chr)
var is_hex = chr === 'x' || chr === 'X'
if (json5 && (is_octal || is_hex)) {
while (position < length
&& (is_hex ? isHexDigit : isOctDigit)( input[position] )
) position++
var sign = 1
if (input[start] === '-') {
sign = -1
start++
} else if (input[start] === '+') {
start++
}
return sign * to_num(is_octal)
}
}
if (chr === '.') {
// ex: -5982475.249875e+29384
// ^^^ skipping these
while (position < length && isDecDigit(input[position])) position++
chr = input[position++]
}
if (chr === 'e' || chr === 'E') {
chr = input[position++]
if (chr === '-' || chr === '+') position++
// ex: -5982475.249875e+29384
// ^^^ skipping these
while (position < length && isDecDigit(input[position])) position++
chr = input[position++]
}
// we have char in the buffer, so count for it
position--
return to_num()
}
function parseIdentifier() {
// rewind because we don't know first char
position--
var result = ''
while (position < length) {
var chr = input[position++]
if (chr === '\\'
&& input[position] === 'u'
&& isHexDigit(input[position+1])
&& isHexDigit(input[position+2])
&& isHexDigit(input[position+3])
&& isHexDigit(input[position+4])
) {
// UnicodeEscapeSequence
chr = String.fromCharCode(parseInt(input.substr(position+1, 4), 16))
position += 5
}
if (result.length) {
// identifier started
if (Uni.isIdentifierPart(chr)) {
result += chr
} else {
position--
return result
}
} else {
if (Uni.isIdentifierStart(chr)) {
result += chr
} else {
return undefined
}
}
}
fail()
}
function parseString(endChar) {
// 7.8.4 of ES262 spec
var result = ''
while (position < length) {
var chr = input[position++]
if (chr === endChar) {
return result
} else if (chr === '\\') {
if (position >= length) fail()
chr = input[position++]
if (unescapeMap[chr] && (json5 || (chr != 'v' && chr != "'"))) {
result += unescapeMap[chr]
} else if (json5 && isLineTerminator(chr)) {
// line continuation
newline(chr)
} else if (chr === 'u' || (chr === 'x' && json5)) {
// unicode/character escape sequence
var off = chr === 'u' ? 4 : 2
// validation for \uXXXX
for (var i=0; i<off; i++) {
if (position >= length) fail()
if (!isHexDigit(input[position])) fail('Bad escape sequence')
position++
}
result += String.fromCharCode(parseInt(input.substr(position-off, off), 16))
} else if (json5 && isOctDigit(chr)) {
if (chr < '4' && isOctDigit(input[position]) && isOctDigit(input[position+1])) {
// three-digit octal
var digits = 3
} else if (isOctDigit(input[position])) {
// two-digit octal
var digits = 2
} else {
var digits = 1
}
position += digits - 1
result += String.fromCharCode(parseInt(input.substr(position-digits, digits), 8))
/*if (!isOctDigit(input[position])) {
// \0 is allowed still
result += '\0'
} else {
fail('Octal literals are not supported')
}*/
} else if (json5) {
// \X -> x
result += chr
} else {
position--
fail()
}
} else if (isLineTerminator(chr)) {
fail()
} else {
if (!json5 && chr.charCodeAt(0) < 32) {
position--
fail('Unexpected control character')
}
// SourceCharacter but not one of " or \ or LineTerminator
result += chr
}
}
fail()
}
skipWhiteSpace()
var return_value = parseGeneric()
if (return_value !== undefined || position < length) {
skipWhiteSpace()
if (position >= length) {
if (typeof(options.reviver) === 'function') {
return_value = options.reviver.call(null, '', return_value)
}
return return_value
} else {
fail()
}
} else {
if (position) {
fail('No data, only a whitespace')
} else {
fail('No data, empty input')
}
}
}
/*
* parse(text, options)
* or
* parse(text, reviver)
*
* where:
* text - string
* options - object
* reviver - function
*/
module.exports.parse = function parseJSON(input, options) {
// support legacy functions
if (typeof(options) === 'function') {
options = {
reviver: options
}
}
if (input === undefined) {
// parse(stringify(x)) should be equal x
// with JSON functions it is not 'cause of undefined
// so we're fixing it
return undefined
}
// JSON.parse compat
if (typeof(input) !== 'string') input = String(input)
if (options == null) options = {}
if (options.reserved_keys == null) options.reserved_keys = 'ignore'
if (options.reserved_keys === 'throw' || options.reserved_keys === 'ignore') {
if (options.null_prototype == null) {
options.null_prototype = true
}
}
try {
return parse(input, options)
} catch(err) {
// jju is a recursive parser, so JSON.parse("{{{{{{{") could blow up the stack
//
// this catch is used to skip all those internal calls
if (err instanceof SyntaxError && err.row != null && err.column != null) {
var old_err = err
err = SyntaxError(old_err.message)
err.column = old_err.column
err.row = old_err.row
}
throw err
}
}
module.exports.tokenize = function tokenizeJSON(input, options) {
if (options == null) options = {}
options._tokenize = function(smth) {
if (options._addstack) smth.stack.unshift.apply(smth.stack, options._addstack)
tokens.push(smth)
}
var tokens = []
tokens.data = module.exports.parse(input, options)
return tokens
}

View File

@@ -1,383 +0,0 @@
/*
* Author: Alex Kocharin <alex@kocharin.ru>
* GIT: https://github.com/rlidwka/jju
* License: WTFPL, grab your copy here: http://www.wtfpl.net/txt/copying/
*/
var Uni = require('./unicode')
// Fix Function#name on browsers that do not support it (IE)
// http://stackoverflow.com/questions/6903762/function-name-not-supported-in-ie
if (!(function f(){}).name) {
Object.defineProperty((function(){}).constructor.prototype, 'name', {
get: function() {
var name = this.toString().match(/^\s*function\s*(\S*)\s*\(/)[1]
// For better performance only parse once, and then cache the
// result through a new accessor for repeated access.
Object.defineProperty(this, 'name', { value: name })
return name
}
})
}
var special_chars = {
0: '\\0', // this is not an octal literal
8: '\\b',
9: '\\t',
10: '\\n',
11: '\\v',
12: '\\f',
13: '\\r',
92: '\\\\',
}
// for oddballs
var hasOwnProperty = Object.prototype.hasOwnProperty
// some people escape those, so I'd copy this to be safe
var escapable = /[\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/
function _stringify(object, options, recursiveLvl, currentKey) {
var json5 = (options.mode === 'json5' || !options.mode)
/*
* Opinionated decision warning:
*
* Objects are serialized in the following form:
* { type: 'Class', data: DATA }
*
* Class is supposed to be a function, and new Class(DATA) is
* supposed to be equivalent to the original value
*/
/*function custom_type() {
return stringify({
type: object.constructor.name,
data: object.toString()
})
}*/
// if add, it's an internal indentation, so we add 1 level and a eol
// if !add, it's an ending indentation, so we just indent
function indent(str, add) {
var prefix = options._prefix ? options._prefix : ''
if (!options.indent) return prefix + str
var result = ''
var count = recursiveLvl + (add || 0)
for (var i=0; i<count; i++) result += options.indent
return prefix + result + str + (add ? '\n' : '')
}
function _stringify_key(key) {
if (options.quote_keys) return _stringify_str(key)
if (String(Number(key)) == key && key[0] != '-') return key
if (key == '') return _stringify_str(key)
var result = ''
for (var i=0; i<key.length; i++) {
if (i > 0) {
if (!Uni.isIdentifierPart(key[i]))
return _stringify_str(key)
} else {
if (!Uni.isIdentifierStart(key[i]))
return _stringify_str(key)
}
var chr = key.charCodeAt(i)
if (options.ascii) {
if (chr < 0x80) {
result += key[i]
} else {
result += '\\u' + ('0000' + chr.toString(16)).slice(-4)
}
} else {
if (escapable.exec(key[i])) {
result += '\\u' + ('0000' + chr.toString(16)).slice(-4)
} else {
result += key[i]
}
}
}
return result
}
function _stringify_str(key) {
var quote = options.quote
var quoteChr = quote.charCodeAt(0)
var result = ''
for (var i=0; i<key.length; i++) {
var chr = key.charCodeAt(i)
if (chr < 0x10) {
if (chr === 0 && json5) {
result += '\\0'
} else if (chr >= 8 && chr <= 13 && (json5 || chr !== 11)) {
result += special_chars[chr]
} else if (json5) {
result += '\\x0' + chr.toString(16)
} else {
result += '\\u000' + chr.toString(16)
}
} else if (chr < 0x20) {
if (json5) {
result += '\\x' + chr.toString(16)
} else {
result += '\\u00' + chr.toString(16)
}
} else if (chr >= 0x20 && chr < 0x80) {
// ascii range
if (chr === 47 && i && key[i-1] === '<') {
// escaping slashes in </script>
result += '\\' + key[i]
} else if (chr === 92) {
result += '\\\\'
} else if (chr === quoteChr) {
result += '\\' + quote
} else {
result += key[i]
}
} else if (options.ascii || Uni.isLineTerminator(key[i]) || escapable.exec(key[i])) {
if (chr < 0x100) {
if (json5) {
result += '\\x' + chr.toString(16)
} else {
result += '\\u00' + chr.toString(16)
}
} else if (chr < 0x1000) {
result += '\\u0' + chr.toString(16)
} else if (chr < 0x10000) {
result += '\\u' + chr.toString(16)
} else {
throw Error('weird codepoint')
}
} else {
result += key[i]
}
}
return quote + result + quote
}
function _stringify_object() {
if (object === null) return 'null'
var result = []
, len = 0
, braces
if (Array.isArray(object)) {
braces = '[]'
for (var i=0; i<object.length; i++) {
var s = _stringify(object[i], options, recursiveLvl+1, String(i))
if (s === undefined) s = 'null'
len += s.length + 2
result.push(s + ',')
}
} else {
braces = '{}'
var fn = function(key) {
var t = _stringify(object[key], options, recursiveLvl+1, key)
if (t !== undefined) {
t = _stringify_key(key) + ':' + (options.indent ? ' ' : '') + t + ','
len += t.length + 1
result.push(t)
}
}
if (Array.isArray(options.replacer)) {
for (var i=0; i<options.replacer.length; i++)
if (hasOwnProperty.call(object, options.replacer[i]))
fn(options.replacer[i])
} else {
var keys = Object.keys(object)
if (options.sort_keys)
keys = keys.sort(typeof(options.sort_keys) === 'function'
? options.sort_keys : undefined)
keys.forEach(fn)
}
}
// objects shorter than 30 characters are always inlined
// objects longer than 60 characters are always splitted to multiple lines
// anything in the middle depends on indentation level
len -= 2
if (options.indent && (len > options._splitMax - recursiveLvl * options.indent.length || len > options._splitMin) ) {
// remove trailing comma in multiline if asked to
if (options.no_trailing_comma && result.length) {
result[result.length-1] = result[result.length-1].substring(0, result[result.length-1].length-1)
}
var innerStuff = result.map(function(x) {return indent(x, 1)}).join('')
return braces[0]
+ (options.indent ? '\n' : '')
+ innerStuff
+ indent(braces[1])
} else {
// always remove trailing comma in one-lined arrays
if (result.length) {
result[result.length-1] = result[result.length-1].substring(0, result[result.length-1].length-1)
}
var innerStuff = result.join(options.indent ? ' ' : '')
return braces[0]
+ innerStuff
+ braces[1]
}
}
function _stringify_nonobject(object) {
if (typeof(options.replacer) === 'function') {
object = options.replacer.call(null, currentKey, object)
}
switch(typeof(object)) {
case 'string':
return _stringify_str(object)
case 'number':
if (object === 0 && 1/object < 0) {
// Opinionated decision warning:
//
// I want cross-platform negative zero in all js engines
// I know they're equal, but why lose that tiny bit of
// information needlessly?
return '-0'
}
if (!json5 && !Number.isFinite(object)) {
// json don't support infinity (= sucks)
return 'null'
}
return object.toString()
case 'boolean':
return object.toString()
case 'undefined':
return undefined
case 'function':
// return custom_type()
default:
// fallback for something weird
return JSON.stringify(object)
}
}
if (options._stringify_key) {
return _stringify_key(object)
}
if (typeof(object) === 'object') {
if (object === null) return 'null'
var str
if (typeof(str = object.toJSON5) === 'function' && options.mode !== 'json') {
object = str.call(object, currentKey)
} else if (typeof(str = object.toJSON) === 'function') {
object = str.call(object, currentKey)
}
if (object === null) return 'null'
if (typeof(object) !== 'object') return _stringify_nonobject(object)
if (object.constructor === Number || object.constructor === Boolean || object.constructor === String) {
object = object.valueOf()
return _stringify_nonobject(object)
} else if (object.constructor === Date) {
// only until we can't do better
return _stringify_nonobject(object.toISOString())
} else {
if (typeof(options.replacer) === 'function') {
object = options.replacer.call(null, currentKey, object)
if (typeof(object) !== 'object') return _stringify_nonobject(object)
}
return _stringify_object(object)
}
} else {
return _stringify_nonobject(object)
}
}
/*
* stringify(value, options)
* or
* stringify(value, replacer, space)
*
* where:
* value - anything
* options - object
* replacer - function or array
* space - boolean or number or string
*/
module.exports.stringify = function stringifyJSON(object, options, _space) {
// support legacy syntax
if (typeof(options) === 'function' || Array.isArray(options)) {
options = {
replacer: options
}
} else if (typeof(options) === 'object' && options !== null) {
// nothing to do
} else {
options = {}
}
if (_space != null) options.indent = _space
if (options.indent == null) options.indent = '\t'
if (options.quote == null) options.quote = "'"
if (options.ascii == null) options.ascii = false
if (options.mode == null) options.mode = 'json5'
if (options.mode === 'json' || options.mode === 'cjson') {
// json only supports double quotes (= sucks)
options.quote = '"'
// json don't support trailing commas (= sucks)
options.no_trailing_comma = true
// json don't support unquoted property names (= sucks)
options.quote_keys = true
}
// why would anyone use such objects?
if (typeof(options.indent) === 'object') {
if (options.indent.constructor === Number
|| options.indent.constructor === Boolean
|| options.indent.constructor === String)
options.indent = options.indent.valueOf()
}
// gap is capped at 10 characters
if (typeof(options.indent) === 'number') {
if (options.indent >= 0) {
options.indent = Array(Math.min(~~options.indent, 10) + 1).join(' ')
} else {
options.indent = false
}
} else if (typeof(options.indent) === 'string') {
options.indent = options.indent.substr(0, 10)
}
if (options._splitMin == null) options._splitMin = 50
if (options._splitMax == null) options._splitMax = 70
return _stringify(object, options, 0, '')
}

File diff suppressed because one or more lines are too long

View File

@@ -1,46 +0,0 @@
var FS = require('fs')
var jju = require('../')
// this function registers json5 extension, so you
// can do `require("./config.json5")` kind of thing
module.exports.register = function() {
var r = require, e = 'extensions'
r[e]['.json5'] = function(m, f) {
/*eslint no-sync:0*/
m.exports = jju.parse(FS.readFileSync(f, 'utf8'))
}
}
// this function monkey-patches JSON.parse, so it
// will return an exact position of error in case
// of parse failure
module.exports.patch_JSON_parse = function() {
var _parse = JSON.parse
JSON.parse = function(text, rev) {
try {
return _parse(text, rev)
} catch(err) {
// this call should always throw
require('jju').parse(text, {
mode: 'json',
legacy: true,
reviver: rev,
reserved_keys: 'replace',
null_prototype: false,
})
// if it didn't throw, but original parser did,
// this is an error in this library and should be reported
throw err
}
}
}
// this function is an express/connect middleware
// that accepts uploads in application/json5 format
module.exports.middleware = function() {
return function(req, res, next) {
throw Error('this function is removed, use express-json5 instead')
}
}

View File

@@ -1,67 +0,0 @@
{
"name": "jju",
"version": "1.3.0",
"description": "a set of utilities to work with JSON / JSON5 documents",
"author": {
"name": "Alex Kocharin",
"email": "alex@kocharin.ru"
},
"repository": {
"type": "git",
"url": "git://github.com/rlidwka/jju.git"
},
"bugs": {
"url": "https://github.com/rlidwka/jju/issues"
},
"homepage": "http://rlidwka.github.io/jju/",
"devDependencies": {
"mocha": ">=1.21.0",
"js-yaml": ">=3.1.0",
"eslint": "~0.4.2"
},
"scripts": {
"test": "mocha test/*.js",
"lint": "eslint -c ./.eslint.yaml ./lib"
},
"keywords": [
"json",
"json5",
"parser",
"serializer",
"data"
],
"publishConfig": {
"registry": "https://registry.npmjs.org/"
},
"license": {
"type": "WTFPL",
"url": "http://www.wtfpl.net/txt/copying/"
},
"gitHead": "6a1248fc29abb3f418fa143e31ee548cd5a2477c",
"_id": "jju@1.3.0",
"_shasum": "dadd9ef01924bc728b03f2f7979bdbd62f7a2aaa",
"_from": "jju@>=1.1.0 <2.0.0",
"_npmVersion": "2.0.1",
"_nodeVersion": "2.2.1",
"_npmUser": {
"name": "rlidwka",
"email": "alex@kocharin.ru"
},
"maintainers": [
{
"name": "rlidwka",
"email": "alex@kocharin.ru"
}
],
"dist": {
"shasum": "dadd9ef01924bc728b03f2f7979bdbd62f7a2aaa",
"tarball": "https://registry.npmjs.org/jju/-/jju-1.3.0.tgz"
},
"_npmOperationalInternal": {
"host": "packages-6-west.internal.npmjs.com",
"tmp": "tmp/jju-1.3.0.tgz_1455989902144_0.8787874563131481"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/jju/-/jju-1.3.0.tgz",
"readme": "ERROR: No README data found!"
}

View File

@@ -1,46 +0,0 @@
# use "yapm install ." if you're installing this from git repository
# "jju" stands for "json/json5 utils"
name: jju
version: 1.3.0
description: a set of utilities to work with JSON / JSON5 documents
author:
name: Alex Kocharin
email: alex@kocharin.ru
repository:
type: git
url: git://github.com/rlidwka/jju
bugs:
url: https://github.com/rlidwka/jju/issues
homepage: http://rlidwka.github.io/jju/
devDependencies:
mocha: '>=1.21.0'
js-yaml: '>=3.1.0'
# linting tools
eslint: '~0.4.2'
scripts:
test: 'mocha test/*.js'
lint: 'eslint -c ./.eslint.yaml ./lib'
keywords:
- json
- json5
- parser
- serializer
- data
publishConfig:
registry: https://registry.npmjs.org/
license:
type: WTFPL
url: http://www.wtfpl.net/txt/copying/

View File

@@ -1,61 +0,0 @@
{
"name": "json-parse-helpfulerror",
"version": "1.0.3",
"description": "A drop-in replacement for JSON.parse that uses `jju` to give helpful errors",
"main": "index.js",
"scripts": {
"test": "lab -c",
"lint": "jslint --edition=latest --terse *.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/smikes/json-parse-helpfulerror.git"
},
"keywords": [
"json",
"parse",
"line",
"doublequote",
"error"
],
"author": {
"name": "Sam Mikes",
"email": "smikes@cubane.com"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/smikes/json-parse-helpfulerror/issues"
},
"homepage": "https://github.com/smikes/json-parse-helpfulerror",
"devDependencies": {
"code": "^1.2.1",
"jslint": "^0.7.1",
"lab": "^5.1.1"
},
"dependencies": {
"jju": "^1.1.0"
},
"gitHead": "eedb116ec96b5c479be3919b526d6de0a521be5e",
"_id": "json-parse-helpfulerror@1.0.3",
"_shasum": "13f14ce02eed4e981297b64eb9e3b932e2dd13dc",
"_from": "json-parse-helpfulerror@>=1.0.3 <2.0.0",
"_npmVersion": "2.1.16",
"_nodeVersion": "0.10.35",
"_npmUser": {
"name": "smikes",
"email": "smikes@cubane.com"
},
"maintainers": [
{
"name": "smikes",
"email": "smikes@cubane.com"
}
],
"dist": {
"shasum": "13f14ce02eed4e981297b64eb9e3b932e2dd13dc",
"tarball": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz"
},
"directories": {},
"_resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz",
"readme": "ERROR: No README data found!"
}

View File

@@ -1,32 +0,0 @@
var Code = require('code'),
Lab = require('lab'),
lab = Lab.script(),
jph = require('..'); // 'json-parse-helpfulerror'
exports.lab = lab;
lab.test('can parse', function (done) {
var o = jph.parse('{"foo": "bar"}');
Code.expect(o.foo).to.equal('bar');
done();
});
lab.test('helpful error for bad JSON', function (done) {
var bad = "{'foo': 'bar'}";
Code.expect(function () { JSON.parse(bad) }).to.throw();
Code.expect(function () { jph.parse(bad) }).to.throw(SyntaxError, "Unexpected token '\\'' at 1:2\n" + bad + '\n ^');
done();
});
lab.test('fails if reviver throws', function (done) {
function badReviver() { throw new ReferenceError('silly'); }
Code.expect(function () { jph.parse('3', badReviver) }).to.throw(ReferenceError, 'silly');
done();
});

View File

@@ -1,11 +0,0 @@
var Code = require('code'),
Lab = require('lab'),
lab = lab.script;
exports.lab = lab;
lab.test('tests run and work', function (done) {
Code.expect(1+1).to.equal(2);
done();
});

View File

@@ -1,47 +0,0 @@
Copyright jQuery Foundation and other contributors <https://jquery.org/>
Based on Underscore.js, copyright Jeremy Ashkenas,
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
This software consists of voluntary contributions made by many
individuals. For exact contribution history, see the revision history
available at https://github.com/lodash/lodash
The following license applies to all parts of this software except as
documented below:
====
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
====
Copyright and related rights for sample code are waived via CC0. Sample
code is defined as all source code displayed within the prose of the
documentation.
CC0: http://creativecommons.org/publicdomain/zero/1.0/
====
Files located in the node_modules and vendor directories are externally
maintained libraries used by this software which have their own
licenses; we recommend you read them, as their terms may differ from the
terms above.

View File

@@ -1,40 +0,0 @@
# lodash v4.13.1
The [Lodash](https://lodash.com/) library exported as [Node.js](https://nodejs.org/) modules.
## Installation
Using npm:
```bash
$ {sudo -H} npm i -g npm
$ npm i --save lodash
```
In Node.js:
```js
// Load the full build.
var _ = require('lodash');
// Load the core build.
var _ = require('lodash/core');
// Load the fp build for immutable auto-curried iteratee-first data-last methods.
var fp = require('lodash/fp');
// Load a method category.
var array = require('lodash/array');
var object = require('lodash/fp/object');
// Load a single method for smaller builds with browserify/rollup/webpack.
var chunk = require('lodash/chunk');
var extend = require('lodash/fp/extend');
```
See the [package source](https://github.com/lodash/lodash/tree/4.13.1-npm) for more details.
**Note:**<br>
Dont assign values to the [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` in the Node.js < 6 REPL.<br>
Install [n_](https://www.npmjs.com/package/n_) for a REPL that includes `lodash` by default.
## Support
Tested in Chrome 49-50, Firefox 45-46, IE 9-11, Edge 13, Safari 8-9, Node.js 0.10-6, & PhantomJS 1.9.8.<br>
Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available.

View File

@@ -1,7 +0,0 @@
var getNative = require('./_getNative'),
root = require('./_root');
/* Built-in method references that are verified to be native. */
var DataView = getNative(root, 'DataView');
module.exports = DataView;

View File

@@ -1,32 +0,0 @@
var hashClear = require('./_hashClear'),
hashDelete = require('./_hashDelete'),
hashGet = require('./_hashGet'),
hashHas = require('./_hashHas'),
hashSet = require('./_hashSet');
/**
* Creates a hash object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function Hash(entries) {
var index = -1,
length = entries ? entries.length : 0;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `Hash`.
Hash.prototype.clear = hashClear;
Hash.prototype['delete'] = hashDelete;
Hash.prototype.get = hashGet;
Hash.prototype.has = hashHas;
Hash.prototype.set = hashSet;
module.exports = Hash;

View File

@@ -1,28 +0,0 @@
var baseCreate = require('./_baseCreate'),
baseLodash = require('./_baseLodash');
/** Used as references for the maximum length and index of an array. */
var MAX_ARRAY_LENGTH = 4294967295;
/**
* Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
*
* @private
* @constructor
* @param {*} value The value to wrap.
*/
function LazyWrapper(value) {
this.__wrapped__ = value;
this.__actions__ = [];
this.__dir__ = 1;
this.__filtered__ = false;
this.__iteratees__ = [];
this.__takeCount__ = MAX_ARRAY_LENGTH;
this.__views__ = [];
}
// Ensure `LazyWrapper` is an instance of `baseLodash`.
LazyWrapper.prototype = baseCreate(baseLodash.prototype);
LazyWrapper.prototype.constructor = LazyWrapper;
module.exports = LazyWrapper;

View File

@@ -1,32 +0,0 @@
var listCacheClear = require('./_listCacheClear'),
listCacheDelete = require('./_listCacheDelete'),
listCacheGet = require('./_listCacheGet'),
listCacheHas = require('./_listCacheHas'),
listCacheSet = require('./_listCacheSet');
/**
* Creates an list cache object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function ListCache(entries) {
var index = -1,
length = entries ? entries.length : 0;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `ListCache`.
ListCache.prototype.clear = listCacheClear;
ListCache.prototype['delete'] = listCacheDelete;
ListCache.prototype.get = listCacheGet;
ListCache.prototype.has = listCacheHas;
ListCache.prototype.set = listCacheSet;
module.exports = ListCache;

View File

@@ -1,22 +0,0 @@
var baseCreate = require('./_baseCreate'),
baseLodash = require('./_baseLodash');
/**
* The base constructor for creating `lodash` wrapper objects.
*
* @private
* @param {*} value The value to wrap.
* @param {boolean} [chainAll] Enable explicit method chain sequences.
*/
function LodashWrapper(value, chainAll) {
this.__wrapped__ = value;
this.__actions__ = [];
this.__chain__ = !!chainAll;
this.__index__ = 0;
this.__values__ = undefined;
}
LodashWrapper.prototype = baseCreate(baseLodash.prototype);
LodashWrapper.prototype.constructor = LodashWrapper;
module.exports = LodashWrapper;

View File

@@ -1,7 +0,0 @@
var getNative = require('./_getNative'),
root = require('./_root');
/* Built-in method references that are verified to be native. */
var Map = getNative(root, 'Map');
module.exports = Map;

View File

@@ -1,32 +0,0 @@
var mapCacheClear = require('./_mapCacheClear'),
mapCacheDelete = require('./_mapCacheDelete'),
mapCacheGet = require('./_mapCacheGet'),
mapCacheHas = require('./_mapCacheHas'),
mapCacheSet = require('./_mapCacheSet');
/**
* Creates a map cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function MapCache(entries) {
var index = -1,
length = entries ? entries.length : 0;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `MapCache`.
MapCache.prototype.clear = mapCacheClear;
MapCache.prototype['delete'] = mapCacheDelete;
MapCache.prototype.get = mapCacheGet;
MapCache.prototype.has = mapCacheHas;
MapCache.prototype.set = mapCacheSet;
module.exports = MapCache;

View File

@@ -1,7 +0,0 @@
var getNative = require('./_getNative'),
root = require('./_root');
/* Built-in method references that are verified to be native. */
var Promise = getNative(root, 'Promise');
module.exports = Promise;

View File

@@ -1,6 +0,0 @@
var root = require('./_root');
/** Built-in value references. */
var Reflect = root.Reflect;
module.exports = Reflect;

View File

@@ -1,7 +0,0 @@
var getNative = require('./_getNative'),
root = require('./_root');
/* Built-in method references that are verified to be native. */
var Set = getNative(root, 'Set');
module.exports = Set;

View File

@@ -1,27 +0,0 @@
var MapCache = require('./_MapCache'),
setCacheAdd = require('./_setCacheAdd'),
setCacheHas = require('./_setCacheHas');
/**
*
* Creates an array cache object to store unique values.
*
* @private
* @constructor
* @param {Array} [values] The values to cache.
*/
function SetCache(values) {
var index = -1,
length = values ? values.length : 0;
this.__data__ = new MapCache;
while (++index < length) {
this.add(values[index]);
}
}
// Add methods to `SetCache`.
SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
SetCache.prototype.has = setCacheHas;
module.exports = SetCache;

View File

@@ -1,26 +0,0 @@
var ListCache = require('./_ListCache'),
stackClear = require('./_stackClear'),
stackDelete = require('./_stackDelete'),
stackGet = require('./_stackGet'),
stackHas = require('./_stackHas'),
stackSet = require('./_stackSet');
/**
* Creates a stack cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function Stack(entries) {
this.__data__ = new ListCache(entries);
}
// Add methods to `Stack`.
Stack.prototype.clear = stackClear;
Stack.prototype['delete'] = stackDelete;
Stack.prototype.get = stackGet;
Stack.prototype.has = stackHas;
Stack.prototype.set = stackSet;
module.exports = Stack;

View File

@@ -1,6 +0,0 @@
var root = require('./_root');
/** Built-in value references. */
var Symbol = root.Symbol;
module.exports = Symbol;

View File

@@ -1,6 +0,0 @@
var root = require('./_root');
/** Built-in value references. */
var Uint8Array = root.Uint8Array;
module.exports = Uint8Array;

View File

@@ -1,7 +0,0 @@
var getNative = require('./_getNative'),
root = require('./_root');
/* Built-in method references that are verified to be native. */
var WeakMap = getNative(root, 'WeakMap');
module.exports = WeakMap;

View File

@@ -1,15 +0,0 @@
/**
* Adds the key-value `pair` to `map`.
*
* @private
* @param {Object} map The map to modify.
* @param {Array} pair The key-value pair to add.
* @returns {Object} Returns `map`.
*/
function addMapEntry(map, pair) {
// Don't return `Map#set` because it doesn't return the map instance in IE 11.
map.set(pair[0], pair[1]);
return map;
}
module.exports = addMapEntry;

View File

@@ -1,14 +0,0 @@
/**
* Adds `value` to `set`.
*
* @private
* @param {Object} set The set to modify.
* @param {*} value The value to add.
* @returns {Object} Returns `set`.
*/
function addSetEntry(set, value) {
set.add(value);
return set;
}
module.exports = addSetEntry;

View File

@@ -1,22 +0,0 @@
/**
* A faster alternative to `Function#apply`, this function invokes `func`
* with the `this` binding of `thisArg` and the arguments of `args`.
*
* @private
* @param {Function} func The function to invoke.
* @param {*} thisArg The `this` binding of `func`.
* @param {Array} args The arguments to invoke `func` with.
* @returns {*} Returns the result of `func`.
*/
function apply(func, thisArg, args) {
var length = args.length;
switch (length) {
case 0: return func.call(thisArg);
case 1: return func.call(thisArg, args[0]);
case 2: return func.call(thisArg, args[0], args[1]);
case 3: return func.call(thisArg, args[0], args[1], args[2]);
}
return func.apply(thisArg, args);
}
module.exports = apply;

View File

@@ -1,22 +0,0 @@
/**
* A specialized version of `baseAggregator` for arrays.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} setter The function to set `accumulator` values.
* @param {Function} iteratee The iteratee to transform keys.
* @param {Object} accumulator The initial aggregated object.
* @returns {Function} Returns `accumulator`.
*/
function arrayAggregator(array, setter, iteratee, accumulator) {
var index = -1,
length = array ? array.length : 0;
while (++index < length) {
var value = array[index];
setter(accumulator, value, iteratee(value), array);
}
return accumulator;
}
module.exports = arrayAggregator;

View File

@@ -1,22 +0,0 @@
/**
* A specialized version of `_.forEach` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns `array`.
*/
function arrayEach(array, iteratee) {
var index = -1,
length = array ? array.length : 0;
while (++index < length) {
if (iteratee(array[index], index, array) === false) {
break;
}
}
return array;
}
module.exports = arrayEach;

View File

@@ -1,21 +0,0 @@
/**
* A specialized version of `_.forEachRight` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns `array`.
*/
function arrayEachRight(array, iteratee) {
var length = array ? array.length : 0;
while (length--) {
if (iteratee(array[length], length, array) === false) {
break;
}
}
return array;
}
module.exports = arrayEachRight;

View File

@@ -1,23 +0,0 @@
/**
* A specialized version of `_.every` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
* @returns {boolean} Returns `true` if all elements pass the predicate check,
* else `false`.
*/
function arrayEvery(array, predicate) {
var index = -1,
length = array ? array.length : 0;
while (++index < length) {
if (!predicate(array[index], index, array)) {
return false;
}
}
return true;
}
module.exports = arrayEvery;

View File

@@ -1,25 +0,0 @@
/**
* A specialized version of `_.filter` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
* @returns {Array} Returns the new filtered array.
*/
function arrayFilter(array, predicate) {
var index = -1,
length = array ? array.length : 0,
resIndex = 0,
result = [];
while (++index < length) {
var value = array[index];
if (predicate(value, index, array)) {
result[resIndex++] = value;
}
}
return result;
}
module.exports = arrayFilter;

View File

@@ -1,17 +0,0 @@
var baseIndexOf = require('./_baseIndexOf');
/**
* A specialized version of `_.includes` for arrays without support for
* specifying an index to search from.
*
* @private
* @param {Array} [array] The array to search.
* @param {*} target The value to search for.
* @returns {boolean} Returns `true` if `target` is found, else `false`.
*/
function arrayIncludes(array, value) {
var length = array ? array.length : 0;
return !!length && baseIndexOf(array, value, 0) > -1;
}
module.exports = arrayIncludes;

View File

@@ -1,22 +0,0 @@
/**
* This function is like `arrayIncludes` except that it accepts a comparator.
*
* @private
* @param {Array} [array] The array to search.
* @param {*} target The value to search for.
* @param {Function} comparator The comparator invoked per element.
* @returns {boolean} Returns `true` if `target` is found, else `false`.
*/
function arrayIncludesWith(array, value, comparator) {
var index = -1,
length = array ? array.length : 0;
while (++index < length) {
if (comparator(value, array[index])) {
return true;
}
}
return false;
}
module.exports = arrayIncludesWith;

View File

@@ -1,21 +0,0 @@
/**
* A specialized version of `_.map` for arrays without support for iteratee
* shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the new mapped array.
*/
function arrayMap(array, iteratee) {
var index = -1,
length = array ? array.length : 0,
result = Array(length);
while (++index < length) {
result[index] = iteratee(array[index], index, array);
}
return result;
}
module.exports = arrayMap;

View File

@@ -1,20 +0,0 @@
/**
* Appends the elements of `values` to `array`.
*
* @private
* @param {Array} array The array to modify.
* @param {Array} values The values to append.
* @returns {Array} Returns `array`.
*/
function arrayPush(array, values) {
var index = -1,
length = values.length,
offset = array.length;
while (++index < length) {
array[offset + index] = values[index];
}
return array;
}
module.exports = arrayPush;

View File

@@ -1,26 +0,0 @@
/**
* A specialized version of `_.reduce` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
* @param {boolean} [initAccum] Specify using the first element of `array` as
* the initial value.
* @returns {*} Returns the accumulated value.
*/
function arrayReduce(array, iteratee, accumulator, initAccum) {
var index = -1,
length = array ? array.length : 0;
if (initAccum && length) {
accumulator = array[++index];
}
while (++index < length) {
accumulator = iteratee(accumulator, array[index], index, array);
}
return accumulator;
}
module.exports = arrayReduce;

View File

@@ -1,24 +0,0 @@
/**
* A specialized version of `_.reduceRight` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
* @param {boolean} [initAccum] Specify using the last element of `array` as
* the initial value.
* @returns {*} Returns the accumulated value.
*/
function arrayReduceRight(array, iteratee, accumulator, initAccum) {
var length = array ? array.length : 0;
if (initAccum && length) {
accumulator = array[--length];
}
while (length--) {
accumulator = iteratee(accumulator, array[length], length, array);
}
return accumulator;
}
module.exports = arrayReduceRight;

View File

@@ -1,23 +0,0 @@
/**
* A specialized version of `_.some` for arrays without support for iteratee
* shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} predicate The function invoked per iteration.
* @returns {boolean} Returns `true` if any element passes the predicate check,
* else `false`.
*/
function arraySome(array, predicate) {
var index = -1,
length = array ? array.length : 0;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
module.exports = arraySome;

View File

@@ -1,27 +0,0 @@
var eq = require('./eq');
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used by `_.defaults` to customize its `_.assignIn` use.
*
* @private
* @param {*} objValue The destination value.
* @param {*} srcValue The source value.
* @param {string} key The key of the property to assign.
* @param {Object} object The parent object of `objValue`.
* @returns {*} Returns the value to assign.
*/
function assignInDefaults(objValue, srcValue, key, object) {
if (objValue === undefined ||
(eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
return srcValue;
}
return objValue;
}
module.exports = assignInDefaults;

View File

@@ -1,19 +0,0 @@
var eq = require('./eq');
/**
* This function is like `assignValue` except that it doesn't assign
* `undefined` values.
*
* @private
* @param {Object} object The object to modify.
* @param {string} key The key of the property to assign.
* @param {*} value The value to assign.
*/
function assignMergeValue(object, key, value) {
if ((value !== undefined && !eq(object[key], value)) ||
(typeof key == 'number' && value === undefined && !(key in object))) {
object[key] = value;
}
}
module.exports = assignMergeValue;

View File

@@ -1,27 +0,0 @@
var eq = require('./eq');
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Assigns `value` to `key` of `object` if the existing value is not equivalent
* using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* for equality comparisons.
*
* @private
* @param {Object} object The object to modify.
* @param {string} key The key of the property to assign.
* @param {*} value The value to assign.
*/
function assignValue(object, key, value) {
var objValue = object[key];
if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
(value === undefined && !(key in object))) {
object[key] = value;
}
}
module.exports = assignValue;

View File

@@ -1,21 +0,0 @@
var eq = require('./eq');
/**
* Gets the index at which the `key` is found in `array` of key-value pairs.
*
* @private
* @param {Array} array The array to search.
* @param {*} key The key to search for.
* @returns {number} Returns the index of the matched value, else `-1`.
*/
function assocIndexOf(array, key) {
var length = array.length;
while (length--) {
if (eq(array[length][0], key)) {
return length;
}
}
return -1;
}
module.exports = assocIndexOf;

View File

@@ -1,21 +0,0 @@
var baseEach = require('./_baseEach');
/**
* Aggregates elements of `collection` on `accumulator` with keys transformed
* by `iteratee` and values set by `setter`.
*
* @private
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} setter The function to set `accumulator` values.
* @param {Function} iteratee The iteratee to transform keys.
* @param {Object} accumulator The initial aggregated object.
* @returns {Function} Returns `accumulator`.
*/
function baseAggregator(collection, setter, iteratee, accumulator) {
baseEach(collection, function(value, key, collection) {
setter(accumulator, value, iteratee(value), collection);
});
return accumulator;
}
module.exports = baseAggregator;

View File

@@ -1,17 +0,0 @@
var copyObject = require('./_copyObject'),
keys = require('./keys');
/**
* The base implementation of `_.assign` without support for multiple sources
* or `customizer` functions.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @returns {Object} Returns `object`.
*/
function baseAssign(object, source) {
return object && copyObject(source, keys(source), object);
}
module.exports = baseAssign;

View File

@@ -1,23 +0,0 @@
var get = require('./get');
/**
* The base implementation of `_.at` without support for individual paths.
*
* @private
* @param {Object} object The object to iterate over.
* @param {string[]} paths The property paths of elements to pick.
* @returns {Array} Returns the picked elements.
*/
function baseAt(object, paths) {
var index = -1,
isNil = object == null,
length = paths.length,
result = Array(length);
while (++index < length) {
result[index] = isNil ? undefined : get(object, paths[index]);
}
return result;
}
module.exports = baseAt;

View File

@@ -1,22 +0,0 @@
/**
* The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
*
* @private
* @param {number} number The number to clamp.
* @param {number} [lower] The lower bound.
* @param {number} upper The upper bound.
* @returns {number} Returns the clamped number.
*/
function baseClamp(number, lower, upper) {
if (number === number) {
if (upper !== undefined) {
number = number <= upper ? number : upper;
}
if (lower !== undefined) {
number = number >= lower ? number : lower;
}
}
return number;
}
module.exports = baseClamp;

View File

@@ -1,139 +0,0 @@
var Stack = require('./_Stack'),
arrayEach = require('./_arrayEach'),
assignValue = require('./_assignValue'),
baseAssign = require('./_baseAssign'),
cloneBuffer = require('./_cloneBuffer'),
copyArray = require('./_copyArray'),
copySymbols = require('./_copySymbols'),
getAllKeys = require('./_getAllKeys'),
getTag = require('./_getTag'),
initCloneArray = require('./_initCloneArray'),
initCloneByTag = require('./_initCloneByTag'),
initCloneObject = require('./_initCloneObject'),
isArray = require('./isArray'),
isBuffer = require('./isBuffer'),
isHostObject = require('./_isHostObject'),
isObject = require('./isObject'),
keys = require('./keys');
/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
arrayTag = '[object Array]',
boolTag = '[object Boolean]',
dateTag = '[object Date]',
errorTag = '[object Error]',
funcTag = '[object Function]',
genTag = '[object GeneratorFunction]',
mapTag = '[object Map]',
numberTag = '[object Number]',
objectTag = '[object Object]',
regexpTag = '[object RegExp]',
setTag = '[object Set]',
stringTag = '[object String]',
symbolTag = '[object Symbol]',
weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
dataViewTag = '[object DataView]',
float32Tag = '[object Float32Array]',
float64Tag = '[object Float64Array]',
int8Tag = '[object Int8Array]',
int16Tag = '[object Int16Array]',
int32Tag = '[object Int32Array]',
uint8Tag = '[object Uint8Array]',
uint8ClampedTag = '[object Uint8ClampedArray]',
uint16Tag = '[object Uint16Array]',
uint32Tag = '[object Uint32Array]';
/** Used to identify `toStringTag` values supported by `_.clone`. */
var cloneableTags = {};
cloneableTags[argsTag] = cloneableTags[arrayTag] =
cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
cloneableTags[boolTag] = cloneableTags[dateTag] =
cloneableTags[float32Tag] = cloneableTags[float64Tag] =
cloneableTags[int8Tag] = cloneableTags[int16Tag] =
cloneableTags[int32Tag] = cloneableTags[mapTag] =
cloneableTags[numberTag] = cloneableTags[objectTag] =
cloneableTags[regexpTag] = cloneableTags[setTag] =
cloneableTags[stringTag] = cloneableTags[symbolTag] =
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
cloneableTags[errorTag] = cloneableTags[funcTag] =
cloneableTags[weakMapTag] = false;
/**
* The base implementation of `_.clone` and `_.cloneDeep` which tracks
* traversed objects.
*
* @private
* @param {*} value The value to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @param {boolean} [isFull] Specify a clone including symbols.
* @param {Function} [customizer] The function to customize cloning.
* @param {string} [key] The key of `value`.
* @param {Object} [object] The parent object of `value`.
* @param {Object} [stack] Tracks traversed objects and their clone counterparts.
* @returns {*} Returns the cloned value.
*/
function baseClone(value, isDeep, isFull, customizer, key, object, stack) {
var result;
if (customizer) {
result = object ? customizer(value, key, object, stack) : customizer(value);
}
if (result !== undefined) {
return result;
}
if (!isObject(value)) {
return value;
}
var isArr = isArray(value);
if (isArr) {
result = initCloneArray(value);
if (!isDeep) {
return copyArray(value, result);
}
} else {
var tag = getTag(value),
isFunc = tag == funcTag || tag == genTag;
if (isBuffer(value)) {
return cloneBuffer(value, isDeep);
}
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
if (isHostObject(value)) {
return object ? value : {};
}
result = initCloneObject(isFunc ? {} : value);
if (!isDeep) {
return copySymbols(value, baseAssign(result, value));
}
} else {
if (!cloneableTags[tag]) {
return object ? value : {};
}
result = initCloneByTag(value, tag, baseClone, isDeep);
}
}
// Check for circular references and return its corresponding clone.
stack || (stack = new Stack);
var stacked = stack.get(value);
if (stacked) {
return stacked;
}
stack.set(value, result);
if (!isArr) {
var props = isFull ? getAllKeys(value) : keys(value);
}
// Recursively populate clone (susceptible to call stack limits).
arrayEach(props || value, function(subValue, key) {
if (props) {
key = subValue;
subValue = value[key];
}
assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));
});
return result;
}
module.exports = baseClone;

View File

@@ -1,33 +0,0 @@
var keys = require('./keys');
/**
* The base implementation of `_.conforms` which doesn't clone `source`.
*
* @private
* @param {Object} source The object of property predicates to conform to.
* @returns {Function} Returns the new spec function.
*/
function baseConforms(source) {
var props = keys(source),
length = props.length;
return function(object) {
if (object == null) {
return !length;
}
var index = length;
while (index--) {
var key = props[index],
predicate = source[key],
value = object[key];
if ((value === undefined &&
!(key in Object(object))) || !predicate(value)) {
return false;
}
}
return true;
};
}
module.exports = baseConforms;

View File

@@ -1,18 +0,0 @@
var isObject = require('./isObject');
/** Built-in value references. */
var objectCreate = Object.create;
/**
* The base implementation of `_.create` without support for assigning
* properties to the created object.
*
* @private
* @param {Object} prototype The object to inherit from.
* @returns {Object} Returns the new object.
*/
function baseCreate(proto) {
return isObject(proto) ? objectCreate(proto) : {};
}
module.exports = baseCreate;

View File

@@ -1,21 +0,0 @@
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
/**
* The base implementation of `_.delay` and `_.defer` which accepts an array
* of `func` arguments.
*
* @private
* @param {Function} func The function to delay.
* @param {number} wait The number of milliseconds to delay invocation.
* @param {Object} args The arguments to provide to `func`.
* @returns {number} Returns the timer id.
*/
function baseDelay(func, wait, args) {
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
return setTimeout(function() { func.apply(undefined, args); }, wait);
}
module.exports = baseDelay;

View File

@@ -1,67 +0,0 @@
var SetCache = require('./_SetCache'),
arrayIncludes = require('./_arrayIncludes'),
arrayIncludesWith = require('./_arrayIncludesWith'),
arrayMap = require('./_arrayMap'),
baseUnary = require('./_baseUnary'),
cacheHas = require('./_cacheHas');
/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;
/**
* The base implementation of methods like `_.difference` without support
* for excluding multiple arrays or iteratee shorthands.
*
* @private
* @param {Array} array The array to inspect.
* @param {Array} values The values to exclude.
* @param {Function} [iteratee] The iteratee invoked per element.
* @param {Function} [comparator] The comparator invoked per element.
* @returns {Array} Returns the new array of filtered values.
*/
function baseDifference(array, values, iteratee, comparator) {
var index = -1,
includes = arrayIncludes,
isCommon = true,
length = array.length,
result = [],
valuesLength = values.length;
if (!length) {
return result;
}
if (iteratee) {
values = arrayMap(values, baseUnary(iteratee));
}
if (comparator) {
includes = arrayIncludesWith;
isCommon = false;
}
else if (values.length >= LARGE_ARRAY_SIZE) {
includes = cacheHas;
isCommon = false;
values = new SetCache(values);
}
outer:
while (++index < length) {
var value = array[index],
computed = iteratee ? iteratee(value) : value;
value = (comparator || value !== 0) ? value : 0;
if (isCommon && computed === computed) {
var valuesIndex = valuesLength;
while (valuesIndex--) {
if (values[valuesIndex] === computed) {
continue outer;
}
}
result.push(value);
}
else if (!includes(values, computed, comparator)) {
result.push(value);
}
}
return result;
}
module.exports = baseDifference;

View File

@@ -1,14 +0,0 @@
var baseForOwn = require('./_baseForOwn'),
createBaseEach = require('./_createBaseEach');
/**
* The base implementation of `_.forEach` without support for iteratee shorthands.
*
* @private
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array|Object} Returns `collection`.
*/
var baseEach = createBaseEach(baseForOwn);
module.exports = baseEach;

View File

@@ -1,14 +0,0 @@
var baseForOwnRight = require('./_baseForOwnRight'),
createBaseEach = require('./_createBaseEach');
/**
* The base implementation of `_.forEachRight` without support for iteratee shorthands.
*
* @private
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array|Object} Returns `collection`.
*/
var baseEachRight = createBaseEach(baseForOwnRight, true);
module.exports = baseEachRight;

View File

@@ -1,21 +0,0 @@
var baseEach = require('./_baseEach');
/**
* The base implementation of `_.every` without support for iteratee shorthands.
*
* @private
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} predicate The function invoked per iteration.
* @returns {boolean} Returns `true` if all elements pass the predicate check,
* else `false`
*/
function baseEvery(collection, predicate) {
var result = true;
baseEach(collection, function(value, index, collection) {
result = !!predicate(value, index, collection);
return result;
});
return result;
}
module.exports = baseEvery;

View File

@@ -1,32 +0,0 @@
var isSymbol = require('./isSymbol');
/**
* The base implementation of methods like `_.max` and `_.min` which accepts a
* `comparator` to determine the extremum value.
*
* @private
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The iteratee invoked per iteration.
* @param {Function} comparator The comparator used to compare values.
* @returns {*} Returns the extremum value.
*/
function baseExtremum(array, iteratee, comparator) {
var index = -1,
length = array.length;
while (++index < length) {
var value = array[index],
current = iteratee(value);
if (current != null && (computed === undefined
? (current === current && !isSymbol(current))
: comparator(current, computed)
)) {
var computed = current,
result = value;
}
}
return result;
}
module.exports = baseExtremum;

View File

@@ -1,32 +0,0 @@
var toInteger = require('./toInteger'),
toLength = require('./toLength');
/**
* The base implementation of `_.fill` without an iteratee call guard.
*
* @private
* @param {Array} array The array to fill.
* @param {*} value The value to fill `array` with.
* @param {number} [start=0] The start position.
* @param {number} [end=array.length] The end position.
* @returns {Array} Returns `array`.
*/
function baseFill(array, value, start, end) {
var length = array.length;
start = toInteger(start);
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
end = (end === undefined || end > length) ? length : toInteger(end);
if (end < 0) {
end += length;
}
end = start > end ? 0 : toLength(end);
while (start < end) {
array[start++] = value;
}
return array;
}
module.exports = baseFill;

Some files were not shown because too many files have changed in this diff Show More