function dateDifference(date1, date2, differenceType) {
    var diffMilliseconds = Math.abs(date1 - date2);

    switch(differenceType) {
        case 'days':
            return dates._getDaysDiff(diffMilliseconds);
        case 'hours':
            return dates._differenceInHours(diffMilliseconds);
        case 'minutes':
            return dates._differenceInMinutes(diffMilliseconds);
        case 'milliseconds':
            return diffMilliseconds;

        default:
            return {
                days: dates._getDaysDiff(diffMilliseconds),
                hours: dates._getHoursDiff(diffMilliseconds),
                minutes: dates._getMinutesDiff(diffMilliseconds),
                milliseconds: diffMilliseconds
            }
    }
}

function dateDifference ( date1 , date2 , differenceType ) { var diffMilliseconds = Math . abs ( date1 - date2 ) ; switch ( differenceType ) { case 'days' : return dates . _getDaysDiff ( diffMilliseconds ) ; case 'hours' : return dates . _differenceInHours ( diffMilliseconds ) ; case 'minutes' : return dates . _differenceInMinutes ( diffMilliseconds ) ; case 'milliseconds' : return diffMilliseconds ; default : return { days : dates . _getDaysDiff ( diffMilliseconds ) , hours : dates . _getHoursDiff ( diffMilliseconds ) , minutes : dates . _getMinutesDiff ( diffMilliseconds ) , milliseconds : diffMilliseconds } } }

Difference between dates which are passed, in formats 'milliseconds', 'days', 'hours', 'minutes'

@customNeeds -

@since 2.0.0
@category Date

@param {Date} date1 - The Date for compare
@param {Date} date2 - The Date for compare
@param {String} differenceType - [ 'days', 'hours', 'minutes', 'milliseconds', 'all' ]

@returns {Number|Object} Returns the numeric value or object depends on passed differenceType param

@example

famulus.dateDifference(new Date('06-20-2018'), new Date('06-26-2018'), 'days')
// => 6

famulus.dateDifference(new Date('06-20-2018'), new Date('06-26-2018'), 'hours')
// => 144

famulus.dateDifference(new Date('06-20-2018'), new Date('06-26-2018'), 'minutes')
// => 8640

famulus.dateDifference(new Date('06-26-2018'), new Date('06-20-2018'), 'milliseconds')
// => 518400000

famulus.dateDifference(new Date('06-26-2018 10:10'), new Date('06-20-2018 08:00'), 'all')
// => {days: 6, hours: 2, minutes: 10, milliseconds: 526200000}

Difference between dates which are passed in formats milliseconds days hours minutes


function initErrorHandler({
  ENV = {},
  DEBUG_NODE_ENVS = DEFAULT_DEBUG_NODE_ENVS,
  STRINGIFYERS = DEFAULT_STRINGIFYERS,
}) {
  return Promise.resolve(errorHandler);

  /**
   * Handle an HTTP transaction error and
   * map it to a serializable response
   * @param  {String}  transactionId
   * A raw NodeJS HTTP incoming message
   * @param  {Object} responseSpec
   * The response specification
   * @param  {HTTPError} err
   * The encountered error
   * @return {Promise}
   * A promise resolving when the operation
   *  completes
   */
  function errorHandler(transactionId, responseSpec, err) {
    return Promise.resolve().then(() => {
      const response = {};

      response.status = err.httpCode || 500;
      response.headers = Object.assign({}, err.headers || {}, {
        // Avoid caching errors
        'cache-control': 'private',
        // Fallback to the default stringifyer to always be
        // able to display errors
        'content-type':
          responseSpec &&
          responseSpec.contentTypes[0] &&
          STRINGIFYERS[responseSpec.contentTypes[0]]
            ? responseSpec.contentTypes[0]
            : Object.keys(STRINGIFYERS)[0],
      });

      response.body = {
        error: {
          code: err.code || 'E_UNEXPECTED',
          // Enjoy nerdy stuff:
          // https://en.wikipedia.org/wiki/Guru_Meditation
          guruMeditation: transactionId,
        },
      };

      if (ENV && DEBUG_NODE_ENVS.includes(ENV.NODE_ENV)) {
        response.body.error.stack = err.stack;
        response.body.error.params = err.params;
      }

      return response;
    });
  }
}

Initialize an error handler for the
HTTP router
@param  {Object}   services
The services the server depends on
@param  {Object}   [services.ENV]
The services the server depends on
@param  {Array}   [services.DEBUG_NODE_ENVS]
The environnement that activate debugging
(prints stack trace in HTTP errors responses)
@param  {Object} [services.STRINGIFYERS]
The synchronous body stringifyers
@return {Promise}
A promise of a function to handle errors


function dateDifferenceFromNow(date, differenceType) {
    var now = new Date(),
        diffMilliseconds = Math.abs(date - now);

    switch(differenceType) {
        case 'days':
            return dates._getDaysDiff(diffMilliseconds);
        case 'hours':
            return dates._differenceInHours(diffMilliseconds);
        case 'minutes':
            return dates._differenceInMinutes(diffMilliseconds);
        case 'milliseconds':
            return diffMilliseconds;

        default:
            return {
                days: dates._getDaysDiff(diffMilliseconds),
                hours: dates._getHoursDiff(diffMilliseconds),
                minutes: dates._getMinutesDiff(diffMilliseconds),
                milliseconds: diffMilliseconds
            }
    }
}

function dateDifferenceFromNow ( date , differenceType ) { var now = new Date ( ) , diffMilliseconds = Math . abs ( date - now ) ; switch ( differenceType ) { case 'days' : return dates . _getDaysDiff ( diffMilliseconds ) ; case 'hours' : return dates . _differenceInHours ( diffMilliseconds ) ; case 'minutes' : return dates . _differenceInMinutes ( diffMilliseconds ) ; case 'milliseconds' : return diffMilliseconds ; default : return { days : dates . _getDaysDiff ( diffMilliseconds ) , hours : dates . _getHoursDiff ( diffMilliseconds ) , minutes : dates . _getMinutesDiff ( diffMilliseconds ) , milliseconds : diffMilliseconds } } }

Difference between now and date which is passed, in formats 'milliseconds', 'days', 'hours', 'minutes'

@customNeeds -

@since 2.0.0
@category Date

@param {Date} date - The Date to inspect
@param {String} differenceType - [ 'days', 'hours', 'minutes', 'milliseconds', 'all' ]

@returns {Number|Object} Returns the numeric value or object depends on passed differenceType param

@example
example result for now is new Date('12-26-2017')

famulus.dateDifferenceFromNow(new Date('12-20-2017'), 'milliseconds')
// => 555261242

famulus.dateDifferenceFromNow(new Date('12-20-2017'), 'days')
// => 6

famulus.dateDifferenceFromNow(new Date('12-20-2017'), 'hours')
// => 156

Difference between now and date which is passed in formats milliseconds days hours minutes


function consumePair(stream, close, open) {
	const start = stream.pos;
	if (stream.eat(close)) {
		while (!stream.sol()) {
			if (stream.eat(open)) {
				return true;
			}

			stream.pos--;
		}
	}

	stream.pos = start;
	return false;
}

function consumePair ( stream , close , open ) { const start = stream . pos ; if ( stream . eat ( close ) ) { while ( ! stream . sol ( ) ) { if ( stream . eat ( open ) ) { return true ; } stream . pos -- ; } } stream . pos = start ; return false ; }

Consumes full character pair, if possible
@param {StreamReader} stream
@param {Number} close
@param {Number} open
@return {Boolean}

Consumes full character pair if possible


function consumeArray(stream, arr) {
	const start = stream.pos;
	let consumed = false;

	for (let i = arr.length - 1; i >= 0 && !stream.sol(); i--) {
		if (!stream.eat(arr[i])) {
			break;
		}

		consumed = i === 0;
	}

	if (!consumed) {
		stream.pos = start;
	}

	return consumed;
}

function consumeArray ( stream , arr ) { const start = stream . pos ; let consumed = false ; for ( let i = arr . length - 1 ; i >= 0 && ! stream . sol ( ) ; i -- ) { if ( ! stream . eat ( arr [ i ] ) ) { break ; } consumed = i === 0 ; } if ( ! consumed ) { stream . pos = start ; } return consumed ; }

Consumes all character codes from given array, right-to-left, if possible
@param {StreamReader} stream
@param {Number[]} arr

Consumes all character codes from given array right - to - left if possible


function isIdent(c) {
	return c === COLON || c === DASH || isAlpha(c) || isNumber(c);
}

function isIdent ( c ) { return c === COLON || c === DASH || isAlpha ( c ) || isNumber ( c ) ; }

Check if given character code belongs to HTML identifier
@param  {Number}  c
@return {Boolean}


function onCycle(event) {
  if(objectPool.length == 0) {
    throw new Error('Pool ran out of objects');
  }
  console.log(String(event.target));
  initPool();
}

function
onCycle
(
event
)
{
if
(
objectPool
.
length
==
0
)
{
throw
new
Error
(
'Pool ran out of objects'
)
;
}
console
.
log
(
String
(
event
.
target
)
)
;
initPool
(
)
;
}


function json(file) {
  var filename = path.basename(file.path, path.extname(file.path)) + ".json";
  return optional(path.join(path.dirname(file.path), filename)) || {};
}

function json ( file ) { var filename = path . basename ( file . path , path . extname ( file . path ) ) + ".json" ; return optional ( path . join ( path . dirname ( file . path ) , filename ) ) || { } ; }

Load JSON data from a companion file and store in file data.

@param {Object} file Vinyl File object
@return JSON data

Load JSON data from a companion file and store in file data .


function (event) {
      if (event.name === 'goToLevel'
        && event.level !== self.level) {
        self.pushLevel(event.level);
      }
    }

function ( event ) { if ( event . name === 'goToLevel' && event . level !== self . level ) { self . pushLevel ( event . level ) ; } }

As the elevator's doors are currently opened
we push any user request to go to
a level on the level stack.

As the elevator s doors are currently opened we push any user request to go to a level on the level stack .


function (event) {
      if (event.name === 'goToLevel') {
        if (event.level === self.level) {
          this.transitionTo(open);
        } else {
          self.pushLevel(event.level);
          this.transitionTo(moving);
        }
      }
    }

function ( event ) { if ( event . name === 'goToLevel' ) { if ( event . level === self . level ) { this . transitionTo ( open ) ; } else { self . pushLevel ( event . level ) ; this . transitionTo ( moving ) ; } } }

When the elevator's doors are closed,
we wait for a request to move to another
level.

When the elevator s doors are closed we wait for a request to move to another level .


function decryptGCM(encryptedComponents, keyDerivationInfo) {
    // Extract the components
    const encryptedContent = encryptedComponents.content;
    const iv = new Buffer(encryptedComponents.iv, "hex");
    const { auth: tagHex, salt } = encryptedComponents;
    // Prepare tool
    const decryptTool = crypto.createDecipheriv(ENC_ALGORITHM_GCM, keyDerivationInfo.key, iv);
    // Add additional auth data
    decryptTool.setAAD(new Buffer(`${encryptedComponents.iv}${keyDerivationInfo.salt}`, "utf8"));
    // Set auth tag
    decryptTool.setAuthTag(new Buffer(tagHex, "hex"));
    // Perform decryption
    const decryptedText = decryptTool.update(encryptedContent, "base64", "utf8");
    return Promise.resolve(`${decryptedText}${decryptTool.final("utf8")}`);
}

function
decryptGCM
(
encryptedComponents
,
keyDerivationInfo
)
{
// Extract the components
const
encryptedContent
=
encryptedComponents
.
content
;
const
iv
=
new
Buffer
(
encryptedComponents
.
iv
,
"hex"
)
;
const
{
auth
:
tagHex
,
salt
}
=
encryptedComponents
;
// Prepare tool
const
decryptTool
=
crypto
.
createDecipheriv
(
ENC_ALGORITHM_GCM
,
keyDerivationInfo
.
key
,
iv
)
;
// Add additional auth data
decryptTool
.
setAAD
(
new
Buffer
(
`
${
encryptedComponents
.
iv
}
${
keyDerivationInfo
.
salt
}
`
,
"utf8"
)
)
;
// Set auth tag
decryptTool
.
setAuthTag
(
new
Buffer
(
tagHex
,
"hex"
)
)
;
// Perform decryption
const
decryptedText
=
decryptTool
.
update
(
encryptedContent
,
"base64"
,
"utf8"
)
;
return
Promise
.
resolve
(
`
${
decryptedText
}
${
decryptTool
.
final
(
"utf8"
)
}
`
)
;
}

Decrypt text using AES-GCM
@param {EncryptedComponents} encryptedComponents Encrypted components
@param {DerivedKeyInfo} keyDerivationInfo Key derivation information
@returns {Promise.<String>} A promise that resolves with the decrypted string


function encryptCBC(text, keyDerivationInfo, iv) {
    return Promise.resolve().then(() => {
        const ivHex = iv.toString("hex");
        const encryptTool = crypto.createCipheriv(ENC_ALGORITHM_CBC, keyDerivationInfo.key, iv);
        const hmacTool = crypto.createHmac(HMAC_ALGORITHM, keyDerivationInfo.hmac);
        const { rounds } = keyDerivationInfo;
        // Perform encryption
        let encryptedContent = encryptTool.update(text, "utf8", "base64");
        encryptedContent += encryptTool.final("base64");
        // Generate hmac
        hmacTool.update(encryptedContent);
        hmacTool.update(ivHex);
        hmacTool.update(keyDerivationInfo.salt);
        const hmacHex = hmacTool.digest("hex");
        // Output encrypted components
        return {
            mode: "cbc",
            auth: hmacHex,
            iv: ivHex,
            salt: keyDerivationInfo.salt,
            rounds,
            content: encryptedContent
        };
    });
}

function
encryptCBC
(
text
,
keyDerivationInfo
,
iv
)
{
return
Promise
.
resolve
(
)
.
then
(
(
)
=>
{
const
ivHex
=
iv
.
toString
(
"hex"
)
;
const
encryptTool
=
crypto
.
createCipheriv
(
ENC_ALGORITHM_CBC
,
keyDerivationInfo
.
key
,
iv
)
;
const
hmacTool
=
crypto
.
createHmac
(
HMAC_ALGORITHM
,
keyDerivationInfo
.
hmac
)
;
const
{
rounds
}
=
keyDerivationInfo
;
// Perform encryption
let
encryptedContent
=
encryptTool
.
update
(
text
,
"utf8"
,
"base64"
)
;
encryptedContent
+=
encryptTool
.
final
(
"base64"
)
;
// Generate hmac
hmacTool
.
update
(
encryptedContent
)
;
hmacTool
.
update
(
ivHex
)
;
hmacTool
.
update
(
keyDerivationInfo
.
salt
)
;
const
hmacHex
=
hmacTool
.
digest
(
"hex"
)
;
// Output encrypted components
return
{
mode
:
"cbc"
,
auth
:
hmacHex
,
iv
:
ivHex
,
salt
:
keyDerivationInfo
.
salt
,
rounds
,
content
:
encryptedContent
}
;
}
)
;
}

Encrypt text using AES-CBC
@param {String} text The text to encrypt
@param {DerivedKeyInfo} keyDerivationInfo Key derivation information
@param {Buffer} iv A buffer containing the IV
@returns {Promise.<EncryptedComponents>} A promise that resolves with encrypted components


function encryptGCM(text, keyDerivationInfo, iv) {
    return Promise.resolve().then(() => {
        const ivHex = iv.toString("hex");
        const { rounds } = keyDerivationInfo;
        const encryptTool = crypto.createCipheriv(ENC_ALGORITHM_GCM, keyDerivationInfo.key, iv);
        // Add additional auth data
        encryptTool.setAAD(new Buffer(`${ivHex}${keyDerivationInfo.salt}`, "utf8"));
        // Perform encryption
        let encryptedContent = encryptTool.update(text, "utf8", "base64");
        encryptedContent += encryptTool.final("base64");
        // Handle authentication
        const tag = encryptTool.getAuthTag();
        // Output encrypted components
        return {
            mode: "gcm",
            iv: ivHex,
            salt: keyDerivationInfo.salt,
            rounds,
            content: encryptedContent,
            auth: tag.toString("hex")
        };
    });
}

function
encryptGCM
(
text
,
keyDerivationInfo
,
iv
)
{
return
Promise
.
resolve
(
)
.
then
(
(
)
=>
{
const
ivHex
=
iv
.
toString
(
"hex"
)
;
const
{
rounds
}
=
keyDerivationInfo
;
const
encryptTool
=
crypto
.
createCipheriv
(
ENC_ALGORITHM_GCM
,
keyDerivationInfo
.
key
,
iv
)
;
// Add additional auth data
encryptTool
.
setAAD
(
new
Buffer
(
`
${
ivHex
}
${
keyDerivationInfo
.
salt
}
`
,
"utf8"
)
)
;
// Perform encryption
let
encryptedContent
=
encryptTool
.
update
(
text
,
"utf8"
,
"base64"
)
;
encryptedContent
+=
encryptTool
.
final
(
"base64"
)
;
// Handle authentication
const
tag
=
encryptTool
.
getAuthTag
(
)
;
// Output encrypted components
return
{
mode
:
"gcm"
,
iv
:
ivHex
,
salt
:
keyDerivationInfo
.
salt
,
rounds
,
content
:
encryptedContent
,
auth
:
tag
.
toString
(
"hex"
)
}
;
}
)
;
}

Encrypt text using AES-GCM
@param {String} text The text to encrypt
@param {DerivedKeyInfo} keyDerivationInfo Key derivation information
@param {Buffer} iv A buffer containing the IV
@returns {Promise.<EncryptedComponents>} A promise that resolves with encrypted components


function unpackEncryptedContent(encryptedContent) {
    const [content, iv, salt, auth, roundsRaw, methodRaw] = encryptedContent.split("$");
    // iocane was originally part of Buttercup's core package and used defaults from that originally.
    // There will be 4 components for pre 0.15.0 archives, and 5 in newer archives. The 5th component
    // is the pbkdf2 round count, which is optional:
    const rounds = roundsRaw ? parseInt(roundsRaw, 10) : PBKDF2_ROUND_DEFAULT;
    // Originally only "cbc" was supported, but GCM was added in version 1
    const method = methodRaw || "cbc";
    return {
        content,
        iv,
        salt,
        auth,
        rounds,
        method
    };
}

Unpack encrypted content components from an encrypted string
@param {String} encryptedContent The encrypted string
@returns {EncryptedComponents} The extracted components
@throws {Error} Throws if the number of components is incorrect


function deriveFromPassword(pbkdf2Gen, password, salt, rounds, generateHMAC = true) {
    if (!password) {
        return Promise.reject(new Error("Failed deriving key: Password must be provided"));
    }
    if (!salt) {
        return Promise.reject(new Error("Failed deriving key: Salt must be provided"));
    }
    if (!rounds || rounds <= 0) {
        return Promise.reject(new Error("Failed deriving key: Rounds must be greater than 0"));
    }
    const bits = generateHMAC ? (PASSWORD_KEY_SIZE + HMAC_KEY_SIZE) * 8 : PASSWORD_KEY_SIZE * 8;
    return pbkdf2Gen(password, salt, rounds, bits)
        .then(derivedKeyData => derivedKeyData.toString("hex"))
        .then(function(derivedKeyHex) {
            const dkhLength = derivedKeyHex.length;
            const keyBuffer = generateHMAC
                ? new Buffer(derivedKeyHex.substr(0, dkhLength / 2), "hex")
                : new Buffer(derivedKeyHex, "hex");
            const output = {
                salt: salt,
                key: keyBuffer,
                rounds: rounds
            };
            if (generateHMAC) {
                output.hmac = new Buffer(derivedKeyHex.substr(dkhLength / 2, dkhLength / 2), "hex");
            }
            return output;
        });
}

Derived key info
@typedef DerivedKeyInfo
@property {String} salt - The salt used
@property {Buffer} key - The derived key
@property {Buffer} hmac - The HMAC
@property {Number} rounds - The number of rounds used

Derive a key from a password
@param {Function} pbkdf2Gen The generator method
@param {String} password The password to derive from
@param {String} salt The salt (Optional)
@param {Number} rounds The number of iterations
@param {Boolean=} generateHMAC Enable HMAC key generation
@throws {Error} Rejects if no password is provided
@throws {Error} Rejects if no salt is provided
@throws {Error} Rejects if no rounds are provided
@returns {Promise.<DerivedKeyInfo>} A promise that resolves with an object (DerivedKeyInfo)


function pbkdf2(password, salt, rounds, bits) {
    return new Promise((resolve, reject) => {
        deriveKey(password, salt, rounds, bits / 8, DERIVED_KEY_ALGORITHM, (err, key) => {
            if (err) {
                return reject(err);
            }
            return resolve(key);
        });
    });
}

function pbkdf2 ( password , salt , rounds , bits ) { return new Promise ( ( resolve , reject ) => { deriveKey ( password , salt , rounds , bits / 8 , DERIVED_KEY_ALGORITHM , ( err , key ) => { if ( err ) { return reject ( err ) ; } return resolve ( key ) ; } ) ; } ) ; }

The default PBKDF2 function
@param {String} password The password to use
@param {String} salt The salt to use
@param {Number} rounds The number of iterations
@param {Number} bits The size of the key to generate, in bits
@returns {Promise.<Buffer>} A Promise that resolves with the hash


function createEncodeStream(schema) {
  const stream = new BinaryStream({
    readableObjectMode: false,
    writableObjectMode: true,
    transform: transformEncode,
  });

  stream[kschema] = schema;
  return stream;
}

function createEncodeStream ( schema ) { const stream = new BinaryStream ( { readableObjectMode : false , writableObjectMode : true , transform : transformEncode , } ) ; stream [ kschema ] = schema ; return stream ; }

Create transform stream to encode objects into Buffer.
@param {Object} [schema]
@returns {EncodeStream}

Create transform stream to encode objects into Buffer .


function createDecodeStream(bufOrSchema) {
  let schema = null;
  const isBuffer = Buffer.isBuffer(bufOrSchema);

  if (!isBuffer) {
    schema = bufOrSchema;
  }

  const stream = new BinaryStream({
    transform: transformDecode,
    readableObjectMode: true,
    writableObjectMode: false,
  });

  stream[kschema] = schema;

  if (isBuffer) {
    stream.append(bufOrSchema);
  }

  return stream;
}

function createDecodeStream ( bufOrSchema ) { let schema = null ; const isBuffer = Buffer . isBuffer ( bufOrSchema ) ; if ( ! isBuffer ) { schema = bufOrSchema ; } const stream = new BinaryStream ( { transform : transformDecode , readableObjectMode : true , writableObjectMode : false , } ) ; stream [ kschema ] = schema ; if ( isBuffer ) { stream . append ( bufOrSchema ) ; } return stream ; }

Create transform stream to decode binary data into object.
@param {Buffer|Object} [bufOrSchema]
@returns {DecodeStream}

Create transform stream to decode binary data into object .


function erdosRenyi(GraphClass, options) {
  if (!isGraphConstructor(GraphClass))
    throw new Error('graphology-generators/random/erdos-renyi: invalid Graph constructor.');

  var order = options.order,
      probability = options.probability,
      rng = options.rng || Math.random;

  var graph = new GraphClass();

  // If user gave a size, we need to compute probability
  if (typeof options.approximateSize === 'number') {
    var densityFunction = density[graph.type + 'Density'];
    probability = densityFunction(order, options.approximateSize);
  }

  if (typeof order !== 'number' || order <= 0)
    throw new Error('graphology-generators/random/erdos-renyi: invalid `order`. Should be a positive number.');

  if (typeof probability !== 'number' || probability < 0 || probability > 1)
    throw new Error('graphology-generators/random/erdos-renyi: invalid `probability`. Should be a number between 0 and 1. Or maybe you gave an `approximateSize` exceeding the graph\'s density.');

  if (typeof rng !== 'function')
    throw new Error('graphology-generators/random/erdos-renyi: invalid `rng`. Should be a function.');

  for (var i = 0; i < order; i++)
    graph.addNode(i);

  if (probability <= 0)
    return graph;

  if (order > 1) {
    var iterator = combinations(range(order), 2),
        path,
        step;

    while ((step = iterator.next(), !step.done)) {
      path = step.value;

      if (graph.type !== 'directed') {
        if (rng() < probability)
          graph.addUndirectedEdge(path[0], path[1]);
      }

      if (graph.type !== 'undirected') {

        if (rng() < probability)
          graph.addDirectedEdge(path[0], path[1]);

        if (rng() < probability)
          graph.addDirectedEdge(path[1], path[0]);
      }
    }
  }

  return graph;
}

Generates a binomial graph graph with n nodes.

@param  {Class}    GraphClass    - The Graph Class to instantiate.
@param  {object}   options       - Options:
@param  {number}     order       - Number of nodes in the graph.
@param  {number}     probability - Probability for edge creation.
@param  {function}   rng         - Custom RNG function.
@return {Graph}

Generates a binomial graph graph with n nodes .


function erdosRenyiSparse(GraphClass, options) {
  if (!isGraphConstructor(GraphClass))
    throw new Error('graphology-generators/random/erdos-renyi: invalid Graph constructor.');

  var order = options.order,
      probability = options.probability,
      rng = options.rng || Math.random;

  var graph = new GraphClass();

  // If user gave a size, we need to compute probability
  if (typeof options.approximateSize === 'number') {
    var densityFunction = density[graph.type + 'Density'];
    probability = densityFunction(order, options.approximateSize);
  }

  if (typeof order !== 'number' || order <= 0)
    throw new Error('graphology-generators/random/erdos-renyi: invalid `order`. Should be a positive number.');

  if (typeof probability !== 'number' || probability < 0 || probability > 1)
    throw new Error('graphology-generators/random/erdos-renyi: invalid `probability`. Should be a number between 0 and 1. Or maybe you gave an `approximateSize` exceeding the graph\'s density.');

  if (typeof rng !== 'function')
    throw new Error('graphology-generators/random/erdos-renyi: invalid `rng`. Should be a function.');

  for (var i = 0; i < order; i++)
    graph.addNode(i);

  if (probability <= 0)
    return graph;

  var w = -1,
      lp = Math.log(1 - probability),
      lr,
      v;

  if (graph.type !== 'undirected') {
    v = 0;

    while (v < order) {
      lr = Math.log(1 - rng());
      w += 1 + ((lr / lp) | 0);

      // Avoiding self loops
      if (v === w) {
        w++;
      }

      while (v < order && order <= w) {
        w -= order;
        v++;

        // Avoiding self loops
        if (v === w)
          w++;
      }

      if (v < order)
        graph.addDirectedEdge(v, w);
    }
  }

  w = -1;

  if (graph.type !== 'directed') {
    v = 1;

    while (v < order) {
      lr = Math.log(1 - rng());

      w += 1 + ((lr / lp) | 0);

      while (w >= v && v < order) {
        w -= v;
        v++;
      }

      if (v < order)
        graph.addUndirectedEdge(v, w);
    }
  }

  return graph;
}

Generates a binomial graph graph with n nodes using a faster algorithm
for sparse graphs.

@param  {Class}    GraphClass    - The Graph Class to instantiate.
@param  {object}   options       - Options:
@param  {number}     order       - Number of nodes in the graph.
@param  {number}     probability - Probability for edge creation.
@param  {function}   rng         - Custom RNG function.
@return {Graph}

Generates a binomial graph graph with n nodes using a faster algorithm for sparse graphs .


function single_curve(d, ctx) {

        var centroids = compute_centroids(d);
        var cps = compute_control_points(centroids);

        ctx.moveTo(cps[0].e(1), cps[0].e(2));
        for (var i = 1; i < cps.length; i += 3) {
            if (__.showControlPoints) {
                for (var j = 0; j < 3; j++) {
                    ctx.fillRect(cps[i+j].e(1), cps[i+j].e(2), 2, 2);
                }
            }
            ctx.bezierCurveTo(cps[i].e(1), cps[i].e(2), cps[i+1].e(1), cps[i+1].e(2), cps[i+2].e(1), cps[i+2].e(2));
        }
    }

function single_curve ( d , ctx ) { var centroids = compute_centroids ( d ) ; var cps = compute_control_points ( centroids ) ; ctx . moveTo ( cps [ 0 ] . e ( 1 ) , cps [ 0 ] . e ( 2 ) ) ; for ( var i = 1 ; i < cps . length ; i += 3 ) { if ( __ . showControlPoints ) { for ( var j = 0 ; j < 3 ; j ++ ) { ctx . fillRect ( cps [ i + j ] . e ( 1 ) , cps [ i + j ] . e ( 2 ) , 2 , 2 ) ; } } ctx . bezierCurveTo ( cps [ i ] . e ( 1 ) , cps [ i ] . e ( 2 ) , cps [ i + 1 ] . e ( 1 ) , cps [ i + 1 ] . e ( 2 ) , cps [ i + 2 ] . e ( 1 ) , cps [ i + 2 ] . e ( 2 ) ) ; } }


function color_path(d, ctx) {
        ctx.beginPath();
        if ((__.bundleDimension !== null && __.bundlingStrength > 0) || __.smoothness > 0) {
            single_curve(d, ctx);
        } else {
            single_path(d, ctx);
        }
        ctx.stroke();
    }

function color_path ( d , ctx ) { ctx . beginPath ( ) ; if ( ( __ . bundleDimension !== null && __ . bundlingStrength > 0 ) || __ . smoothness > 0 ) { single_curve ( d , ctx ) ; } else { single_path ( d , ctx ) ; } ctx . stroke ( ) ; }


function paths(data, ctx) {
        ctx.clearRect(-1, -1, w() + 2, h() + 2);
        ctx.beginPath();
        data.forEach(function(d) {
            if ((__.bundleDimension !== null && __.bundlingStrength > 0) || __.smoothness > 0) {
                single_curve(d, ctx);
            } else {
                single_path(d, ctx);
            }
        });
        ctx.stroke();
    }

function paths ( data , ctx ) { ctx . clearRect ( - 1 , - 1 , w ( ) + 2 , h ( ) + 2 ) ; ctx . beginPath ( ) ; data . forEach ( function ( d ) { if ( ( __ . bundleDimension !== null && __ . bundlingStrength > 0 ) || __ . smoothness > 0 ) { single_curve ( d , ctx ) ; } else { single_path ( d , ctx ) ; } } ) ; ctx . stroke ( ) ; }


function brushUpdated(newSelection) {
        __.brushed = newSelection;
        events.brush.call(pc,__.brushed);
        pc.renderBrushed();
    }

function brushUpdated ( newSelection ) { __ . brushed = newSelection ; events . brush . call ( pc , __ . brushed ) ; pc . renderBrushed ( ) ; }

This function can be used for 'live' updates of brushes. That is, during the specification of a brush, this method can be called to update the view.  @param newSelection - The new set of data items that is currently contained by the brushes

This function can be used for live updates of brushes . That is during the specification of a brush this method can be called to update the view .


function selected() {
            var actives = d3.keys(__.dimensions).filter(is_brushed),
                extents = actives.map(function(p) { return brushes[p].extent(); });

            // We don't want to return the full data set when there are no axes brushed.
            // Actually, when there are no axes brushed, by definition, no items are
            // selected. So, let's avoid the filtering and just return false.
            //if (actives.length === 0) return false;

            // Resolves broken examples for now. They expect to get the full dataset back from empty brushes
            if (actives.length === 0) return __.data;

            // test if within range
            var within = {
                "date": function(d,p,dimension) {
                    if (typeof __.dimensions[p].yscale.rangePoints === "function") { // if it is ordinal
                        return extents[dimension][0] <= __.dimensions[p].yscale(d[p]) && __.dimensions[p].yscale(d[p]) <= extents[dimension][1]
                    } else {
                        return extents[dimension][0] <= d[p] && d[p] <= extents[dimension][1]
                    }
                },
                "number": function(d,p,dimension) {
                    if (typeof __.dimensions[p].yscale.rangePoints === "function") { // if it is ordinal
                        return extents[dimension][0] <= __.dimensions[p].yscale(d[p]) && __.dimensions[p].yscale(d[p]) <= extents[dimension][1]
                    } else {
                        return extents[dimension][0] <= d[p] && d[p] <= extents[dimension][1]
                    }
                },
                "string": function(d,p,dimension) {
                    return extents[dimension][0] <= __.dimensions[p].yscale(d[p]) && __.dimensions[p].yscale(d[p]) <= extents[dimension][1]
                }
            };

            return __.data
                .filter(function(d) {
                    switch(brush.predicate) {
                        case "AND":
                            return actives.every(function(p, dimension) {
                                return within[__.dimensions[p].type](d,p,dimension);
                            });
                        case "OR":
                            return actives.some(function(p, dimension) {
                                return within[__.dimensions[p].type](d,p,dimension);
                            });
                        default:
                            throw new Error("Unknown brush predicate " + __.brushPredicate);
                    }
                });
        }


function consecutive(first, second) {
                    var length = d3.keys(__.dimensions).length;
                    return d3.keys(__.dimensions).some(function(d, i) {
                        return (d === first)
                            ? i + i < length && __.dimensions[i + 1] === second
                            : false;
                    });
                }

function consecutive ( first , second ) { var length = d3 . keys ( __ . dimensions ) . length ; return d3 . keys ( __ . dimensions ) . some ( function ( d , i ) { return ( d === first ) ? i + i < length && __ . dimensions [ i + 1 ] === second : false ; } ) ; }

Checks if the first dimension is directly left of the second dimension.

Checks if the first dimension is directly left of the second dimension .


function convertProperty(originalKey, originalValue, isRtl) {
  const key = getPropertyDoppelganger(originalKey, isRtl)
  const value = getValueDoppelganger(key, originalValue, isRtl)
  return {key, value}
}

function convertProperty ( originalKey , originalValue , isRtl ) { const key = getPropertyDoppelganger ( originalKey , isRtl ) const value = getValueDoppelganger ( key , originalValue , isRtl ) return { key , value } }

Logically converts a property and its value based on the flow direction context
@param {String} originalKey the original property key
@param {Number|String|Object} originalValue the original css property value
@param {Boolean} isRtl Should conversion happen in RTL context?
@return {Object} the new {key, value} pair


function getPropertyDoppelganger(property, isRtl) {
  const convertedProperty = isRtl
    ? propertiesToConvert.rtl[property]
    : propertiesToConvert.ltr[property]

  return convertedProperty || property
}

function getPropertyDoppelganger ( property , isRtl ) { const convertedProperty = isRtl ? propertiesToConvert . rtl [ property ] : propertiesToConvert . ltr [ property ] return convertedProperty || property }

Logically gets the direction of the given property based on the flow direction context
@param {String} property the name of the property
@param {Boolean} isRtl Should conversion happen in RTL context?
@return {String} the name of the RTL property


function ReadFileCache(sourceDir, charset) {
    assert.ok(this instanceof ReadFileCache);
    assert.strictEqual(typeof sourceDir, "string");

    this.charset = charset;

    EventEmitter.call(this);

    Object.defineProperties(this, {
        sourceDir: { value: sourceDir },
        sourceCache: { value: {} }
    });
}

function ReadFileCache ( sourceDir , charset ) { assert . ok ( this instanceof ReadFileCache ) ; assert . strictEqual ( typeof sourceDir , "string" ) ; this . charset = charset ; EventEmitter . call ( this ) ; Object . defineProperties ( this , { sourceDir : { value : sourceDir } , sourceCache : { value : { } } } ) ; }

ReadFileCache is an EventEmitter subclass that caches file contents in
memory so that subsequent calls to readFileP return the same contents,
regardless of any changes in the underlying file.

ReadFileCache is an EventEmitter subclass that caches file contents in memory so that subsequent calls to readFileP return the same contents regardless of any changes in the underlying file .


function done(err, resource) {
            totalRequestElapsed += ((new Date().getTime()) - started);
            ++totalRequests;
            stats.avgFetchTime = parseInt(totalRequestElapsed / totalRequests);
            if (err || verbose) util.log('cache|execute|done|err='+err+'|result='+(resource ? 'found':'null'));
            if (err) {
                ++stats.failed;
            }
            if (!err && defaultCacheTTL) {    // ttl ===  0 --> expire imediatly.
                if (stats.inCache >= defaultCacheSize) {
                    weedOutCache();
                }
                var now = new Date().getTime();
                resourceCache[key] = {
                    'key'   : key,
                    'epoch' : now,
                    'access': now,
                    'expire': defaultCacheTTL,
                    'hits'  : 0,
                    'data'  : resource
                };
                ++stats.inCache;
            }

            var pendingRequests = requestQueue[key];
            delete requestQueue[key];
            for (var i = 0, size = pendingRequests.length ; i < size ; ++i) {
                if (debug) util.log('cache|calling='+i+'|err='+err+'|resource='+(resource ? 'found':'null'));
                if (!err && defaultCacheTTL) {
                    ++resourceCache[key].hits;
                }
                pendingRequests[i].call(this, err, resource, resourceCache[key]);
                --stats.waiting;
            }
            --stats.fetching;
            if (stats.fetching === 0 && stats.waiting === 0) {
                self.emit('stats', stats);
            } else {
                bufferedEmitter.call(self, 'stats', stats);
            }
        }

function
done
(
err
,
resource
)
{
totalRequestElapsed
+=
(
(
new
Date
(
)
.
getTime
(
)
)
started
)
;
++
totalRequests
;
stats
.
avgFetchTime
=
parseInt
(
totalRequestElapsed
/
totalRequests
)
;
if
(
err
||
verbose
)
util
.
log
(
'cache|execute|done|err='
+
err
+
'|result='
+
(
resource
'found'
:
'null'
)
)
;
if
(
err
)
{
++
stats
.
failed
;
}
if
(
!
err
&&
defaultCacheTTL
)
{
// ttl ===  0 --> expire imediatly.
if
(
stats
.
inCache
>=
defaultCacheSize
)
{
weedOutCache
(
)
;
}
var
now
=
new
Date
(
)
.
getTime
(
)
;
resourceCache
[
key
]
=
{
'key'
:
key
,
'epoch'
:
now
,
'access'
:
now
,
'expire'
:
defaultCacheTTL
,
'hits'
:
0
,
'data'
:
resource
}
;
++
stats
.
inCache
;
}
var
pendingRequests
=
requestQueue
[
key
]
;
delete
requestQueue
[
key
]
;
for
(
var
i
=
0
,
size
=
pendingRequests
.
length
;
i
<
size
;
++
i
)
{
if
(
debug
)
util
.
log
(
'cache|calling='
+
i
+
'|err='
+
err
+
'|resource='
+
(
resource
'found'
:
'null'
)
)
;
if
(
!
err
&&
defaultCacheTTL
)
{
++
resourceCache
[
key
]
.
hits
;
}
pendingRequests
[
i
]
.
call
(
this
,
err
,
resource
,
resourceCache
[
key
]
)
;
stats
.
waiting
;
}
stats
.
fetching
;
if
(
stats
.
fetching
===
0
&&
stats
.
waiting
===
0
)
{
self
.
emit
(
'stats'
,
stats
)
;
}
else
{
bufferedEmitter
.
call
(
self
,
'stats'
,
stats
)
;
}
}

Fetch the resource and call 'done' when it is fetched

Fetch the resource and call done when it is fetched


function(options) {
  options = (options||{});
  this.agent = options.agent;
  this.defaults = options.defaults||{};
  this.log = options.logger||(new Ax({ level: "info" }));
  this._sharedCookieJar = new CookieJar();
  this.logCurl = options.logCurl || false;
}

function ( options ) { options = ( options || { } ) ; this . agent = options . agent ; this . defaults = options . defaults || { } ; this . log = options . logger || ( new Ax ( { level : "info" } ) ) ; this . _sharedCookieJar = new CookieJar ( ) ; this . logCurl = options . logCurl || false ; }

Shred takes some options, including a logger and request defaults.

Shred takes some options including a logger and request defaults .


function(level,message) {
  var debug = (level=="debug"||level=="error");
  if (!message) { return message.toString(); }
  if (typeof(message) == "object") {
    if (message instanceof Error && debug) {
      return message.stack;
    } else {
      return inspect(message);
    }
  } else {
    return message.toString();
  }
}

function ( level , message ) { var debug = ( level == "debug" || level == "error" ) ; if ( ! message ) { return message . toString ( ) ; } if ( typeof ( message ) == "object" ) { if ( message instanceof Error && debug ) { return message . stack ; } else { return inspect ( message ) ; } } else { return message . toString ( ) ; } }

this is a quick-and-dirty logger. there are other nicer loggers out there but the ones i found were also somewhat involved. this one has a Ruby logger type interface  we can easily replace this, provide the info, debug, etc. methods are the same. or, we can change Haiku to use a more standard node.js interface

this is a quick - and - dirty logger . there are other nicer loggers out there but the ones i found were also somewhat involved . this one has a Ruby logger type interface we can easily replace this provide the info debug etc . methods are the same . or we can change Haiku to use a more standard node . js interface


function(options) {
  this.log = options.logger;
  this.cookieJar = options.cookieJar;
  this.encoding = options.encoding;
  this.logCurl = options.logCurl;
  processOptions(this,options||{});
  createRequest(this);
}

function ( options ) { this . log = options . logger ; this . cookieJar = options . cookieJar ; this . encoding = options . encoding ; this . logCurl = options . logCurl ; processOptions ( this , options || { } ) ; createRequest ( this ) ; }

The Shred object itself constructs the `Request` object. You should rarely need to do this directly.

The Shred object itself constructs the Request object . You should rarely need to do this directly .


function(request,options) {

  request.log.debug("Processing request options ..");

  // We'll use `request.emitter` to manage the `on` event handlers.
  request.emitter = (new Emitter);

  request.agent = options.agent;

  // Set up the handlers ...
  if (options.on) {
    for (var key in options.on) {
      if (options.on.hasOwnProperty(key)) {
        request.emitter.on(key, options.on[key]);
      }
    }
  }

  // Make sure we were give a URL or a host
  if (!options.url && !options.host) {
    request.emitter.emit("request_error",
        new Error("No url or url options (host, port, etc.)"));
    return;
  }

  // Allow for the [use of a proxy](http://www.jmarshall.com/easy/http/#proxies).

  if (options.url) {
    if (options.proxy) {
      request.url = options.proxy;
      request.path = options.url;
    } else {
      request.url = options.url;
    }
  }

  // Set the remaining options.
  request.query = options.query||options.parameters||request.query ;
  request.method = options.method;
  request.setHeader("user-agent",options.agent||"Shred");
  request.setHeaders(options.headers);

  if (request.cookieJar) {
    var cookies = request.cookieJar.getCookies( CookieAccessInfo( request.host, request.path ) );
    if (cookies.length) {
      var cookieString = request.getHeader('cookie')||'';
      for (var cookieIndex = 0; cookieIndex < cookies.length; ++cookieIndex) {
          if ( cookieString.length && cookieString[ cookieString.length - 1 ] != ';' )
          {
              cookieString += ';';
          }
          cookieString += cookies[ cookieIndex ].name + '=' + cookies[ cookieIndex ].value + ';';
      }
      request.setHeader("cookie", cookieString);
    }
  }

  // The content entity can be set either using the `body` or `content` attributes.
  if (options.body||options.content) {
    request.content = options.body||options.content;
  }
  request.timeout = options.timeout;

}

`processOptions` is called from the constructor to handle all the work associated with making sure we do our best to ensure we have a valid request.

processOptions is called from the constructor to handle all the work associated with making sure we do our best to ensure we have a valid request .


function(event) {
        var emitter = request.emitter;
        var textStatus = STATUS_CODES[response.status] ? STATUS_CODES[response.status].toLowerCase() : null;
        if (emitter.listeners(response.status).length > 0 || emitter.listeners(textStatus).length > 0) {
          emitter.emit(response.status, response);
          emitter.emit(textStatus, response);
        } else {
          if (emitter.listeners(event).length>0) {
            emitter.emit(event, response);
          } else if (!response.isRedirect) {
            emitter.emit("response", response);
            //console.warn("Request has no event listener for status code " + response.status);
          }
        }
      }

Set up some event magic. The precedence is given first to status-specific handlers, then to responses for a given event, and then finally to the more general `response` handler. In the last case, we need to first make sure we're not dealing with a a redirect.

Set up some event magic . The precedence is given first to status - specific handlers then to responses for a given event and then finally to the more general response handler . In the last case we need to first make sure we re not dealing with a a redirect .


function (req) {
  var headers = req.getHeaders();
  var headerString = "";

  for (var key in headers) {
    headerString += '-H "' + key + ": " + headers[key] + '" ';
  }

  var bodyString = ""

  if (req.content) {
    bodyString += "-d '" + req.content.body + "' ";
  }

  var query = req.query ? '?' + req.query : "";

  console.log("curl " +
    "-X " + req.method.toUpperCase() + " " +
    req.scheme + "://" + req.host + ":" + req.port + req.path + query + " " +
    headerString +
    bodyString
  );
}

function
(
req
)
{
var
headers
=
req
.
getHeaders
(
)
;
var
headerString
=
""
;
for
(
var
key
in
headers
)
{
headerString
+=
'-H "'
+
key
+
": "
+
headers
[
key
]
+
'" '
;
}
var
bodyString
=
""
if
(
req
.
content
)
{
bodyString
+=
"-d '"
+
req
.
content
.
body
+
"' "
;
}
var
query
=
req
.
query
'?'
+
req
.
query
:
""
;
console
.
log
(
"curl "
+
"-X "
+
req
.
method
.
toUpperCase
(
)
+
" "
+
req
.
scheme
+
"://"
+
req
.
host
+
":"
+
req
.
port
+
req
.
path
+
query
+
" "
+
headerString
+
bodyString
)
;
}


function(raw, request, callback) {
  var response = this;
  this._raw = raw;

  // The `._setHeaders` method is "private"; you can't otherwise set headers on
  // the response.
  this._setHeaders.call(this,raw.headers);

  // store any cookies
  if (request.cookieJar && this.getHeader('set-cookie')) {
    var cookieStrings = this.getHeader('set-cookie');
    var cookieObjs = []
      , cookie;

    for (var i = 0; i < cookieStrings.length; i++) {
      var cookieString = cookieStrings[i];
      if (!cookieString) {
        continue;
      }

      if (!cookieString.match(/domain\=/i)) {
        cookieString += '; domain=' + request.host;
      }

      if (!cookieString.match(/path\=/i)) {
        cookieString += '; path=' + request.path;
      }

      try {
        cookie = new Cookie(cookieString);
        if (cookie) {
          cookieObjs.push(cookie);
        }
      } catch (e) {
        console.warn("Tried to set bad cookie: " + cookieString);
      }
    }

    request.cookieJar.setCookies(cookieObjs);
  }

  this.request = request;
  this.client = request.client;
  this.log = this.request.log;

  // Stream the response content entity and fire the callback when we're done.
  // Store the incoming data in a array of Buffers which we concatinate into one
  // buffer at the end.  We need to use buffers instead of strings here in order
  // to preserve binary data.
  var chunkBuffers = [];
  var dataLength = 0;
  raw.on("data", function(chunk) {
    chunkBuffers.push(chunk);
    dataLength += chunk.length;
  });
  raw.on("end", function() {
    var body;
    if (typeof Buffer === 'undefined') {
      // Just concatinate into a string
      body = chunkBuffers.join('');
    } else {
      // Initialize new buffer and add the chunks one-at-a-time.
      body = new Buffer(dataLength);
      for (var i = 0, pos = 0; i < chunkBuffers.length; i++) {
        chunkBuffers[i].copy(body, pos);
        pos += chunkBuffers[i].length;
      }
    }

    var setBodyAndFinish = function (body) {
      response._body = new Content({
        body: body,
        type: response.getHeader("Content-Type")
      });
      callback(response);
    }

    if (zlib && response.getHeader("Content-Encoding") === 'gzip'){
      zlib.gunzip(body, function (err, gunzippedBody) {
        if (Iconv && response.request.encoding){
          body = Iconv.fromEncoding(gunzippedBody,response.request.encoding);
        } else {
          body = gunzippedBody.toString();
        }
        setBodyAndFinish(body);
      })
    }
    else{
       if (response.request.encoding){
            body = Iconv.fromEncoding(body,response.request.encoding);
        }
      setBodyAndFinish(body);
    }
  });
}

Construct a `Response` object. You should never have to do this directly. The `Request` object handles this, getting the raw response object and passing it in here, along with the request. The callback allows us to stream the response and then use the callback to let the request know when it's ready.

Construct a Response object . You should never have to do this directly . The Request object handles this getting the raw response object and passing it in here along with the request . The callback allows us to stream the response and then use the callback to let the request know when it s ready .


function(constructor) {
    constructor.prototype.getHeader = function(name) { return getHeader(this,name); };
    constructor.prototype.getHeaders = function() { return getHeaders(this,arguments); };
  }

function ( constructor ) { constructor . prototype . getHeader = function ( name ) { return getHeader ( this , name ) ; } ; constructor . prototype . getHeaders = function ( ) { return getHeaders ( this , arguments ) ; } ; }


function(constructor) {
    constructor.prototype._setHeader = function(key,value) { return setHeader(this,key,value); };
    constructor.prototype._setHeaders = function(hash) { return setHeaders(this,hash); };
  }

function ( constructor ) { constructor . prototype . _setHeader = function ( key , value ) { return setHeader ( this , key , value ) ; } ; constructor . prototype . _setHeaders = function ( hash ) { return setHeaders ( this , hash ) ; } ; }


function(constructor) {
    constructor.prototype.setHeader = function(key,value) { return setHeader(this,key,value); };
    constructor.prototype.setHeaders = function(hash) { return setHeaders(this,hash); };
  }

function ( constructor ) { constructor . prototype . setHeader = function ( key , value ) { return setHeader ( this , key , value ) ; } ; constructor . prototype . setHeaders = function ( hash ) { return setHeaders ( this , hash ) ; } ; }


function(constructor) {
    constructor.prototype.getHeader = function(name) { return getHeader(this,name); };
    constructor.prototype.getHeaders = function() { return getHeaders(this,arguments); };
    constructor.prototype.setHeader = function(key,value) { return setHeader(this,key,value); };
    constructor.prototype.setHeaders = function(hash) { return setHeaders(this,hash); };
  }

function ( constructor ) { constructor . prototype . getHeader = function ( name ) { return getHeader ( this , name ) ; } ; constructor . prototype . getHeaders = function ( ) { return getHeaders ( this , arguments ) ; } ; constructor . prototype . setHeader = function ( key , value ) { return setHeader ( this , key , value ) ; } ; constructor . prototype . setHeaders = function ( hash ) { return setHeaders ( this , hash ) ; } ; }


function(encoding) {
        var enc = encoding || "utf8";
        var codecOptions = undefined;
        while (1) {
            if (getType(enc) === "String")
                enc = enc.replace(/[- ]/g, "").toLowerCase();
            var codec = iconv.encodings[enc];
            var type = getType(codec);
            if (type === "String") {
                // Link to other encoding.
                codecOptions = {originalEncoding: enc};
                enc = codec;
            }
            else if (type === "Object" && codec.type != undefined) {
                // Options for other encoding.
                codecOptions = codec;
                enc = codec.type;
            }
            else if (type === "Function")
                // Codec itself.
                return codec(codecOptions);
            else
                throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '"+enc+"')");
        }
    }

function
(
encoding
)
{
var
enc
=
encoding
||
"utf8"
;
var
codecOptions
=
undefined
;
while
(
1
)
{
if
(
getType
(
enc
)
===
"String"
)
enc
=
enc
.
replace
(
/
[- ]
/
g
,
""
)
.
toLowerCase
(
)
;
var
codec
=
iconv
.
encodings
[
enc
]
;
var
type
=
getType
(
codec
)
;
if
(
type
===
"String"
)
{
// Link to other encoding.
codecOptions
=
{
originalEncoding
:
enc
}
;
enc
=
codec
;
}
else
if
(
type
===
"Object"
&&
codec
.
type
!=
undefined
)
{
// Options for other encoding.
codecOptions
=
codec
;
enc
=
codec
.
type
;
}
else
if
(
type
===
"Function"
)
// Codec itself.
return
codec
(
codecOptions
)
;
else
throw
new
Error
(
"Encoding not recognized: '"
+
encoding
+
"' (searched as: '"
+
enc
+
"')"
)
;
}
}


function(options) {
            // Prepare chars if needed
            if (!options.chars || (options.chars.length !== 128 && options.chars.length !== 256))
                throw new Error("Encoding '"+options.type+"' has incorrect 'chars' (must be of len 128 or 256)");

            if (options.chars.length === 128)
                options.chars = asciiString + options.chars;

            if (!options.charsBuf) {
                options.charsBuf = new Buffer(options.chars, 'ucs2');
            }

            if (!options.revCharsBuf) {
                options.revCharsBuf = new Buffer(65536);
                var defChar = iconv.defaultCharSingleByte.charCodeAt(0);
                for (var i = 0; i < options.revCharsBuf.length; i++)
                    options.revCharsBuf[i] = defChar;
                for (var i = 0; i < options.chars.length; i++)
                    options.revCharsBuf[options.chars.charCodeAt(i)] = i;
            }

            return {
                toEncoding: function(str) {
                    str = ensureString(str);

                    var buf = new Buffer(str.length);
                    var revCharsBuf = options.revCharsBuf;
                    for (var i = 0; i < str.length; i++)
                        buf[i] = revCharsBuf[str.charCodeAt(i)];

                    return buf;
                },
                fromEncoding: function(buf) {
                    buf = ensureBuffer(buf);

                    // Strings are immutable in JS -> we use ucs2 buffer to speed up computations.
                    var charsBuf = options.charsBuf;
                    var newBuf = new Buffer(buf.length*2);
                    var idx1 = 0, idx2 = 0;
                    for (var i = 0, _len = buf.length; i < _len; i++) {
                        idx1 = buf[i]*2; idx2 = i*2;
                        newBuf[idx2] = charsBuf[idx1];
                        newBuf[idx2+1] = charsBuf[idx1+1];
                    }
                    return newBuf.toString('ucs2');
                }
            };
        }


function(options) {
            var table = options.table, key, revCharsTable = options.revCharsTable;
            if (!table) {
                throw new Error("Encoding '" + options.type +"' has incorect 'table' option");
            }
            if(!revCharsTable) {
                revCharsTable = options.revCharsTable = {};
                for (key in table) {
                    revCharsTable[table[key]] = parseInt(key);
                }
            }

            return {
                toEncoding: function(str) {
                    str = ensureString(str);
                    var strLen = str.length;
                    var bufLen = strLen;
                    for (var i = 0; i < strLen; i++)
                        if (str.charCodeAt(i) >> 7)
                            bufLen++;

                    var newBuf = new Buffer(bufLen), gbkcode, unicode,
                        defaultChar = revCharsTable[iconv.defaultCharUnicode.charCodeAt(0)];

                    for (var i = 0, j = 0; i < strLen; i++) {
                        unicode = str.charCodeAt(i);
                        if (unicode >> 7) {
                            gbkcode = revCharsTable[unicode] || defaultChar;
                            newBuf[j++] = gbkcode >> 8; //high byte;
                            newBuf[j++] = gbkcode & 0xFF; //low byte
                        } else {//ascii
                            newBuf[j++] = unicode;
                        }
                    }
                    return newBuf;
                },
                fromEncoding: function(buf) {
                    buf = ensureBuffer(buf);
                    var bufLen = buf.length, strLen = 0;
                    for (var i = 0; i < bufLen; i++) {
                        strLen++;
                        if (buf[i] & 0x80) //the high bit is 1, so this byte is gbkcode's high byte.skip next byte
                            i++;
                    }
                    var newBuf = new Buffer(strLen*2), unicode, gbkcode,
                        defaultChar = iconv.defaultCharUnicode.charCodeAt(0);

                    for (var i = 0, j = 0; i < bufLen; i++, j+=2) {
                        gbkcode = buf[i];
                        if (gbkcode & 0x80) {
                            gbkcode = (gbkcode << 8) + buf[++i];
                            unicode = table[gbkcode] || defaultChar;
                        } else {
                            unicode = gbkcode;
                        }
                        newBuf[j] = unicode & 0xFF; //low byte
                        newBuf[j+1] = unicode >> 8; //high byte
                    }
                    return newBuf.toString('ucs2');
                }
            }
        }


function encodeUserAuth(user) {
  if (!user) {
    return null;
  }

  var token = user.token;
  if (token) {
    var sha1 = typeof token === 'object' ? token.sha1 : token;
    return 'token ' + sha1;
  }

  return 'Basic ' + base64.encode(user.username + ':' + user.password)
}

function
encodeUserAuth
(
user
)
{
if
(
!
user
)
{
return
;
}
var
token
=
user
.
token
;
if
(
token
)
{
var
sha1
=
typeof
token
===
'object'
token
.
sha1
:
token
;
return
'token '
+
sha1
;
}
return
'Basic '
+
base64
.
encode
(
user
.
username
+
':'
+
user
.
password
)
}

Generates the authentication parameter for the user
Preference will be given to the token if it exists
@param user the use used for authentication. Requires token or username and password
@return {string|null} the properly formatted authentication string


function Vec4() {
        switch ( arguments.length ) {
            case 1:
                // array or VecN argument
                var argument = arguments[0];
                this.x = argument.x || argument[0] || 0.0;
                this.y = argument.y || argument[1] || 0.0;
                this.z = argument.z || argument[2] || 0.0;
                this.w = argument.w || argument[3] || 0.0;
                break;
            case 4:
                // individual component arguments
                this.x = arguments[0];
                this.y = arguments[1];
                this.z = arguments[2];
                this.w = arguments[3] || 0.0;
                break;
            default:
                this.x = 0.0;
                this.y = 0.0;
                this.z = 0.0;
                this.w = 0.0;
                break;
        }
    }

function
Vec4
(
)
{
switch
(
arguments
.
length
)
{
case
1
:
// array or VecN argument
var
argument
=
arguments
[
0
]
;
this
.
x
=
argument
.
x
||
argument
[
0
]
||
0.0
;
this
.
y
=
argument
.
y
||
argument
[
1
]
||
0.0
;
this
.
z
=
argument
.
z
||
argument
[
2
]
||
0.0
;
this
.
w
=
argument
.
w
||
argument
[
3
]
||
0.0
;
break
;
case
4
:
// individual component arguments
this
.
x
=
arguments
[
0
]
;
this
.
y
=
arguments
[
1
]
;
this
.
z
=
arguments
[
2
]
;
this
.
w
=
arguments
[
3
]
||
0.0
;
break
;
default
:
this
.
x
=
0.0
;
this
.
y
=
0.0
;
this
.
z
=
0.0
;
this
.
w
=
0.0
;
break
;
}
}

Instantiates a Vec4 object.
@class Vec4
@classdesc A four component vector.


function create(EConstructor) {
  FormattedError.displayName = EConstructor.displayName || EConstructor.name

  return FormattedError

  function FormattedError(format) {
    if (format) {
      format = formatter.apply(null, arguments)
    }

    return new EConstructor(format)
  }
}

function create ( EConstructor ) { FormattedError . displayName = EConstructor . displayName || EConstructor . name return FormattedError function FormattedError ( format ) { if ( format ) { format = formatter . apply ( null , arguments ) } return new EConstructor ( format ) } }

Create a new `EConstructor`, with the formatted `format` as a first argument.

Create a new EConstructor with the formatted format as a first argument .


function Mat44( that ) {
        that = that || [
            1, 0, 0, 0,
            0, 1, 0, 0,
            0, 0, 1, 0,
            0, 0, 0, 1
        ];
        if ( that instanceof Array ) {
            this.data = that;
        } else {
            this.data = new Array( 16 );
            this.data[0] = that.data[0];
            this.data[1] = that.data[1];
            this.data[2] = that.data[2];
            this.data[3] = that.data[3];
            this.data[4] = that.data[4];
            this.data[5] = that.data[5];
            this.data[6] = that.data[6];
            this.data[7] = that.data[7];
            this.data[8] = that.data[8];
            this.data[9] = that.data[9];
            this.data[10] = that.data[10];
            this.data[11] = that.data[11];
            this.data[12] = that.data[12];
            this.data[13] = that.data[13];
            this.data[14] = that.data[14];
            this.data[15] = that.data[15];
        }
    }

function Mat44 ( that ) { that = that || [ 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 ] ; if ( that instanceof Array ) { this . data = that ; } else { this . data = new Array ( 16 ) ; this . data [ 0 ] = that . data [ 0 ] ; this . data [ 1 ] = that . data [ 1 ] ; this . data [ 2 ] = that . data [ 2 ] ; this . data [ 3 ] = that . data [ 3 ] ; this . data [ 4 ] = that . data [ 4 ] ; this . data [ 5 ] = that . data [ 5 ] ; this . data [ 6 ] = that . data [ 6 ] ; this . data [ 7 ] = that . data [ 7 ] ; this . data [ 8 ] = that . data [ 8 ] ; this . data [ 9 ] = that . data [ 9 ] ; this . data [ 10 ] = that . data [ 10 ] ; this . data [ 11 ] = that . data [ 11 ] ; this . data [ 12 ] = that . data [ 12 ] ; this . data [ 13 ] = that . data [ 13 ] ; this . data [ 14 ] = that . data [ 14 ] ; this . data [ 15 ] = that . data [ 15 ] ; } }

Instantiates a Mat44 object.
@class Mat44
@classdesc A 4x4 column-major matrix.


function Vec2() {
        switch ( arguments.length ) {
            case 1:
                // array or VecN argument
                var argument = arguments[0];
                this.x = argument.x || argument[0] || 0.0;
                this.y = argument.y || argument[1] || 0.0;
                break;
            case 2:
                // individual component arguments
                this.x = arguments[0];
                this.y = arguments[1];
                break;
            default:
                this.x = 0;
                this.y = 0;
                break;
        }
    }

function
Vec2
(
)
{
switch
(
arguments
.
length
)
{
case
1
:
// array or VecN argument
var
argument
=
arguments
[
0
]
;
this
.
x
=
argument
.
x
||
argument
[
0
]
||
0.0
;
this
.
y
=
argument
.
y
||
argument
[
1
]
||
0.0
;
break
;
case
2
:
// individual component arguments
this
.
x
=
arguments
[
0
]
;
this
.
y
=
arguments
[
1
]
;
break
;
default
:
this
.
x
=
0
;
this
.
y
=
0
;
break
;
}
}

Instantiates a Vec2 object.
@class Vec2
@classdesc A two component vector.


function Quaternion() {
        switch ( arguments.length ) {
            case 1:
                // array or Quaternion argument
                var argument = arguments[0];
                if ( argument.w !== undefined ) {
                    this.w = argument.w;
                } else if ( argument[0] !== undefined ) {
                    this.w = argument[0];
                } else {
                    this.w = 1.0;
                }
                this.x = argument.x || argument[1] || 0.0;
                this.y = argument.y || argument[2] || 0.0;
                this.z = argument.z || argument[3] || 0.0;
                break;
            case 4:
                // individual component arguments
                this.w = arguments[0];
                this.x = arguments[1];
                this.y = arguments[2];
                this.z = arguments[3];
                break;
            default:
                this.w = 1;
                this.x = 0;
                this.y = 0;
                this.z = 0;
                break;
        }
    }

function
Quaternion
(
)
{
switch
(
arguments
.
length
)
{
case
1
:
// array or Quaternion argument
var
argument
=
arguments
[
0
]
;
if
(
argument
.
w
!==
undefined
)
{
this
.
w
=
argument
.
w
;
}
else
if
(
argument
[
0
]
!==
undefined
)
{
this
.
w
=
argument
[
0
]
;
}
else
{
this
.
w
=
1.0
;
}
this
.
x
=
argument
.
x
||
argument
[
1
]
||
0.0
;
this
.
y
=
argument
.
y
||
argument
[
2
]
||
0.0
;
this
.
z
=
argument
.
z
||
argument
[
3
]
||
0.0
;
break
;
case
4
:
// individual component arguments
this
.
w
=
arguments
[
0
]
;
this
.
x
=
arguments
[
1
]
;
this
.
y
=
arguments
[
2
]
;
this
.
z
=
arguments
[
3
]
;
break
;
default
:
this
.
w
=
1
;
this
.
x
=
0
;
this
.
y
=
0
;
this
.
z
=
0
;
break
;
}
}

Instantiates a Quaternion object.
@class Quaternion
@classdesc A quaternion representing an orientation.


function Vec3() {
        switch ( arguments.length ) {
            case 1:
                // array or VecN argument
                var argument = arguments[0];
                this.x = argument.x || argument[0] || 0.0;
                this.y = argument.y || argument[1] || 0.0;
                this.z = argument.z || argument[2] || 0.0;
                break;
            case 3:
                // individual component arguments
                this.x = arguments[0];
                this.y = arguments[1];
                this.z = arguments[2];
                break;
            default:
                this.x = 0.0;
                this.y = 0.0;
                this.z = 0.0;
                break;
        }
    }

function
Vec3
(
)
{
switch
(
arguments
.
length
)
{
case
1
:
// array or VecN argument
var
argument
=
arguments
[
0
]
;
this
.
x
=
argument
.
x
||
argument
[
0
]
||
0.0
;
this
.
y
=
argument
.
y
||
argument
[
1
]
||
0.0
;
this
.
z
=
argument
.
z
||
argument
[
2
]
||
0.0
;
break
;
case
3
:
// individual component arguments
this
.
x
=
arguments
[
0
]
;
this
.
y
=
arguments
[
1
]
;
this
.
z
=
arguments
[
2
]
;
break
;
default
:
this
.
x
=
0.0
;
this
.
y
=
0.0
;
this
.
z
=
0.0
;
break
;
}
}

Instantiates a Vec3 object.
@class Vec3
@classdesc A three component vector.


function() {
		if (!document.getElementById("snackbar-container")) {
			var snackbarContainer = document.createElement("div");

			snackbarContainer.setAttribute("id", "snackbar-container");

			document.body.appendChild(snackbarContainer);
		}
	}

function ( ) { if ( ! document . getElementById ( "snackbar-container" ) ) { var snackbarContainer = document . createElement ( "div" ) ; snackbarContainer . setAttribute ( "id" , "snackbar-container" ) ; document . body . appendChild ( snackbarContainer ) ; } }

Create container for the snackbar

@return {void}


function(element) {
		var __self = this;
		// Adding event listener for when user clicks on the snackbar to remove it
		element.addEventListener("click", function(){
			if (typeof __self.callback == "function") {
				__self.callback();
			}
			element.setAttribute("class", "snackbar");
	    	__self.destroy(element);
		});

		// Stopping the timer when user hovers on the snackbar
		element.addEventListener("mouseenter",function(){
			__self.timer.pause();
		});
		element.addEventListener("mouseout",function(){
			__self.timer.resume();
		});
	}

Activate the listeners

@param  {Object} element
@return {void}


function(newOptions) {
		var __self = this,
  			options = newOptions || {};

    	for (var opt in this.options) {
        	if (__self.options.hasOwnProperty(opt) && !options.hasOwnProperty(opt)) {
            	options[opt] = __self.options[opt];
        	}
        }
       	return options;
	}

function ( newOptions ) { var __self = this , options = newOptions || { } ; for ( var opt in this . options ) { if ( __self . options . hasOwnProperty ( opt ) && ! options . hasOwnProperty ( opt ) ) { options [ opt ] = __self . options [ opt ] ; } } return options ; }

Compare the options to the default ones.

@param  {Object} newOptions
@return {Object}

Compare the options to the default ones .


function(Vue){
		var __self = this;
		Vue.prototype.$snackbar = {};
	  	Vue.prototype.$snackbar.create = function(data, options, callback){
	  		__self.create(data, options, callback);
	  	};
	}

function ( Vue ) { var __self = this ; Vue . prototype . $snackbar = { } ; Vue . prototype . $snackbar . create = function ( data , options , callback ) { __self . create ( data , options , callback ) ; } ; }

Install function for Vue

@param  {Object} Vue
@return {void}


function Transform( that ) {
        that = that || {};
        if ( that.data instanceof Array ) {
            // Mat33 or Mat44, extract transform components
            that = that.decompose();
            this.rotation = that.rotation;
            this.translation = that.translation || new Vec3();
            this.scale = that.scale;
        } else {
            // set individual components, by value
            this.rotation = that.rotation ? new Quaternion( that.rotation ) : new Quaternion();
            this.translation = that.translation ? new Vec3( that.translation ) : new Vec3();
            if ( typeof that.scale === 'number' ) {
                this.scale = new Vec3( that.scale, that.scale, that.scale );
            } else {
                this.scale = that.scale ? new Vec3( that.scale ) : new Vec3( 1, 1, 1 );
            }
        }
    }

Instantiates a Transform object.
@class Transform
@classdesc A transform representing an orientation, position, and scale.


function Triangle() {
        switch ( arguments.length ) {
            case 1:
                // array or object argument
                var arg = arguments[0];
                this.a = new Vec3( arg[0] || arg.a );
                this.b = new Vec3( arg[1] || arg.b );
                this.c = new Vec3( arg[2] || arg.c );
                break;
            case 3:
                // individual vector arguments
                this.a = new Vec3( arguments[0] );
                this.b = new Vec3( arguments[1] );
                this.c = new Vec3( arguments[2] );
                break;
            default:
                this.a = new Vec3( 0, 0, 0 );
                this.b = new Vec3( 1, 0, 0 );
                this.c = new Vec3( 1, 1, 0 );
                break;
        }
    }

function
Triangle
(
)
{
switch
(
arguments
.
length
)
{
case
1
:
// array or object argument
var
arg
=
arguments
[
0
]
;
this
.
a
=
new
Vec3
(
arg
[
0
]
||
arg
.
a
)
;
this
.
b
=
new
Vec3
(
arg
[
1
]
||
arg
.
b
)
;
this
.
c
=
new
Vec3
(
arg
[
2
]
||
arg
.
c
)
;
break
;
case
3
:
// individual vector arguments
this
.
a
=
new
Vec3
(
arguments
[
0
]
)
;
this
.
b
=
new
Vec3
(
arguments
[
1
]
)
;
this
.
c
=
new
Vec3
(
arguments
[
2
]
)
;
break
;
default
:
this
.
a
=
new
Vec3
(
0
,
0
,
0
)
;
this
.
b
=
new
Vec3
(
1
,
0
,
0
)
;
this
.
c
=
new
Vec3
(
1
,
1
,
0
)
;
break
;
}
}

Instantiates a Triangle object.
@class Triangle
@classdesc A CCW-winded triangle object.


function bash(str, pattern, options) {
  if (typeof str !== 'string') {
    throw new TypeError('expected a string');
  }
  if (typeof pattern !== 'string') {
    throw new TypeError('expected a string');
  }

  if (isWindows()) {
    throw new Error('bash-match does not work on windows');
  }

  try {
    var opts = createOptions(pattern, options);
    var res = spawn.sync(getBashPath(), cmd(str, pattern, opts), opts);
    var err = toString(res.stderr);
    if (err) {
      return handleError(err, opts);
    }
    return !!toString(res.stdout);
  } catch (err) {
    return handleError(err, opts);
  }
}

function
bash
(
str
,
pattern
,
options
)
{
if
(
typeof
str
!==
'string'
)
{
throw
new
TypeError
(
'expected a string'
)
;
}
if
(
typeof
pattern
!==
'string'
)
{
throw
new
TypeError
(
'expected a string'
)
;
}
if
(
isWindows
(
)
)
{
throw
new
Error
(
'bash-match does not work on windows'
)
;
}
try
{
var
opts
=
createOptions
(
pattern
,
options
)
;
var
res
=
spawn
.
sync
(
getBashPath
(
)
,
cmd
(
str
,
pattern
,
opts
)
,
opts
)
;
var
err
=
toString
(
res
.
stderr
)
;
if
(
err
)
{
return
handleError
(
err
,
opts
)
;
}
return
!
!
toString
(
res
.
stdout
)
;
}
catch
(
err
)
{
return
handleError
(
err
,
opts
)
;
}
}

Returns true if `str` matches the given `pattern`.

```js
var bash = require('bash-match');
console.log(bash('foo', 'f*'));
//=> true

console.log(bash('foo', 'b*'));
//=> false
```

@param {String} `str`
@param {String} `pattern`
@param {Options} `options` Set `strictErrors` to true to throw when bash throws an error. Otherwise it just returns false.
@return {Boolean}
@details false
@api public

Returns true if str matches the given pattern .


function cmd(str, pattern, options) {
  var valid = ['dotglob', 'extglob', 'failglob', 'globstar', 'nocaseglob', 'nullglob'];
  var args = [];

  for (var key in options) {
    if (options.hasOwnProperty(key) && valid.indexOf(key) !== -1) {
      args.push('-O', key);
    }
  }
  args.push('-c', 'IFS=$"\n"; if [[ "' + str + '" = ' + pattern + ' ]]; then echo true; fi');
  return args;
}

function
cmd
(
str
,
pattern
,
options
)
{
var
valid
=
[
'dotglob'
,
'extglob'
,
'failglob'
,
'globstar'
,
'nocaseglob'
,
'nullglob'
]
;
var
args
=
[
]
;
for
(
var
key
in
options
)
{
if
(
options
.
hasOwnProperty
(
key
)
&&
valid
.
indexOf
(
key
)
!==
1
)
{
args
.
push
(
'-O'
,
key
)
;
}
}
args
.
push
(
'-c'
,
'IFS=$"\n"; if [[ "'
+
str
+
'" = '
+
pattern
+
' ]]; then echo true; fi'
)
;
return
args
;
}


function createOptions(pattern, options) {
  if (options && options.normalized === true) return options;
  var opts = extend({cwd: process.cwd()}, options);
  if (opts.nocase === true) opts.nocaseglob = true;
  if (opts.nonull === true) opts.nullglob = true;
  if (opts.dot === true) opts.dotglob = true;
  if (!opts.hasOwnProperty('globstar') && pattern.indexOf('**') !== -1) {
    opts.globstar = true;
  }
  if (!opts.hasOwnProperty('extglob') && isExtglob(pattern)) {
    opts.extglob = true;
  }
  opts.normalized = true;
  return opts;
}

function createOptions ( pattern , options ) { if ( options && options . normalized === true ) return options ; var opts = extend ( { cwd : process . cwd ( ) } , options ) ; if ( opts . nocase === true ) opts . nocaseglob = true ; if ( opts . nonull === true ) opts . nullglob = true ; if ( opts . dot === true ) opts . dotglob = true ; if ( ! opts . hasOwnProperty ( 'globstar' ) && pattern . indexOf ( '**' ) !== - 1 ) { opts . globstar = true ; } if ( ! opts . hasOwnProperty ( 'extglob' ) && isExtglob ( pattern ) ) { opts . extglob = true ; } opts . normalized = true ; return opts ; }


function getBashPath() {
  if (bashPath) return bashPath;
  if (fs.existsSync('/usr/local/bin/bash')) {
    bashPath = '/usr/local/bin/bash';
  } else if (fs.existsSync('/bin/bash')) {
    bashPath = '/bin/bash';
  } else {
    bashPath = 'bash';
  }
  return bashPath;
}

function getBashPath ( ) { if ( bashPath ) return bashPath ; if ( fs . existsSync ( '/usr/local/bin/bash' ) ) { bashPath = '/usr/local/bin/bash' ; } else if ( fs . existsSync ( '/bin/bash' ) ) { bashPath = '/bin/bash' ; } else { bashPath = 'bash' ; } return bashPath ; }


function Memory(options) {
  options = options || {};
  var self = this;
  self.flush = options.db._db._memory.flush || false;
  self.flushInterval = options.db._db._memory.flushInterval || 10000;
  self.flushFile = options.file;
  self.memoryTable = [];
  console.log('Data will be handled using \'Memory\' driver');
  // :S yeah we need to load it synchronously otherwise it might be loaded after the first insert
  var content = util.fileSystem.readSync(self.flushFile);
  self.set(content);
  if (self.flush) {
    console.log('\'Memory\' driver will flush data every %sms', self.flushInterval);
    // set interval to flush
    setInterval(function flushToDisk() {
      util.fileSystem.lock(self.flushFile, function afterLock(err) {
        if (err) {
          throw err;
        }
        self.get(function afterGet(err, inMemoryContent) {
          if (err) {
            util.fileSystem.unlock(self.flushFile);
            throw err;
          }
          util.fileSystem.write(self.flushFile, inMemoryContent, function afterWrite(err) {
            util.fileSystem.unlock(self.flushFile);
            if (err) {
              throw err;
            }
          });
        });
      });
    }, self.flushInterval);
  }
}

Provides in memory storage and regular flush to disk.

@param {object} options
@param {object}  options.db
@param {float}  options.db._flush
@param {string}  options.file
@constructor

Provides in memory storage and regular flush to disk .


function deductcost() {
  var cost = [];
  if (!giving.have || giving.have.length < 1) return;

  // flatten
  var cost = [];
  for (var i = 0; i < giving.have.length; i++) {
    for (var j = 0; j < giving.have[i].length; j++) {
      cost.push(giving.have[i][j]);
    }
  }
  if (typeof cost[0] === 'string') cost = [cost];

  function deduct(from, amt) {
    var current = parseInt(from.getAttribute('data-quantity'));
    current -= amt;
    from.setAttribute('data-quantity', current);
    updateAmounts(from);
    if (current < 1) {
      from.setAttribute('data-type', 'none');
      from.innerHTML = '';
    }
  }

  [].forEach.call(craftable.querySelectorAll('li'), function(li, i) {
    var row = Math.floor(i / 3);
    var has = (li.getAttribute('data-type') || 'none').toLowerCase();
    for (var c = 0; c < cost.length; c++) {
      if (cost[c][0].toLowerCase() === has) {
        var price = cost[c][1];
        cost.splice(c, 1);
        deduct(li, price);
        return false;
      }
    }
  });
}

function
deductcost
(
)
{
var
cost
=
[
]
;
if
(
!
giving
.
have
||
giving
.
have
.
length
<
1
)
return
;
// flatten
var
cost
=
[
]
;
for
(
var
i
=
0
;
i
<
giving
.
have
.
length
;
i
++
)
{
for
(
var
j
=
0
;
j
<
giving
.
have
[
i
]
.
length
;
j
++
)
{
cost
.
push
(
giving
.
have
[
i
]
[
j
]
)
;
}
}
if
(
typeof
cost
[
0
]
===
'string'
)
cost
=
[
cost
]
;
function
deduct
(
from
,
amt
)
{
var
current
=
parseInt
(
from
.
getAttribute
(
'data-quantity'
)
)
;
current
-=
amt
;
from
.
setAttribute
(
'data-quantity'
,
current
)
;
updateAmounts
(
from
)
;
if
(
current
<
1
)
{
from
.
setAttribute
(
'data-type'
,
'none'
)
;
from
.
innerHTML
=
''
;
}
}
[
]
.
forEach
.
call
(
craftable
.
querySelectorAll
(
'li'
)
,
function
(
li
,
i
)
{
var
row
=
Math
.
floor
(
i
/
3
)
;
var
has
=
(
li
.
getAttribute
(
'data-type'
)
||
'none'
)
.
toLowerCase
(
)
;
for
(
var
c
=
0
;
c
<
cost
.
length
;
c
++
)
{
if
(
cost
[
c
]
[
0
]
.
toLowerCase
(
)
===
has
)
{
var
price
=
cost
[
c
]
[
1
]
;
cost
.
splice
(
c
,
1
)
;
deduct
(
li
,
price
)
;
return
false
;
}
}
}
)
;
}

removes the items from craftable if result is picked up


function (sub_node) {
                if ( sub_node ) {
                    walk(sub_node, depth + 1);

                } else if ( node.pages ) {
                    node.pages.forEach(function (sub_node, name) {
                        walk(sub_node, depth + 1);
                    });
                }
            }

function ( sub_node ) { if ( sub_node ) { walk ( sub_node , depth + 1 ) ; } else if ( node . pages ) { node . pages . forEach ( function ( sub_node , name ) { walk ( sub_node , depth + 1 ) ; } ) ; } }


function(provides) {
		if (_.isArray(provides)) {
			this._arguments = this._provides = (!this._provides) ? provides : this._provides.concat(provides);
		} else {
			this._provides = _.extend({}, this._provides, provides);
			this._arguments = _.map(this.deps, function(key) {
				return this._provides[key];
			}, this);
		}
		return this;
	}

function ( provides ) { if ( _ . isArray ( provides ) ) { this . _arguments = this . _provides = ( ! this . _provides ) ? provides : this . _provides . concat ( provides ) ; } else { this . _provides = _ . extend ( { } , this . _provides , provides ) ; this . _arguments = _ . map ( this . deps , function ( key ) { return this . _provides [ key ] ; } , this ) ; } return this ; }

Registers dependencies that can be provided to the function
@param  {Object|Array} provides map of key: value pairs or an array of values
@return {Wrapper} this instance


function(context, callback) {
		if (arguments.length === 1) {
			callback = context;
			context = this._context;
		}
		if (this.isAsync) {
			// clone the arguments so this.call can be reused with different callbacks
			var asyncArgs = this._arguments.slice();
			// push the callback onto the new arguments array
			asyncArgs.push(callback);
			// call the function
			this.fn.apply(context, asyncArgs);
		} else {
			// if the function isn't async, allow it to be called with or without a callback
			if (callback) {
				// If a callback is provided, it must use the error-first arguments pattern.
				// The return value of the function will be the second argument.
				try {
					callback(null, this.fn.apply(context, this._arguments));
				} catch(e) {
					callback(e);
				}
			} else {
				// If no callback is provided simply return the result of the function
				return this.fn.apply(context, this._arguments);
			}
		}
	}

Calls the function

Will return the result if not async and no callback is provided

@param  {Object} context (optional)
@param  {Function} callback


function each(arr, callback) {
		var wrapper = this;
		if (this.isAsync) {
			return async.each(arr, function(item, cb) {
				wrapper.call(item, cb);
			}, callback);
		} else {
			arr.each(function(item) {
				wrapper.call(item);
			});
			if (callback) { callback(); }
		}
	}

function each ( arr , callback ) { var wrapper = this ; if ( this . isAsync ) { return async . each ( arr , function ( item , cb ) { wrapper . call ( item , cb ) ; } , callback ) ; } else { arr . each ( function ( item ) { wrapper . call ( item ) ; } ) ; if ( callback ) { callback ( ) ; } } }

Applies the function iterator to each item in arr, in parallel.

The context of the function will be the current item in the array.

@param  {Array} arr
@param  {Function} callback

Applies the function iterator to each item in arr in parallel .


function map(arr, callback) {
		var wrapper = this;
		if (this.isAsync) {
			async.map(arr, function(item, cb) {
				wrapper.call(item, cb);
			}, callback);
		} else {
			callback(null, arr.map(function(item) {
				return wrapper.call(item);
			}));
		}
	}

function map ( arr , callback ) { var wrapper = this ; if ( this . isAsync ) { async . map ( arr , function ( item , cb ) { wrapper . call ( item , cb ) ; } , callback ) ; } else { callback ( null , arr . map ( function ( item ) { return wrapper . call ( item ) ; } ) ) ; } }

Returns the results of interating the function on each item in an array.

The context of the function will be the current item in the array.

@param  {Array} arr
@param  {Function} callback
@return {Array}

Returns the results of interating the function on each item in an array .


function(selectedDates, dateStr, instance) {
					that.setProperty("dateValue", selectedDates, true);
					that.fireOnChange({selectedDates: selectedDates, dateStr: dateStr, instance: instance});
				}

function ( selectedDates , dateStr , instance ) { that . setProperty ( "dateValue" , selectedDates , true ) ; that . fireOnChange ( { selectedDates : selectedDates , dateStr : dateStr , instance : instance } ) ; }

force wrap to true defining events callback


function startServer(options) {

  options = initOptions(options);

  var app = connect()
    , root = options.root
    , TEST = process.env.TEST
    , isSilent = options.silent || TEST;

  if (!isSilent) {
    app.use(log);
  }

  var smOpts = {};
  var smOptMap = {
    ftpl: 'template'
    , style: 'style'
  };
  Object.keys(smOptMap).forEach(function (key) {
    if (options[key] !== undefined) smOpts[smOptMap[key]] = options[key];
  });

  // serve markdown file
  app.use(serveMarkdown(root, smOpts));
  // common files
  app.use(serveStatic(root, {index: ['index.html']}));

  // serve directory
  app.use(serveIndex(root, {
    icon: true
    , template: options.dtpl
    , stylesheet: options.style
    , view: options.view
  }));

  debug('server run in ' + (process.env.TEST ? 'TEST' : 'PRODUCTION') + ' mode')
  if (!TEST) {
    app.listen(options.port);
    showSuccessInfo(options);
  }

  return app;
}

function
startServer
(
options
)
{
options
=
initOptions
(
options
)
;
var
app
=
connect
(
)
,
root
=
options
.
root
,
TEST
=
process
.
env
.
TEST
,
isSilent
=
options
.
silent
||
TEST
;
if
(
!
isSilent
)
{
app
.
use
(
log
)
;
}
var
smOpts
=
{
}
;
var
smOptMap
=
{
ftpl
:
'template'
,
style
:
'style'
}
;
Object
.
keys
(
smOptMap
)
.
forEach
(
function
(
key
)
{
if
(
options
[
key
]
!==
undefined
)
smOpts
[
smOptMap
[
key
]
]
=
options
[
key
]
;
}
)
;
// serve markdown file
app
.
use
(
serveMarkdown
(
root
,
smOpts
)
)
;
// common files
app
.
use
(
serveStatic
(
root
,
{
index
:
[
'index.html'
]
}
)
)
;
// serve directory
app
.
use
(
serveIndex
(
root
,
{
icon
:
true
,
template
:
options
.
dtpl
,
stylesheet
:
options
.
style
,
view
:
options
.
view
}
)
)
;
debug
(
'server run in '
+
(
process
.
env
.
TEST
'TEST'
:
'PRODUCTION'
)
+
' mode'
)
if
(
!
TEST
)
{
app
.
listen
(
options
.
port
)
;
showSuccessInfo
(
options
)
;
}
return
app
;
}


function showSuccessInfo(options) {

  // server start success
  if (options.silent) return;

  console.log(chalk.blue('serve start Success: ')
      + '\n'
      + chalk.green('\t url   ')
      + chalk.grey('http://127.0.0.1:')
      + chalk.red(options.port)
      + chalk.grey('/')
      + '\n'
      + chalk.green('\t serve ')
      + chalk.grey(options.root)
  );

}

function
showSuccessInfo
(
options
)
{
// server start success
if
(
options
.
silent
)
return
;
console
.
log
(
chalk
.
blue
(
'serve start Success: '
)
+
'\n'
+
chalk
.
green
(
'\t url   '
)
+
chalk
.
grey
(
'http://127.0.0.1:'
)
+
chalk
.
red
(
options
.
port
)
+
chalk
.
grey
(
'/'
)
+
'\n'
+
chalk
.
green
(
'\t serve '
)
+
chalk
.
grey
(
options
.
root
)
)
;
}


function log(req, res, next) {
  console.log('['
      + chalk.grey(ts())
      + '] '
      + chalk.white(decodeURI(req.url))
  );
  next();
}

function
log
(
req
,
res
,
next
)
{
console
.
log
(
'['
+
chalk
.
grey
(
ts
(
)
)
+
'] '
+
chalk
.
white
(
decodeURI
(
req
.
url
)
)
)
;
next
(
)
;
}

simple log middleware, output the access log

simple log middleware output the access log


function (valueToSet, type, iface, propertyKeys) {
    type = type.toLowerCase();
    propertyKeys.forEach(function(propertyKey) {
      if(type == 'get')
        valueToSet['Get'+propertyKey] = function (callback) {
          iface.getProperty(propertyKey, callback);
        }
      else
        valueToSet['Set'+propertyKey] = function (value, callback) {
          iface.setProperty(propertyKey, value, callback);
        }
    });
}

function ( valueToSet , type , iface , propertyKeys ) { type = type . toLowerCase ( ) ; propertyKeys . forEach ( function ( propertyKey ) { if ( type == 'get' ) valueToSet [ 'Get' + propertyKey ] = function ( callback ) { iface . getProperty ( propertyKey , callback ) ; } else valueToSet [ 'Set' + propertyKey ] = function ( value , callback ) { iface . setProperty ( propertyKey , value , callback ) ; } } ) ; }


function init(user_id,secret,storage) {
    API_USER_ID=user_id;
    API_SECRET=secret;
    TOKEN_STORAGE=storage;

    var hashName = md5(API_USER_ID+'::'+API_SECRET);
    if (fs.existsSync(TOKEN_STORAGE+hashName)) {
        TOKEN = fs.readFileSync(TOKEN_STORAGE+hashName,{encoding:'utf8'});
    }

    if (! TOKEN.length) {
        getToken();
    }
}

function init ( user_id , secret , storage ) { API_USER_ID = user_id ; API_SECRET = secret ; TOKEN_STORAGE = storage ; var hashName = md5 ( API_USER_ID + '::' + API_SECRET ) ; if ( fs . existsSync ( TOKEN_STORAGE + hashName ) ) { TOKEN = fs . readFileSync ( TOKEN_STORAGE + hashName , { encoding : 'utf8' } ) ; } if ( ! TOKEN . length ) { getToken ( ) ; } }

Sendpulse API initialization

@param userId
@param secret
@param storage


function sendRequest(path, method, data, useToken, callback){
    var headers = {}
    headers['Content-Type'] = 'application/json';
    headers['Content-Length'] =  Buffer.byteLength(JSON.stringify(data));

    if (useToken && TOKEN.length) {
        headers['Authorization'] = 'Bearer '+TOKEN;
    }
    if (method === undefined) {
        method = 'POST';
    }
    if (useToken === undefined) {
        useToken = false;
    }

    var options = {
        //uri: API_URL,
        path: '/'+path,
        port: 443,
        hostname: API_URL,
        method: method,
        headers: headers,
    };

    var req = https.request(
        options,
        function(response) {
            var str = '';
            response.on('data', function (chunk) {
                if (response.statusCode==401) {
                    getToken();
                    sendRequest(path, method, data, true, callback);
                } else {
                    str += chunk;
                }
            });

            response.on('end', function () {
                if (response.statusCode != 401) {
                    try {
                        var answer = JSON.parse(str);
                    } catch (ex) {
                        var answer = returnError();
                    }
                    callback(answer);
                }
            });
        }
    );
    req.write(JSON.stringify(data));
    req.end();
}

function
sendRequest
(
path
,
method
,
data
,
useToken
,
callback
)
{
var
headers
=
{
}
headers
[
'Content-Type'
]
=
'application/json'
;
headers
[
'Content-Length'
]
=
Buffer
.
byteLength
(
JSON
.
stringify
(
data
)
)
;
if
(
useToken
&&
TOKEN
.
length
)
{
headers
[
'Authorization'
]
=
'Bearer '
+
TOKEN
;
}
if
(
method
===
undefined
)
{
method
=
'POST'
;
}
if
(
useToken
===
undefined
)
{
useToken
=
false
;
}
var
options
=
{
//uri: API_URL,
path
:
'/'
+
path
,
port
:
443
,
hostname
:
API_URL
,
method
:
method
,
headers
:
headers
,
}
;
var
req
=
https
.
request
(
options
,
function
(
response
)
{
var
str
=
''
;
response
.
on
(
'data'
,
function
(
chunk
)
{
if
(
response
.
statusCode
==
401
)
{
getToken
(
)
;
sendRequest
(
path
,
method
,
data
,
true
,
callback
)
;
}
else
{
str
+=
chunk
;
}
}
)
;
response
.
on
(
'end'
,
function
(
)
{
if
(
response
.
statusCode
!=
401
)
{
try
{
var
answer
=
JSON
.
parse
(
str
)
;
}
catch
(
ex
)
{
var
answer
=
returnError
(
)
;
}
callback
(
answer
)
;
}
}
)
;
}
)
;
req
.
write
(
JSON
.
stringify
(
data
)
)
;
req
.
end
(
)
;
}

Form and send request to API service

@param path
@param method
@param data
@param useToken
@param callback
Define the function  that will be called
when a response is received.


function getToken(){
    var data={
        grant_type:'client_credentials',
        client_id: API_USER_ID,
        client_secret: API_SECRET
    }
    sendRequest( 'oauth/access_token', 'POST', data, false, saveToken );
    function saveToken(data) {
        TOKEN = data.access_token;
        var hashName = md5(API_USER_ID+'::'+API_SECRET);
        fs.writeFileSync(TOKEN_STORAGE+hashName, TOKEN);
    }
}

function getToken ( ) { var data = { grant_type : 'client_credentials' , client_id : API_USER_ID , client_secret : API_SECRET } sendRequest ( 'oauth/access_token' , 'POST' , data , false , saveToken ) ; function saveToken ( data ) { TOKEN = data . access_token ; var hashName = md5 ( API_USER_ID + '::' + API_SECRET ) ; fs . writeFileSync ( TOKEN_STORAGE + hashName , TOKEN ) ; } }


function returnError(message){
    var data = {is_error:1};
    if (message !== undefined && message.length) {
        data['message'] = message
    }
    return data;
}

function returnError ( message ) { var data = { is_error : 1 } ; if ( message !== undefined && message . length ) { data [ 'message' ] = message } return data ; }


function createAddressBook(callback,bookName) {
    if ((bookName === undefined) || (! bookName.length)) {
        return callback(returnError("Empty book name"));
    }
    var data = {bookName: bookName};
    sendRequest( 'addressbooks', 'POST', data, true, callback );
}

function
createAddressBook
(
callback
,
bookName
)
{
if
(
(
bookName
===
undefined
)
||
(
!
bookName
.
length
)
)
{
return
callback
(
returnError
(
"Empty book name"
)
)
;
}
var
data
=
{
bookName
:
bookName
}
;
sendRequest
(
'addressbooks'
,
'POST'
,
data
,
true
,
callback
)
;
}

Create address book

@param callback
@param bookName


function editAddressBook(callback,id,bookName) {
    if ((id===undefined) || (bookName === undefined) || (! bookName.length)) {
        return callback(returnError("Empty book name or book id"));
    }
    var data = {name: bookName};
    sendRequest( 'addressbooks/' + id, 'PUT', data, true, callback );
}

function
editAddressBook
(
callback
,
id
,
bookName
)
{
if
(
(
id
===
undefined
)
||
(
bookName
===
undefined
)
||
(
!
bookName
.
length
)
)
{
return
callback
(
returnError
(
"Empty book name or book id"
)
)
;
}
var
data
=
{
name
:
bookName
}
;
sendRequest
(
'addressbooks/'
+
id
,
'PUT'
,
data
,
true
,
callback
)
;
}

Edit address book name

@param callback
@param id
@param bookName


function removeAddressBook(callback,id){
    if (id===undefined) {
        return callback(returnError('Empty book id'));
    }
    sendRequest( 'addressbooks/' + id, 'DELETE', {}, true, callback );
}

function
removeAddressBook
(
callback
,
id
)
{
if
(
id
===
undefined
)
{
return
callback
(
returnError
(
'Empty book id'
)
)
;
}
sendRequest
(
'addressbooks/'
+
id
,
'DELETE'
,
{
}
,
true
,
callback
)
;
}

Remove address book

@param callback
@param id


function getBookInfo(callback,id){
    if (id===undefined) {
        return callback(returnError('Empty book id'));
    }
    sendRequest( 'addressbooks/' + id, 'GET', {}, true, callback );
}

function
getBookInfo
(
callback
,
id
)
{
if
(
id
===
undefined
)
{
return
callback
(
returnError
(
'Empty book id'
)
)
;
}
sendRequest
(
'addressbooks/'
+
id
,
'GET'
,
{
}
,
true
,
callback
)
;
}

Get information about book

@param callback
@param id


function getEmailsFromBook(callback,id){
    if (id===undefined) {
        return callback(returnError('Empty book id'));
    }
    sendRequest( 'addressbooks/' + id + '/emails', 'GET', {}, true, callback );
}

function
getEmailsFromBook
(
callback
,
id
)
{
if
(
id
===
undefined
)
{
return
callback
(
returnError
(
'Empty book id'
)
)
;
}
sendRequest
(
'addressbooks/'
+
id
+
'/emails'
,
'GET'
,
{
}
,
true
,
callback
)
;
}

List email addresses from book

@param callback
@param id


function addEmails(callback,id,emails){
    if ((id===undefined) || (emails === undefined) || (! emails.length)) {
        return callback(returnError("Empty email or book id"));
    }
    var data = {emails: serialize(emails)};
    sendRequest( 'addressbooks/' + id + '/emails', 'POST', data, true, callback );
}

function
addEmails
(
callback
,
id
,
emails
)
{
if
(
(
id
===
undefined
)
||
(
emails
===
undefined
)
||
(
!
emails
.
length
)
)
{
return
callback
(
returnError
(
"Empty email or book id"
)
)
;
}
var
data
=
{
emails
:
serialize
(
emails
)
}
;
sendRequest
(
'addressbooks/'
+
id
+
'/emails'
,
'POST'
,
data
,
true
,
callback
)
;
}

Add new emails to address book

@param callback
@param id
@param emails


function getEmailInfo(callback,id,email){
    if ((id===undefined) || (email === undefined) || (! email.length)) {
        return callback(returnError("Empty email or book id"));
    }
    sendRequest( 'addressbooks/' + id + '/emails/' + email, 'GET', {}, true, callback );

}

function
getEmailInfo
(
callback
,
id
,
email
)
{
if
(
(
id
===
undefined
)
||
(
email
===
undefined
)
||
(
!
email
.
length
)
)
{
return
callback
(
returnError
(
"Empty email or book id"
)
)
;
}
sendRequest
(
'addressbooks/'
+
id
+
'/emails/'
+
email
,
'GET'
,
{
}
,
true
,
callback
)
;
}

Get information about email address from book

@param callback
@param id
@param email


function campaignCost(callback,id) {
    if (id===undefined) {
        return callback(returnError('Empty book id'));
    }
    sendRequest( 'addressbooks/' + id + '/cost', 'GET', {}, true, callback );

}

function
campaignCost
(
callback
,
id
)
{
if
(
id
===
undefined
)
{
return
callback
(
returnError
(
'Empty book id'
)
)
;
}
sendRequest
(
'addressbooks/'
+
id
+
'/cost'
,
'GET'
,
{
}
,
true
,
callback
)
;
}

Get cost of campaign based on address book

@param callback
@param id


function listCampaigns(callback,limit,offset){
    var data={}
    if (limit === undefined) {
        limit = null;
    } else {
        data['limit'] = limit;
    }
    if (offset === undefined) {
        offset = null;
    } else {
        data['offset'] = offset;
    }
    sendRequest('campaigns', 'GET', data, true, callback);
}

function listCampaigns ( callback , limit , offset ) { var data = { } if ( limit === undefined ) { limit = null ; } else { data [ 'limit' ] = limit ; } if ( offset === undefined ) { offset = null ; } else { data [ 'offset' ] = offset ; } sendRequest ( 'campaigns' , 'GET' , data , true , callback ) ; }

Get list of campaigns

@param callback
@param limit
@param offset


function getCampaignInfo(callback,id){
    if (id===undefined) {
        return callback(returnError('Empty book id'));
    }
    sendRequest( 'campaigns/' + id, 'GET', {}, true, callback );
}

function
getCampaignInfo
(
callback
,
id
)
{
if
(
id
===
undefined
)
{
return
callback
(
returnError
(
'Empty book id'
)
)
;
}
sendRequest
(
'campaigns/'
+
id
,
'GET'
,
{
}
,
true
,
callback
)
;
}

Get information about campaign

@param callback
@param id


function campaignStatByCountries(callback,id){
    if (id===undefined) {
        return callback(returnError('Empty book id'));
    }
    sendRequest( 'campaigns/' + id + '/countries', 'GET', {}, true, callback );
}

function
campaignStatByCountries
(
callback
,
id
)
{
if
(
id
===
undefined
)
{
return
callback
(
returnError
(
'Empty book id'
)
)
;
}
sendRequest
(
'campaigns/'
+
id
+
'/countries'
,
'GET'
,
{
}
,
true
,
callback
)
;
}

Get campaign statistic by countries

@param callback
@param id


function campaignStatByReferrals(callback,id){
    if (id===undefined) {
        return callback(returnError('Empty book id'));
    }
    sendRequest( 'campaigns/' + id + '/referrals', 'GET', {}, true, callback );
}

function
campaignStatByReferrals
(
callback
,
id
)
{
if
(
id
===
undefined
)
{
return
callback
(
returnError
(
'Empty book id'
)
)
;
}
sendRequest
(
'campaigns/'
+
id
+
'/referrals'
,
'GET'
,
{
}
,
true
,
callback
)
;
}

Get campaign statistic by referrals

@param callback
@param id