Commit project

This commit is contained in:
Rodrigo Pedroso 2019-06-19 10:46:14 -04:00
commit 3ac017a5ad
1030 changed files with 94062 additions and 0 deletions

34
README.md Normal file
View file

@ -0,0 +1,34 @@
# Node server
A server in Node JS to hold transactions for Gift and Loyalty cards.
# Installing
Install [Node JS](https://nodejs.org) by following the instructions on their webpage. NPM will also be necessary, but the installation of Node JS should have it bundled.
Install MongoDB.
Clone this repository.
Install packages
```sh
$ cd cluster-server
$ npm install
```
# Usage
The following command will start the server:
### On Windows
```sh
$ npm run devwin
```
### On Mac / Linux
```sh
$ npm run dev
```

53
etc/error-codes.json Normal file
View file

@ -0,0 +1,53 @@
{
e1: r2,
e2: r3,
e3: r6,
e4: r7,
e5: r9,
e6: r10,
e7: r11,
e8: r12,
e9: r13,
e10: r14,
e11: r15,
e12: r16,
e13: r18,
e14: r20,
e15: r21,
e16: r23,
e17: r24,
e18: r26,
e19: r27,
e20: r30,
e21: r32,
e22: r35,
e23: ,
e24: r37,
e25: r41,
e26: r46,
e27: r48,
e28: r54,
e29: r55,
e30: r56,
e31: r58,
e32: r80,
e33: r85,
e34: r86,
e35: r87,
e36: r90,
e37: r92,
e38: r84,
e39: r61,
e40: r62,
e41: r63,
e42: r64,
e43: ,
e44: r67,
e45: r68,
e46: r69,
e47: r72,
e48: r73,
e49: r74,
e50: r77,
e51: r81
}

3
etc/index.json Normal file
View file

@ -0,0 +1,3 @@
{
"dbUri": "mongodb://localhost:27017"
}

2
etc/mongod.conf Normal file
View file

@ -0,0 +1,2 @@
storage:
dbPath: c:/Users/Proprietaire/data

378
etc/responses.json Normal file
View file

@ -0,0 +1,378 @@
{
"r0": {
"en": "Server error.",
"fr": "Erreur de serveur."
},
"r1": {
"en": "Welcome.",
"fr": "Bienvenue."
},
"r2": {
"en": "Missing name.",
"fr": "Nom manquant."
},
"r3": {
"en": "A branch with this name already exists. Please use another name or delete branch.",
"fr": "Une branche portant ce nom existe déjà. Veuillez utiliser un autre nom ou supprimer une branche."
},
"r4": {
"en": "Branch created.",
"fr": "Branche créée."
},
"r5": {
"en": "Workstation created.",
"fr": "Station de travail créée."
},
"r6": {
"en": "Missing employee_name.",
"fr": "Nom de l'employé manquant (champ «employee_name»)."
},
"r7": {
"en": "Name already exists in this Merchant. Please use a different one.",
"fr": "Le nom existe déjà dans ce marchand. Veuillez en utiliser un autre."
},
"r8": {
"en": "Employee created.",
"fr": "Employé créé."
},
"r9": {
"en": "Please provide client_name.",
"fr": "Veuillez fournir le nom du client (champ «client_name»)."
},
"r10": {
"en": "Please provide client_email.",
"fr": "Veuillez fournir l'email du client (champ «client_email»)."
},
"r11": {
"en": "Please provide branch_id.",
"fr": "Veuillez fournir l'identification de la branch (champ «branch_id»)."
},
"r12": {
"en": "There already is a client with this name registered with this Merchant. Please choose another name.",
"fr": "Il y a déjà un client avec ce nom enregistré dans ce marchand. Veuillez choisir un autre nom."
},
"r13": {
"en": "Missing client_id.",
"fr": "Identification du client manquant (champ «client_id»)."
},
"r14": {
"en": "Missing branch_id.",
"fr": "Identification de la branche manquant (champ «branch_id»)."
},
"r15": {
"en": "Please provide the parameters to be updated in a json dictionary labeled data.",
"fr": "Veuillez fournir les paramètres à actualiser dans un dictionnaire json nommé «data»."
},
"r16": {
"en": "Merchant not found.",
"fr": "Marchand non trouvé."
},
"r17": {
"en": "Merchant updated.",
"fr": "Marchand actualisé."
},
"r18": {
"en": "Branch not found.",
"fr": "Branche non trouvée."
},
"r19": {
"en": "Branch updated.",
"fr": "Branche actualisée."
},
"r20": {
"en": "Please provide the workstation_id.",
"fr": "Veuillez fournir l'identification de station de travail (champ «workstation_id»)."
},
"r21": {
"en": "Workstation not found.",
"fr": "Station de travail non trouvée."
},
"r22": {
"en": "Workstation updated.",
"fr": "Station de travail actualisée."
},
"r23": {
"en": "Please provide client_id.",
"fr": "Veuillez fournir l'identification du client (champ «client_id»)."
},
"r24": {
"en": "Client not found.",
"fr": "Client non trouvé."
},
"r25": {
"en": "Client updated.",
"fr": "Client actualisé."
},
"r26": {
"en": "Please provide the employee_id.",
"fr": "Veuillez fournir l'identification du employé (champ «employee_id»)."
},
"r27": {
"en": "Employee not found.",
"fr": "Employé non trouvé."
},
"r28": {
"en": "Employee updated.",
"fr": "Employé actualisé."
},
"r29": {
"en": "Merchant deleted.",
"fr": "Marchand supprimé."
},
"r30": {
"en": "Please provide the branch_id.",
"fr": "Veuillez fournir l'identification de la branch (champ «branch_id»)."
},
"r31": {
"en": "Branch deleted.",
"fr": "Branche supprimée."
},
"r32": {
"en": "Please provide the workstation_id.",
"fr": "Veuillez fournir l'identification de la station de travail (champ «workstation_id»)."
},
"r33": {
"en": "Workstation deleted.",
"fr": "Station de travail supprimée."
},
"r34": {
"en": "Client deleted.",
"fr": "Client supprimé."
},
"r35": {
"en": "Please provide the employee_id.",
"fr": "Veuillez fournir l'identification de l'employé (champ «employee_id»)."
},
"r36": {
"en": "Employee deleted.",
"fr": "Employé supprimé."
},
"r37": {
"en": "Please provide gift_card_id or gift_card_number.",
"fr": "Veuillez fournir l'identification ou le numéro de la carte cadeau (champ «gift_card_id» ou «gift_card_number»)."
},
"r38": {
"en": "Gift card deleted.",
"fr": "Carte cadeau supprimée."
},
"r39": {
"en": "No merchants found.",
"fr": "Aucun marchand trouvé."
},
"r40": {
"en": "Merchants.",
"fr": "Marchands."
},
"r41": {
"en": "Please provide the merchant_id.",
"fr": "Veuillez fournir l'identification du marchand (champ «merchant_id»)."
},
"r42": {
"en": "No branches found.",
"fr": "Aucune branche trouvée."
},
"r43": {
"en": "Branches.",
"fr": "Branches."
},
"r44": {
"en": "No workstations found.",
"fr": "Aucune station de travail trouvée."
},
"r45": {
"en": "Workstations.",
"fr": "Stations de travail."
},
"r46": {
"en": "No clients found.",
"fr": "Aucun client trouvé."
},
"r47": {
"en": "Clients.",
"fr": "Clients."
},
"r48": {
"en": "Please provide parameters to execute a query, as client_email.",
"fr": "Veuillez fournir des paramètres pour la query, comme l'email du client (champ «client_email»)"
},
"r49": {
"en": "Client details.",
"fr": "Détails du client."
},
"r50": {
"en": "No employees found.",
"fr": "Aucun employé trouvé."
},
"r51": {
"en": "Employees.",
"fr": "Emoployés."
},
"r52": {
"en": "No gift cards found.",
"fr": "Aucune carte cadeau trouvée."
},
"r53": {
"en": "Gift cards.",
"fr": "Cartes cadeaux."
},
"r54": {
"en": "Gift card not found.",
"fr": "Carte cadeau non trouvée."
},
"r55": {
"en": "Merchant not found.",
"fr": "Marchand non trouvé."
},
"r56": {
"en": "Client not found.",
"fr": "Client non trouvé."
},
"r57": {
"en": "Gift card info.",
"fr": "Information sur la carte cadeau."
},
"r58": {
"en": "Please provide a criteria (i.e. merchant_id or gift_card_number).",
"fr": "Veuillez fournir un critère (c'est à dire «merchant_id» ou «gift_card_number»)."
},
"r59": {
"en": "No transactions found.",
"fr": "Aucune transaction trouvée."
},
"r60": {
"en": "Transactions.",
"fr": "Transactions."
},
"r61": {
"en": "Parameters missing.",
"fr": "Paramètres manquants."
},
"r62": {
"en": "Please provide 'money_amount'.",
"fr": "Veulliez fournir la quantité d'argent (champ «money_amount»)."
},
"r63": {
"en": "Please provide either serial_number or workstation_id.",
"fr": "Veulliez fournir le numéro serial ou l'identification de station de travail (champ «serial_number» ou «workstation_id»)."
},
"r64": {
"en": "Please provide employee_id.",
"fr": "Veulliez fournir l'identification de l'employé (champ «employee_id»)."
},
"r65": {
"en": "Gift card reloaded.",
"fr": "Carte cadeau rechargé."
},
"r66": {
"en": "Gift card redeemed.",
"fr": "Carte cadeau racheté."
},
"r67": {
"en": "Transaction not completed. Insufficient funds.",
"fr": "Transaction non complété. Fonds insuffisants."
},
"r68": {
"en": "Please provide transaction_id.",
"fr": "Veulliez fournir l'identification de la transaction (champ «transaction_id»)."
},
"r69": {
"en": "Transaction not found.",
"fr": "Transaction non trouvée."
},
"r70": {
"en": "Gift card activation cancelled.",
"fr": "Activation de carte cadeau cancellée."
},
"r71": {
"en": "Transaction cancelled.",
"fr": "Transaction cancellée."
},
"r72": {
"en": "Remittance not possible. Remaining balance in card is bigger than CAN $ 5.00.",
"fr": "Remittance pas possible. Le solde de la carte est supérieur à CAN $ 5.00."
},
"r73": {
"en": "Remittance not possible. Remaining balance in card is CAN $ 0.00.",
"fr": "Remittance pas possible. Le solde de la carte est CAN $ 0.00."
},
"r74": {
"en": "The remittance transaction is valid only in Quebec. This branch is located in ",
"fr": "La transaction de remittance est valide seul au Québec. La province de cette branche est: "
},
"r75": {
"en": "Remittance executed.",
"fr": "Remittance exécutée."
},
"r76": {
"en": "Transaction recorded. ",
"fr": "Transaction enregistrée. "
},
"r77": {
"en": "Transaction not recorded.",
"fr": "Transaction non enregistrée."
},
"r78": {
"en": "Client and gift card created.",
"fr": "Client et carte cadeau créées."
},
"r79": {
"en": "Gift card created.",
"fr": "Carte cadeau créée."
},
"r80": {
"en": "The assigned card number is not unique.",
"fr": "Le numéro de carte cadeau n'est pas unique."
},
"r81": {
"en": "Please include the authorization headers in the request.",
"fr": "Veuillez inclure les en-têtes d'autorisation dans la demande."
},
"r82": {
"en": " not found in the database.",
"fr": " non trouvé dans la base de données."
},
"r83": {
"en": "Wrong password.",
"fr": "Mauvais mot de passe."
},
"r84": {
"en": "Missing merchant_id.",
"fr": "Identification de marchand manquant (champ «merchant_id»)."
},
"r85": {
"en": "Please provide a correct email address.",
"fr": "Veuillez fournir une adresse e-mail correcte."
},
"r86": {
"en": "Password must have at least 3 characters.",
"fr": "Le mot de pass doit comporter au moins 3 caractères."
},
"r87": {
"en": "Please provide your name.",
"fr": "Veuillez fournir votre nom."
},
"r88": {
"en": "Check the form for errors.",
"fr": "Veuillez vérifier le formulaire."
},
"r89": {
"en": "Check the request for errors.",
"fr": "Veuillez vérifier la demande."
},
"r90": {
"en": "Conflict error.",
"fr": "Erreur de conflit."
},
"r91": {
"en": "Could not process the form. Error: ",
"fr": "Impossible de traiter le formulaire. Erreur: "
},
"r92": {
"en": "Could not process the form.",
"fr": "Impossible de traiter le formulaire."
},
"r93": {
"en": " registered. Welcome.",
"fr": " enregistré. Bienvenu."
}
}

1290
middleware/api.js Normal file

File diff suppressed because it is too large Load diff

65
middleware/auth-check.js Normal file
View file

@ -0,0 +1,65 @@
'use strict';
const Merchant = require('mongoose').model('Merchant');
const config = require('../etc');
const atob = require('abab').atob;
const Response = require('../etc/responses.json');
module.exports = (req, res, next) => {
var lang;
if (req.query.language) {
lang = req.query.language;
}
else if (req.body.language) {
lang = req.body.language;
}
else {
req.body.language = 'en';
}
if (!req.headers.authorization) {
return res.status(401).json({
success: false,
message: Response.r81[lang],
error_code: 'e51'
})
}
const decoded = atob(req.headers.authorization.split(/ /)[1]);
const userId = decoded.split(/:/)[0];
const pwd = decoded.split(/:/)[1];
return Merchant.findById(userId, (userErr, user) => {
// Check user id
if (userErr || !user) {
return res.status(401).json({
success: false,
message: 'UserId ' + userId + Response.r82[lang]
});
}
// Check password
return user.comparePassword(pwd, (pwdErr, isMatch) => {
if (pwdErr) {
return done(pwdErr);
}
if (!isMatch) {
return res.status(401).json({
success: false,
message: Response.r83[lang]
})
}
if (!req.body.merchant_id) {
req.body.merchant_id = userId;
}
else {
console.log('Merchant déjà');
}
return next();
})
});
};

121
middleware/auth.js Normal file
View file

@ -0,0 +1,121 @@
'use strict';
const express = require('express');
const passport = require('passport');
const validator = require('validator');
const config = require('../etc');
const router = new express.Router();
const Merchant = require('mongoose').model('Merchant');
const Response = require('../etc/responses.json');
function validateSignupForm(payload, lang) {
var errors = {};
let isFormValid = true;
let message = '';
if (!payload || typeof payload.merchant_email !== 'string' || !validator.isEmail(payload.merchant_email)) {
isFormValid = false;
message = Response.r85[lang];
errors = 'e33';
}
if (!payload || typeof payload.password !== 'string' || payload.password.trim().length < 3) {
isFormValid = false;
message = Response.r86[lang];
errors = 'e34';
}
if (!payload || typeof payload.merchant_name !== 'string' || payload.merchant_name.trim().length === 0) {
isFormValid = false;
message = Response.r87[lang];
errors = 'e35';
}
return {
success: isFormValid,
message,
errors
};
}
router.post('/signup', (req, res, next) => {
var lang;
if (req.query.language) {
lang = req.query.language;
res.locals.lang = lang;
}
else if (req.body.language) {
lang = req.body.language;
res.locals.lang = lang;
}
else {
req.body.language = 'en';
res.locals.lang = lang;
}
const validationResult = validateSignupForm(req.body, lang);
if (!validationResult.success) {
return res.status(400).json({
success: false,
message: validationResult.message,
error_code: validationResult.errors
});
}
// Get the next higher merchant number
Merchant.findOne({}).sort({number: -1}).limit(1).exec((err, doc) => {
if (err) return res.status(500).json({
success: false,
message: Response.r0[lang],
error_code: 'e0'
});
if (!doc) {
// There are no merchants on the database. Create the very first one.
req.body.number = 1;
next();
}
else {
req.body.number = doc.number + 1;
next();
}
});
}, (req, res, next) => {
let lang = res.locals.lang;
return passport.authenticate('local-signup', (err, doc) => {
if (err) {
if (err.name === 'MongoError' && err.code === 11000) {
// the 11000 Mongo code is for a duplication email error
// the 409 HTTP status code is for conflict error
return res.status(409).json({
success: false,
message: Response.r90[lang],
error_code: 'e36'
});
}
return res.status(400).json({
success: false,
message: Response.r90[lang],
error_code: 'e36'
});
}
if (!doc) {
return res.status(400).json({
success: false,
message: Response.r92[lang],
error_code: 'e37'
});
}
return res.status(200).json({
success: true,
message: 'Merchant ' + req.body.merchant_name + Response.r93[lang],
merchant_id: doc._id
});
})(req, res, next);
});
module.exports = router;

View file

@ -0,0 +1,193 @@
'use strict';
const Merchant = require('mongoose').model('Merchant');
const Branch = require('mongoose').model('Branch');
const GiftCard = require('mongoose').model('GiftCard');
const Response = require('../etc/responses.json');
/*
* Gather date, merchant_id, branch_id and gift card sequence
* to generate a gift_card_number
*/
module.exports = (req, res, next) => {
getMerchantNumber(req, res);
}
// MARK: get merchant number
function getMerchantNumber(req, res) {
// Merchant number
Merchant.findOne({ _id: req.body.merchant_id }, (err, doc) => {
if (err || !doc) return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
else {
// Make sure the merchant number always has 3 digits
var numberString = doc.number.toString();
if (numberString.length === 1) {
numberString = "00" + numberString;
}
else if (numberString.length === 2) {
numberString = "0" + numberString;
}
req.body.merchant_number = numberString;
req.body.merchant_name = doc.merchant_name;
getBranchNumber(req, res);
}
});
}
// MARK: get branch number
function getBranchNumber(req, res) {
// Branch number
Branch.findOne({ _id: req.body.branch_id }, (err, doc) => {
if (err) return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
if (!doc) {
// This Merchant has only the main office, no branches.
req.body.branch_number = req.body.merchant_id;
req.body.branch_number = "00";
req.body.branch_name = req.body.merchant_name;
}
else {
// Make sure the branch number always has 2 digits
var numberString = doc.number.toString();
if (numberString.length === 1) {
numberString = "0" + numberString;
}
req.body.branch_number = numberString;
req.body.branch_name = doc.branch_name;
}
generateCardNumber(req, res);
});
}
// MARK: generate card number
function generateCardNumber(req, res) {
// Get date
var d = new Date();
var year = d.getFullYear().toString().substr(-2);
var month = (d.getMonth() + 1).toString();
if (month.length === 1) {
month = "0" + month;
}
var day = d.getDate().toString();
if (day.length === 1) {
day = "0" + day;
}
// Get next available card number
GiftCard.findOne({ merchant_id: req.body.merchant_id, branch_id: req.body.branch_id }).sort({ number: -1 }).limit(1).exec((err, doc) => {
var numberString;
if (err) return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
if (!doc) {
req.body.number = 1;
numberString = '1';
}
else {
req.body.number = doc.number + 1;
numberString = req.body.number.toString();
}
// Make sure the card number always has 4 digits
if (numberString.length === 1) {
numberString = "000" + numberString;
}
else if (numberString.length === 2) {
numberString = "00" + numberString;
}
else if (numberString.length === 3) {
numberString = "0" + numberString;
}
// Trim numbers with more than 4 digits. The date components will guarantee the cardNumber uniqueness.
else if (numberString.length >= 4) {
numberString = numberString.slice(-4);
}
// Finally compose complete card number
const cardNumber =
year +
month +
day +
req.body.merchant_number +
req.body.branch_number +
numberString
req.body.gift_card_number = cardNumber;
addGiftCard(req, res);
});
}
// MARK: add gift card
function addGiftCard(req, res) {
req.body.balance = 0;
req.body.points = 0;
var msg;
if (res.locals.fromAddClient) {
msg = Response.r78[req.body.language];
}
else {
msg = Response.r79[req.body.language];
}
var newGiftCard = new GiftCard(req.body);
newGiftCard.save((err, doc) => {
if (err) {
// Gift card number not unique due to simultaneous creation
console.log('Gift card number not unique due to simultaneous creation. New number assigned automatically.');
const number = Number(req.body.gift_card_number) + 1;
req.body.gift_card_number = number.toString();
newGiftCard = new GiftCard(req.body);
newGiftCard.save((err2, doc2) => {
if (err2) {
return res.status(400).json({
success: false,
message: Response.r80[req.body.language],
error: 'e32'
});
}
else {
return res.status(200).json({
success: true,
message: msg,
client_name: req.body.client_name,
client_id: req.body.client_id,
gift_card_number: doc2.gift_card_number,
merchant_name: req.body.merchant_name,
branch_name: req.body.branch_name,
balance: doc2.balance,
points: doc2.points
});
}
})
}
else {
return res.status(200).json({
success: true,
message: msg,
client_name: req.body.client_name,
client_id: req.body.client_id,
gift_card_number: doc.gift_card_number,
merchant_name: req.body.merchant_name,
branch_name: req.body.branch_name,
balance: doc.balance,
points: doc.points
});
}
});
}

33
middleware/lang.js Normal file
View file

@ -0,0 +1,33 @@
'use strict';
const Merchant = require('mongoose').model('Merchant');
module.exports = (req, res, next) => {
if (req.body.language) {
return next();
}
else if (req.query.language) {
req.body.language = req.query.language;
return next();
}
else {
Merchant.findOne({_id: req.body.merchant_id}, (err, doc) => {
if (err) return res.status(500).json({
success: false,
message: 'Server error / Erreur de serveur',
error_code: 'e0'
});
else if (!doc) {
return res.status(400).json({
success: false,
message: "Merchant not found / Merchant pas encontré",
error_code: 'e12'
});
}
else {
req.body.language = doc.language;
return next();
}
});
}
}

View file

@ -0,0 +1,32 @@
'use strict';
const express = require('express');
const router = new express.Router();
const Response = require('../etc/responses.json');
router.use((req, res, next) => {
var lang;
if (req.query.language) {
lang = req.query.language;
}
else if (req.body.language) {
lang = req.body.language;
}
else {
lang = 'en';
}
const error = {};
if (!req.body.merchant_id) {
return res.status(400).json({
success: false,
message: Response.r84[lang],
error_code: 'e38'
});
}
next();
});
module.exports = router;

740
middleware/trans.js Normal file
View file

@ -0,0 +1,740 @@
'use strict';
const express = require('express');
const router = new express.Router();
const Merchant = require('mongoose').model('Merchant');
const Branch = require('mongoose').model('Branch');
const Workstation = require('mongoose').model('Workstation');
const Employee = require('mongoose').model('Employee');
const Client = require('mongoose').model('Client');
const GiftCard = require('mongoose').model('GiftCard');
const Transaction = require('mongoose').model('Transaction');
const Response = require('../etc/responses.json');
// MARK: - Transactions
// MARK: validation
function validateTransaction(payload) {
var errors = 'e39';
let isFormValid = true;
var message = Response.r61[req.body.language];
if (!payload.money_amount) {
isFormValid = false;
message = Response.r62[req.body.language];
errors = 'e40';
}
if (!payload.workstation_id && !payload.serial_number) {
isFormValid = false;
message = Response.r63[req.body.language];
errors = 'e41';
}
if (!payload.employee_id) {
isFormValid = false;
message = Response.r64[req.body.language];
errors = 'e42';
}
return {
success: isFormValid,
message,
errors
};
}
// MARK: reload GiftCard
router.put('/reloadGiftCard', (req, res, next) => {
const validationResult = validateTransaction(req.body);
if (!validationResult.success) {
return res.status(400).json({
success: false,
message: validationResult.message,
error_code: validationResult.errors
});
}
// Retrieve serial_number to make sure it gets registered in the transaction
if (!req.body.serial_number) {
Workstation.findOne({_id: req.body.workstation_id}, (err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r21[req.body.language],
error_code: 'e15'
});
}
else {
req.body.serial_number = doc.serial_number;
next();
}
});
}
}, (req, res, next) => {
// Retrieve employee number to guarantee it will be registered in the transaction
Employee.findOne({_id: req.body.employee_id}, (err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r27[req.body.language],
error_code: 'e19'
});
}
else {
req.body.employee_number = doc.employee_number;
next();
}
});
}, (req, res, next) => {
if (req.body.gift_card_id) {
GiftCard.findOneAndUpdate(
{_id: req.body.gift_card_id},
{$inc: {balance: req.body.money_amount}},
{new: true},
(err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r54[req.body.language],
error_code: 'e28'
});
}
else {
req.body.success = true;
req.body.balance = doc.balance;
req.body.branch_id = doc.branch_id;
req.body.client_id = doc.client_id;
req.body.gift_card_id = doc._id;
req.body.gift_card_number = doc.gift_card_number;
req.body.message = Response.r65[req.body.language];
next();
}
});
}
else if (req.body.gift_card_number) {
GiftCard.findOneAndUpdate(
{gift_card_number: req.body.gift_card_number},
{$inc: {balance: req.body.money_amount}},
{new: true},
(err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r54[req.body.language],
error_code: 'e28'
});
}
else {
req.body.success = true;
req.body.balance = doc.balance;
req.body.branch_id = doc.branch_id;
req.body.client_id = doc.client_id;
req.body.gift_card_id = doc._id;
req.body.gift_card_number = doc.gift_card_number;
req.body.message = Response.r65[req.body.language];
next();
}
});
}
else {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
});
// MARK: redeem GiftCard
router.put('/redeemGiftCard', (req, res, next) => {
const validationResult = validateTransaction(req.body);
if (!validationResult.success) {
return res.status(400).json({
success: false,
message: validationResult.message,
errors: validationResult.errors
});
}
// Retrieve serial_number to make sure it gets registered in the transaction
if (!req.body.serial_number) {
Workstation.findOne({_id: req.body.workstation_id}, (err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r21[req.body.language],
error_code: 'e15'
});
}
else {
req.body.serial_number = doc.serial_number;
next();
}
});
}
}, (req, res, next) => {
// Retrieve employee number to guarantee it will be registered in the transaction
Employee.findOne({_id: req.body.employee_id}, (err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r27[req.body.language],
error_code: 'e19'
});
}
else {
req.body.employee_number = doc.employee_number;
next();
}
});
}, (req, res, next) => {
if (req.body.gift_card_id) {
GiftCard.findOne({_id: req.body.gift_card_id}, (err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r54[req.body.language],
error_code: 'e28'
});
}
else {
if (req.body.money_amount <= doc.balance) {
GiftCard.findOneAndUpdate(
{_id: req.body.gift_card_id},
{$inc: {balance: -req.body.money_amount}},
{new: true},
(err, doc2) => {
if (err) return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
else {
req.body.success = true;
req.body.balance = doc2.balance;
req.body.branch_id = doc2.branch_id;
req.body.client_id = doc2.client_id;
req.body.gift_card_id = doc2._id;
req.body.gift_card_number = doc2.gift_card_number;
req.body.message = Response.r66[req.body.language];
next();
}
});
}
else {
return res.status(200).json({
success: false,
message: Response.r67[req.body.language],
error_code: 'e44',
giftCardBalance: doc.balance
});
}
}
});
}
else if (req.body.gift_card_number) {
GiftCard.findOne({gift_card_number: req.body.gift_card_number}, (err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r54[req.body.language],
error_code: 'e28'
});
}
else {
if (req.body.money_amount <= doc.balance) {
GiftCard.findOneAndUpdate(
{gift_card_number: req.body.gift_card_number},
{$inc: {balance: -req.body.money_amount}},
{new: true},
(err, doc2) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else {
req.body.success = true;
req.body.balance = doc2.balance;
req.body.branch_id = doc2.branch_id;
req.body.client_id = doc2.client_id;
req.body.gift_card_id = doc2._id;
req.body.gift_card_number = doc2.gift_card_number;
req.body.message = Response.r66[req.body.language];
next();
}
});
}
else if (req.body.enforce) {
GiftCard.findOneAndUpdate(
{gift_card_number: req.body.gift_card_number},
{$set: {balance: 0}},
{new: true},
(err, doc2) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else {
req.body.success = true;
req.body.balance = doc2.balance;
req.body.gift_card_id = doc2._id;
req.body.branch_id = doc2.branch_id;
req.body.client_id = doc2.client_id;
req.body.gift_card_number = doc2.gift_card_number;
req.body.remainder = req.body.money_amount - doc.balance;
req.body.message = Response.r66[req.body.language];
next();
}
});
}
else {
return res.status(200).json({
success: false,
message: Response.r67[req.body.language],
error_code: 'e44',
giftCardBalance: doc.balance
});
}
}
});
}
});
// MARK: cancel transaction
router.post('/cancelTransaction', (req, res, next) => {
if (!req.body.transaction_id) {
return res.status(400).json({
success: false,
message: Response.r68[req.body.language],
error_code: 'e45'
});
}
if (!req.body.employee_id) {
return res.status(400).json({
success: false,
message: Response.r64[req.body.language],
error_code: 'e42'
});
}
// Retrieve employee number to guarantee it will be registered in the transaction
Employee.findOne({_id: req.body.employee_id}, (err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r27[req.body.language],
error_code: 'e19'
});
}
else {
req.body.employee_number = doc.employee_number;
next();
}
});
}, (req, res, next) => {
Transaction.findOneAndUpdate(
{_id: req.body.transaction_id},
{$set: {cancelled: true}},
{new: true},
(err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r69[req.body.language],
error_code: 'e46'
});
}
else {
if (doc.type === 'Redeem') {
res.locals.gift_card_id = doc.gift_card_id;
res.locals.amount = doc.money_amount;
res.locals.transaction_id = req.body.transaction_id;
res.locals.doc = doc;
next();
}
else if (doc.type === 'Reload') {
res.locals.gift_card_id = doc.gift_card_id;
res.locals.amount = -doc.money_amount;
res.locals.transaction_id = req.body.transaction_id;
res.locals.doc = doc;
next();
}
else if (doc.type === 'Activation'){
res.locals.gift_card_id = doc.gift_card_id;
res.locals.transaction_id = req.body.transaction_id;
res.locals.doc = doc;
next();
}
else if (doc.type === 'Remittance') {
res.locals.gift_card_id = doc.gift_card_id;
res.locals.amount = doc.remainder;
res.locals.transaction_id = req.body.transaction_id;
res.locals.doc = doc;
next();
}
}
});
}, (req, res, next) => {
if (res.locals.doc.type == 'Activation') {
GiftCard.findOneAndRemove({ _id: res.locals.gift_card_id }, (err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r54[req.body.language],
error_code: 'e28'
});
}
else {
req.body.success = true;
req.body.balance = doc.balance;
req.body.branch_id = doc.branch_id;
req.body.client_id = doc.client_id;
req.body.gift_card_id = doc._id;
req.body.gift_card_number = doc.gift_card_number;
req.body.type = 'Cancel';
req.body.cancelled_transaction_id = res.locals.transaction_id;
req.body.message = Response.r70[req.body.language];
next();
}
});
}
else {
GiftCard.findOneAndUpdate(
{_id: res.locals.gift_card_id},
{$inc: {balance: res.locals.amount}},
{new: true},
(err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r54[req.body.language],
error_code: 'e28'
});
}
else {
req.body.success = true;
req.body.balance = doc.balance;
req.body.branch_id = doc.branch_id;
req.body.client_id = doc.client_id;
req.body.gift_card_id = doc._id;
req.body.gift_card_number = doc.gift_card_number;
req.body.type = 'Cancel';
req.body.cancelled_transaction_id = res.locals.transaction_id;
req.body.message = Response.r71[req.body.language];
next();
}
}
);
}
});
// MARK: empty gift card (remittance)
router.post('/emptyGiftCard', (req, res, next) => {
if (!req.body.gift_card_id && !req.body.gift_card_number) {
return res.status(400).json({
success: false,
error_code: 'e24',
message: Response.r37[req.body.language]
});
}
if (!req.body.branch_id) {
return res.status(400).json({
success: false,
error_code: 'e7',
message: Response.r11[req.body.language]
});
}
if (!req.body.employee_id) {
return res.status(400).json({
success: false,
message: Response.r64[req.body.language],
error_code: 'e42'
});
}
// Retrieve employee number to guarantee it will be registered in the transaction
Employee.findOne({_id: req.body.employee_id}, (err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r27[req.body.language],
error_code: 'e19'
});
}
else {
req.body.employee_number = doc.employee_number;
next();
}
});
}, (req, res, next) => {
if (req.body.gift_card_id) {
GiftCard.findOne({ _id: req.body.gift_card_id }, (err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r54[req.body.language],
error_code: 'e28'
});
}
else {
res.locals.balance = doc.balance;
req.body.gift_card_number = doc.gift_card_number;
next();
}
});
}
else if (req.body.gift_card_number) {
GiftCard.findOne({ gift_card_number: req.body.gift_card_number }, (err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else if (!doc) {
return res.status(400).json({
success: false,
message: Response.r54[req.body.language],
error_code: 'e28'
});
}
else {
res.locals.balance = doc.balance;
req.body.gift_card_id = doc._id;
next();
}
});
}
}, (req, res, next) => {
if (res.locals.balance > 5) {
return res.status(400).json({
sucess: false,
error_code: 'e47',
message: Response.r72[req.body.language]
});
}
else if (res.locals.balance == 0) {
return res.status(400).json({
sucess: false,
error_code: 'e48',
message: Response.r73[req.body.language]
});
}
next();
}, (req, res, next) => {
Branch.findOne({ _id: req.body.branch_id }, (err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
if (!doc) {
return res.status(400).json({
success: false,
message: Response.r18[req.body.language],
error_code: 'e13'
});
}
else {
if (doc.province !== 'QC') {
return res.status(400).json({
success: false,
message: Response.r74[req.body.language] + doc.province + '.',
error_code: 'e49'
});
}
else {
GiftCard.findOneAndUpdate(
{gift_card_number: req.body.gift_card_number},
{$set: {balance: 0}},
{new: true},
(err, doc2) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
else {
req.body.success = true;
req.body.balance = doc2.balance;
req.body.gift_card_id = doc2._id;
req.body.branch_id = req.body.branch_id;
req.body.client_id = doc2.client_id;
req.body.gift_card_number = doc2.gift_card_number;
req.body.remainder = res.locals.balance;
req.body.type = 'Remittance';
req.body.message = Response.r75[req.body.language];
next();
}
});
}
}
});
});
// MARK: - Record transaction
router.use((req, res) => {
if (req.body.success) {
const newTransaction = new Transaction(req.body);
newTransaction.save((err, doc) => {
if (err) {
return res.status(500).json({
success: false,
message: Response.r0[req.body.language],
error_code: 'e0'
});
}
return res.status(200).json({
success: true,
message: Response.r76[req.body.language] + req.body.message,
transaction_id: doc._id,
type: req.body.type,
balance: req.body.balance,
remainder: req.body.remainder
})
});
}
else {
return res.status(400).json({
success: false,
message: Response.r77[req.body.language],
error_code: 'e50'
});
}
});
module.exports = router;

21
models/branch.js Normal file
View file

@ -0,0 +1,21 @@
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var BranchSchema = new Schema({
branch_name: String,
number: Number,
street: String,
street_2: String,
city: String,
province: String,
postal_code: String,
country: String,
telephone: String,
cellular: String,
telephone_other: String,
merchant_id: { type: Schema.Types.ObjectId, ref: 'Merchant' }
}, {timestamps: true});
module.exports = mongoose.model('Branch', BranchSchema);

24
models/client.js Normal file
View file

@ -0,0 +1,24 @@
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ClientSchema = new Schema({
client_name: String,
number: Number,
street: String,
street_2: String,
city: String,
province: String,
postal_code: String,
country: String,
client_email: String,
telephone: String,
cellular: String,
telephone_other: String,
birthday: String,
merchant_id: { type: Schema.Types.ObjectId, ref: 'Merchant' },
branch_id: { type: Schema.Types.ObjectId, ref: 'Branch' }
}, {timestamps: true});
module.exports = mongoose.model('Client', ClientSchema);

13
models/employee.js Normal file
View file

@ -0,0 +1,13 @@
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var EmployeeSchema = new Schema({
merchant_id: { type: Schema.Types.ObjectId, ref: 'Merchant' },
branch_id: { type: Schema.Types.ObjectId, ref: 'Branch' },
employee_number: Number,
employee_name: String
}, {timestamps: true});
module.exports = mongoose.model('Employee', EmployeeSchema);

16
models/gift-card.js Normal file
View file

@ -0,0 +1,16 @@
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var GiftCardSchema = new Schema({
gift_card_number: String,
merchant_id: { type: Schema.Types.ObjectId, ref: 'Merchant' },
client_id: { type: Schema.Types.ObjectId, ref: 'Client' },
branch_id: { type: Schema.Types.ObjectId, ref: 'Branch' },
number: Number,
balance: Number,
points: Number
}, {timestamps: true});
module.exports = mongoose.model('GiftCard', GiftCardSchema);

18
models/index.js Normal file
View file

@ -0,0 +1,18 @@
const mongoose = require('mongoose');
module.exports.connect = (uri) => {
mongoose.connect(uri, {
useMongoClient: true,
});
// plug in the promise library:
mongoose.Promise = require('bluebird');
mongoose.connection.on('error', (err) => {
console.error(`Mongoose connection error: ${err}`);
process.exit(1);
});
// load models
require('./merchant');
};

55
models/merchant.js Normal file
View file

@ -0,0 +1,55 @@
'use strict';
var mongoose = require('mongoose');
var bcrypt = require('bcrypt');
var Schema = mongoose.Schema;
var MerchantSchema = new Schema({
name: String,
password: String,
merchant_email: {
type: String,
index: { unique: true }
},
merchant_name: String,
language: String,
street: String,
street_2: String,
city: String,
province: String,
postal_code: String,
country: String,
telephone: String,
cellular: String,
telephone_other: String,
number: Number
}, {timestamps: true});
MerchantSchema.methods.comparePassword = function comparePassword(password, callback) {
bcrypt.compare(password, this.password, callback);
};
MerchantSchema.pre('save', function saveHook(next) {
let user = this;
// proceed only if password is modified or the user is new
if (!user.isModified('password')) {
return next();
}
return bcrypt.genSalt((saltError, salt) => {
if (saltError) {
return next(saltError);
}
return bcrypt.hash(user.password, salt, (hashError, hash) => {
if (hashError) {
return next(hashError);
}
// Replace password string with hash value
user.password = hash;
return next();
});
});
});
module.exports = mongoose.model('Merchant', MerchantSchema);

26
models/transaction.js Normal file
View file

@ -0,0 +1,26 @@
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var TransactionSchema = new Schema({
merchant_id: { type: Schema.Types.ObjectId, ref: 'Merchant' },
client_id: { type: Schema.Types.ObjectId, ref: 'Client' },
branch_id: { type: Schema.Types.ObjectId, ref: 'Branch' },
employee_id: { type: Schema.Types.ObjectId, ref: 'Employee' },
workstation_id: { type: Schema.Types.ObjectId, ref: 'Workstation' },
serial_number: String,
invoice: String,
type: String,
gift_card_id: { type: Schema.Types.ObjectId, ref: 'GiftCard' },
gift_card_number: String,
loyalty_card_id: { type: Schema.Types.ObjectId, ref: 'LoyaltyCard' },
money_amount: Number,
points_amount: Number,
cancelled_transaction_id: { type: Schema.Types.ObjectId, ref: 'Transaction'},
cancelled: Boolean,
remainder: Number,
message: String
}, {timestamps: true});
module.exports = mongoose.model('Transaction', TransactionSchema);

14
models/workstation.js Normal file
View file

@ -0,0 +1,14 @@
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var WorkstationSchema = new Schema({
serial_number: String,
number: Number,
merchant_id: { type: Schema.Types.ObjectId, ref: 'Merchant' },
branch_id: { type: Schema.Types.ObjectId, ref: 'Branch' },
workstation_name: String
}, {timestamps: true});
module.exports = mongoose.model('Workstation', WorkstationSchema);

1
node_modules/.bin/nodemon generated vendored Symbolic link
View file

@ -0,0 +1 @@
../nodemon/bin/nodemon.js

1
node_modules/.bin/nodetouch generated vendored Symbolic link
View file

@ -0,0 +1 @@
../touch/bin/nodetouch.js

1
node_modules/.bin/nopt generated vendored Symbolic link
View file

@ -0,0 +1 @@
../nopt/bin/nopt.js

1
node_modules/.bin/rc generated vendored Symbolic link
View file

@ -0,0 +1 @@
../rc/index.js

1
node_modules/.bin/semver generated vendored Symbolic link
View file

@ -0,0 +1 @@
../semver/bin/semver

1
node_modules/.bin/which generated vendored Symbolic link
View file

@ -0,0 +1 @@
../which/bin/which

46
node_modules/abbrev/LICENSE generated vendored Normal file
View file

@ -0,0 +1,46 @@
This software is dual-licensed under the ISC and MIT licenses.
You may use this software under EITHER of the following licenses.
----------
The ISC License
Copyright (c) Isaac Z. Schlueter 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.
----------
Copyright Isaac Z. Schlueter and Contributors
All rights reserved.
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.

23
node_modules/abbrev/README.md generated vendored Normal file
View file

@ -0,0 +1,23 @@
# abbrev-js
Just like [ruby's Abbrev](http://apidock.com/ruby/Abbrev).
Usage:
var abbrev = require("abbrev");
abbrev("foo", "fool", "folding", "flop");
// returns:
{ fl: 'flop'
, flo: 'flop'
, flop: 'flop'
, fol: 'folding'
, fold: 'folding'
, foldi: 'folding'
, foldin: 'folding'
, folding: 'folding'
, foo: 'foo'
, fool: 'fool'
}
This is handy for command-line scripts, or other cases where you want to be able to accept shorthands.

61
node_modules/abbrev/abbrev.js generated vendored Normal file
View file

@ -0,0 +1,61 @@
module.exports = exports = abbrev.abbrev = abbrev
abbrev.monkeyPatch = monkeyPatch
function monkeyPatch () {
Object.defineProperty(Array.prototype, 'abbrev', {
value: function () { return abbrev(this) },
enumerable: false, configurable: true, writable: true
})
Object.defineProperty(Object.prototype, 'abbrev', {
value: function () { return abbrev(Object.keys(this)) },
enumerable: false, configurable: true, writable: true
})
}
function abbrev (list) {
if (arguments.length !== 1 || !Array.isArray(list)) {
list = Array.prototype.slice.call(arguments, 0)
}
for (var i = 0, l = list.length, args = [] ; i < l ; i ++) {
args[i] = typeof list[i] === "string" ? list[i] : String(list[i])
}
// sort them lexicographically, so that they're next to their nearest kin
args = args.sort(lexSort)
// walk through each, seeing how much it has in common with the next and previous
var abbrevs = {}
, prev = ""
for (var i = 0, l = args.length ; i < l ; i ++) {
var current = args[i]
, next = args[i + 1] || ""
, nextMatches = true
, prevMatches = true
if (current === next) continue
for (var j = 0, cl = current.length ; j < cl ; j ++) {
var curChar = current.charAt(j)
nextMatches = nextMatches && curChar === next.charAt(j)
prevMatches = prevMatches && curChar === prev.charAt(j)
if (!nextMatches && !prevMatches) {
j ++
break
}
}
prev = current
if (j === cl) {
abbrevs[current] = current
continue
}
for (var a = current.substr(0, j) ; j <= cl ; j ++) {
abbrevs[a] = current
a += current.charAt(j)
}
}
return abbrevs
}
function lexSort (a, b) {
return a === b ? 0 : a > b ? 1 : -1
}

60
node_modules/abbrev/package.json generated vendored Normal file
View file

@ -0,0 +1,60 @@
{
"_args": [
[
"abbrev@1.1.1",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "abbrev@1.1.1",
"_id": "abbrev@1.1.1",
"_inBundle": false,
"_integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"_location": "/abbrev",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "abbrev@1.1.1",
"name": "abbrev",
"escapedName": "abbrev",
"rawSpec": "1.1.1",
"saveSpec": null,
"fetchSpec": "1.1.1"
},
"_requiredBy": [
"/nopt"
],
"_resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"_spec": "1.1.1",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me"
},
"bugs": {
"url": "https://github.com/isaacs/abbrev-js/issues"
},
"description": "Like ruby's abbrev module, but in js",
"devDependencies": {
"tap": "^10.1"
},
"files": [
"abbrev.js"
],
"homepage": "https://github.com/isaacs/abbrev-js#readme",
"license": "ISC",
"main": "abbrev.js",
"name": "abbrev",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/isaacs/abbrev-js.git"
},
"scripts": {
"postpublish": "git push origin --all; git push origin --tags",
"postversion": "npm publish",
"preversion": "npm test",
"test": "tap test.js --100"
},
"version": "1.1.1"
}

36
node_modules/ansi-align/CHANGELOG.md generated vendored Normal file
View file

@ -0,0 +1,36 @@
# Change Log
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
<a name="2.0.0"></a>
# [2.0.0](https://github.com/nexdrew/ansi-align/compare/v1.1.0...v2.0.0) (2017-05-01)
### Features
* ES2015ify, dropping support for Node <4 ([#30](https://github.com/nexdrew/ansi-align/issues/30)) ([7b43f48](https://github.com/nexdrew/ansi-align/commit/7b43f48))
### BREAKING CHANGES
* Node 0.10 or 0.12 no longer supported, please update to Node 4+ or use ansi-align@1.1.0
<a name="1.1.0"></a>
# [1.1.0](https://github.com/nexdrew/ansi-align/compare/v1.0.0...v1.1.0) (2016-06-06)
### Features
* support left-alignment as no-op ([#3](https://github.com/nexdrew/ansi-align/issues/3)) ([e581db6](https://github.com/nexdrew/ansi-align/commit/e581db6))
<a name="1.0.0"></a>
# 1.0.0 (2016-04-30)
### Features
* initial commit ([1914d90](https://github.com/nexdrew/ansi-align/commit/1914d90))

13
node_modules/ansi-align/LICENSE generated vendored Normal file
View file

@ -0,0 +1,13 @@
Copyright (c) 2016, 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.

79
node_modules/ansi-align/README.md generated vendored Normal file
View file

@ -0,0 +1,79 @@
# ansi-align
> align-text with ANSI support for CLIs
[![Build Status](https://travis-ci.org/nexdrew/ansi-align.svg?branch=master)](https://travis-ci.org/nexdrew/ansi-align)
[![Coverage Status](https://coveralls.io/repos/github/nexdrew/ansi-align/badge.svg?branch=master)](https://coveralls.io/github/nexdrew/ansi-align?branch=master)
[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version)
Easily center- or right- align a block of text, carefully ignoring ANSI escape codes.
E.g. turn this:
<img width="281" alt="ansi text block no alignment :(" src="https://cloud.githubusercontent.com/assets/1929625/14937509/7c3076dc-0ed7-11e6-8c16-4f6a4ccc8346.png">
Into this:
<img width="278" alt="ansi text block center aligned!" src="https://cloud.githubusercontent.com/assets/1929625/14937510/7c3ca0b0-0ed7-11e6-8f0a-541ca39b6e0a.png">
## Install
```sh
npm install --save ansi-align
```
```js
var ansiAlign = require('ansi-align')
```
## API
### `ansiAlign(text, [opts])`
Align the given text per the line with the greatest [`string-width`](https://github.com/sindresorhus/string-width), returning a new string (or array).
#### Arguments
- `text`: required, string or array
The text to align. If a string is given, it will be split using either the `opts.split` value or `'\n'` by default. If an array is given, a different array of modified strings will be returned.
- `opts`: optional, object
Options to change behavior, see below.
#### Options
- `opts.align`: string, default `'center'`
The alignment mode. Use `'center'` for center-alignment, `'right'` for right-alignment, or `'left'` for left-alignment. Note that the given `text` is assumed to be left-aligned already, so specifying `align: 'left'` just returns the `text` as is (no-op).
- `opts.split`: string or RegExp, default `'\n'`
The separator to use when splitting the text. Only used if text is given as a string.
- `opts.pad`: string, default `' '`
The value used to left-pad (prepend to) lines of lesser width. Will be repeated as necessary to adjust alignment to the line with the greatest width.
### `ansiAlign.center(text)`
Alias for `ansiAlign(text, { align: 'center' })`.
### `ansiAlign.right(text)`
Alias for `ansiAlign(text, { align: 'right' })`.
### `ansiAlign.left(text)`
Alias for `ansiAlign(text, { align: 'left' })`, which is a no-op.
## Similar Packages
- [`center-align`](https://github.com/jonschlinkert/center-align): Very close to this package, except it doesn't support ANSI codes.
- [`left-pad`](https://github.com/camwest/left-pad): Great for left-padding but does not support center alignment or ANSI codes.
- Pretty much anything by the [chalk](https://github.com/chalk) team
## License
ISC © Contributors

61
node_modules/ansi-align/index.js generated vendored Normal file
View file

@ -0,0 +1,61 @@
'use strict'
const stringWidth = require('string-width')
function ansiAlign (text, opts) {
if (!text) return text
opts = opts || {}
const align = opts.align || 'center'
// short-circuit `align: 'left'` as no-op
if (align === 'left') return text
const split = opts.split || '\n'
const pad = opts.pad || ' '
const widthDiffFn = align !== 'right' ? halfDiff : fullDiff
let returnString = false
if (!Array.isArray(text)) {
returnString = true
text = String(text).split(split)
}
let width
let maxWidth = 0
text = text.map(function (str) {
str = String(str)
width = stringWidth(str)
maxWidth = Math.max(width, maxWidth)
return {
str,
width
}
}).map(function (obj) {
return new Array(widthDiffFn(maxWidth, obj.width) + 1).join(pad) + obj.str
})
return returnString ? text.join(split) : text
}
ansiAlign.left = function left (text) {
return ansiAlign(text, { align: 'left' })
}
ansiAlign.center = function center (text) {
return ansiAlign(text, { align: 'center' })
}
ansiAlign.right = function right (text) {
return ansiAlign(text, { align: 'right' })
}
module.exports = ansiAlign
function halfDiff (maxWidth, curWidth) {
return Math.floor((maxWidth - curWidth) / 2)
}
function fullDiff (maxWidth, curWidth) {
return maxWidth - curWidth
}

74
node_modules/ansi-align/package.json generated vendored Normal file
View file

@ -0,0 +1,74 @@
{
"_args": [
[
"ansi-align@2.0.0",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "ansi-align@2.0.0",
"_id": "ansi-align@2.0.0",
"_inBundle": false,
"_integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
"_location": "/ansi-align",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "ansi-align@2.0.0",
"name": "ansi-align",
"escapedName": "ansi-align",
"rawSpec": "2.0.0",
"saveSpec": null,
"fetchSpec": "2.0.0"
},
"_requiredBy": [
"/boxen"
],
"_resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
"_spec": "2.0.0",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "nexdrew"
},
"bugs": {
"url": "https://github.com/nexdrew/ansi-align/issues"
},
"dependencies": {
"string-width": "^2.0.0"
},
"description": "align-text with ANSI support for CLIs",
"devDependencies": {
"ava": "^0.19.1",
"chalk": "^1.1.3",
"coveralls": "^2.13.1",
"nyc": "^10.3.0",
"standard": "^10.0.2",
"standard-version": "^4.0.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/nexdrew/ansi-align#readme",
"keywords": [
"ansi",
"align",
"cli",
"center",
"pad"
],
"license": "ISC",
"main": "index.js",
"name": "ansi-align",
"repository": {
"type": "git",
"url": "git+https://github.com/nexdrew/ansi-align.git"
},
"scripts": {
"coverage": "nyc report --reporter=text-lcov | coveralls",
"pretest": "standard",
"release": "standard-version",
"test": "nyc ava"
},
"version": "2.0.0"
}

10
node_modules/ansi-regex/index.js generated vendored Normal file
View file

@ -0,0 +1,10 @@
'use strict';
module.exports = () => {
const pattern = [
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\\u0007)',
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))'
].join('|');
return new RegExp(pattern, 'g');
};

9
node_modules/ansi-regex/license generated vendored Normal file
View file

@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
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.

89
node_modules/ansi-regex/package.json generated vendored Normal file
View file

@ -0,0 +1,89 @@
{
"_args": [
[
"ansi-regex@3.0.0",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "ansi-regex@3.0.0",
"_id": "ansi-regex@3.0.0",
"_inBundle": false,
"_integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"_location": "/ansi-regex",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "ansi-regex@3.0.0",
"name": "ansi-regex",
"escapedName": "ansi-regex",
"rawSpec": "3.0.0",
"saveSpec": null,
"fetchSpec": "3.0.0"
},
"_requiredBy": [
"/strip-ansi"
],
"_resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"_spec": "3.0.0",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/chalk/ansi-regex/issues"
},
"description": "Regular expression for matching ANSI escape codes",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/chalk/ansi-regex#readme",
"keywords": [
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"command-line",
"text",
"regex",
"regexp",
"re",
"match",
"test",
"find",
"pattern"
],
"license": "MIT",
"name": "ansi-regex",
"repository": {
"type": "git",
"url": "git+https://github.com/chalk/ansi-regex.git"
},
"scripts": {
"test": "xo && ava",
"view-supported": "node fixtures/view-codes.js"
},
"version": "3.0.0"
}

46
node_modules/ansi-regex/readme.md generated vendored Normal file
View file

@ -0,0 +1,46 @@
# ansi-regex [![Build Status](https://travis-ci.org/chalk/ansi-regex.svg?branch=master)](https://travis-ci.org/chalk/ansi-regex)
> Regular expression for matching [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code)
## Install
```
$ npm install ansi-regex
```
## Usage
```js
const ansiRegex = require('ansi-regex');
ansiRegex().test('\u001B[4mcake\u001B[0m');
//=> true
ansiRegex().test('cake');
//=> false
'\u001B[4mcake\u001B[0m'.match(ansiRegex());
//=> ['\u001B[4m', '\u001B[0m']
```
## FAQ
### Why do you test for codes not in the ECMA 48 standard?
Some of the codes we run as a test are codes that we acquired finding various lists of non-standard or manufacturer specific codes. We test for both standard and non-standard codes, as most of them follow the same or similar format and can be safely matched in strings without the risk of removing actual string content. There are a few non-standard control codes that do not follow the traditional format (i.e. they end in numbers) thus forcing us to exclude them from the test because we cannot reliably match them.
On the historical side, those ECMA standards were established in the early 90's whereas the VT100, for example, was designed in the mid/late 70's. At that point in time, control codes were still pretty ungoverned and engineers used them for a multitude of things, namely to activate hardware ports that may have been proprietary. Somewhere else you see a similar 'anarchy' of codes is in the x86 architecture for processors; there are a ton of "interrupts" that can mean different things on certain brands of processors, most of which have been phased out.
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)
## License
MIT

152
node_modules/ansi-styles/index.js generated vendored Normal file
View file

@ -0,0 +1,152 @@
'use strict';
const colorConvert = require('color-convert');
const wrapAnsi16 = (fn, offset) => function () {
const code = fn.apply(colorConvert, arguments);
return `\u001B[${code + offset}m`;
};
const wrapAnsi256 = (fn, offset) => function () {
const code = fn.apply(colorConvert, arguments);
return `\u001B[${38 + offset};5;${code}m`;
};
const wrapAnsi16m = (fn, offset) => function () {
const rgb = fn.apply(colorConvert, arguments);
return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
};
function assembleStyles() {
const codes = new Map();
const styles = {
modifier: {
reset: [0, 0],
// 21 isn't widely supported and 22 does the same thing
bold: [1, 22],
dim: [2, 22],
italic: [3, 23],
underline: [4, 24],
inverse: [7, 27],
hidden: [8, 28],
strikethrough: [9, 29]
},
color: {
black: [30, 39],
red: [31, 39],
green: [32, 39],
yellow: [33, 39],
blue: [34, 39],
magenta: [35, 39],
cyan: [36, 39],
white: [37, 39],
gray: [90, 39],
// Bright color
redBright: [91, 39],
greenBright: [92, 39],
yellowBright: [93, 39],
blueBright: [94, 39],
magentaBright: [95, 39],
cyanBright: [96, 39],
whiteBright: [97, 39]
},
bgColor: {
bgBlack: [40, 49],
bgRed: [41, 49],
bgGreen: [42, 49],
bgYellow: [43, 49],
bgBlue: [44, 49],
bgMagenta: [45, 49],
bgCyan: [46, 49],
bgWhite: [47, 49],
// Bright color
bgBlackBright: [100, 49],
bgRedBright: [101, 49],
bgGreenBright: [102, 49],
bgYellowBright: [103, 49],
bgBlueBright: [104, 49],
bgMagentaBright: [105, 49],
bgCyanBright: [106, 49],
bgWhiteBright: [107, 49]
}
};
// Fix humans
styles.color.grey = styles.color.gray;
for (const groupName of Object.keys(styles)) {
const group = styles[groupName];
for (const styleName of Object.keys(group)) {
const style = group[styleName];
styles[styleName] = {
open: `\u001B[${style[0]}m`,
close: `\u001B[${style[1]}m`
};
group[styleName] = styles[styleName];
codes.set(style[0], style[1]);
}
Object.defineProperty(styles, groupName, {
value: group,
enumerable: false
});
Object.defineProperty(styles, 'codes', {
value: codes,
enumerable: false
});
}
const rgb2rgb = (r, g, b) => [r, g, b];
styles.color.close = '\u001B[39m';
styles.bgColor.close = '\u001B[49m';
styles.color.ansi = {};
styles.color.ansi256 = {};
styles.color.ansi16m = {
rgb: wrapAnsi16m(rgb2rgb, 0)
};
styles.bgColor.ansi = {};
styles.bgColor.ansi256 = {};
styles.bgColor.ansi16m = {
rgb: wrapAnsi16m(rgb2rgb, 10)
};
for (const key of Object.keys(colorConvert)) {
if (typeof colorConvert[key] !== 'object') {
continue;
}
const suite = colorConvert[key];
if ('ansi16' in suite) {
styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0);
styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10);
}
if ('ansi256' in suite) {
styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0);
styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10);
}
if ('rgb' in suite) {
styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0);
styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10);
}
}
return styles;
}
// Make the export immutable
Object.defineProperty(module, 'exports', {
enumerable: true,
get: assembleStyles
});

9
node_modules/ansi-styles/license generated vendored Normal file
View file

@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
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.

90
node_modules/ansi-styles/package.json generated vendored Normal file
View file

@ -0,0 +1,90 @@
{
"_args": [
[
"ansi-styles@3.2.0",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "ansi-styles@3.2.0",
"_id": "ansi-styles@3.2.0",
"_inBundle": false,
"_integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
"_location": "/ansi-styles",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "ansi-styles@3.2.0",
"name": "ansi-styles",
"escapedName": "ansi-styles",
"rawSpec": "3.2.0",
"saveSpec": null,
"fetchSpec": "3.2.0"
},
"_requiredBy": [
"/chalk"
],
"_resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
"_spec": "3.2.0",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"ava": {
"require": "babel-polyfill"
},
"bugs": {
"url": "https://github.com/chalk/ansi-styles/issues"
},
"dependencies": {
"color-convert": "^1.9.0"
},
"description": "ANSI escape codes for styling strings in the terminal",
"devDependencies": {
"ava": "*",
"babel-polyfill": "^6.23.0",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/chalk/ansi-styles#readme",
"keywords": [
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text"
],
"license": "MIT",
"name": "ansi-styles",
"repository": {
"type": "git",
"url": "git+https://github.com/chalk/ansi-styles.git"
},
"scripts": {
"test": "xo && ava"
},
"version": "3.2.0"
}

147
node_modules/ansi-styles/readme.md generated vendored Normal file
View file

@ -0,0 +1,147 @@
# ansi-styles [![Build Status](https://travis-ci.org/chalk/ansi-styles.svg?branch=master)](https://travis-ci.org/chalk/ansi-styles)
> [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for styling strings in the terminal
You probably want the higher-level [chalk](https://github.com/chalk/chalk) module for styling your strings.
![](screenshot.png)
## Install
```
$ npm install ansi-styles
```
## Usage
```js
const style = require('ansi-styles');
console.log(`${style.green.open}Hello world!${style.green.close}`);
// Color conversion between 16/256/truecolor
// NOTE: If conversion goes to 16 colors or 256 colors, the original color
// may be degraded to fit that color palette. This means terminals
// that do not support 16 million colors will best-match the
// original color.
console.log(style.bgColor.ansi.hsl(120, 80, 72) + 'Hello world!' + style.bgColor.close);
console.log(style.color.ansi256.rgb(199, 20, 250) + 'Hello world!' + style.color.close);
console.log(style.color.ansi16m.hex('#ABCDEF') + 'Hello world!' + style.color.close);
```
## API
Each style has an `open` and `close` property.
## Styles
### Modifiers
- `reset`
- `bold`
- `dim`
- `italic` *(Not widely supported)*
- `underline`
- `inverse`
- `hidden`
- `strikethrough` *(Not widely supported)*
### Colors
- `black`
- `red`
- `green`
- `yellow`
- `blue`
- `magenta`
- `cyan`
- `white`
- `gray` ("bright black")
- `redBright`
- `greenBright`
- `yellowBright`
- `blueBright`
- `magentaBright`
- `cyanBright`
- `whiteBright`
### Background colors
- `bgBlack`
- `bgRed`
- `bgGreen`
- `bgYellow`
- `bgBlue`
- `bgMagenta`
- `bgCyan`
- `bgWhite`
- `bgBlackBright`
- `bgRedBright`
- `bgGreenBright`
- `bgYellowBright`
- `bgBlueBright`
- `bgMagentaBright`
- `bgCyanBright`
- `bgWhiteBright`
## Advanced usage
By default, you get a map of styles, but the styles are also available as groups. They are non-enumerable so they don't show up unless you access them explicitly. This makes it easier to expose only a subset in a higher-level module.
- `style.modifier`
- `style.color`
- `style.bgColor`
###### Example
```js
console.log(style.color.green.open);
```
Raw escape codes (i.e. without the CSI escape prefix `\u001B[` and render mode postfix `m`) are available under `style.codes`, which returns a `Map` with the open codes as keys and close codes as values.
###### Example
```js
console.log(style.codes.get(36));
//=> 39
```
## [256 / 16 million (TrueColor) support](https://gist.github.com/XVilka/8346728)
`ansi-styles` uses the [`color-convert`](https://github.com/Qix-/color-convert) package to allow for converting between various colors and ANSI escapes, with support for 256 and 16 million colors.
To use these, call the associated conversion function with the intended output, for example:
```js
style.color.ansi.rgb(100, 200, 15); // RGB to 16 color ansi foreground code
style.bgColor.ansi.rgb(100, 200, 15); // RGB to 16 color ansi background code
style.color.ansi256.hsl(120, 100, 60); // HSL to 256 color ansi foreground code
style.bgColor.ansi256.hsl(120, 100, 60); // HSL to 256 color ansi foreground code
style.color.ansi16m.hex('#C0FFEE'); // Hex (RGB) to 16 million color foreground code
style.bgColor.ansi16m.hex('#C0FFEE'); // Hex (RGB) to 16 million color background code
```
## Related
- [ansi-escapes](https://github.com/sindresorhus/ansi-escapes) - ANSI escape codes for manipulating the terminal
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)
## License
MIT

15
node_modules/anymatch/LICENSE generated vendored Normal file
View file

@ -0,0 +1,15 @@
The ISC License
Copyright (c) 2014 Elan Shanker
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.

98
node_modules/anymatch/README.md generated vendored Normal file
View file

@ -0,0 +1,98 @@
anymatch [![Build Status](https://travis-ci.org/es128/anymatch.svg?branch=master)](https://travis-ci.org/es128/anymatch) [![Coverage Status](https://img.shields.io/coveralls/es128/anymatch.svg?branch=master)](https://coveralls.io/r/es128/anymatch?branch=master)
======
Javascript module to match a string against a regular expression, glob, string,
or function that takes the string as an argument and returns a truthy or falsy
value. The matcher can also be an array of any or all of these. Useful for
allowing a very flexible user-defined config to define things like file paths.
[![NPM](https://nodei.co/npm/anymatch.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/anymatch/)
[![NPM](https://nodei.co/npm-dl/anymatch.png?height=3&months=9)](https://nodei.co/npm-dl/anymatch/)
Usage
-----
```sh
npm install anymatch --save
```
#### anymatch (matchers, testString, [returnIndex], [startIndex], [endIndex])
* __matchers__: (_Array|String|RegExp|Function_)
String to be directly matched, string with glob patterns, regular expression
test, function that takes the testString as an argument and returns a truthy
value if it should be matched, or an array of any number and mix of these types.
* __testString__: (_String|Array_) The string to test against the matchers. If
passed as an array, the first element of the array will be used as the
`testString` for non-function matchers, while the entire array will be applied
as the arguments for function matchers.
* __returnIndex__: (_Boolean [optional]_) If true, return the array index of
the first matcher that that testString matched, or -1 if no match, instead of a
boolean result.
* __startIndex, endIndex__: (_Integer [optional]_) Can be used to define a
subset out of the array of provided matchers to test against. Can be useful
with bound matcher functions (see below). When used with `returnIndex = true`
preserves original indexing. Behaves the same as `Array.prototype.slice` (i.e.
includes array members up to, but not including endIndex).
```js
var anymatch = require('anymatch');
var matchers = [
'path/to/file.js',
'path/anyjs/**/*.js',
/foo\.js$/,
function (string) {
return string.indexOf('bar') !== -1 && string.length > 10
}
];
anymatch(matchers, 'path/to/file.js'); // true
anymatch(matchers, 'path/anyjs/baz.js'); // true
anymatch(matchers, 'path/to/foo.js'); // true
anymatch(matchers, 'path/to/bar.js'); // true
anymatch(matchers, 'bar.js'); // false
// returnIndex = true
anymatch(matchers, 'foo.js', true); // 2
anymatch(matchers, 'path/anyjs/foo.js', true); // 1
// skip matchers
anymatch(matchers, 'path/to/file.js', false, 1); // false
anymatch(matchers, 'path/anyjs/foo.js', true, 2, 3); // 2
anymatch(matchers, 'path/to/bar.js', true, 0, 3); // -1
// using globs to match directories and their children
anymatch('node_modules', 'node_modules'); // true
anymatch('node_modules', 'node_modules/somelib/index.js'); // false
anymatch('node_modules/**', 'node_modules/somelib/index.js'); // true
anymatch('node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // false
anymatch('**/node_modules/**', '/absolute/path/to/node_modules/somelib/index.js'); // true
```
#### anymatch (matchers)
You can also pass in only your matcher(s) to get a curried function that has
already been bound to the provided matching criteria. This can be used as an
`Array.prototype.filter` callback.
```js
var matcher = anymatch(matchers);
matcher('path/to/file.js'); // true
matcher('path/anyjs/baz.js', true); // 1
matcher('path/anyjs/baz.js', true, 2); // -1
['foo.js', 'bar.js'].filter(matcher); // ['foo.js']
```
Change Log
----------
[See release notes page on GitHub](https://github.com/es128/anymatch/releases)
NOTE: As of v1.2.0, anymatch uses [micromatch](https://github.com/jonschlinkert/micromatch)
for glob pattern matching. The glob matching behavior should be functionally
equivalent to the commonly used [minimatch](https://github.com/isaacs/minimatch)
library (aside from some fixed bugs and greater performance), so a major
version bump wasn't merited. Issues with glob pattern matching should be
reported directly to the [micromatch issue tracker](https://github.com/jonschlinkert/micromatch/issues).
License
-------
[ISC](https://raw.github.com/es128/anymatch/master/LICENSE)

67
node_modules/anymatch/index.js generated vendored Normal file
View file

@ -0,0 +1,67 @@
'use strict';
var micromatch = require('micromatch');
var normalize = require('normalize-path');
var path = require('path'); // required for tests.
var arrify = function(a) { return a == null ? [] : (Array.isArray(a) ? a : [a]); };
var anymatch = function(criteria, value, returnIndex, startIndex, endIndex) {
criteria = arrify(criteria);
value = arrify(value);
if (arguments.length === 1) {
return anymatch.bind(null, criteria.map(function(criterion) {
return typeof criterion === 'string' && criterion[0] !== '!' ?
micromatch.matcher(criterion) : criterion;
}));
}
startIndex = startIndex || 0;
var string = value[0];
var altString, altValue;
var matched = false;
var matchIndex = -1;
function testCriteria(criterion, index) {
var result;
switch (Object.prototype.toString.call(criterion)) {
case '[object String]':
result = string === criterion || altString && altString === criterion;
result = result || micromatch.isMatch(string, criterion);
break;
case '[object RegExp]':
result = criterion.test(string) || altString && criterion.test(altString);
break;
case '[object Function]':
result = criterion.apply(null, value);
result = result || altValue && criterion.apply(null, altValue);
break;
default:
result = false;
}
if (result) {
matchIndex = index + startIndex;
}
return result;
}
var crit = criteria;
var negGlobs = crit.reduce(function(arr, criterion, index) {
if (typeof criterion === 'string' && criterion[0] === '!') {
if (crit === criteria) {
// make a copy before modifying
crit = crit.slice();
}
crit[index] = null;
arr.push(criterion.substr(1));
}
return arr;
}, []);
if (!negGlobs.length || !micromatch.any(string, negGlobs)) {
if (path.sep === '\\' && typeof string === 'string') {
altString = normalize(string);
altString = altString === string ? null : altString;
if (altString) altValue = [altString].concat(value.slice(1));
}
matched = crit.slice(startIndex, endIndex).some(testCriteria);
}
return returnIndex === true ? matchIndex : matched;
};
module.exports = anymatch;

76
node_modules/anymatch/package.json generated vendored Normal file
View file

@ -0,0 +1,76 @@
{
"_args": [
[
"anymatch@1.3.2",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "anymatch@1.3.2",
"_id": "anymatch@1.3.2",
"_inBundle": false,
"_integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
"_location": "/anymatch",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "anymatch@1.3.2",
"name": "anymatch",
"escapedName": "anymatch",
"rawSpec": "1.3.2",
"saveSpec": null,
"fetchSpec": "1.3.2"
},
"_requiredBy": [
"/chokidar"
],
"_resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
"_spec": "1.3.2",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Elan Shanker",
"url": "http://github.com/es128"
},
"bugs": {
"url": "https://github.com/es128/anymatch/issues"
},
"dependencies": {
"micromatch": "^2.1.5",
"normalize-path": "^2.0.0"
},
"description": "Matches strings against configurable strings, globs, regular expressions, and/or functions",
"devDependencies": {
"coveralls": "^2.11.2",
"istanbul": "^0.3.13",
"mocha": "^2.2.4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/es128/anymatch",
"keywords": [
"match",
"any",
"string",
"file",
"fs",
"list",
"glob",
"regex",
"regexp",
"regular",
"expression",
"function"
],
"license": "ISC",
"name": "anymatch",
"repository": {
"type": "git",
"url": "git+https://github.com/es128/anymatch.git"
},
"scripts": {
"test": "istanbul cover _mocha && cat ./coverage/lcov.info | coveralls"
},
"version": "1.3.2"
}

21
node_modules/arr-diff/LICENSE generated vendored Executable file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2015, Jon Schlinkert.
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.

74
node_modules/arr-diff/README.md generated vendored Normal file
View file

@ -0,0 +1,74 @@
# arr-diff [![NPM version](https://img.shields.io/npm/v/arr-diff.svg)](https://www.npmjs.com/package/arr-diff) [![Build Status](https://img.shields.io/travis/jonschlinkert/base.svg)](https://travis-ci.org/jonschlinkert/base)
> Returns an array with only the unique values from the first array, by excluding all values from additional arrays using strict equality for comparisons.
## Install
Install with [npm](https://www.npmjs.com/)
```sh
$ npm i arr-diff --save
```
Install with [bower](http://bower.io/)
```sh
$ bower install arr-diff --save
```
## API
### [diff](index.js#L33)
Return the difference between the first array and additional arrays.
**Params**
* `a` **{Array}**
* `b` **{Array}**
* `returns` **{Array}**
**Example**
```js
var diff = require('arr-diff');
var a = ['a', 'b', 'c', 'd'];
var b = ['b', 'c'];
console.log(diff(a, b))
//=> ['a', 'd']
```
## Related projects
* [arr-flatten](https://www.npmjs.com/package/arr-flatten): Recursively flatten an array or arrays. This is the fastest implementation of array flatten. | [homepage](https://github.com/jonschlinkert/arr-flatten)
* [array-filter](https://www.npmjs.com/package/array-filter): Array#filter for older browsers. | [homepage](https://github.com/juliangruber/array-filter)
* [array-intersection](https://www.npmjs.com/package/array-intersection): Return an array with the unique values present in _all_ given arrays using strict equality… [more](https://www.npmjs.com/package/array-intersection) | [homepage](https://github.com/jonschlinkert/array-intersection)
## Running tests
Install dev dependencies:
```sh
$ npm i -d && npm test
```
## Contributing
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/arr-diff/issues/new).
## Author
**Jon Schlinkert**
+ [github/jonschlinkert](https://github.com/jonschlinkert)
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
## License
Copyright © 2015 [Jon Schlinkert](https://github.com/jonschlinkert)
Released under the MIT license.
***
_This file was generated by [verb](https://github.com/verbose/verb) on Sat Dec 05 2015 23:24:53 GMT-0500 (EST)._

58
node_modules/arr-diff/index.js generated vendored Normal file
View file

@ -0,0 +1,58 @@
/*!
* arr-diff <https://github.com/jonschlinkert/arr-diff>
*
* Copyright (c) 2014 Jon Schlinkert, contributors.
* Licensed under the MIT License
*/
'use strict';
var flatten = require('arr-flatten');
var slice = [].slice;
/**
* Return the difference between the first array and
* additional arrays.
*
* ```js
* var diff = require('{%= name %}');
*
* var a = ['a', 'b', 'c', 'd'];
* var b = ['b', 'c'];
*
* console.log(diff(a, b))
* //=> ['a', 'd']
* ```
*
* @param {Array} `a`
* @param {Array} `b`
* @return {Array}
* @api public
*/
function diff(arr, arrays) {
var argsLen = arguments.length;
var len = arr.length, i = -1;
var res = [], arrays;
if (argsLen === 1) {
return arr;
}
if (argsLen > 2) {
arrays = flatten(slice.call(arguments, 1));
}
while (++i < len) {
if (!~arrays.indexOf(arr[i])) {
res.push(arr[i]);
}
}
return res;
}
/**
* Expose `diff`
*/
module.exports = diff;

84
node_modules/arr-diff/package.json generated vendored Normal file
View file

@ -0,0 +1,84 @@
{
"_args": [
[
"arr-diff@2.0.0",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "arr-diff@2.0.0",
"_id": "arr-diff@2.0.0",
"_inBundle": false,
"_integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
"_location": "/arr-diff",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "arr-diff@2.0.0",
"name": "arr-diff",
"escapedName": "arr-diff",
"rawSpec": "2.0.0",
"saveSpec": null,
"fetchSpec": "2.0.0"
},
"_requiredBy": [
"/micromatch"
],
"_resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
"_spec": "2.0.0",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Jon Schlinkert",
"url": "https://github.com/jonschlinkert"
},
"bugs": {
"url": "https://github.com/jonschlinkert/arr-diff/issues"
},
"dependencies": {
"arr-flatten": "^1.0.1"
},
"description": "Returns an array with only the unique values from the first array, by excluding all values from additional arrays using strict equality for comparisons.",
"devDependencies": {
"array-differ": "^1.0.0",
"array-slice": "^0.2.3",
"benchmarked": "^0.1.4",
"chalk": "^1.1.1",
"mocha": "*",
"should": "*"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/jonschlinkert/arr-diff",
"keywords": [
"arr",
"array",
"diff",
"differ",
"difference"
],
"license": "MIT",
"main": "index.js",
"name": "arr-diff",
"repository": {
"type": "git",
"url": "git+https://github.com/jonschlinkert/arr-diff.git"
},
"scripts": {
"test": "mocha"
},
"verb": {
"related": {
"list": [
"arr-flatten",
"array-filter",
"array-intersection"
]
}
},
"version": "2.0.0"
}

21
node_modules/arr-flatten/LICENSE generated vendored Executable file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2017, Jon Schlinkert.
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.

86
node_modules/arr-flatten/README.md generated vendored Executable file
View file

@ -0,0 +1,86 @@
# arr-flatten [![NPM version](https://img.shields.io/npm/v/arr-flatten.svg?style=flat)](https://www.npmjs.com/package/arr-flatten) [![NPM monthly downloads](https://img.shields.io/npm/dm/arr-flatten.svg?style=flat)](https://npmjs.org/package/arr-flatten) [![NPM total downloads](https://img.shields.io/npm/dt/arr-flatten.svg?style=flat)](https://npmjs.org/package/arr-flatten) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/arr-flatten.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/arr-flatten) [![Windows Build Status](https://img.shields.io/appveyor/ci/jonschlinkert/arr-flatten.svg?style=flat&label=AppVeyor)](https://ci.appveyor.com/project/jonschlinkert/arr-flatten)
> Recursively flatten an array or arrays.
## Install
Install with [npm](https://www.npmjs.com/):
```sh
$ npm install --save arr-flatten
```
## Install
Install with [bower](https://bower.io/)
```sh
$ bower install arr-flatten --save
```
## Usage
```js
var flatten = require('arr-flatten');
flatten(['a', ['b', ['c']], 'd', ['e']]);
//=> ['a', 'b', 'c', 'd', 'e']
```
## Why another flatten utility?
I wanted the fastest implementation I could find, with implementation choices that should work for 95% of use cases, but no cruft to cover the other 5%.
## About
### Related projects
* [arr-filter](https://www.npmjs.com/package/arr-filter): Faster alternative to javascript's native filter method. | [homepage](https://github.com/jonschlinkert/arr-filter "Faster alternative to javascript's native filter method.")
* [arr-union](https://www.npmjs.com/package/arr-union): Combines a list of arrays, returning a single array with unique values, using strict equality… [more](https://github.com/jonschlinkert/arr-union) | [homepage](https://github.com/jonschlinkert/arr-union "Combines a list of arrays, returning a single array with unique values, using strict equality for comparisons.")
* [array-each](https://www.npmjs.com/package/array-each): Loop over each item in an array and call the given function on every element. | [homepage](https://github.com/jonschlinkert/array-each "Loop over each item in an array and call the given function on every element.")
* [array-unique](https://www.npmjs.com/package/array-unique): Remove duplicate values from an array. Fastest ES5 implementation. | [homepage](https://github.com/jonschlinkert/array-unique "Remove duplicate values from an array. Fastest ES5 implementation.")
### Contributing
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
### Contributors
| **Commits** | **Contributor** |
| --- | --- |
| 20 | [jonschlinkert](https://github.com/jonschlinkert) |
| 1 | [lukeed](https://github.com/lukeed) |
### Building docs
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
To generate the readme, run the following command:
```sh
$ npm install -g verbose/verb#dev verb-generate-readme && verb
```
### Running tests
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
```sh
$ npm install && npm test
```
### Author
**Jon Schlinkert**
* [github/jonschlinkert](https://github.com/jonschlinkert)
* [twitter/jonschlinkert](https://twitter.com/jonschlinkert)
### License
Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert).
Released under the [MIT License](LICENSE).
***
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on July 05, 2017._

22
node_modules/arr-flatten/index.js generated vendored Normal file
View file

@ -0,0 +1,22 @@
/*!
* arr-flatten <https://github.com/jonschlinkert/arr-flatten>
*
* Copyright (c) 2014-2017, Jon Schlinkert.
* Released under the MIT License.
*/
'use strict';
module.exports = function (arr) {
return flat(arr, []);
};
function flat(arr, res) {
var i = 0, cur;
var len = arr.length;
for (; i < len; i++) {
cur = arr[i];
Array.isArray(cur) ? flat(cur, res) : res.push(cur);
}
return res;
}

117
node_modules/arr-flatten/package.json generated vendored Normal file
View file

@ -0,0 +1,117 @@
{
"_args": [
[
"arr-flatten@1.1.0",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "arr-flatten@1.1.0",
"_id": "arr-flatten@1.1.0",
"_inBundle": false,
"_integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
"_location": "/arr-flatten",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "arr-flatten@1.1.0",
"name": "arr-flatten",
"escapedName": "arr-flatten",
"rawSpec": "1.1.0",
"saveSpec": null,
"fetchSpec": "1.1.0"
},
"_requiredBy": [
"/arr-diff"
],
"_resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
"_spec": "1.1.0",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Jon Schlinkert",
"url": "https://github.com/jonschlinkert"
},
"bugs": {
"url": "https://github.com/jonschlinkert/arr-flatten/issues"
},
"contributors": [
{
"name": "Jon Schlinkert",
"url": "http://twitter.com/jonschlinkert"
},
{
"name": "Luke Edwards",
"url": "https://lukeed.com"
}
],
"description": "Recursively flatten an array or arrays.",
"devDependencies": {
"ansi-bold": "^0.1.1",
"array-flatten": "^2.1.1",
"array-slice": "^1.0.0",
"benchmarked": "^1.0.0",
"compute-flatten": "^1.0.0",
"flatit": "^1.1.1",
"flatten": "^1.0.2",
"flatten-array": "^1.0.0",
"glob": "^7.1.1",
"gulp-format-md": "^0.1.12",
"just-flatten-it": "^1.1.23",
"lodash.flattendeep": "^4.4.0",
"m_flattened": "^1.0.1",
"mocha": "^3.2.0",
"utils-flatten": "^1.0.0",
"write": "^0.3.3"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/jonschlinkert/arr-flatten",
"keywords": [
"arr",
"array",
"elements",
"flat",
"flatten",
"nested",
"recurse",
"recursive",
"recursively"
],
"license": "MIT",
"main": "index.js",
"name": "arr-flatten",
"repository": {
"type": "git",
"url": "git+https://github.com/jonschlinkert/arr-flatten.git"
},
"scripts": {
"test": "mocha"
},
"verb": {
"toc": false,
"layout": "default",
"tasks": [
"readme"
],
"plugins": [
"gulp-format-md"
],
"related": {
"list": [
"arr-filter",
"arr-union",
"array-each",
"array-unique"
]
},
"lint": {
"reflinks": true
}
},
"version": "1.1.0"
}

21
node_modules/array-unique/LICENSE generated vendored Executable file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2015, Jon Schlinkert.
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.

51
node_modules/array-unique/README.md generated vendored Executable file
View file

@ -0,0 +1,51 @@
# array-unique [![NPM version](https://badge.fury.io/js/array-unique.svg)](http://badge.fury.io/js/array-unique) [![Build Status](https://travis-ci.org/jonschlinkert/array-unique.svg)](https://travis-ci.org/jonschlinkert/array-unique)
> Return an array free of duplicate values. Fastest ES5 implementation.
## Install with [npm](npmjs.org)
```bash
npm i array-unique --save
```
## Usage
```js
var unique = require('array-unique');
unique(['a', 'b', 'c', 'c']);
//=> ['a', 'b', 'c']
```
## Related
* [arr-diff](https://github.com/jonschlinkert/arr-diff): Returns an array with only the unique values from the first array, by excluding all values from additional arrays using strict equality for comparisons.
* [arr-union](https://github.com/jonschlinkert/arr-union): Returns an array of unique values using strict equality for comparisons.
* [arr-flatten](https://github.com/jonschlinkert/arr-flatten): Recursively flatten an array or arrays. This is the fastest implementation of array flatten.
* [arr-reduce](https://github.com/jonschlinkert/arr-reduce): Fast array reduce that also loops over sparse elements.
* [arr-map](https://github.com/jonschlinkert/arr-map): Faster, node.js focused alternative to JavaScript's native array map.
* [arr-pluck](https://github.com/jonschlinkert/arr-pluck): Retrieves the value of a specified property from all elements in the collection.
## Run tests
Install dev dependencies.
```bash
npm i -d && npm test
```
## Contributing
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/array-unique/issues)
## Author
**Jon Schlinkert**
+ [github/jonschlinkert](https://github.com/jonschlinkert)
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
## License
Copyright (c) 2015 Jon Schlinkert
Released under the MIT license
***
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 24, 2015._

28
node_modules/array-unique/index.js generated vendored Executable file
View file

@ -0,0 +1,28 @@
/*!
* array-unique <https://github.com/jonschlinkert/array-unique>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
module.exports = function unique(arr) {
if (!Array.isArray(arr)) {
throw new TypeError('array-unique expects an array.');
}
var len = arr.length;
var i = -1;
while (i++ < len) {
var j = i + 1;
for (; j < arr.length; ++j) {
if (arr[i] === arr[j]) {
arr.splice(j--, 1);
}
}
}
return arr;
};

66
node_modules/array-unique/package.json generated vendored Executable file
View file

@ -0,0 +1,66 @@
{
"_args": [
[
"array-unique@0.2.1",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "array-unique@0.2.1",
"_id": "array-unique@0.2.1",
"_inBundle": false,
"_integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
"_location": "/array-unique",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "array-unique@0.2.1",
"name": "array-unique",
"escapedName": "array-unique",
"rawSpec": "0.2.1",
"saveSpec": null,
"fetchSpec": "0.2.1"
},
"_requiredBy": [
"/micromatch"
],
"_resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
"_spec": "0.2.1",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Jon Schlinkert",
"url": "https://github.com/jonschlinkert"
},
"bugs": {
"url": "https://github.com/jonschlinkert/array-unique/issues"
},
"description": "Return an array free of duplicate values. Fastest ES5 implementation.",
"devDependencies": {
"array-uniq": "^1.0.2",
"benchmarked": "^0.1.3",
"mocha": "*",
"should": "*"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/jonschlinkert/array-unique",
"license": {
"type": "MIT",
"url": "https://github.com/jonschlinkert/array-unique/blob/master/LICENSE"
},
"main": "index.js",
"name": "array-unique",
"repository": {
"type": "git",
"url": "git://github.com/jonschlinkert/array-unique.git"
},
"scripts": {
"test": "mocha"
},
"version": "0.2.1"
}

3
node_modules/async-each/.npmignore generated vendored Normal file
View file

@ -0,0 +1,3 @@
bower.json
component.json
CHANGELOG.md

23
node_modules/async-each/CHANGELOG.md generated vendored Normal file
View file

@ -0,0 +1,23 @@
# async-each 1.0.0 (26 November 2015)
* Bumped version to 1.0.0 (no functional changes)
# async-each 0.1.6 (5 November 2014)
* Add license to package.json
# async-each 0.1.5 (22 October 2014)
* Clean up package.json to fix npm warning about `repo`
# async-each 0.1.4 (12 November 2013)
* Fixed AMD definition.
# async-each 0.1.3 (25 July 2013)
* Fixed double wrapping of errors.
# async-each 0.1.2 (7 July 2013)
* Fixed behaviour on empty arrays.
# async-each 0.1.1 (14 June 2013)
* Wrapped function in closure, enabled strict mode.
# async-each 0.1.0 (14 June 2013)
* Initial release.

38
node_modules/async-each/README.md generated vendored Normal file
View file

@ -0,0 +1,38 @@
# async-each
No-bullshit, ultra-simple, 35-lines-of-code async parallel forEach function for JavaScript.
We don't need junky 30K async libs. Really.
For browsers and node.js.
## Installation
* Just include async-each before your scripts.
* `npm install async-each` if youre using node.js.
* `bower install async-each` if youre using [Bower](http://bower.io).
## Usage
* `each(array, iterator, callback);``Array`, `Function`, `(optional) Function`
* `iterator(item, next)` receives current item and a callback that will mark the item as done. `next` callback receives optional `error, transformedItem` arguments.
* `callback(error, transformedArray)` optionally receives first error and transformed result `Array`.
Node.js:
```javascript
var each = require('async-each');
each(['a.js', 'b.js', 'c.js'], fs.readFile, function(error, contents) {
if (error) console.error(error);
console.log('Contents for a, b and c:', contents);
});
```
Browser:
```javascript
window.asyncEach(list, fn, callback);
```
## License
[The MIT License](https://raw.githubusercontent.com/paulmillr/mit/master/README.md)

38
node_modules/async-each/index.js generated vendored Normal file
View file

@ -0,0 +1,38 @@
// async-each MIT license (by Paul Miller from http://paulmillr.com).
(function(globals) {
'use strict';
var each = function(items, next, callback) {
if (!Array.isArray(items)) throw new TypeError('each() expects array as first argument');
if (typeof next !== 'function') throw new TypeError('each() expects function as second argument');
if (typeof callback !== 'function') callback = Function.prototype; // no-op
if (items.length === 0) return callback(undefined, items);
var transformed = new Array(items.length);
var count = 0;
var returned = false;
items.forEach(function(item, index) {
next(item, function(error, transformedItem) {
if (returned) return;
if (error) {
returned = true;
return callback(error);
}
transformed[index] = transformedItem;
count += 1;
if (count === items.length) return callback(undefined, transformed);
});
});
};
if (typeof define !== 'undefined' && define.amd) {
define([], function() {
return each;
}); // RequireJS
} else if (typeof module !== 'undefined' && module.exports) {
module.exports = each; // CommonJS
} else {
globals.asyncEach = each; // <script>
}
})(this);

64
node_modules/async-each/package.json generated vendored Normal file
View file

@ -0,0 +1,64 @@
{
"_args": [
[
"async-each@1.0.1",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "async-each@1.0.1",
"_id": "async-each@1.0.1",
"_inBundle": false,
"_integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
"_location": "/async-each",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "async-each@1.0.1",
"name": "async-each",
"escapedName": "async-each",
"rawSpec": "1.0.1",
"saveSpec": null,
"fetchSpec": "1.0.1"
},
"_requiredBy": [
"/chokidar"
],
"_resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
"_spec": "1.0.1",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Paul Miller",
"url": "http://paulmillr.com/"
},
"bugs": {
"url": "https://github.com/paulmillr/async-each/issues"
},
"dependencies": {},
"description": "No-bullshit, ultra-simple, 35-lines-of-code async parallel forEach / map function for JavaScript.",
"homepage": "https://github.com/paulmillr/async-each/",
"keywords": [
"async",
"forEach",
"each",
"map",
"asynchronous",
"iteration",
"iterate",
"loop",
"parallel",
"concurrent",
"array",
"flow",
"control flow"
],
"license": "MIT",
"main": "index.js",
"name": "async-each",
"repository": {
"type": "git",
"url": "git://github.com/paulmillr/async-each.git"
},
"version": "1.0.1"
}

5
node_modules/balanced-match/.npmignore generated vendored Normal file
View file

@ -0,0 +1,5 @@
test
.gitignore
.travis.yml
Makefile
example.js

21
node_modules/balanced-match/LICENSE.md generated vendored Normal file
View file

@ -0,0 +1,21 @@
(MIT)
Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
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.

91
node_modules/balanced-match/README.md generated vendored Normal file
View file

@ -0,0 +1,91 @@
# balanced-match
Match balanced string pairs, like `{` and `}` or `<b>` and `</b>`. Supports regular expressions as well!
[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match)
[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match)
[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match)
## Example
Get the first matching pair of braces:
```js
var balanced = require('balanced-match');
console.log(balanced('{', '}', 'pre{in{nested}}post'));
console.log(balanced('{', '}', 'pre{first}between{second}post'));
console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post'));
```
The matches are:
```bash
$ node example.js
{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' }
{ start: 3,
end: 9,
pre: 'pre',
body: 'first',
post: 'between{second}post' }
{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' }
```
## API
### var m = balanced(a, b, str)
For the first non-nested matching pair of `a` and `b` in `str`, return an
object with those keys:
* **start** the index of the first match of `a`
* **end** the index of the matching `b`
* **pre** the preamble, `a` and `b` not included
* **body** the match, `a` and `b` not included
* **post** the postscript, `a` and `b` not included
If there's no match, `undefined` will be returned.
If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`.
### var r = balanced.range(a, b, str)
For the first non-nested matching pair of `a` and `b` in `str`, return an
array with indexes: `[ <a index>, <b index> ]`.
If there's no match, `undefined` will be returned.
If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`.
## Installation
With [npm](https://npmjs.org) do:
```bash
npm install balanced-match
```
## License
(MIT)
Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
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.

59
node_modules/balanced-match/index.js generated vendored Normal file
View file

@ -0,0 +1,59 @@
'use strict';
module.exports = balanced;
function balanced(a, b, str) {
if (a instanceof RegExp) a = maybeMatch(a, str);
if (b instanceof RegExp) b = maybeMatch(b, str);
var r = range(a, b, str);
return r && {
start: r[0],
end: r[1],
pre: str.slice(0, r[0]),
body: str.slice(r[0] + a.length, r[1]),
post: str.slice(r[1] + b.length)
};
}
function maybeMatch(reg, str) {
var m = str.match(reg);
return m ? m[0] : null;
}
balanced.range = range;
function range(a, b, str) {
var begs, beg, left, right, result;
var ai = str.indexOf(a);
var bi = str.indexOf(b, ai + 1);
var i = ai;
if (ai >= 0 && bi > 0) {
begs = [];
left = str.length;
while (i >= 0 && !result) {
if (i == ai) {
begs.push(i);
ai = str.indexOf(a, i + 1);
} else if (begs.length == 1) {
result = [ begs.pop(), bi ];
} else {
beg = begs.pop();
if (beg < left) {
left = beg;
right = bi;
}
bi = str.indexOf(b, i + 1);
}
i = ai < bi && ai >= 0 ? ai : bi;
}
if (begs.length) {
result = [ left, right ];
}
}
return result;
}

81
node_modules/balanced-match/package.json generated vendored Normal file
View file

@ -0,0 +1,81 @@
{
"_args": [
[
"balanced-match@1.0.0",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "balanced-match@1.0.0",
"_id": "balanced-match@1.0.0",
"_inBundle": false,
"_integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"_location": "/balanced-match",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "balanced-match@1.0.0",
"name": "balanced-match",
"escapedName": "balanced-match",
"rawSpec": "1.0.0",
"saveSpec": null,
"fetchSpec": "1.0.0"
},
"_requiredBy": [
"/brace-expansion"
],
"_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"_spec": "1.0.0",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Julian Gruber",
"email": "mail@juliangruber.com",
"url": "http://juliangruber.com"
},
"bugs": {
"url": "https://github.com/juliangruber/balanced-match/issues"
},
"dependencies": {},
"description": "Match balanced character pairs, like \"{\" and \"}\"",
"devDependencies": {
"matcha": "^0.7.0",
"tape": "^4.6.0"
},
"homepage": "https://github.com/juliangruber/balanced-match",
"keywords": [
"match",
"regexp",
"test",
"balanced",
"parse"
],
"license": "MIT",
"main": "index.js",
"name": "balanced-match",
"repository": {
"type": "git",
"url": "git://github.com/juliangruber/balanced-match.git"
},
"scripts": {
"bench": "make bench",
"test": "make test"
},
"testling": {
"files": "test/*.js",
"browsers": [
"ie/8..latest",
"firefox/20..latest",
"firefox/nightly",
"chrome/25..latest",
"chrome/canary",
"opera/12..latest",
"opera/next",
"safari/5.1..latest",
"ipad/6.0..latest",
"iphone/6.0..latest",
"android-browser/4.2..latest"
]
},
"version": "1.0.0"
}

242
node_modules/binary-extensions/binary-extensions.json generated vendored Normal file
View file

@ -0,0 +1,242 @@
[
"3ds",
"3g2",
"3gp",
"7z",
"a",
"aac",
"adp",
"ai",
"aif",
"aiff",
"alz",
"ape",
"apk",
"ar",
"arj",
"asf",
"au",
"avi",
"bak",
"bh",
"bin",
"bk",
"bmp",
"btif",
"bz2",
"bzip2",
"cab",
"caf",
"cgm",
"class",
"cmx",
"cpio",
"cr2",
"csv",
"cur",
"dat",
"dcm",
"deb",
"dex",
"djvu",
"dll",
"dmg",
"dng",
"doc",
"docm",
"docx",
"dot",
"dotm",
"dra",
"DS_Store",
"dsk",
"dts",
"dtshd",
"dvb",
"dwg",
"dxf",
"ecelp4800",
"ecelp7470",
"ecelp9600",
"egg",
"eol",
"eot",
"epub",
"exe",
"f4v",
"fbs",
"fh",
"fla",
"flac",
"fli",
"flv",
"fpx",
"fst",
"fvt",
"g3",
"gif",
"graffle",
"gz",
"gzip",
"h261",
"h263",
"h264",
"icns",
"ico",
"ief",
"img",
"ipa",
"iso",
"jar",
"jpeg",
"jpg",
"jpgv",
"jpm",
"jxr",
"key",
"ktx",
"lha",
"lvp",
"lz",
"lzh",
"lzma",
"lzo",
"m3u",
"m4a",
"m4v",
"mar",
"mdi",
"mht",
"mid",
"midi",
"mj2",
"mka",
"mkv",
"mmr",
"mng",
"mobi",
"mov",
"movie",
"mp3",
"mp4",
"mp4a",
"mpeg",
"mpg",
"mpga",
"mxu",
"nef",
"npx",
"numbers",
"o",
"oga",
"ogg",
"ogv",
"otf",
"pages",
"pbm",
"pcx",
"pdf",
"pea",
"pgm",
"pic",
"png",
"pnm",
"pot",
"potm",
"potx",
"ppa",
"ppam",
"ppm",
"pps",
"ppsm",
"ppsx",
"ppt",
"pptm",
"pptx",
"psd",
"pya",
"pyc",
"pyo",
"pyv",
"qt",
"rar",
"ras",
"raw",
"rgb",
"rip",
"rlc",
"rmf",
"rmvb",
"rtf",
"rz",
"s3m",
"s7z",
"scpt",
"sgi",
"shar",
"sil",
"sketch",
"slk",
"smv",
"so",
"sub",
"swf",
"tar",
"tbz",
"tbz2",
"tga",
"tgz",
"thmx",
"tif",
"tiff",
"tlz",
"ttc",
"ttf",
"txz",
"udf",
"uvh",
"uvi",
"uvm",
"uvp",
"uvs",
"uvu",
"viv",
"vob",
"war",
"wav",
"wax",
"wbmp",
"wdp",
"weba",
"webm",
"webp",
"whl",
"wim",
"wm",
"wma",
"wmv",
"wmx",
"woff",
"woff2",
"wvx",
"xbm",
"xif",
"xla",
"xlam",
"xls",
"xlsb",
"xlsm",
"xlsx",
"xlt",
"xltm",
"xltx",
"xm",
"xmind",
"xpi",
"xpm",
"xwd",
"xz",
"z",
"zip",
"zipx"
]

9
node_modules/binary-extensions/license generated vendored Normal file
View file

@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
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.

72
node_modules/binary-extensions/package.json generated vendored Normal file
View file

@ -0,0 +1,72 @@
{
"_args": [
[
"binary-extensions@1.10.0",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "binary-extensions@1.10.0",
"_id": "binary-extensions@1.10.0",
"_inBundle": false,
"_integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=",
"_location": "/binary-extensions",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "binary-extensions@1.10.0",
"name": "binary-extensions",
"escapedName": "binary-extensions",
"rawSpec": "1.10.0",
"saveSpec": null,
"fetchSpec": "1.10.0"
},
"_requiredBy": [
"/is-binary-path"
],
"_resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz",
"_spec": "1.10.0",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/binary-extensions/issues"
},
"description": "List of binary file extensions",
"devDependencies": {
"ava": "0.16.0"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"binary-extensions.json"
],
"homepage": "https://github.com/sindresorhus/binary-extensions#readme",
"keywords": [
"bin",
"binary",
"ext",
"extensions",
"extension",
"file",
"json",
"list",
"array"
],
"license": "MIT",
"main": "binary-extensions.json",
"name": "binary-extensions",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/binary-extensions.git"
},
"scripts": {
"test": "ava"
},
"version": "1.10.0"
}

33
node_modules/binary-extensions/readme.md generated vendored Normal file
View file

@ -0,0 +1,33 @@
# binary-extensions [![Build Status](https://travis-ci.org/sindresorhus/binary-extensions.svg?branch=master)](https://travis-ci.org/sindresorhus/binary-extensions)
> List of binary file extensions
The list is just a [JSON file](binary-extensions.json) and can be used wherever.
## Install
```
$ npm install binary-extensions
```
## Usage
```js
const binaryExtensions = require('binary-extensions');
console.log(binaryExtensions);
//=> ['3ds', '3g2', …]
```
## Related
- [is-binary-path](https://github.com/sindresorhus/is-binary-path) - Check if a filepath is a binary file
- [text-extensions](https://github.com/sindresorhus/text-extensions) - List of text file extensions
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)

138
node_modules/boxen/index.js generated vendored Normal file
View file

@ -0,0 +1,138 @@
'use strict';
const stringWidth = require('string-width');
const chalk = require('chalk');
const widestLine = require('widest-line');
const cliBoxes = require('cli-boxes');
const camelCase = require('camelcase');
const ansiAlign = require('ansi-align');
const termSize = require('term-size');
const getObject = detail => {
let obj;
if (typeof detail === 'number') {
obj = {
top: detail,
right: detail * 3,
bottom: detail,
left: detail * 3
};
} else {
obj = Object.assign({
top: 0,
right: 0,
bottom: 0,
left: 0
}, detail);
}
return obj;
};
const getBorderChars = borderStyle => {
const sides = [
'topLeft',
'topRight',
'bottomRight',
'bottomLeft',
'vertical',
'horizontal'
];
let chars;
if (typeof borderStyle === 'string') {
chars = cliBoxes[borderStyle];
if (!chars) {
throw new TypeError(`Invalid border style: ${borderStyle}`);
}
} else {
sides.forEach(key => {
if (!borderStyle[key] || typeof borderStyle[key] !== 'string') {
throw new TypeError(`Invalid border style: ${key}`);
}
});
chars = borderStyle;
}
return chars;
};
const getBackgroundColorName = x => camelCase('bg', x);
module.exports = (text, opts) => {
opts = Object.assign({
padding: 0,
borderStyle: 'single',
dimBorder: false,
align: 'left',
float: 'left'
}, opts);
if (opts.backgroundColor) {
opts.backgroundColor = getBackgroundColorName(opts.backgroundColor);
}
if (opts.borderColor && !chalk[opts.borderColor]) {
throw new Error(`${opts.borderColor} is not a valid borderColor`);
}
if (opts.backgroundColor && !chalk[opts.backgroundColor]) {
throw new Error(`${opts.backgroundColor} is not a valid backgroundColor`);
}
const chars = getBorderChars(opts.borderStyle);
const padding = getObject(opts.padding);
const margin = getObject(opts.margin);
const colorizeBorder = x => {
const ret = opts.borderColor ? chalk[opts.borderColor](x) : x;
return opts.dimBorder ? chalk.dim(ret) : ret;
};
const colorizeContent = x => opts.backgroundColor ? chalk[opts.backgroundColor](x) : x;
text = ansiAlign(text, {align: opts.align});
const NL = '\n';
const PAD = ' ';
let lines = text.split(NL);
if (padding.top > 0) {
lines = Array(padding.top).fill('').concat(lines);
}
if (padding.bottom > 0) {
lines = lines.concat(Array(padding.bottom).fill(''));
}
const contentWidth = widestLine(text) + padding.left + padding.right;
const paddingLeft = PAD.repeat(padding.left);
const columns = termSize().columns;
let marginLeft = PAD.repeat(margin.left);
if (opts.float === 'center') {
const padWidth = Math.max((columns - contentWidth) / 2, 0);
marginLeft = PAD.repeat(padWidth);
} else if (opts.float === 'right') {
const padWidth = Math.max(columns - contentWidth - margin.right - 2, 0);
marginLeft = PAD.repeat(padWidth);
}
const horizontal = chars.horizontal.repeat(contentWidth);
const top = colorizeBorder(NL.repeat(margin.top) + marginLeft + chars.topLeft + horizontal + chars.topRight);
const bottom = colorizeBorder(marginLeft + chars.bottomLeft + horizontal + chars.bottomRight + NL.repeat(margin.bottom));
const side = colorizeBorder(chars.vertical);
const middle = lines.map(line => {
const paddingRight = PAD.repeat(contentWidth - stringWidth(line) - padding.left);
return marginLeft + side + colorizeContent(paddingLeft + line + paddingRight) + side;
}).join(NL);
return top + NL + middle + NL + bottom;
};
module.exports._borderStyles = cliBoxes;

9
node_modules/boxen/license generated vendored Normal file
View file

@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
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.

83
node_modules/boxen/package.json generated vendored Normal file
View file

@ -0,0 +1,83 @@
{
"_args": [
[
"boxen@1.2.2",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "boxen@1.2.2",
"_id": "boxen@1.2.2",
"_inBundle": false,
"_integrity": "sha1-Px1AMsMP/qnUsCwyLq8up0HcvOU=",
"_location": "/boxen",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "boxen@1.2.2",
"name": "boxen",
"escapedName": "boxen",
"rawSpec": "1.2.2",
"saveSpec": null,
"fetchSpec": "1.2.2"
},
"_requiredBy": [
"/update-notifier"
],
"_resolved": "https://registry.npmjs.org/boxen/-/boxen-1.2.2.tgz",
"_spec": "1.2.2",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/boxen/issues"
},
"dependencies": {
"ansi-align": "^2.0.0",
"camelcase": "^4.0.0",
"chalk": "^2.0.1",
"cli-boxes": "^1.0.0",
"string-width": "^2.0.0",
"term-size": "^1.2.0",
"widest-line": "^1.0.0"
},
"description": "Create boxes in the terminal",
"devDependencies": {
"ava": "*",
"nyc": "^11.0.3",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/sindresorhus/boxen#readme",
"keywords": [
"cli",
"box",
"boxes",
"terminal",
"term",
"console",
"ascii",
"unicode",
"border",
"text"
],
"license": "MIT",
"name": "boxen",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/boxen.git"
},
"scripts": {
"test": "xo && nyc ava"
},
"version": "1.2.2"
}

175
node_modules/boxen/readme.md generated vendored Normal file
View file

@ -0,0 +1,175 @@
# <img src="screenshot.png" width="400" alt="boxen">
> Create boxes in the terminal
[![Build Status](https://travis-ci.org/sindresorhus/boxen.svg?branch=master)](https://travis-ci.org/sindresorhus/boxen)
## Install
```
$ npm install boxen
```
## Usage
```js
const boxen = require('boxen');
console.log(boxen('unicorn', {padding: 1}));
/*
┌─────────────┐
│ │
│ unicorn │
│ │
└─────────────┘
*/
console.log(boxen('unicorn', {padding: 1, margin: 1, borderStyle: 'double'}));
/*
╔═════════════╗
║ ║
║ unicorn ║
║ ║
╚═════════════╝
*/
```
## API
### boxen(input, [options])
#### input
Type: `string`
Text inside the box.
#### options
##### borderColor
Type: `string`<br>
Values: `black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `gray`
Color of the box border.
##### borderStyle
Type: `string` `object`<br>
Default: `single`<br>
Values:
- `single`
```
┌───┐
│foo│
└───┘
```
- `double`
```
╔═══╗
║foo║
╚═══╝
```
- `round` (`single` sides with round corners)
```
╭───╮
│foo│
╰───╯
```
- `single-double` (`single` on top and bottom, `double` on right and left)
```
╓───╖
║foo║
╙───╜
```
- `double-single` (`double` on top and bottom, `single` on right and left)
```
╒═══╕
│foo│
╘═══╛
```
- `classic`
```
+---+
|foo|
+---+
```
Style of the box border.
Can be any of the above predefined styles or an object with the following keys:
```js
{
topLeft: '+',
topRight: '+',
bottomLeft: '+',
bottomRight: '+',
horizontal: '-',
vertical: '|'
}
```
##### dimBorder
Type: `boolean`<br>
Default: `false`
Reduce opacity of the border.
##### padding
Type: `number` `Object`<br>
Default: `0`
Space between the text and box border.
Accepts a number or an object with any of the `top`, `right`, `bottom`, `left` properties. When a number is specified, the left/right padding is 3 times the top/bottom to make it look nice.
##### margin
Type: `number` `Object`<br>
Default: `0`
Space around the box.
Accepts a number or an object with any of the `top`, `right`, `bottom`, `left` properties. When a number is specified, the left/right margin is 3 times the top/bottom to make it look nice.
##### float
Type: `string`<br>
Values: `right` `center` `left`<br>
Default: `left`
Float the box on the available terminal screen space.
##### backgroundColor
Type: `string`<br>
Values: `black` `red` `green` `yellow` `blue` `magenta` `cyan` `white`
Color of the background.
##### align
Type: `string`<br>
Default: `left`<br>
Values: `left` `center` `right`
Align the text in the box based on the widest line.
## Related
- [boxen-cli](https://github.com/sindresorhus/boxen-cli) - CLI for this module
- [cli-boxes](https://github.com/sindresorhus/cli-boxes) - Boxes for use in the terminal
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)

123
node_modules/brace-expansion/README.md generated vendored Normal file
View file

@ -0,0 +1,123 @@
# brace-expansion
[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html),
as known from sh/bash, in JavaScript.
[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion)
[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion)
[![Greenkeeper badge](https://badges.greenkeeper.io/juliangruber/brace-expansion.svg)](https://greenkeeper.io/)
[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion)
## Example
```js
var expand = require('brace-expansion');
expand('file-{a,b,c}.jpg')
// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg']
expand('-v{,,}')
// => ['-v', '-v', '-v']
expand('file{0..2}.jpg')
// => ['file0.jpg', 'file1.jpg', 'file2.jpg']
expand('file-{a..c}.jpg')
// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg']
expand('file{2..0}.jpg')
// => ['file2.jpg', 'file1.jpg', 'file0.jpg']
expand('file{0..4..2}.jpg')
// => ['file0.jpg', 'file2.jpg', 'file4.jpg']
expand('file-{a..e..2}.jpg')
// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg']
expand('file{00..10..5}.jpg')
// => ['file00.jpg', 'file05.jpg', 'file10.jpg']
expand('{{A..C},{a..c}}')
// => ['A', 'B', 'C', 'a', 'b', 'c']
expand('ppp{,config,oe{,conf}}')
// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf']
```
## API
```js
var expand = require('brace-expansion');
```
### var expanded = expand(str)
Return an array of all possible and valid expansions of `str`. If none are
found, `[str]` is returned.
Valid expansions are:
```js
/^(.*,)+(.+)?$/
// {a,b,...}
```
A comma seperated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`.
```js
/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
// {x..y[..incr]}
```
A numeric sequence from `x` to `y` inclusive, with optional increment.
If `x` or `y` start with a leading `0`, all the numbers will be padded
to have equal length. Negative numbers and backwards iteration work too.
```js
/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
// {x..y[..incr]}
```
An alphabetic sequence from `x` to `y` inclusive, with optional increment.
`x` and `y` must be exactly one character, and if given, `incr` must be a
number.
For compatibility reasons, the string `${` is not eligible for brace expansion.
## Installation
With [npm](https://npmjs.org) do:
```bash
npm install brace-expansion
```
## Contributors
- [Julian Gruber](https://github.com/juliangruber)
- [Isaac Z. Schlueter](https://github.com/isaacs)
## License
(MIT)
Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
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.

201
node_modules/brace-expansion/index.js generated vendored Normal file
View file

@ -0,0 +1,201 @@
var concatMap = require('concat-map');
var balanced = require('balanced-match');
module.exports = expandTop;
var escSlash = '\0SLASH'+Math.random()+'\0';
var escOpen = '\0OPEN'+Math.random()+'\0';
var escClose = '\0CLOSE'+Math.random()+'\0';
var escComma = '\0COMMA'+Math.random()+'\0';
var escPeriod = '\0PERIOD'+Math.random()+'\0';
function numeric(str) {
return parseInt(str, 10) == str
? parseInt(str, 10)
: str.charCodeAt(0);
}
function escapeBraces(str) {
return str.split('\\\\').join(escSlash)
.split('\\{').join(escOpen)
.split('\\}').join(escClose)
.split('\\,').join(escComma)
.split('\\.').join(escPeriod);
}
function unescapeBraces(str) {
return str.split(escSlash).join('\\')
.split(escOpen).join('{')
.split(escClose).join('}')
.split(escComma).join(',')
.split(escPeriod).join('.');
}
// Basically just str.split(","), but handling cases
// where we have nested braced sections, which should be
// treated as individual members, like {a,{b,c},d}
function parseCommaParts(str) {
if (!str)
return [''];
var parts = [];
var m = balanced('{', '}', str);
if (!m)
return str.split(',');
var pre = m.pre;
var body = m.body;
var post = m.post;
var p = pre.split(',');
p[p.length-1] += '{' + body + '}';
var postParts = parseCommaParts(post);
if (post.length) {
p[p.length-1] += postParts.shift();
p.push.apply(p, postParts);
}
parts.push.apply(parts, p);
return parts;
}
function expandTop(str) {
if (!str)
return [];
// I don't know why Bash 4.3 does this, but it does.
// Anything starting with {} will have the first two bytes preserved
// but *only* at the top level, so {},a}b will not expand to anything,
// but a{},b}c will be expanded to [a}c,abc].
// One could argue that this is a bug in Bash, but since the goal of
// this module is to match Bash's rules, we escape a leading {}
if (str.substr(0, 2) === '{}') {
str = '\\{\\}' + str.substr(2);
}
return expand(escapeBraces(str), true).map(unescapeBraces);
}
function identity(e) {
return e;
}
function embrace(str) {
return '{' + str + '}';
}
function isPadded(el) {
return /^-?0\d/.test(el);
}
function lte(i, y) {
return i <= y;
}
function gte(i, y) {
return i >= y;
}
function expand(str, isTop) {
var expansions = [];
var m = balanced('{', '}', str);
if (!m || /\$$/.test(m.pre)) return [str];
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
var isSequence = isNumericSequence || isAlphaSequence;
var isOptions = m.body.indexOf(',') >= 0;
if (!isSequence && !isOptions) {
// {a},b}
if (m.post.match(/,.*\}/)) {
str = m.pre + '{' + m.body + escClose + m.post;
return expand(str);
}
return [str];
}
var n;
if (isSequence) {
n = m.body.split(/\.\./);
} else {
n = parseCommaParts(m.body);
if (n.length === 1) {
// x{{a,b}}y ==> x{a}y x{b}y
n = expand(n[0], false).map(embrace);
if (n.length === 1) {
var post = m.post.length
? expand(m.post, false)
: [''];
return post.map(function(p) {
return m.pre + n[0] + p;
});
}
}
}
// at this point, n is the parts, and we know it's not a comma set
// with a single entry.
// no need to expand pre, since it is guaranteed to be free of brace-sets
var pre = m.pre;
var post = m.post.length
? expand(m.post, false)
: [''];
var N;
if (isSequence) {
var x = numeric(n[0]);
var y = numeric(n[1]);
var width = Math.max(n[0].length, n[1].length)
var incr = n.length == 3
? Math.abs(numeric(n[2]))
: 1;
var test = lte;
var reverse = y < x;
if (reverse) {
incr *= -1;
test = gte;
}
var pad = n.some(isPadded);
N = [];
for (var i = x; test(i, y); i += incr) {
var c;
if (isAlphaSequence) {
c = String.fromCharCode(i);
if (c === '\\')
c = '';
} else {
c = String(i);
if (pad) {
var need = width - c.length;
if (need > 0) {
var z = new Array(need + 1).join('0');
if (i < 0)
c = '-' + z + c.slice(1);
else
c = z + c;
}
}
}
N.push(c);
}
} else {
N = concatMap(n, function(el) { return expand(el, false) });
}
for (var j = 0; j < N.length; j++) {
for (var k = 0; k < post.length; k++) {
var expansion = pre + N[j] + post[k];
if (!isTop || isSequence || expansion)
expansions.push(expansion);
}
}
return expansions;
}

79
node_modules/brace-expansion/package.json generated vendored Normal file
View file

@ -0,0 +1,79 @@
{
"_args": [
[
"brace-expansion@1.1.8",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "brace-expansion@1.1.8",
"_id": "brace-expansion@1.1.8",
"_inBundle": false,
"_integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
"_location": "/brace-expansion",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "brace-expansion@1.1.8",
"name": "brace-expansion",
"escapedName": "brace-expansion",
"rawSpec": "1.1.8",
"saveSpec": null,
"fetchSpec": "1.1.8"
},
"_requiredBy": [
"/minimatch"
],
"_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
"_spec": "1.1.8",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Julian Gruber",
"email": "mail@juliangruber.com",
"url": "http://juliangruber.com"
},
"bugs": {
"url": "https://github.com/juliangruber/brace-expansion/issues"
},
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
},
"description": "Brace expansion as known from sh/bash",
"devDependencies": {
"matcha": "^0.7.0",
"tape": "^4.6.0"
},
"homepage": "https://github.com/juliangruber/brace-expansion",
"keywords": [],
"license": "MIT",
"main": "index.js",
"name": "brace-expansion",
"repository": {
"type": "git",
"url": "git://github.com/juliangruber/brace-expansion.git"
},
"scripts": {
"bench": "matcha test/perf/bench.js",
"gentest": "bash test/generate.sh",
"test": "tape test/*.js"
},
"testling": {
"files": "test/*.js",
"browsers": [
"ie/8..latest",
"firefox/20..latest",
"firefox/nightly",
"chrome/25..latest",
"chrome/canary",
"opera/12..latest",
"opera/next",
"safari/5.1..latest",
"ipad/6.0..latest",
"iphone/6.0..latest",
"android-browser/4.2..latest"
]
},
"version": "1.1.8"
}

21
node_modules/braces/LICENSE generated vendored Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2016, Jon Schlinkert.
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.

248
node_modules/braces/README.md generated vendored Normal file
View file

@ -0,0 +1,248 @@
# braces [![NPM version](https://img.shields.io/npm/v/braces.svg?style=flat)](https://www.npmjs.com/package/braces) [![NPM downloads](https://img.shields.io/npm/dm/braces.svg?style=flat)](https://npmjs.org/package/braces) [![Build Status](https://img.shields.io/travis/jonschlinkert/braces.svg?style=flat)](https://travis-ci.org/jonschlinkert/braces)
Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces specification.
## Install
Install with [npm](https://www.npmjs.com/):
```sh
$ npm install braces --save
```
## Features
* Complete support for the braces part of the [Bash 4.3 Brace Expansion](www.gnu.org/software/bash/). Braces passes [all of the relevant unit tests](#bash-4-3-support) from the spec.
* Expands comma-separated values: `a/{b,c}/d` => `['a/b/d', 'a/c/d']`
* Expands alphabetical or numerical ranges: `{1..3}` => `['1', '2', '3']`
* [Very fast](#benchmarks)
* [Special characters](./patterns.md) can be used to generate interesting patterns.
## Example usage
```js
var braces = require('braces');
braces('a/{x,y}/c{d}e')
//=> ['a/x/cde', 'a/y/cde']
braces('a/b/c/{x,y}')
//=> ['a/b/c/x', 'a/b/c/y']
braces('a/{x,{1..5},y}/c{d}e')
//=> ['a/x/cde', 'a/1/cde', 'a/y/cde', 'a/2/cde', 'a/3/cde', 'a/4/cde', 'a/5/cde']
```
### Use case: fixtures
> Use braces to generate test fixtures!
**Example**
```js
var braces = require('./');
var path = require('path');
var fs = require('fs');
braces('blah/{a..z}.js').forEach(function(fp) {
if (!fs.existsSync(path.dirname(fp))) {
fs.mkdirSync(path.dirname(fp));
}
fs.writeFileSync(fp, '');
});
```
See the [tests](./test/test.js) for more examples and use cases (also see the [bash spec tests](./test/bash-mm-adjusted.js));
### Range expansion
Uses [expand-range](https://github.com/jonschlinkert/expand-range) for range expansion.
```js
braces('a{1..3}b')
//=> ['a1b', 'a2b', 'a3b']
braces('a{5..8}b')
//=> ['a5b', 'a6b', 'a7b', 'a8b']
braces('a{00..05}b')
//=> ['a00b', 'a01b', 'a02b', 'a03b', 'a04b', 'a05b']
braces('a{01..03}b')
//=> ['a01b', 'a02b', 'a03b']
braces('a{000..005}b')
//=> ['a000b', 'a001b', 'a002b', 'a003b', 'a004b', 'a005b']
braces('a{a..e}b')
//=> ['aab', 'abb', 'acb', 'adb', 'aeb']
braces('a{A..E}b')
//=> ['aAb', 'aBb', 'aCb', 'aDb', 'aEb']
```
Pass a function as the last argument to customize range expansions:
```js
var range = braces('x{a..e}y', function (str, i) {
return String.fromCharCode(str) + i;
});
console.log(range);
//=> ['xa0y', 'xb1y', 'xc2y', 'xd3y', 'xe4y']
```
See [expand-range](https://github.com/jonschlinkert/expand-range) for benchmarks, tests and the full list of range expansion features.
## Options
### options.makeRe
Type: `Boolean`
Deafault: `false`
Return a regex-optimal string. If you're using braces to generate regex, this will result in dramatically faster performance.
**Examples**
With the default settings (`{makeRe: false}`):
```js
braces('{1..5}');
//=> ['1', '2', '3', '4', '5']
```
With `{makeRe: true}`:
```js
braces('{1..5}', {makeRe: true});
//=> ['[1-5]']
braces('{3..9..3}', {makeRe: true});
//=> ['(3|6|9)']
```
### options.bash
Type: `Boolean`
Default: `false`
Enables complete support for the Bash specification. The downside is a 20-25% speed decrease.
**Example**
Using the default setting (`{bash: false}`):
```js
braces('a{b}c');
//=> ['abc']
```
In bash (and minimatch), braces with one item are not expanded. To get the same result with braces, set `{bash: true}`:
```js
braces('a{b}c', {bash: true});
//=> ['a{b}c']
```
### options.nodupes
Type: `Boolean`
Deafault: `true`
Duplicates are removed by default. To keep duplicates, pass `{nodupes: false}` on the options
## Bash 4.3 Support
> Better support for Bash 4.3 than minimatch
This project has comprehensive unit tests, including tests coverted from [Bash 4.3](www.gnu.org/software/bash/). Currently only 8 of 102 unit tests fail, and
## Run benchmarks
Install dev dependencies:
```bash
npm i -d && npm benchmark
```
### Latest results
```bash
#1: escape.js
brace-expansion.js x 114,934 ops/sec ±1.24% (93 runs sampled)
braces.js x 342,254 ops/sec ±0.84% (90 runs sampled)
#2: exponent.js
brace-expansion.js x 12,359 ops/sec ±0.86% (96 runs sampled)
braces.js x 20,389 ops/sec ±0.71% (97 runs sampled)
#3: multiple.js
brace-expansion.js x 114,469 ops/sec ±1.44% (94 runs sampled)
braces.js x 401,621 ops/sec ±0.87% (91 runs sampled)
#4: nested.js
brace-expansion.js x 102,769 ops/sec ±1.55% (92 runs sampled)
braces.js x 314,088 ops/sec ±0.71% (98 runs sampled)
#5: normal.js
brace-expansion.js x 157,577 ops/sec ±1.65% (91 runs sampled)
braces.js x 1,115,950 ops/sec ±0.74% (94 runs sampled)
#6: range.js
brace-expansion.js x 138,822 ops/sec ±1.71% (91 runs sampled)
braces.js x 1,108,353 ops/sec ±0.85% (94 runs sampled)
```
## Related projects
You might also be interested in these projects:
* [expand-range](https://www.npmjs.com/package/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See… [more](https://www.npmjs.com/package/expand-range) | [homepage](https://github.com/jonschlinkert/expand-range)
* [fill-range](https://www.npmjs.com/package/fill-range): Fill in a range of numbers or letters, optionally passing an increment or multiplier to… [more](https://www.npmjs.com/package/fill-range) | [homepage](https://github.com/jonschlinkert/fill-range)
* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. | [homepage](https://github.com/jonschlinkert/micromatch)
## Contributing
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/braces/issues/new).
## Building docs
Generate readme and API documentation with [verb](https://github.com/verbose/verb):
```sh
$ npm install verb && npm run docs
```
Or, if [verb](https://github.com/verbose/verb) is installed globally:
```sh
$ verb
```
## Running tests
Install dev dependencies:
```sh
$ npm install -d && npm test
```
## Author
**Jon Schlinkert**
* [github/jonschlinkert](https://github.com/jonschlinkert)
* [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
## License
Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert).
Released under the [MIT license](https://github.com/jonschlinkert/braces/blob/master/LICENSE).
***
_This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on May 21, 2016._

399
node_modules/braces/index.js generated vendored Normal file
View file

@ -0,0 +1,399 @@
/*!
* braces <https://github.com/jonschlinkert/braces>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT license.
*/
'use strict';
/**
* Module dependencies
*/
var expand = require('expand-range');
var repeat = require('repeat-element');
var tokens = require('preserve');
/**
* Expose `braces`
*/
module.exports = function(str, options) {
if (typeof str !== 'string') {
throw new Error('braces expects a string');
}
return braces(str, options);
};
/**
* Expand `{foo,bar}` or `{1..5}` braces in the
* given `string`.
*
* @param {String} `str`
* @param {Array} `arr`
* @param {Object} `options`
* @return {Array}
*/
function braces(str, arr, options) {
if (str === '') {
return [];
}
if (!Array.isArray(arr)) {
options = arr;
arr = [];
}
var opts = options || {};
arr = arr || [];
if (typeof opts.nodupes === 'undefined') {
opts.nodupes = true;
}
var fn = opts.fn;
var es6;
if (typeof opts === 'function') {
fn = opts;
opts = {};
}
if (!(patternRe instanceof RegExp)) {
patternRe = patternRegex();
}
var matches = str.match(patternRe) || [];
var m = matches[0];
switch(m) {
case '\\,':
return escapeCommas(str, arr, opts);
case '\\.':
return escapeDots(str, arr, opts);
case '\/.':
return escapePaths(str, arr, opts);
case ' ':
return splitWhitespace(str);
case '{,}':
return exponential(str, opts, braces);
case '{}':
return emptyBraces(str, arr, opts);
case '\\{':
case '\\}':
return escapeBraces(str, arr, opts);
case '${':
if (!/\{[^{]+\{/.test(str)) {
return arr.concat(str);
} else {
es6 = true;
str = tokens.before(str, es6Regex());
}
}
if (!(braceRe instanceof RegExp)) {
braceRe = braceRegex();
}
var match = braceRe.exec(str);
if (match == null) {
return [str];
}
var outter = match[1];
var inner = match[2];
if (inner === '') { return [str]; }
var segs, segsLength;
if (inner.indexOf('..') !== -1) {
segs = expand(inner, opts, fn) || inner.split(',');
segsLength = segs.length;
} else if (inner[0] === '"' || inner[0] === '\'') {
return arr.concat(str.split(/['"]/).join(''));
} else {
segs = inner.split(',');
if (opts.makeRe) {
return braces(str.replace(outter, wrap(segs, '|')), opts);
}
segsLength = segs.length;
if (segsLength === 1 && opts.bash) {
segs[0] = wrap(segs[0], '\\');
}
}
var len = segs.length;
var i = 0, val;
while (len--) {
var path = segs[i++];
if (/(\.[^.\/])/.test(path)) {
if (segsLength > 1) {
return segs;
} else {
return [str];
}
}
val = splice(str, outter, path);
if (/\{[^{}]+?\}/.test(val)) {
arr = braces(val, arr, opts);
} else if (val !== '') {
if (opts.nodupes && arr.indexOf(val) !== -1) { continue; }
arr.push(es6 ? tokens.after(val) : val);
}
}
if (opts.strict) { return filter(arr, filterEmpty); }
return arr;
}
/**
* Expand exponential ranges
*
* `a{,}{,}` => ['a', 'a', 'a', 'a']
*/
function exponential(str, options, fn) {
if (typeof options === 'function') {
fn = options;
options = null;
}
var opts = options || {};
var esc = '__ESC_EXP__';
var exp = 0;
var res;
var parts = str.split('{,}');
if (opts.nodupes) {
return fn(parts.join(''), opts);
}
exp = parts.length - 1;
res = fn(parts.join(esc), opts);
var len = res.length;
var arr = [];
var i = 0;
while (len--) {
var ele = res[i++];
var idx = ele.indexOf(esc);
if (idx === -1) {
arr.push(ele);
} else {
ele = ele.split('__ESC_EXP__').join('');
if (!!ele && opts.nodupes !== false) {
arr.push(ele);
} else {
var num = Math.pow(2, exp);
arr.push.apply(arr, repeat(ele, num));
}
}
}
return arr;
}
/**
* Wrap a value with parens, brackets or braces,
* based on the given character/separator.
*
* @param {String|Array} `val`
* @param {String} `ch`
* @return {String}
*/
function wrap(val, ch) {
if (ch === '|') {
return '(' + val.join(ch) + ')';
}
if (ch === ',') {
return '{' + val.join(ch) + '}';
}
if (ch === '-') {
return '[' + val.join(ch) + ']';
}
if (ch === '\\') {
return '\\{' + val + '\\}';
}
}
/**
* Handle empty braces: `{}`
*/
function emptyBraces(str, arr, opts) {
return braces(str.split('{}').join('\\{\\}'), arr, opts);
}
/**
* Filter out empty-ish values
*/
function filterEmpty(ele) {
return !!ele && ele !== '\\';
}
/**
* Handle patterns with whitespace
*/
function splitWhitespace(str) {
var segs = str.split(' ');
var len = segs.length;
var res = [];
var i = 0;
while (len--) {
res.push.apply(res, braces(segs[i++]));
}
return res;
}
/**
* Handle escaped braces: `\\{foo,bar}`
*/
function escapeBraces(str, arr, opts) {
if (!/\{[^{]+\{/.test(str)) {
return arr.concat(str.split('\\').join(''));
} else {
str = str.split('\\{').join('__LT_BRACE__');
str = str.split('\\}').join('__RT_BRACE__');
return map(braces(str, arr, opts), function(ele) {
ele = ele.split('__LT_BRACE__').join('{');
return ele.split('__RT_BRACE__').join('}');
});
}
}
/**
* Handle escaped dots: `{1\\.2}`
*/
function escapeDots(str, arr, opts) {
if (!/[^\\]\..+\\\./.test(str)) {
return arr.concat(str.split('\\').join(''));
} else {
str = str.split('\\.').join('__ESC_DOT__');
return map(braces(str, arr, opts), function(ele) {
return ele.split('__ESC_DOT__').join('.');
});
}
}
/**
* Handle escaped dots: `{1\\.2}`
*/
function escapePaths(str, arr, opts) {
str = str.split('\/.').join('__ESC_PATH__');
return map(braces(str, arr, opts), function(ele) {
return ele.split('__ESC_PATH__').join('\/.');
});
}
/**
* Handle escaped commas: `{a\\,b}`
*/
function escapeCommas(str, arr, opts) {
if (!/\w,/.test(str)) {
return arr.concat(str.split('\\').join(''));
} else {
str = str.split('\\,').join('__ESC_COMMA__');
return map(braces(str, arr, opts), function(ele) {
return ele.split('__ESC_COMMA__').join(',');
});
}
}
/**
* Regex for common patterns
*/
function patternRegex() {
return /\${|( (?=[{,}])|(?=[{,}]) )|{}|{,}|\\,(?=.*[{}])|\/\.(?=.*[{}])|\\\.(?={)|\\{|\\}/;
}
/**
* Braces regex.
*/
function braceRegex() {
return /.*(\\?\{([^}]+)\})/;
}
/**
* es6 delimiter regex.
*/
function es6Regex() {
return /\$\{([^}]+)\}/;
}
var braceRe;
var patternRe;
/**
* Faster alternative to `String.replace()` when the
* index of the token to be replaces can't be supplied
*/
function splice(str, token, replacement) {
var i = str.indexOf(token);
return str.substr(0, i) + replacement
+ str.substr(i + token.length);
}
/**
* Fast array map
*/
function map(arr, fn) {
if (arr == null) {
return [];
}
var len = arr.length;
var res = new Array(len);
var i = -1;
while (++i < len) {
res[i] = fn(arr[i], i, arr);
}
return res;
}
/**
* Fast array filter
*/
function filter(arr, cb) {
if (arr == null) return [];
if (typeof cb !== 'function') {
throw new TypeError('braces: filter expects a callback function.');
}
var len = arr.length;
var res = arr.slice();
var i = 0;
while (len--) {
if (!cb(arr[len], i++)) {
res.splice(len, 1);
}
}
return res;
}

118
node_modules/braces/package.json generated vendored Normal file
View file

@ -0,0 +1,118 @@
{
"_args": [
[
"braces@1.8.5",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "braces@1.8.5",
"_id": "braces@1.8.5",
"_inBundle": false,
"_integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
"_location": "/braces",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "braces@1.8.5",
"name": "braces",
"escapedName": "braces",
"rawSpec": "1.8.5",
"saveSpec": null,
"fetchSpec": "1.8.5"
},
"_requiredBy": [
"/micromatch"
],
"_resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
"_spec": "1.8.5",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Jon Schlinkert",
"url": "https://github.com/jonschlinkert"
},
"bugs": {
"url": "https://github.com/jonschlinkert/braces/issues"
},
"dependencies": {
"expand-range": "^1.8.1",
"preserve": "^0.2.0",
"repeat-element": "^1.1.2"
},
"description": "Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces specification.",
"devDependencies": {
"benchmarked": "^0.1.5",
"brace-expansion": "^1.1.3",
"chalk": "^1.1.3",
"gulp-format-md": "^0.1.8",
"minimatch": "^3.0.0",
"minimist": "^1.2.0",
"mocha": "^2.4.5",
"should": "^8.3.1"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/jonschlinkert/braces",
"keywords": [
"alpha",
"alphabetical",
"bash",
"brace",
"expand",
"expansion",
"filepath",
"fill",
"fs",
"glob",
"globbing",
"letter",
"match",
"matches",
"matching",
"number",
"numerical",
"path",
"range",
"ranges",
"sh"
],
"license": "MIT",
"main": "index.js",
"name": "braces",
"repository": {
"type": "git",
"url": "git+https://github.com/jonschlinkert/braces.git"
},
"scripts": {
"test": "mocha"
},
"verb": {
"plugins": [
"gulp-format-md"
],
"reflinks": [
"verb"
],
"toc": false,
"layout": "default",
"lint": {
"reflinks": true
},
"tasks": [
"readme"
],
"related": {
"list": [
"micromatch",
"expand-range",
"fill-range"
]
}
},
"version": "1.8.5"
}

64
node_modules/camelcase/index.js generated vendored Normal file
View file

@ -0,0 +1,64 @@
'use strict';
function preserveCamelCase(str) {
let isLastCharLower = false;
let isLastCharUpper = false;
let isLastLastCharUpper = false;
for (let i = 0; i < str.length; i++) {
const c = str[i];
if (isLastCharLower && /[a-zA-Z]/.test(c) && c.toUpperCase() === c) {
str = str.substr(0, i) + '-' + str.substr(i);
isLastCharLower = false;
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = true;
i++;
} else if (isLastCharUpper && isLastLastCharUpper && /[a-zA-Z]/.test(c) && c.toLowerCase() === c) {
str = str.substr(0, i - 1) + '-' + str.substr(i - 1);
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = false;
isLastCharLower = true;
} else {
isLastCharLower = c.toLowerCase() === c;
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = c.toUpperCase() === c;
}
}
return str;
}
module.exports = function (str) {
if (arguments.length > 1) {
str = Array.from(arguments)
.map(x => x.trim())
.filter(x => x.length)
.join('-');
} else {
str = str.trim();
}
if (str.length === 0) {
return '';
}
if (str.length === 1) {
return str.toLowerCase();
}
if (/^[a-z0-9]+$/.test(str)) {
return str;
}
const hasUpperCase = str !== str.toLowerCase();
if (hasUpperCase) {
str = preserveCamelCase(str);
}
return str
.replace(/^[_.\- ]+/, '')
.toLowerCase()
.replace(/[_.\- ]+(\w|$)/g, (m, p1) => p1.toUpperCase());
};

21
node_modules/camelcase/license generated vendored Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
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.

78
node_modules/camelcase/package.json generated vendored Normal file
View file

@ -0,0 +1,78 @@
{
"_args": [
[
"camelcase@4.1.0",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "camelcase@4.1.0",
"_id": "camelcase@4.1.0",
"_inBundle": false,
"_integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
"_location": "/camelcase",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "camelcase@4.1.0",
"name": "camelcase",
"escapedName": "camelcase",
"rawSpec": "4.1.0",
"saveSpec": null,
"fetchSpec": "4.1.0"
},
"_requiredBy": [
"/boxen"
],
"_resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
"_spec": "4.1.0",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/camelcase/issues"
},
"description": "Convert a dash/dot/underscore/space separated string to camelCase: foo-bar → fooBar",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/sindresorhus/camelcase#readme",
"keywords": [
"camelcase",
"camel-case",
"camel",
"case",
"dash",
"hyphen",
"dot",
"underscore",
"separator",
"string",
"text",
"convert"
],
"license": "MIT",
"name": "camelcase",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/camelcase.git"
},
"scripts": {
"test": "xo && ava"
},
"version": "4.1.0",
"xo": {
"esnext": true
}
}

57
node_modules/camelcase/readme.md generated vendored Normal file
View file

@ -0,0 +1,57 @@
# camelcase [![Build Status](https://travis-ci.org/sindresorhus/camelcase.svg?branch=master)](https://travis-ci.org/sindresorhus/camelcase)
> Convert a dash/dot/underscore/space separated string to camelCase: `foo-bar``fooBar`
## Install
```
$ npm install --save camelcase
```
## Usage
```js
const camelCase = require('camelcase');
camelCase('foo-bar');
//=> 'fooBar'
camelCase('foo_bar');
//=> 'fooBar'
camelCase('Foo-Bar');
//=> 'fooBar'
camelCase('--foo.bar');
//=> 'fooBar'
camelCase('__foo__bar__');
//=> 'fooBar'
camelCase('foo bar');
//=> 'fooBar'
console.log(process.argv[3]);
//=> '--foo-bar'
camelCase(process.argv[3]);
//=> 'fooBar'
camelCase('foo', 'bar');
//=> 'fooBar'
camelCase('__foo__', '--bar');
//=> 'fooBar'
```
## Related
- [decamelize](https://github.com/sindresorhus/decamelize) - The inverse of this module
- [uppercamelcase](https://github.com/SamVerschueren/uppercamelcase) - Like this module, but to PascalCase instead of camelCase
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)

18
node_modules/capture-stack-trace/index.js generated vendored Normal file
View file

@ -0,0 +1,18 @@
'use strict';
module.exports = Error.captureStackTrace || function (error) {
var container = new Error();
Object.defineProperty(error, 'stack', {
configurable: true,
get: function getStack() {
var stack = container.stack;
Object.defineProperty(this, 'stack', {
value: stack
});
return stack;
}
});
};

65
node_modules/capture-stack-trace/package.json generated vendored Normal file
View file

@ -0,0 +1,65 @@
{
"_args": [
[
"capture-stack-trace@1.0.0",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "capture-stack-trace@1.0.0",
"_id": "capture-stack-trace@1.0.0",
"_inBundle": false,
"_integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=",
"_location": "/capture-stack-trace",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "capture-stack-trace@1.0.0",
"name": "capture-stack-trace",
"escapedName": "capture-stack-trace",
"rawSpec": "1.0.0",
"saveSpec": null,
"fetchSpec": "1.0.0"
},
"_requiredBy": [
"/create-error-class"
],
"_resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz",
"_spec": "1.0.0",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"author": {
"name": "Vsevolod Strukchinsky",
"email": "floatdrop@gmail.com",
"url": "github.com/floatdrop"
},
"bugs": {
"url": "https://github.com/floatdrop/capture-stack-trace/issues"
},
"dependencies": {},
"description": "Error.captureStackTrace ponyfill",
"devDependencies": {
"mocha": "*"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/floatdrop/capture-stack-trace#readme",
"keywords": [
"Error",
"captureStackTrace"
],
"license": "MIT",
"name": "capture-stack-trace",
"repository": {
"type": "git",
"url": "git+https://github.com/floatdrop/capture-stack-trace.git"
},
"scripts": {
"test": "mocha"
},
"version": "1.0.0"
}

36
node_modules/capture-stack-trace/readme.md generated vendored Normal file
View file

@ -0,0 +1,36 @@
# capture-stack-trace [![Build Status](https://travis-ci.org/floatdrop/capture-stack-trace.svg?branch=master)](https://travis-ci.org/floatdrop/capture-stack-trace)
> Ponyfill for Error.captureStackTrace
## Install
```
$ npm install --save capture-stack-trace
```
## Usage
```js
var captureStackTrace = require('capture-stack-trace');
captureStackTrace({});
// => {stack: ...}
```
## API
### captureStackTrace(error)
#### error
*Required*
Type: `Object`
Target Object, that will recieve stack property.
## License
MIT © [Vsevolod Strukchinsky](http://github.com/floatdrop)

228
node_modules/chalk/index.js generated vendored Normal file
View file

@ -0,0 +1,228 @@
'use strict';
const escapeStringRegexp = require('escape-string-regexp');
const ansiStyles = require('ansi-styles');
const supportsColor = require('supports-color');
const template = require('./templates.js');
const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm');
// `supportsColor.level` → `ansiStyles.color[name]` mapping
const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m'];
// `color-convert` models to exclude from the Chalk API due to conflicts and such
const skipModels = new Set(['gray']);
const styles = Object.create(null);
function applyOptions(obj, options) {
options = options || {};
// Detect level if not set manually
const scLevel = supportsColor ? supportsColor.level : 0;
obj.level = options.level === undefined ? scLevel : options.level;
obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0;
}
function Chalk(options) {
// We check for this.template here since calling `chalk.constructor()`
// by itself will have a `this` of a previously constructed chalk object
if (!this || !(this instanceof Chalk) || this.template) {
const chalk = {};
applyOptions(chalk, options);
chalk.template = function () {
const args = [].slice.call(arguments);
return chalkTag.apply(null, [chalk.template].concat(args));
};
Object.setPrototypeOf(chalk, Chalk.prototype);
Object.setPrototypeOf(chalk.template, chalk);
chalk.template.constructor = Chalk;
return chalk.template;
}
applyOptions(this, options);
}
// Use bright blue on Windows as the normal blue color is illegible
if (isSimpleWindowsTerm) {
ansiStyles.blue.open = '\u001B[94m';
}
for (const key of Object.keys(ansiStyles)) {
ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
styles[key] = {
get() {
const codes = ansiStyles[key];
return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key);
}
};
}
styles.visible = {
get() {
return build.call(this, this._styles || [], true, 'visible');
}
};
ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g');
for (const model of Object.keys(ansiStyles.color.ansi)) {
if (skipModels.has(model)) {
continue;
}
styles[model] = {
get() {
const level = this.level;
return function () {
const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments);
const codes = {
open,
close: ansiStyles.color.close,
closeRe: ansiStyles.color.closeRe
};
return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
};
}
};
}
ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g');
for (const model of Object.keys(ansiStyles.bgColor.ansi)) {
if (skipModels.has(model)) {
continue;
}
const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
styles[bgModel] = {
get() {
const level = this.level;
return function () {
const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments);
const codes = {
open,
close: ansiStyles.bgColor.close,
closeRe: ansiStyles.bgColor.closeRe
};
return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
};
}
};
}
const proto = Object.defineProperties(() => {}, styles);
function build(_styles, _empty, key) {
const builder = function () {
return applyStyle.apply(builder, arguments);
};
builder._styles = _styles;
builder._empty = _empty;
const self = this;
Object.defineProperty(builder, 'level', {
enumerable: true,
get() {
return self.level;
},
set(level) {
self.level = level;
}
});
Object.defineProperty(builder, 'enabled', {
enumerable: true,
get() {
return self.enabled;
},
set(enabled) {
self.enabled = enabled;
}
});
// See below for fix regarding invisible grey/dim combination on Windows
builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey';
// `__proto__` is used because we must return a function, but there is
// no way to create a function with a different prototype
builder.__proto__ = proto; // eslint-disable-line no-proto
return builder;
}
function applyStyle() {
// Support varags, but simply cast to string in case there's only one arg
const args = arguments;
const argsLen = args.length;
let str = String(arguments[0]);
if (argsLen === 0) {
return '';
}
if (argsLen > 1) {
// Don't slice `arguments`, it prevents V8 optimizations
for (let a = 1; a < argsLen; a++) {
str += ' ' + args[a];
}
}
if (!this.enabled || this.level <= 0 || !str) {
return this._empty ? '' : str;
}
// Turns out that on Windows dimmed gray text becomes invisible in cmd.exe,
// see https://github.com/chalk/chalk/issues/58
// If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop.
const originalDim = ansiStyles.dim.open;
if (isSimpleWindowsTerm && this.hasGrey) {
ansiStyles.dim.open = '';
}
for (const code of this._styles.slice().reverse()) {
// Replace any instances already present with a re-opening code
// otherwise only the part of the string until said closing code
// will be colored, and the rest will simply be 'plain'.
str = code.open + str.replace(code.closeRe, code.open) + code.close;
// Close the styling before a linebreak and reopen
// after next line to fix a bleed issue on macOS
// https://github.com/chalk/chalk/pull/92
str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`);
}
// Reset the original `dim` if we changed it to work around the Windows dimmed gray issue
ansiStyles.dim.open = originalDim;
return str;
}
function chalkTag(chalk, strings) {
if (!Array.isArray(strings)) {
// If chalk() was called by itself or with a string,
// return the string itself as a string.
return [].slice.call(arguments, 1).join(' ');
}
const args = [].slice.call(arguments, 2);
const parts = [strings.raw[0]];
for (let i = 1; i < strings.length; i++) {
parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&'));
parts.push(String(strings.raw[i]));
}
return template(chalk, parts.join(''));
}
Object.defineProperties(Chalk.prototype, styles);
module.exports = Chalk(); // eslint-disable-line new-cap
module.exports.supportsColor = supportsColor;
module.exports.default = module.exports; // For TypeScript

9
node_modules/chalk/license generated vendored Normal file
View file

@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
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.

103
node_modules/chalk/package.json generated vendored Normal file
View file

@ -0,0 +1,103 @@
{
"_args": [
[
"chalk@2.3.0",
"/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server"
]
],
"_development": true,
"_from": "chalk@2.3.0",
"_id": "chalk@2.3.0",
"_inBundle": false,
"_integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
"_location": "/chalk",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "chalk@2.3.0",
"name": "chalk",
"escapedName": "chalk",
"rawSpec": "2.3.0",
"saveSpec": null,
"fetchSpec": "2.3.0"
},
"_requiredBy": [
"/boxen",
"/update-notifier"
],
"_resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
"_spec": "2.3.0",
"_where": "/Users/rodrigopinto/Documents/Development/ClusterSystems/cluster-server",
"bugs": {
"url": "https://github.com/chalk/chalk/issues"
},
"dependencies": {
"ansi-styles": "^3.1.0",
"escape-string-regexp": "^1.0.5",
"supports-color": "^4.0.0"
},
"description": "Terminal string styling done right",
"devDependencies": {
"ava": "*",
"coveralls": "^3.0.0",
"execa": "^0.8.0",
"import-fresh": "^2.0.0",
"matcha": "^0.7.0",
"nyc": "^11.0.2",
"resolve-from": "^4.0.0",
"typescript": "^2.5.3",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js",
"templates.js",
"types/index.d.ts"
],
"homepage": "https://github.com/chalk/chalk#readme",
"keywords": [
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"str",
"ansi",
"style",
"styles",
"tty",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text"
],
"license": "MIT",
"name": "chalk",
"repository": {
"type": "git",
"url": "git+https://github.com/chalk/chalk.git"
},
"scripts": {
"bench": "matcha benchmark.js",
"coveralls": "nyc report --reporter=text-lcov | coveralls",
"test": "xo && tsc --project types && nyc ava"
},
"types": "types/index.d.ts",
"version": "2.3.0",
"xo": {
"envs": [
"node",
"mocha"
]
}
}

309
node_modules/chalk/readme.md generated vendored Normal file
View file

@ -0,0 +1,309 @@
<h1 align="center">
<br>
<br>
<img width="320" src="https://cdn.rawgit.com/chalk/chalk/19935d6484811c5e468817f846b7b3d417d7bf4a/logo.svg" alt="chalk">
<br>
<br>
<br>
</h1>
> Terminal string styling done right
[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) [![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs)
### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0)
![](https://github.com/chalk/ansi-styles/raw/master/screenshot.png)
## Highlights
- Expressive API
- Highly performant
- Ability to nest styles
- [256/Truecolor color support](#256-and-truecolor-color-support)
- Auto-detects color support
- Doesn't extend `String.prototype`
- Clean and focused
- Actively maintained
- [Used by ~17,000 packages](https://www.npmjs.com/browse/depended/chalk) as of June 20th, 2017
## Install
```console
$ npm install chalk
```
## Usage
```js
const chalk = require('chalk');
console.log(chalk.blue('Hello world!'));
```
Chalk comes with an easy to use composable API where you just chain and nest the styles you want.
```js
const chalk = require('chalk');
const log = console.log;
// Combine styled and normal strings
log(chalk.blue('Hello') + 'World' + chalk.red('!'));
// Compose multiple styles using the chainable API
log(chalk.blue.bgRed.bold('Hello world!'));
// Pass in multiple arguments
log(chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz'));
// Nest styles
log(chalk.red('Hello', chalk.underline.bgBlue('world') + '!'));
// Nest styles of the same type even (color, underline, background)
log(chalk.green(
'I am a green line ' +
chalk.blue.underline.bold('with a blue substring') +
' that becomes green again!'
));
// ES2015 template literal
log(`
CPU: ${chalk.red('90%')}
RAM: ${chalk.green('40%')}
DISK: ${chalk.yellow('70%')}
`);
// ES2015 tagged template literal
log(chalk`
CPU: {red ${cpu.totalPercent}%}
RAM: {green ${ram.used / ram.total * 100}%}
DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%}
`);
// Use RGB colors in terminal emulators that support it.
log(chalk.keyword('orange')('Yay for orange colored text!'));
log(chalk.rgb(123, 45, 67).underline('Underlined reddish color'));
log(chalk.hex('#DEADED').bold('Bold gray!'));
```
Easily define your own themes:
```js
const chalk = require('chalk');
const error = chalk.bold.red;
const warning = chalk.keyword('orange');
console.log(error('Error!'));
console.log(warning('Warning!'));
```
Take advantage of console.log [string substitution](https://nodejs.org/docs/latest/api/console.html#console_console_log_data_args):
```js
const name = 'Sindre';
console.log(chalk.green('Hello %s'), name);
//=> 'Hello Sindre'
```
## API
### chalk.`<style>[.<style>...](string, [string...])`
Example: `chalk.red.bold.underline('Hello', 'world');`
Chain [styles](#styles) and call the last one as a method with a string argument. Order doesn't matter, and later styles take precedent in case of a conflict. This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`.
Multiple arguments will be separated by space.
### chalk.enabled
Color support is automatically detected, as is the level (see `chalk.level`). However, if you'd like to simply enable/disable Chalk, you can do so via the `.enabled` property.
Chalk is enabled by default unless expicitly disabled via the constructor or `chalk.level` is `0`.
If you need to change this in a reusable module, create a new instance:
```js
const ctx = new chalk.constructor({enabled: false});
```
### chalk.level
Color support is automatically detected, but you can override it by setting the `level` property. You should however only do this in your own code as it applies globally to all Chalk consumers.
If you need to change this in a reusable module, create a new instance:
```js
const ctx = new chalk.constructor({level: 0});
```
Levels are as follows:
0. All colors disabled
1. Basic color support (16 colors)
2. 256 color support
3. Truecolor support (16 million colors)
### chalk.supportsColor
Detect whether the terminal [supports color](https://github.com/chalk/supports-color). Used internally and handled for you, but exposed for convenience.
Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, add the environment variable `FORCE_COLOR=1` to forcefully enable color or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks.
Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively.
## Styles
### Modifiers
- `reset`
- `bold`
- `dim`
- `italic` *(Not widely supported)*
- `underline`
- `inverse`
- `hidden`
- `strikethrough` *(Not widely supported)*
- `visible` (Text is emitted only if enabled)
### Colors
- `black`
- `red`
- `green`
- `yellow`
- `blue` *(On Windows the bright version is used since normal blue is illegible)*
- `magenta`
- `cyan`
- `white`
- `gray` ("bright black")
- `redBright`
- `greenBright`
- `yellowBright`
- `blueBright`
- `magentaBright`
- `cyanBright`
- `whiteBright`
### Background colors
- `bgBlack`
- `bgRed`
- `bgGreen`
- `bgYellow`
- `bgBlue`
- `bgMagenta`
- `bgCyan`
- `bgWhite`
- `bgBlackBright`
- `bgRedBright`
- `bgGreenBright`
- `bgYellowBright`
- `bgBlueBright`
- `bgMagentaBright`
- `bgCyanBright`
- `bgWhiteBright`
## Tagged template literal
Chalk can be used as a [tagged template literal](http://exploringjs.com/es6/ch_template-literals.html#_tagged-template-literals).
```js
const chalk = require('chalk');
const miles = 18;
const calculateFeet = miles => miles * 5280;
console.log(chalk`
There are {bold 5280 feet} in a mile.
In {bold ${miles} miles}, there are {green.bold ${calculateFeet(miles)} feet}.
`);
```
Blocks are delimited by an opening curly brace (`{`), a style, some content, and a closing curly brace (`}`).
Template styles are chained exactly like normal Chalk styles. The following two statements are equivalent:
```js
console.log(chalk.bold.rgb(10, 100, 200)('Hello!'));
console.log(chalk`{bold.rgb(10,100,200) Hello!}`);
```
Note that function styles (`rgb()`, `hsl()`, `keyword()`, etc.) may not contain spaces between parameters.
All interpolated values (`` chalk`${foo}` ``) are converted to strings via the `.toString()` method. All curly braces (`{` and `}`) in interpolated value strings are escaped.
## 256 and Truecolor color support
Chalk supports 256 colors and [Truecolor](https://gist.github.com/XVilka/8346728) (16 million colors) on supported terminal apps.
Colors are downsampled from 16 million RGB values to an ANSI color format that is supported by the terminal emulator (or by specifying `{level: n}` as a Chalk option). For example, Chalk configured to run at level 1 (basic color support) will downsample an RGB value of #FF0000 (red) to 31 (ANSI escape for red).
Examples:
- `chalk.hex('#DEADED').underline('Hello, world!')`
- `chalk.keyword('orange')('Some orange text')`
- `chalk.rgb(15, 100, 204).inverse('Hello!')`
Background versions of these models are prefixed with `bg` and the first level of the module capitalized (e.g. `keyword` for foreground colors and `bgKeyword` for background colors).
- `chalk.bgHex('#DEADED').underline('Hello, world!')`
- `chalk.bgKeyword('orange')('Some orange text')`
- `chalk.bgRgb(15, 100, 204).inverse('Hello!')`
The following color models can be used:
- [`rgb`](https://en.wikipedia.org/wiki/RGB_color_model) - Example: `chalk.rgb(255, 136, 0).bold('Orange!')`
- [`hex`](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet) - Example: `chalk.hex('#FF8800').bold('Orange!')`
- [`keyword`](https://www.w3.org/wiki/CSS/Properties/color/keywords) (CSS keywords) - Example: `chalk.keyword('orange').bold('Orange!')`
- [`hsl`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsl(32, 100, 50).bold('Orange!')`
- [`hsv`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsl(32, 1, 1).bold('Orange!')`
- [`hwb`](https://en.wikipedia.org/wiki/HWB_color_model) - Example: `chalk.hsl(32, 0, 50).bold('Orange!')`
- `ansi16`
- `ansi256`
## Windows
If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) instead of `cmd.exe`.
## Origin story
[colors.js](https://github.com/Marak/colors.js) used to be the most popular string styling module, but it has serious deficiencies like extending `String.prototype` which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68) and the package is unmaintained. Although there are other packages, they either do too much or not enough. Chalk is a clean and focused alternative.
## Related
- [chalk-cli](https://github.com/chalk/chalk-cli) - CLI for this module
- [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal
- [supports-color](https://github.com/chalk/supports-color) - Detect whether a terminal supports color
- [strip-ansi](https://github.com/chalk/strip-ansi) - Strip ANSI escape codes
- [strip-ansi-stream](https://github.com/chalk/strip-ansi-stream) - Strip ANSI escape codes from a stream
- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes
- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes
- [wrap-ansi](https://github.com/chalk/wrap-ansi) - Wordwrap a string with ANSI escape codes
- [slice-ansi](https://github.com/chalk/slice-ansi) - Slice a string with ANSI escape codes
- [color-convert](https://github.com/qix-/color-convert) - Converts colors between different models
- [chalk-animation](https://github.com/bokub/chalk-animation) - Animate strings in the terminal
- [gradient-string](https://github.com/bokub/gradient-string) - Apply color gradients to strings
- [chalk-pipe](https://github.com/LitoMore/chalk-pipe) - Create chalk style schemes with simpler style strings
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)
## License
MIT

128
node_modules/chalk/templates.js generated vendored Normal file
View file

@ -0,0 +1,128 @@
'use strict';
const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi;
const ESCAPES = new Map([
['n', '\n'],
['r', '\r'],
['t', '\t'],
['b', '\b'],
['f', '\f'],
['v', '\v'],
['0', '\0'],
['\\', '\\'],
['e', '\u001B'],
['a', '\u0007']
]);
function unescape(c) {
if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) {
return String.fromCharCode(parseInt(c.slice(1), 16));
}
return ESCAPES.get(c) || c;
}
function parseArguments(name, args) {
const results = [];
const chunks = args.trim().split(/\s*,\s*/g);
let matches;
for (const chunk of chunks) {
if (!isNaN(chunk)) {
results.push(Number(chunk));
} else if ((matches = chunk.match(STRING_REGEX))) {
results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr));
} else {
throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
}
}
return results;
}
function parseStyle(style) {
STYLE_REGEX.lastIndex = 0;
const results = [];
let matches;
while ((matches = STYLE_REGEX.exec(style)) !== null) {
const name = matches[1];
if (matches[2]) {
const args = parseArguments(name, matches[2]);
results.push([name].concat(args));
} else {
results.push([name]);
}
}
return results;
}
function buildStyle(chalk, styles) {
const enabled = {};
for (const layer of styles) {
for (const style of layer.styles) {
enabled[style[0]] = layer.inverse ? null : style.slice(1);
}
}
let current = chalk;
for (const styleName of Object.keys(enabled)) {
if (Array.isArray(enabled[styleName])) {
if (!(styleName in current)) {
throw new Error(`Unknown Chalk style: ${styleName}`);
}
if (enabled[styleName].length > 0) {
current = current[styleName].apply(current, enabled[styleName]);
} else {
current = current[styleName];
}
}
}
return current;
}
module.exports = (chalk, tmp) => {
const styles = [];
const chunks = [];
let chunk = [];
// eslint-disable-next-line max-params
tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => {
if (escapeChar) {
chunk.push(unescape(escapeChar));
} else if (style) {
const str = chunk.join('');
chunk = [];
chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str));
styles.push({inverse, styles: parseStyle(style)});
} else if (close) {
if (styles.length === 0) {
throw new Error('Found extraneous } in Chalk template literal');
}
chunks.push(buildStyle(chalk, styles)(chunk.join('')));
chunk = [];
styles.pop();
} else {
chunk.push(chr);
}
});
chunks.push(chunk.join(''));
if (styles.length > 0) {
const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`;
throw new Error(errMsg);
}
return chunks.join('');
};

97
node_modules/chalk/types/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,97 @@
// Type definitions for Chalk
// Definitions by: Thomas Sauer <https://github.com/t-sauer>
export const enum Level {
None = 0,
Basic = 1,
Ansi256 = 2,
TrueColor = 3
}
export interface ChalkOptions {
enabled?: boolean;
level?: Level;
}
export interface ChalkConstructor {
new (options?: ChalkOptions): Chalk;
(options?: ChalkOptions): Chalk;
}
export interface ColorSupport {
level: Level;
hasBasic: boolean;
has256: boolean;
has16m: boolean;
}
export interface Chalk {
(...text: string[]): string;
(text: TemplateStringsArray, ...placeholders: string[]): string;
constructor: ChalkConstructor;
enabled: boolean;
level: Level;
rgb(r: number, g: number, b: number): this;
hsl(h: number, s: number, l: number): this;
hsv(h: number, s: number, v: number): this;
hwb(h: number, w: number, b: number): this;
bgHex(color: string): this;
bgKeyword(color: string): this;
bgRgb(r: number, g: number, b: number): this;
bgHsl(h: number, s: number, l: number): this;
bgHsv(h: number, s: number, v: number): this;
bgHwb(h: number, w: number, b: number): this;
hex(color: string): this;
keyword(color: string): this;
readonly reset: this;
readonly bold: this;
readonly dim: this;
readonly italic: this;
readonly underline: this;
readonly inverse: this;
readonly hidden: this;
readonly strikethrough: this;
readonly visible: this;
readonly black: this;
readonly red: this;
readonly green: this;
readonly yellow: this;
readonly blue: this;
readonly magenta: this;
readonly cyan: this;
readonly white: this;
readonly gray: this;
readonly grey: this;
readonly blackBright: this;
readonly redBright: this;
readonly greenBright: this;
readonly yellowBright: this;
readonly blueBright: this;
readonly magentaBright: this;
readonly cyanBright: this;
readonly whiteBright: this;
readonly bgBlack: this;
readonly bgRed: this;
readonly bgGreen: this;
readonly bgYellow: this;
readonly bgBlue: this;
readonly bgMagenta: this;
readonly bgCyan: this;
readonly bgWhite: this;
readonly bgBlackBright: this;
readonly bgRedBright: this;
readonly bgGreenBright: this;
readonly bgYellowBright: this;
readonly bgBlueBright: this;
readonly bgMagentaBright: this;
readonly bgCyanBright: this;
readonly bgWhiteBright: this;
}
declare const chalk: Chalk & { supportsColor: ColorSupport };
export default chalk

274
node_modules/chokidar/CHANGELOG.md generated vendored Normal file
View file

@ -0,0 +1,274 @@
# Chokidar 1.7.0 (May 8, 2017)
* Add `disableGlobbing` option
* Add ability to force interval value by setting CHOKIDAR_INTERVAL env
variable
* Fix issue with `.close()` being called before `ready`
# Chokidar 1.6.0 (Jun 22, 2016)
* Added ability for force `usePolling` mode by setting `CHOKIDAR_USEPOLLING`
env variable
# Chokidar 1.5.2 (Jun 7, 2016)
* Fix missing `addDir` events when using `cwd` and `alwaysStat` options
* Fix missing `add` events for files within a renamed directory
# Chokidar 1.5.1 (May 20, 2016)
* To help prevent exhaustion of FSEvents system limitations, consolidate watch
instances to the common parent upon detection of separate watch instances on
many siblings
# Chokidar 1.5.0 (May 10, 2016)
* Make debounce delay setting used with `atomic: true` user-customizable
* Fixes and improvements to `awaitWriteFinish` features
# Chokidar 1.4.3 (Feb 26, 2016)
* Update async-each dependency to ^1.0.0
# Chokidar 1.4.2 (Dec 30, 2015)
* Now correctly emitting `stats` with `awaitWriteFinish` option.
# Chokidar 1.4.1 (Dec 9, 2015)
* The watcher could now be correctly subclassed with ES6 class syntax.
# Chokidar 1.4.0 (Dec 3, 2015)
* Add `.getWatched()` method, exposing all file system entries being watched
* Apply `awaitWriteFinish` methodology to `change` events (in addition to `add`)
* Fix handling of symlinks within glob paths (#293)
* Fix `addDir` and `unlinkDir` events under globs (#337, #401)
* Fix issues with `.unwatch()` (#374, #403)
# Chokidar 1.3.0 (Nov 18, 2015)
* Improve `awaitWriteFinish` option behavior
* Fix some `cwd` option behavior on Windows
* `awaitWriteFinish` and `cwd` are now compatible
* Fix some race conditions.
* #379: Recreating deleted directory doesn't trigger event
* When adding a previously-deleted file, emit 'add', not 'change'
# Chokidar 1.2.0 (Oct 1, 2015)
* Allow nested arrays of paths to be provided to `.watch()` and `.add()`
* Add `awaitWriteFinish` option
# Chokidar 1.1.0 (Sep 23, 2015)
* Dependency updates including fsevents@1.0.0, improving installation
# Chokidar 1.0.6 (Sep 18, 2015)
* Fix issue with `.unwatch()` method and relative paths
# Chokidar 1.0.5 (Jul 20, 2015)
* Fix regression with regexes/fns using in `ignored`
# Chokidar 1.0.4 (Jul 15, 2015)
* Fix bug with `ignored` files/globs while `cwd` option is set
# Chokidar 1.0.3 (Jun 4, 2015)
* Fix race issue with `alwaysStat` option and removed files
# Chokidar 1.0.2 (May 30, 2015)
* Fix bug with absolute paths and ENAMETOOLONG error
# Chokidar 1.0.1 (Apr 8, 2015)
* Fix bug with `.close()` method in `fs.watch` mode with `persistent: false`
option
# Chokidar 1.0.0 (Apr 7, 2015)
* Glob support! Use globs in `watch`, `add`, and `unwatch` methods
* Comprehensive symlink support
* New `unwatch` method to turn off watching of previously watched paths
* More flexible `ignored` option allowing regex, function, glob, or array
courtesy of [anymatch](https://github.com/es128/anymatch)
* New `cwd` option to set base dir from which relative paths are derived
* New `depth` option for limiting recursion
* New `alwaysStat` option to ensure
[`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) gets passed
with every add/change event
* New `ready` event emitted when initial fs tree scan is done and watcher is
ready for changes
* New `raw` event exposing data and events from the lower-level watch modules
* New `followSymlinks` option to impact whether symlinks' targets or the symlink
files themselves are watched
* New `atomic` option for normalizing artifacts from text editors that use
atomic write methods
* Ensured watcher's stability with lots of bugfixes.
# Chokidar 0.12.6 (Jan 6, 2015)
* Fix bug which breaks `persistent: false` mode when change events occur
# Chokidar 0.12.5 (Dec 17, 2014)
* Fix bug with matching parent path detection for fsevents instance sharing
* Fix bug with ignored watch path in nodefs modes
# Chokidar 0.12.4 (Dec 14, 2014)
* Fix bug in `fs.watch` mode that caused watcher to leak into `cwd`
* Fix bug preventing ready event when there are symlinks to ignored paths
# Chokidar 0.12.3 (Dec 13, 2014)
* Fix handling of special files such as named pipes and sockets
# Chokidar 0.12.2 (Dec 12, 2014)
* Fix recursive symlink handling and some other path resolution problems
# Chokidar 0.12.1 (Dec 10, 2014)
* Fix a case where file symlinks were not followed properly
# Chokidar 0.12.0 (Dec 8, 2014)
* Symlink support
* Add `followSymlinks` option, which defaults to `true`
* Change default watch mode on Linux to non-polling `fs.watch`
* Add `atomic` option to normalize events from editors using atomic writes
* Particularly Vim and Sublime
* Add `raw` event which exposes data from the underlying watch method
# Chokidar 0.11.1 (Nov 19, 2014)
* Fix a bug where an error is thrown when `fs.watch` instantiation fails
# Chokidar 0.11.0 (Nov 16, 2014)
* Add a `ready` event, which is emitted after initial file scan completes
* Fix issue with options keys passed in defined as `undefined`
* Rename some internal `FSWatcher` properties to indicate they're private
# Chokidar 0.10.9 (Nov 15, 2014)
* Fix some leftover issues from adding watcher reuse
# Chokidar 0.10.8 (Nov 14, 2014)
* Remove accidentally committed/published `console.log` statement.
* Sry 'bout that :crying_cat_face:
# Chokidar 0.10.7 (Nov 14, 2014)
* Apply watcher reuse methodology to `fs.watch` and `fs.watchFile` as well
# Chokidar 0.10.6 (Nov 12, 2014)
* More efficient creation/reuse of FSEvents instances to avoid system limits
* Reduce simultaneous FSEvents instances allowed in a process
* Handle errors thrown by `fs.watch` upon invocation
# Chokidar 0.10.5 (Nov 6, 2014)
* Limit number of simultaneous FSEvents instances (fall back to other methods)
* Prevent some cases of EMFILE errors during initialization
* Fix ignored files emitting events in some fsevents-mode circumstances
# Chokidar 0.10.4 (Nov 5, 2014)
* Bump fsevents dependency to ~0.3.1
* Should resolve build warnings and `npm rebuild` on non-Macs
# Chokidar 0.10.3 (Oct 28, 2014)
* Fix removed dir emitting as `unlink` instead of `unlinkDir`
* Fix issues with file changing to dir or vice versa (gh-165)
* Fix handling of `ignored` option in fsevents mode
# Chokidar 0.10.2 (Oct 23, 2014)
* Improve individual file watching
* Fix fsevents keeping process alive when `persistent: false`
# Chokidar 0.10.1 (19 October 2014)
* Improve handling of text editor atomic writes
# Chokidar 0.10.0 (Oct 18, 2014)
* Many stability and consistency improvements
* Resolve many cases of duplicate or wrong events
* Correct for fsevents inconsistencies
* Standardize handling of errors and relative paths
* Fix issues with watching `./`
# Chokidar 0.9.0 (Sep 25, 2014)
* Updated fsevents to 0.3
* Update per-system defaults
* Fix issues with closing chokidar instance
* Fix duplicate change events on win32
# Chokidar 0.8.2 (Mar 26, 2014)
* Fixed npm issues related to fsevents dep.
* Updated fsevents to 0.2.
# Chokidar 0.8.1 (Dec 16, 2013)
* Optional deps are now truly optional on windows and
linux.
* Rewritten in JS, again.
* Fixed some FSEvents-related bugs.
# Chokidar 0.8.0 (Nov 29, 2013)
* Added ultra-fast low-CPU OS X file watching with FSEvents.
It is enabled by default.
* Added `addDir` and `unlinkDir` events.
* Polling is now disabled by default on all platforms.
# Chokidar 0.7.1 (Nov 18, 2013)
* `Watcher#close` now also removes all event listeners.
# Chokidar 0.7.0 (Oct 22, 2013)
* When `options.ignored` is two-argument function, it will
also be called after stating the FS, with `stats` argument.
* `unlink` is no longer emitted on directories.
# Chokidar 0.6.3 (Aug 12, 2013)
* Added `usePolling` option (default: `true`).
When `false`, chokidar will use `fs.watch` as backend.
`fs.watch` is much faster, but not like super reliable.
# Chokidar 0.6.2 (Mar 19, 2013)
* Fixed watching initially empty directories with `ignoreInitial` option.
# Chokidar 0.6.1 (Mar 19, 2013)
* Added node.js 0.10 support.
# Chokidar 0.6.0 (Mar 10, 2013)
* File attributes (stat()) are now passed to `add` and `change` events as second
arguments.
* Changed default polling interval for binary files to 300ms.
# Chokidar 0.5.3 (Jan 13, 2013)
* Removed emitting of `change` events before `unlink`.
# Chokidar 0.5.2 (Jan 13, 2013)
* Removed postinstall script to prevent various npm bugs.
# Chokidar 0.5.1 (Jan 6, 2013)
* When starting to watch non-existing paths, chokidar will no longer throw
ENOENT error.
* Fixed bug with absolute path.
# Chokidar 0.5.0 (Dec 9, 2012)
* Added a bunch of new options:
* `ignoreInitial` that allows to ignore initial `add` events.
* `ignorePermissionErrors` that allows to ignore ENOENT etc perm errors.
* `interval` and `binaryInterval` that allow to change default
fs polling intervals.
# Chokidar 0.4.0 (Jul 26, 2012)
* Added `all` event that receives two args (event name and path) that combines
`add`, `change` and `unlink` events.
* Switched to `fs.watchFile` on node.js 0.8 on windows.
* Files are now correctly unwatched after unlink.
# Chokidar 0.3.0 (Jun 24, 2012)
* `unlink` event are no longer emitted for directories, for consistency with
`add`.
# Chokidar 0.2.6 (Jun 8, 2012)
* Prevented creating of duplicate 'add' events.
# Chokidar 0.2.5 (Jun 8, 2012)
* Fixed a bug when new files in new directories hadn't been added.
# Chokidar 0.2.4 (Jun 7, 2012)
* Fixed a bug when unlinked files emitted events after unlink.
# Chokidar 0.2.3 (May 12, 2012)
* Fixed watching of files on windows.
# Chokidar 0.2.2 (May 4, 2012)
* Fixed watcher signature.
# Chokidar 0.2.1 (May 4, 2012)
* Fixed invalid API bug when using `watch()`.
# Chokidar 0.2.0 (May 4, 2012)
* Rewritten in js.
# Chokidar 0.1.1 (Apr 26, 2012)
* Changed api to `chokidar.watch()`.
* Fixed compilation on windows.
# Chokidar 0.1.0 (Apr 20, 2012)
* Initial release, extracted from
[Brunch](https://github.com/brunch/brunch/blob/9847a065aea300da99bd0753f90354cde9de1261/src/helpers.coffee#L66)

293
node_modules/chokidar/README.md generated vendored Normal file
View file

@ -0,0 +1,293 @@
# Chokidar [![Mac/Linux Build Status](https://img.shields.io/travis/paulmillr/chokidar/master.svg?label=Mac%20OSX%20%26%20Linux)](https://travis-ci.org/paulmillr/chokidar) [![Windows Build status](https://img.shields.io/appveyor/ci/es128/chokidar/master.svg?label=Windows)](https://ci.appveyor.com/project/es128/chokidar/branch/master) [![Coverage Status](https://coveralls.io/repos/paulmillr/chokidar/badge.svg)](https://coveralls.io/r/paulmillr/chokidar) [![Join the chat at https://gitter.im/paulmillr/chokidar](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/paulmillr/chokidar?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
> A neat wrapper around node.js fs.watch / fs.watchFile / fsevents.
[![NPM](https://nodei.co/npm-dl/chokidar.png)](https://nodei.co/npm/chokidar/)
[![NPM](https://nodei.co/npm/chokidar.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/chokidar/)
## Why?
Node.js `fs.watch`:
* Doesn't report filenames on OS X.
* Doesn't report events at all when using editors like Sublime on OS X.
* Often reports events twice.
* Emits most changes as `rename`.
* Has [a lot of other issues](https://github.com/joyent/node/search?q=fs.watch&type=Issues)
* Does not provide an easy way to recursively watch file trees.
Node.js `fs.watchFile`:
* Almost as bad at event handling.
* Also does not provide any recursive watching.
* Results in high CPU utilization.
Chokidar resolves these problems.
Initially made for [brunch](http://brunch.io) (an ultra-swift web app build tool), it is now used in
[gulp](https://github.com/gulpjs/gulp/),
[karma](http://karma-runner.github.io),
[PM2](https://github.com/Unitech/PM2),
[browserify](http://browserify.org/),
[webpack](http://webpack.github.io/),
[BrowserSync](http://www.browsersync.io/),
[Microsoft's Visual Studio Code](https://github.com/microsoft/vscode),
and [many others](https://www.npmjs.org/browse/depended/chokidar/).
It has proven itself in production environments.
## How?
Chokidar does still rely on the Node.js core `fs` module, but when using
`fs.watch` and `fs.watchFile` for watching, it normalizes the events it
receives, often checking for truth by getting file stats and/or dir contents.
On Mac OS X, chokidar by default uses a native extension exposing the Darwin
`FSEvents` API. This provides very efficient recursive watching compared with
implementations like `kqueue` available on most \*nix platforms. Chokidar still
does have to do some work to normalize the events received that way as well.
On other platforms, the `fs.watch`-based implementation is the default, which
avoids polling and keeps CPU usage down. Be advised that chokidar will initiate
watchers recursively for everything within scope of the paths that have been
specified, so be judicious about not wasting system resources by watching much
more than needed.
## Getting started
Install with npm:
npm install chokidar --save
Then `require` and use it in your code:
```javascript
var chokidar = require('chokidar');
// One-liner for current directory, ignores .dotfiles
chokidar.watch('.', {ignored: /(^|[\/\\])\../}).on('all', (event, path) => {
console.log(event, path);
});
```
```javascript
// Example of a more typical implementation structure:
// Initialize watcher.
var watcher = chokidar.watch('file, dir, glob, or array', {
ignored: /(^|[\/\\])\../,
persistent: true
});
// Something to use when events are received.
var log = console.log.bind(console);
// Add event listeners.
watcher
.on('add', path => log(`File ${path} has been added`))
.on('change', path => log(`File ${path} has been changed`))
.on('unlink', path => log(`File ${path} has been removed`));
// More possible events.
watcher
.on('addDir', path => log(`Directory ${path} has been added`))
.on('unlinkDir', path => log(`Directory ${path} has been removed`))
.on('error', error => log(`Watcher error: ${error}`))
.on('ready', () => log('Initial scan complete. Ready for changes'))
.on('raw', (event, path, details) => {
log('Raw event info:', event, path, details);
});
// 'add', 'addDir' and 'change' events also receive stat() results as second
// argument when available: http://nodejs.org/api/fs.html#fs_class_fs_stats
watcher.on('change', (path, stats) => {
if (stats) console.log(`File ${path} changed size to ${stats.size}`);
});
// Watch new files.
watcher.add('new-file');
watcher.add(['new-file-2', 'new-file-3', '**/other-file*']);
// Get list of actual paths being watched on the filesystem
var watchedPaths = watcher.getWatched();
// Un-watch some files.
watcher.unwatch('new-file*');
// Stop watching.
watcher.close();
// Full list of options. See below for descriptions. (do not use this example)
chokidar.watch('file', {
persistent: true,
ignored: '*.txt',
ignoreInitial: false,
followSymlinks: true,
cwd: '.',
disableGlobbing: false,
usePolling: true,
interval: 100,
binaryInterval: 300,
alwaysStat: false,
depth: 99,
awaitWriteFinish: {
stabilityThreshold: 2000,
pollInterval: 100
},
ignorePermissionErrors: false,
atomic: true // or a custom 'atomicity delay', in milliseconds (default 100)
});
```
## API
`chokidar.watch(paths, [options])`
* `paths` (string or array of strings). Paths to files, dirs to be watched
recursively, or glob patterns.
* `options` (object) Options object as defined below:
#### Persistence
* `persistent` (default: `true`). Indicates whether the process
should continue to run as long as files are being watched. If set to
`false` when using `fsevents` to watch, no more events will be emitted
after `ready`, even if the process continues to run.
#### Path filtering
* `ignored` ([anymatch](https://github.com/es128/anymatch)-compatible definition)
Defines files/paths to be ignored. The whole relative or absolute path is
tested, not just filename. If a function with two arguments is provided, it
gets called twice per path - once with a single argument (the path), second
time with two arguments (the path and the
[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats)
object of that path).
* `ignoreInitial` (default: `false`). If set to `false` then `add`/`addDir` events are also emitted for matching paths while
instantiating the watching as chokidar discovers these file paths (before the `ready` event).
* `followSymlinks` (default: `true`). When `false`, only the
symlinks themselves will be watched for changes instead of following
the link references and bubbling events through the link's path.
* `cwd` (no default). The base directory from which watch `paths` are to be
derived. Paths emitted with events will be relative to this.
* `disableGlobbing` (default: `false`). If set to `true` then the strings passed to `.watch()` and `.add()` are treated as
literal path names, even if they look like globs.
#### Performance
* `usePolling` (default: `false`).
Whether to use fs.watchFile (backed by polling), or fs.watch. If polling
leads to high CPU utilization, consider setting this to `false`. It is
typically necessary to **set this to `true` to successfully watch files over
a network**, and it may be necessary to successfully watch files in other
non-standard situations. Setting to `true` explicitly on OS X overrides the
`useFsEvents` default. You may also set the CHOKIDAR_USEPOLLING env variable
to true (1) or false (0) in order to override this option.
* _Polling-specific settings_ (effective when `usePolling: true`)
* `interval` (default: `100`). Interval of file system polling. You may also
set the CHOKIDAR_INTERVAL env variable to override this option.
* `binaryInterval` (default: `300`). Interval of file system
polling for binary files.
([see list of binary extensions](https://github.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json))
* `useFsEvents` (default: `true` on OS X). Whether to use the
`fsevents` watching interface if available. When set to `true` explicitly
and `fsevents` is available this supercedes the `usePolling` setting. When
set to `false` on OS X, `usePolling: true` becomes the default.
* `alwaysStat` (default: `false`). If relying upon the
[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats)
object that may get passed with `add`, `addDir`, and `change` events, set
this to `true` to ensure it is provided even in cases where it wasn't
already available from the underlying watch events.
* `depth` (default: `undefined`). If set, limits how many levels of
subdirectories will be traversed.
* `awaitWriteFinish` (default: `false`).
By default, the `add` event will fire when a file first appears on disk, before
the entire file has been written. Furthermore, in some cases some `change`
events will be emitted while the file is being written. In some cases,
especially when watching for large files there will be a need to wait for the
write operation to finish before responding to a file creation or modification.
Setting `awaitWriteFinish` to `true` (or a truthy value) will poll file size,
holding its `add` and `change` events until the size does not change for a
configurable amount of time. The appropriate duration setting is heavily
dependent on the OS and hardware. For accurate detection this parameter should
be relatively high, making file watching much less responsive.
Use with caution.
* *`options.awaitWriteFinish` can be set to an object in order to adjust
timing params:*
* `awaitWriteFinish.stabilityThreshold` (default: 2000). Amount of time in
milliseconds for a file size to remain constant before emitting its event.
* `awaitWriteFinish.pollInterval` (default: 100). File size polling interval.
#### Errors
* `ignorePermissionErrors` (default: `false`). Indicates whether to watch files
that don't have read permissions if possible. If watching fails due to `EPERM`
or `EACCES` with this set to `true`, the errors will be suppressed silently.
* `atomic` (default: `true` if `useFsEvents` and `usePolling` are `false`).
Automatically filters out artifacts that occur when using editors that use
"atomic writes" instead of writing directly to the source file. If a file is
re-added within 100 ms of being deleted, Chokidar emits a `change` event
rather than `unlink` then `add`. If the default of 100 ms does not work well
for you, you can override it by setting `atomic` to a custom value, in
milliseconds.
### Methods & Events
`chokidar.watch()` produces an instance of `FSWatcher`. Methods of `FSWatcher`:
* `.add(path / paths)`: Add files, directories, or glob patterns for tracking.
Takes an array of strings or just one string.
* `.on(event, callback)`: Listen for an FS event.
Available events: `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `ready`,
`raw`, `error`.
Additionally `all` is available which gets emitted with the underlying event
name and path for every event other than `ready`, `raw`, and `error`.
* `.unwatch(path / paths)`: Stop watching files, directories, or glob patterns.
Takes an array of strings or just one string.
* `.close()`: Removes all listeners from watched files.
* `.getWatched()`: Returns an object representing all the paths on the file
system being watched by this `FSWatcher` instance. The object's keys are all the
directories (using absolute paths unless the `cwd` option was used), and the
values are arrays of the names of the items contained in each directory.
## CLI
If you need a CLI interface for your file watching, check out
[chokidar-cli](https://github.com/kimmobrunfeldt/chokidar-cli), allowing you to
execute a command on each change, or get a stdio stream of change events.
## Install Troubleshooting
* `npm WARN optional dep failed, continuing fsevents@n.n.n`
* This message is normal part of how `npm` handles optional dependencies and is
not indicative of a problem. Even if accompanied by other related error messages,
Chokidar should function properly.
* `ERR! stack Error: Python executable "python" is v3.4.1, which is not supported by gyp.`
* You should be able to resolve this by installing python 2.7 and running:
`npm config set python python2.7`
* `gyp ERR! stack Error: not found: make`
* On Mac, install the XCode command-line tools
## License
The MIT License (MIT)
Copyright (c) 2016 Paul Miller (http://paulmillr.com) & Elan Shanker
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.

716
node_modules/chokidar/index.js generated vendored Normal file
View file

@ -0,0 +1,716 @@
'use strict';
var EventEmitter = require('events').EventEmitter;
var fs = require('fs');
var sysPath = require('path');
var asyncEach = require('async-each');
var anymatch = require('anymatch');
var globParent = require('glob-parent');
var isGlob = require('is-glob');
var isAbsolute = require('path-is-absolute');
var inherits = require('inherits');
var NodeFsHandler = require('./lib/nodefs-handler');
var FsEventsHandler = require('./lib/fsevents-handler');
var arrify = function(value) {
if (value == null) return [];
return Array.isArray(value) ? value : [value];
};
var flatten = function(list, result) {
if (result == null) result = [];
list.forEach(function(item) {
if (Array.isArray(item)) {
flatten(item, result);
} else {
result.push(item);
}
});
return result;
};
// Little isString util for use in Array#every.
var isString = function(thing) {
return typeof thing === 'string';
};
// Public: Main class.
// Watches files & directories for changes.
//
// * _opts - object, chokidar options hash
//
// Emitted events:
// `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error`
//
// Examples
//
// var watcher = new FSWatcher()
// .add(directories)
// .on('add', path => console.log('File', path, 'was added'))
// .on('change', path => console.log('File', path, 'was changed'))
// .on('unlink', path => console.log('File', path, 'was removed'))
// .on('all', (event, path) => console.log(path, ' emitted ', event))
//
function FSWatcher(_opts) {
EventEmitter.call(this);
var opts = {};
// in case _opts that is passed in is a frozen object
if (_opts) for (var opt in _opts) opts[opt] = _opts[opt];
this._watched = Object.create(null);
this._closers = Object.create(null);
this._ignoredPaths = Object.create(null);
Object.defineProperty(this, '_globIgnored', {
get: function() { return Object.keys(this._ignoredPaths); }
});
this.closed = false;
this._throttled = Object.create(null);
this._symlinkPaths = Object.create(null);
function undef(key) {
return opts[key] === undefined;
}
// Set up default options.
if (undef('persistent')) opts.persistent = true;
if (undef('ignoreInitial')) opts.ignoreInitial = false;
if (undef('ignorePermissionErrors')) opts.ignorePermissionErrors = false;
if (undef('interval')) opts.interval = 100;
if (undef('binaryInterval')) opts.binaryInterval = 300;
if (undef('disableGlobbing')) opts.disableGlobbing = false;
this.enableBinaryInterval = opts.binaryInterval !== opts.interval;
// Enable fsevents on OS X when polling isn't explicitly enabled.
if (undef('useFsEvents')) opts.useFsEvents = !opts.usePolling;
// If we can't use fsevents, ensure the options reflect it's disabled.
if (!FsEventsHandler.canUse()) opts.useFsEvents = false;
// Use polling on Mac if not using fsevents.
// Other platforms use non-polling fs.watch.
if (undef('usePolling') && !opts.useFsEvents) {
opts.usePolling = process.platform === 'darwin';
}
// Global override (useful for end-developers that need to force polling for all
// instances of chokidar, regardless of usage/dependency depth)
var envPoll = process.env.CHOKIDAR_USEPOLLING;
if (envPoll !== undefined) {
var envLower = envPoll.toLowerCase();
if (envLower === 'false' || envLower === '0') {
opts.usePolling = false;
} else if (envLower === 'true' || envLower === '1') {
opts.usePolling = true;
} else {
opts.usePolling = !!envLower
}
}
var envInterval = process.env.CHOKIDAR_INTERVAL;
if (envInterval) {
opts.interval = parseInt(envInterval);
}
// Editor atomic write normalization enabled by default with fs.watch
if (undef('atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents;
if (opts.atomic) this._pendingUnlinks = Object.create(null);
if (undef('followSymlinks')) opts.followSymlinks = true;
if (undef('awaitWriteFinish')) opts.awaitWriteFinish = false;
if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {};
var awf = opts.awaitWriteFinish;
if (awf) {
if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000;
if (!awf.pollInterval) awf.pollInterval = 100;
this._pendingWrites = Object.create(null);
}
if (opts.ignored) opts.ignored = arrify(opts.ignored);
this._isntIgnored = function(path, stat) {
return !this._isIgnored(path, stat);
}.bind(this);
var readyCalls = 0;
this._emitReady = function() {
if (++readyCalls >= this._readyCount) {
this._emitReady = Function.prototype;
this._readyEmitted = true;
// use process.nextTick to allow time for listener to be bound
process.nextTick(this.emit.bind(this, 'ready'));
}
}.bind(this);
this.options = opts;
// Youre frozen when your hearts not open.
Object.freeze(opts);
}
inherits(FSWatcher, EventEmitter);
// Common helpers
// --------------
// Private method: Normalize and emit events
//
// * event - string, type of event
// * path - string, file or directory path
// * val[1..3] - arguments to be passed with event
//
// Returns the error if defined, otherwise the value of the
// FSWatcher instance's `closed` flag
FSWatcher.prototype._emit = function(event, path, val1, val2, val3) {
if (this.options.cwd) path = sysPath.relative(this.options.cwd, path);
var args = [event, path];
if (val3 !== undefined) args.push(val1, val2, val3);
else if (val2 !== undefined) args.push(val1, val2);
else if (val1 !== undefined) args.push(val1);
var awf = this.options.awaitWriteFinish;
if (awf && this._pendingWrites[path]) {
this._pendingWrites[path].lastChange = new Date();
return this;
}
if (this.options.atomic) {
if (event === 'unlink') {
this._pendingUnlinks[path] = args;
setTimeout(function() {
Object.keys(this._pendingUnlinks).forEach(function(path) {
this.emit.apply(this, this._pendingUnlinks[path]);
this.emit.apply(this, ['all'].concat(this._pendingUnlinks[path]));
delete this._pendingUnlinks[path];
}.bind(this));
}.bind(this), typeof this.options.atomic === "number"
? this.options.atomic
: 100);
return this;
} else if (event === 'add' && this._pendingUnlinks[path]) {
event = args[0] = 'change';
delete this._pendingUnlinks[path];
}
}
var emitEvent = function() {
this.emit.apply(this, args);
if (event !== 'error') this.emit.apply(this, ['all'].concat(args));
}.bind(this);
if (awf && (event === 'add' || event === 'change') && this._readyEmitted) {
var awfEmit = function(err, stats) {
if (err) {
event = args[0] = 'error';
args[1] = err;
emitEvent();
} else if (stats) {
// if stats doesn't exist the file must have been deleted
if (args.length > 2) {
args[2] = stats;
} else {
args.push(stats);
}
emitEvent();
}
};
this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit);
return this;
}
if (event === 'change') {
if (!this._throttle('change', path, 50)) return this;
}
if (
this.options.alwaysStat && val1 === undefined &&
(event === 'add' || event === 'addDir' || event === 'change')
) {
var fullPath = this.options.cwd ? sysPath.join(this.options.cwd, path) : path;
fs.stat(fullPath, function(error, stats) {
// Suppress event when fs.stat fails, to avoid sending undefined 'stat'
if (error || !stats) return;
args.push(stats);
emitEvent();
});
} else {
emitEvent();
}
return this;
};
// Private method: Common handler for errors
//
// * error - object, Error instance
//
// Returns the error if defined, otherwise the value of the
// FSWatcher instance's `closed` flag
FSWatcher.prototype._handleError = function(error) {
var code = error && error.code;
var ipe = this.options.ignorePermissionErrors;
if (error &&
code !== 'ENOENT' &&
code !== 'ENOTDIR' &&
(!ipe || (code !== 'EPERM' && code !== 'EACCES'))
) this.emit('error', error);
return error || this.closed;
};
// Private method: Helper utility for throttling
//
// * action - string, type of action being throttled
// * path - string, path being acted upon
// * timeout - int, duration of time to suppress duplicate actions
//
// Returns throttle tracking object or false if action should be suppressed
FSWatcher.prototype._throttle = function(action, path, timeout) {
if (!(action in this._throttled)) {
this._throttled[action] = Object.create(null);
}
var throttled = this._throttled[action];
if (path in throttled) return false;
function clear() {
delete throttled[path];
clearTimeout(timeoutObject);
}
var timeoutObject = setTimeout(clear, timeout);
throttled[path] = {timeoutObject: timeoutObject, clear: clear};
return throttled[path];
};
// Private method: Awaits write operation to finish
//
// * path - string, path being acted upon
// * threshold - int, time in milliseconds a file size must be fixed before
// acknowledgeing write operation is finished
// * awfEmit - function, to be called when ready for event to be emitted
// Polls a newly created file for size variations. When files size does not
// change for 'threshold' milliseconds calls callback.
FSWatcher.prototype._awaitWriteFinish = function(path, threshold, event, awfEmit) {
var timeoutHandler;
var fullPath = path;
if (this.options.cwd && !isAbsolute(path)) {
fullPath = sysPath.join(this.options.cwd, path);
}
var now = new Date();
var awaitWriteFinish = (function (prevStat) {
fs.stat(fullPath, function(err, curStat) {
if (err) {
if (err.code !== 'ENOENT') awfEmit(err);
return;
}
var now = new Date();
if (prevStat && curStat.size != prevStat.size) {
this._pendingWrites[path].lastChange = now;
}
if (now - this._pendingWrites[path].lastChange >= threshold) {
delete this._pendingWrites[path];
awfEmit(null, curStat);
} else {
timeoutHandler = setTimeout(
awaitWriteFinish.bind(this, curStat),
this.options.awaitWriteFinish.pollInterval
);
}
}.bind(this));
}.bind(this));
if (!(path in this._pendingWrites)) {
this._pendingWrites[path] = {
lastChange: now,
cancelWait: function() {
delete this._pendingWrites[path];
clearTimeout(timeoutHandler);
return event;
}.bind(this)
};
timeoutHandler = setTimeout(
awaitWriteFinish.bind(this),
this.options.awaitWriteFinish.pollInterval
);
}
};
// Private method: Determines whether user has asked to ignore this path
//
// * path - string, path to file or directory
// * stats - object, result of fs.stat
//
// Returns boolean
var dotRe = /\..*\.(sw[px])$|\~$|\.subl.*\.tmp/;
FSWatcher.prototype._isIgnored = function(path, stats) {
if (this.options.atomic && dotRe.test(path)) return true;
if (!this._userIgnored) {
var cwd = this.options.cwd;
var ignored = this.options.ignored;
if (cwd && ignored) {
ignored = ignored.map(function (path) {
if (typeof path !== 'string') return path;
return isAbsolute(path) ? path : sysPath.join(cwd, path);
});
}
var paths = arrify(ignored)
.filter(function(path) {
return typeof path === 'string' && !isGlob(path);
}).map(function(path) {
return path + '/**';
});
this._userIgnored = anymatch(
this._globIgnored.concat(ignored).concat(paths)
);
}
return this._userIgnored([path, stats]);
};
// Private method: Provides a set of common helpers and properties relating to
// symlink and glob handling
//
// * path - string, file, directory, or glob pattern being watched
// * depth - int, at any depth > 0, this isn't a glob
//
// Returns object containing helpers for this path
var replacerRe = /^\.[\/\\]/;
FSWatcher.prototype._getWatchHelpers = function(path, depth) {
path = path.replace(replacerRe, '');
var watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path);
var fullWatchPath = sysPath.resolve(watchPath);
var hasGlob = watchPath !== path;
var globFilter = hasGlob ? anymatch(path) : false;
var follow = this.options.followSymlinks;
var globSymlink = hasGlob && follow ? null : false;
var checkGlobSymlink = function(entry) {
// only need to resolve once
// first entry should always have entry.parentDir === ''
if (globSymlink == null) {
globSymlink = entry.fullParentDir === fullWatchPath ? false : {
realPath: entry.fullParentDir,
linkPath: fullWatchPath
};
}
if (globSymlink) {
return entry.fullPath.replace(globSymlink.realPath, globSymlink.linkPath);
}
return entry.fullPath;
};
var entryPath = function(entry) {
return sysPath.join(watchPath,
sysPath.relative(watchPath, checkGlobSymlink(entry))
);
};
var filterPath = function(entry) {
if (entry.stat && entry.stat.isSymbolicLink()) return filterDir(entry);
var resolvedPath = entryPath(entry);
return (!hasGlob || globFilter(resolvedPath)) &&
this._isntIgnored(resolvedPath, entry.stat) &&
(this.options.ignorePermissionErrors ||
this._hasReadPermissions(entry.stat));
}.bind(this);
var getDirParts = function(path) {
if (!hasGlob) return false;
var parts = sysPath.relative(watchPath, path).split(/[\/\\]/);
return parts;
};
var dirParts = getDirParts(path);
if (dirParts && dirParts.length > 1) dirParts.pop();
var unmatchedGlob;
var filterDir = function(entry) {
if (hasGlob) {
var entryParts = getDirParts(checkGlobSymlink(entry));
var globstar = false;
unmatchedGlob = !dirParts.every(function(part, i) {
if (part === '**') globstar = true;
return globstar || !entryParts[i] || anymatch(part, entryParts[i]);
});
}
return !unmatchedGlob && this._isntIgnored(entryPath(entry), entry.stat);
}.bind(this);
return {
followSymlinks: follow,
statMethod: follow ? 'stat' : 'lstat',
path: path,
watchPath: watchPath,
entryPath: entryPath,
hasGlob: hasGlob,
globFilter: globFilter,
filterPath: filterPath,
filterDir: filterDir
};
};
// Directory helpers
// -----------------
// Private method: Provides directory tracking objects
//
// * directory - string, path of the directory
//
// Returns the directory's tracking object
FSWatcher.prototype._getWatchedDir = function(directory) {
var dir = sysPath.resolve(directory);
var watcherRemove = this._remove.bind(this);
if (!(dir in this._watched)) this._watched[dir] = {
_items: Object.create(null),
add: function(item) {
if (item !== '.' && item !== '..') this._items[item] = true;
},
remove: function(item) {
delete this._items[item];
if (!this.children().length) {
fs.readdir(dir, function(err) {
if (err) watcherRemove(sysPath.dirname(dir), sysPath.basename(dir));
});
}
},
has: function(item) {return item in this._items;},
children: function() {return Object.keys(this._items);}
};
return this._watched[dir];
};
// File helpers
// ------------
// Private method: Check for read permissions
// Based on this answer on SO: http://stackoverflow.com/a/11781404/1358405
//
// * stats - object, result of fs.stat
//
// Returns boolean
FSWatcher.prototype._hasReadPermissions = function(stats) {
return Boolean(4 & parseInt(((stats && stats.mode) & 0x1ff).toString(8)[0], 10));
};
// Private method: Handles emitting unlink events for
// files and directories, and via recursion, for
// files and directories within directories that are unlinked
//
// * directory - string, directory within which the following item is located
// * item - string, base path of item/directory
//
// Returns nothing
FSWatcher.prototype._remove = function(directory, item) {
// if what is being deleted is a directory, get that directory's paths
// for recursive deleting and cleaning of watched object
// if it is not a directory, nestedDirectoryChildren will be empty array
var path = sysPath.join(directory, item);
var fullPath = sysPath.resolve(path);
var isDirectory = this._watched[path] || this._watched[fullPath];
// prevent duplicate handling in case of arriving here nearly simultaneously
// via multiple paths (such as _handleFile and _handleDir)
if (!this._throttle('remove', path, 100)) return;
// if the only watched file is removed, watch for its return
var watchedDirs = Object.keys(this._watched);
if (!isDirectory && !this.options.useFsEvents && watchedDirs.length === 1) {
this.add(directory, item, true);
}
// This will create a new entry in the watched object in either case
// so we got to do the directory check beforehand
var nestedDirectoryChildren = this._getWatchedDir(path).children();
// Recursively remove children directories / files.
nestedDirectoryChildren.forEach(function(nestedItem) {
this._remove(path, nestedItem);
}, this);
// Check if item was on the watched list and remove it
var parent = this._getWatchedDir(directory);
var wasTracked = parent.has(item);
parent.remove(item);
// If we wait for this file to be fully written, cancel the wait.
var relPath = path;
if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path);
if (this.options.awaitWriteFinish && this._pendingWrites[relPath]) {
var event = this._pendingWrites[relPath].cancelWait();
if (event === 'add') return;
}
// The Entry will either be a directory that just got removed
// or a bogus entry to a file, in either case we have to remove it
delete this._watched[path];
delete this._watched[fullPath];
var eventName = isDirectory ? 'unlinkDir' : 'unlink';
if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path);
// Avoid conflicts if we later create another file with the same name
if (!this.options.useFsEvents) {
this._closePath(path);
}
};
FSWatcher.prototype._closePath = function(path) {
if (!this._closers[path]) return;
this._closers[path]();
delete this._closers[path];
this._getWatchedDir(sysPath.dirname(path)).remove(sysPath.basename(path));
}
// Public method: Adds paths to be watched on an existing FSWatcher instance
// * paths - string or array of strings, file/directory paths and/or globs
// * _origAdd - private boolean, for handling non-existent paths to be watched
// * _internal - private boolean, indicates a non-user add
// Returns an instance of FSWatcher for chaining.
FSWatcher.prototype.add = function(paths, _origAdd, _internal) {
var cwd = this.options.cwd;
this.closed = false;
paths = flatten(arrify(paths));
if (!paths.every(isString)) {
throw new TypeError('Non-string provided as watch path: ' + paths);
}
if (cwd) paths = paths.map(function(path) {
if (isAbsolute(path)) {
return path;
} else if (path[0] === '!') {
return '!' + sysPath.join(cwd, path.substring(1));
} else {
return sysPath.join(cwd, path);
}
});
// set aside negated glob strings
paths = paths.filter(function(path) {
if (path[0] === '!') {
this._ignoredPaths[path.substring(1)] = true;
} else {
// if a path is being added that was previously ignored, stop ignoring it
delete this._ignoredPaths[path];
delete this._ignoredPaths[path + '/**'];
// reset the cached userIgnored anymatch fn
// to make ignoredPaths changes effective
this._userIgnored = null;
return true;
}
}, this);
if (this.options.useFsEvents && FsEventsHandler.canUse()) {
if (!this._readyCount) this._readyCount = paths.length;
if (this.options.persistent) this._readyCount *= 2;
paths.forEach(this._addToFsEvents, this);
} else {
if (!this._readyCount) this._readyCount = 0;
this._readyCount += paths.length;
asyncEach(paths, function(path, next) {
this._addToNodeFs(path, !_internal, 0, 0, _origAdd, function(err, res) {
if (res) this._emitReady();
next(err, res);
}.bind(this));
}.bind(this), function(error, results) {
results.forEach(function(item) {
if (!item || this.closed) return;
this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item));
}, this);
}.bind(this));
}
return this;
};
// Public method: Close watchers or start ignoring events from specified paths.
// * paths - string or array of strings, file/directory paths and/or globs
// Returns instance of FSWatcher for chaining.
FSWatcher.prototype.unwatch = function(paths) {
if (this.closed) return this;
paths = flatten(arrify(paths));
paths.forEach(function(path) {
// convert to absolute path unless relative path already matches
if (!isAbsolute(path) && !this._closers[path]) {
if (this.options.cwd) path = sysPath.join(this.options.cwd, path);
path = sysPath.resolve(path);
}
this._closePath(path);
this._ignoredPaths[path] = true;
if (path in this._watched) {
this._ignoredPaths[path + '/**'] = true;
}
// reset the cached userIgnored anymatch fn
// to make ignoredPaths changes effective
this._userIgnored = null;
}, this);
return this;
};
// Public method: Close watchers and remove all listeners from watched paths.
// Returns instance of FSWatcher for chaining.
FSWatcher.prototype.close = function() {
if (this.closed) return this;
this.closed = true;
Object.keys(this._closers).forEach(function(watchPath) {
this._closers[watchPath]();
delete this._closers[watchPath];
}, this);
this._watched = Object.create(null);
this.removeAllListeners();
return this;
};
// Public method: Expose list of watched paths
// Returns object w/ dir paths as keys and arrays of contained paths as values.
FSWatcher.prototype.getWatched = function() {
var watchList = {};
Object.keys(this._watched).forEach(function(dir) {
var key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir;
watchList[key || '.'] = Object.keys(this._watched[dir]._items).sort();
}.bind(this));
return watchList;
};
// Attach watch handler prototype methods
function importHandler(handler) {
Object.keys(handler.prototype).forEach(function(method) {
FSWatcher.prototype[method] = handler.prototype[method];
});
}
importHandler(NodeFsHandler);
if (FsEventsHandler.canUse()) importHandler(FsEventsHandler);
// Export FSWatcher class
exports.FSWatcher = FSWatcher;
// Public function: Instantiates watcher with paths to be tracked.
// * paths - string or array of strings, file/directory paths and/or globs
// * options - object, chokidar options
// Returns an instance of FSWatcher for chaining.
exports.watch = function(paths, options) {
return new FSWatcher(options).add(paths);
};

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