<commit_before>var postcss = require('postcss');
var vars    = require('postcss-simple-vars');
var path    = require('path');
var globby  = require('globby');
var fs      = require('fs');

var stringToAtRule = function (str, obj) {
    obj.name   = str.match(/^@([^\s]*)/)[1];
    obj.params = str.replace(/^@[^\s]*\s+/, '');
    return obj;
};

var objectToNodes = function (node, obj, source) {
    var name, value, decl, rule;
    for ( name in obj ) {
        value = obj[name];
        if ( typeof value === 'object' ) {
            if ( name[0] === '@' ) {
                rule = postcss.atRule(stringToAtRule(name, { source: source }));
            } else {
                rule = postcss.rule({ selector: name, source: source });
            }
            node.append(rule);
            if ( typeof value === 'object' ) objectToNodes(rule, value, source);
        } else {
            decl = postcss.decl({
                prop:   name,
                value:  value.toString(),
                source: source
            });
            node.append(decl);
        }
    }
    return node;
};

var insertObject = function (rule, obj) {
    var root = objectToNodes(postcss.root(), obj, rule.source);
    rule.parent.insertBefore(rule, root);
};

var insertMixin = function (result, mixins, rule, opts) {
    var name   = rule.params.split(/\s/, 1)[0];
    var params = rule.params.slice(name.length).trim();
    if ( params.indexOf(',') === -1 ) {
        params = postcss.list.space(params);
        if ( params.length > 1 ) {
            result.warn('Space argument separation is depreacted and ' +
                        'will be removed in next version. Use comma.',
                        { node: rule });
        }
    } else {
        params = postcss.list.comma(params);
    }

    var meta   = mixins[name];
    var mixin  = meta && meta.mixin;

    if ( !meta ) {
        if ( !opts.silent ) {
            throw rule.error('Undefined mixin ' + name);
        }

    } else if ( mixin.name === 'define-mixin' ) {
        var i;
        var values = { };
        for ( i = 0; i < meta.args.length; i++ ) {
            values[meta.args[i][0]] = params[i] || meta.args[i][1];
        }

        var clones = [];
        for ( i = 0; i < mixin.nodes.length; i++ ) {
            clones.push( mixin.nodes[i].clone() );
        }

        var proxy = postcss.rule({ nodes: clones });
        if ( meta.args.length ) {
            vars({ only: values })(proxy);
        }
        if ( meta.content ) {
            proxy.walkAtRules('mixin-content', function (place) {
                place.replaceWith(rule.nodes);
            });
        }

        rule.parent.insertBefore(rule, clones);

    } else if ( typeof mixin === 'object' ) {
        insertObject(rule, mixin, rule.source);

    } else if ( typeof mixin === 'function' ) {
        var args  = [rule].concat(params);
        var nodes = mixin.apply(this, args);
        if ( typeof nodes === 'object' ) {
            insertObject(rule, nodes, rule.source);
        }
    }

    if ( rule.parent ) rule.remove();
};

var defineMixin = function (result, mixins, rule) {
    var name  = rule.params.split(/\s/, 1)[0];
    var other = rule.params.slice(name.length).trim();

    var args = [];
    if ( other.length ) {
        if ( other.indexOf(',') === -1 && other.indexOf(':') === -1 ) {
            args = other.split(/\s/).map(function (str) {
                return [str.slice(1), ''];
            });
            if ( args.length > 1 ) {
                result.warn('Space argument separation is depreacted and ' +
                            'will be removed in next version. Use comma.',
                            { node: rule });
            }

        } else {
            args = postcss.list.comma(other).map(function (str) {
                var arg      = str.split(':', 1)[0];
                var defaults = str.slice(arg.length + 1);
                return [arg.slice(1).trim(), defaults.trim()];
            });
        }
    }

    var content = false;
    rule.walkAtRules('mixin-content', function () {
        content = true;
        return false;
    });

    mixins[name] = { mixin: rule, args: args, content: content };
    rule.remove();
};

var requireCss = function (filename) {
    var source = fs.readFileSync(filename);
    return postcss.parse(source);
};

module.exports = postcss.plugin('postcss-mixins', function (opts) {
    if ( typeof opts === 'undefined' ) opts = { };

    var i;
    var cwd    = process.cwd();
    var globs  = [];
    var mixins = { };

    if ( opts.mixinsDir ) {
        if ( !Array.isArray(opts.mixinsDir) ) {
            opts.mixinsDir = [opts.mixinsDir];
        }
        globs = opts.mixinsDir.map(function (dir) {
            return path.join(dir, '*.{js,json,css}');
        });
    }

    if ( opts.mixinsFiles ) globs = globs.concat(opts.mixinsFiles);

    return function (css, result) {
        var discoverMixins = function (atrule) {
            if ( atrule.name === 'mixin' ) {
                insertMixin(result, mixins, atrule, opts);
            } else if ( atrule.name === 'define-mixin' ) {
                defineMixin(result, mixins, atrule);
            }
        };
        return globby(globs).then(function (files) {
            files.forEach(function (file) {
                var ext = path.extname(file);
                var name = path.basename(file, ext);
                file = path.join(cwd, path.relative(cwd, file));
                if (ext === '.css') {
                    requireCss(file).walkAtRules(discoverMixins);
                    return;
                }
                mixins[name] = { mixin: require(file) };
            });

            if ( typeof opts.mixins === 'object' ) {
                for ( i in opts.mixins ) {
                    mixins[i] = { mixin: opts.mixins[i] };
                }
            }

            css.walkAtRules(discoverMixins);
        });
    };
});
<commit_msg>Async CSS mixin import<commit_after>var postcss = require('postcss');
var vars    = require('postcss-simple-vars');
var path    = require('path');
var globby  = require('globby');
var fs      = require('fs');

var stringToAtRule = function (str, obj) {
    obj.name   = str.match(/^@([^\s]*)/)[1];
    obj.params = str.replace(/^@[^\s]*\s+/, '');
    return obj;
};

var objectToNodes = function (node, obj, source) {
    var name, value, decl, rule;
    for ( name in obj ) {
        value = obj[name];
        if ( typeof value === 'object' ) {
            if ( name[0] === '@' ) {
                rule = postcss.atRule(stringToAtRule(name, { source: source }));
            } else {
                rule = postcss.rule({ selector: name, source: source });
            }
            node.append(rule);
            if ( typeof value === 'object' ) objectToNodes(rule, value, source);
        } else {
            decl = postcss.decl({
                prop:   name,
                value:  value.toString(),
                source: source
            });
            node.append(decl);
        }
    }
    return node;
};

var insertObject = function (rule, obj) {
    var root = objectToNodes(postcss.root(), obj, rule.source);
    rule.parent.insertBefore(rule, root);
};

var insertMixin = function (result, mixins, rule, opts) {
    var name   = rule.params.split(/\s/, 1)[0];
    var params = rule.params.slice(name.length).trim();
    if ( params.indexOf(',') === -1 ) {
        params = postcss.list.space(params);
        if ( params.length > 1 ) {
            result.warn('Space argument separation is depreacted and ' +
                        'will be removed in next version. Use comma.',
                        { node: rule });
        }
    } else {
        params = postcss.list.comma(params);
    }

    var meta   = mixins[name];
    var mixin  = meta && meta.mixin;

    if ( !meta ) {
        if ( !opts.silent ) {
            throw rule.error('Undefined mixin ' + name);
        }

    } else if ( mixin.name === 'define-mixin' ) {
        var i;
        var values = { };
        for ( i = 0; i < meta.args.length; i++ ) {
            values[meta.args[i][0]] = params[i] || meta.args[i][1];
        }

        var clones = [];
        for ( i = 0; i < mixin.nodes.length; i++ ) {
            clones.push( mixin.nodes[i].clone() );
        }

        var proxy = postcss.rule({ nodes: clones });
        if ( meta.args.length ) {
            vars({ only: values })(proxy);
        }
        if ( meta.content ) {
            proxy.walkAtRules('mixin-content', function (place) {
                place.replaceWith(rule.nodes);
            });
        }

        rule.parent.insertBefore(rule, clones);

    } else if ( typeof mixin === 'object' ) {
        insertObject(rule, mixin, rule.source);

    } else if ( typeof mixin === 'function' ) {
        var args  = [rule].concat(params);
        var nodes = mixin.apply(this, args);
        if ( typeof nodes === 'object' ) {
            insertObject(rule, nodes, rule.source);
        }
    }

    if ( rule.parent ) rule.remove();
};

var defineMixin = function (result, mixins, rule) {
    var name  = rule.params.split(/\s/, 1)[0];
    var other = rule.params.slice(name.length).trim();

    var args = [];
    if ( other.length ) {
        if ( other.indexOf(',') === -1 && other.indexOf(':') === -1 ) {
            args = other.split(/\s/).map(function (str) {
                return [str.slice(1), ''];
            });
            if ( args.length > 1 ) {
                result.warn('Space argument separation is depreacted and ' +
                            'will be removed in next version. Use comma.',
                            { node: rule });
            }

        } else {
            args = postcss.list.comma(other).map(function (str) {
                var arg      = str.split(':', 1)[0];
                var defaults = str.slice(arg.length + 1);
                return [arg.slice(1).trim(), defaults.trim()];
            });
        }
    }

    var content = false;
    rule.walkAtRules('mixin-content', function () {
        content = true;
        return false;
    });

    mixins[name] = { mixin: rule, args: args, content: content };
    rule.remove();
};

module.exports = postcss.plugin('postcss-mixins', function (opts) {
    if ( typeof opts === 'undefined' ) opts = { };

    var i;
    var cwd    = process.cwd();
    var globs  = [];
    var mixins = { };

    if ( opts.mixinsDir ) {
        if ( !Array.isArray(opts.mixinsDir) ) {
            opts.mixinsDir = [opts.mixinsDir];
        }
        globs = opts.mixinsDir.map(function (dir) {
            return path.join(dir, '*.{js,json,css}');
        });
    }

    if ( opts.mixinsFiles ) globs = globs.concat(opts.mixinsFiles);

    return function (css, result) {
        var discoverMixins = function (atrule) {
            if ( atrule.name === 'mixin' ) {
                insertMixin(result, mixins, atrule, opts);
            } else if ( atrule.name === 'define-mixin' ) {
                defineMixin(result, mixins, atrule);
            }
        };
        return globby(globs).then(function (files) {
            return Promise.all(files.map(function (file) {
                var ext = path.extname(file);
                var name = path.basename(file, ext);
                file = path.join(cwd, path.relative(cwd, file));
                return new Promise(function (resolve, reject) {
                    if (ext === '.css') {
                        fs.readFile(file, function (err, contents) {
                            if ( err ) return reject(err);
                            postcss.parse(contents).walkAtRules(discoverMixins);
                            resolve();
                        });
                        return;
                    }
                    mixins[name] = { mixin: require(file) };
                    resolve();
                });
            }));
        }).then(function () {
            if ( typeof opts.mixins === 'object' ) {
                for ( i in opts.mixins ) {
                    mixins[i] = { mixin: opts.mixins[i] };
                }
            }

            css.walkAtRules(discoverMixins);
        });
    };
});
<|endoftext|>


<commit_before>#ifndef __COMMON__
#define __COMMON__

// define if debugging (insecure!)
#define DEBUG true

// initialize namespace
var rndphrase = {};

#endif
<commit_msg>Disable debug mode<commit_after>#ifndef __COMMON__
#define __COMMON__

// define if debugging (insecure!)
#define DEBUG false

// initialize namespace
var rndphrase = {};

#endif
<|endoftext|>


<commit_before>'use strict';

var Pagelet = require('pagelet')
  , Sapling = require('sapling')
  , qs = require('querystring')
  , t = require('t');

//
// BigPipe depends heavily on the support of JavaScript in browsers as the
// rendering of the page's components is done through JavaScript. When the
// user has JavaScript disabled they will see a blank page instead. To prevent
// this from happening we're injecting a `noscript` tag in to the page which
// forces the `sync` render mode.
//
var noscript = [
  '',
  '<meta http-equiv="refresh" content="0; URL={path}?{query}">',
  ''
].join('');

//
// Also when we have JavaScript enabled make sure the user doesn't accidentally
// force them selfs in to a `sync` render mode as the URL could have been
// shared through social media.
//
var script = [
  ''
].join('');

//
// Map of available content types.
//
var contentTypes = {
  'html': 'text/html',
  'json': 'application/json'
};

//
// This basic HEAD/bootstrap pagelet can easily be extended.
// Bootstrap adds specific directives to the HEAD element, which are required
// for BigPipe to function.
//
// - Sets a default set of meta tags in the HEAD element
// - It includes the pipe.js JavaScript client and initializes it.
// - It includes "core" library files for the page (pagelet dependencies).
// - It includes "core" CSS for the page (pagelet dependencies).
// - It adds a noscript meta refresh to force a `sync` method which fully
//   renders the HTML server side.
//
// Do NOT change the name of the bootstrap pagelet or BigPipe will not
// be able to find it in the pagelet collection.
//
Pagelet.extend({
  name: 'bootstrap',
  title: 'BigPipe',
  description: 'Default description for BigPipe\'s pagelets',
  keywords: ['BigPipe', 'pagelets', 'bootstrap'],
  robots: ['index', 'follow'],
  favicon: '/favicon.ico',
  author: 'BigPipe',

  //
  // Used for proper client side library initialization. Overrules the
  // default pagelet children length getter.
  //
  length: 0,

  //
  // Set of keys used by the HTML renderer to deduce the required data.
  //
  keys: [
    'title', 'description', 'keywords', 'robots', 'favicon', 'author',
    'dependencies', 'fallback', 'charset', 'child', 'length', 'id'
  ],

  /**
   * Get the value of the child's name.
   *
   * @return {String} Child's name
   * @api private
   */
  get child() {
    return this._child;
  },

  /**
   * Set the value of the child's name, only allows strings.
   *
   * @param {String} value Child's name.
   * @api private
   */
  set child(value) {
    if ('string' !== typeof value) return;
    this._child = value;
  },

  /**
   * Render the HTML template with the data provided. Temper provides a minimal
   * templater to handle data in HTML templates. Data has to be specifically
   * provided, properties of `this` are not enumerable and would not be included.
   *
   * @returns {Pagelet} this
   * @api public
   */
  render: function render() {
    var framework = this._bigpipe._framework
      , bootstrap = this;

    //
    // Adds initial HTML headers to the queue. The first flush will
    // push out these headers immediately. If the render mode is sync
    // the headers will be injected with the other content. Since each
    // front-end framework might require custom bootstrapping, data is
    // passed to fittings, which will return valid bootstrap content.
    //
    this.debug('Queueing initial headers');
    this._queue.push({
      name: this.name,
      view: framework.get('bootstrap', this.keys.reduce(function reduce(memo, key) {
        memo[key] = bootstrap[key];
        return memo;
      }, {}))
    });

    return this;
  },

  /**
   * Change the contentType header if possible.
   *
   * @param {String} type html|json
   * @api private
   */
  contentTypeHeader: function contentTypeHeader(type) {
    if (this._res.headersSent) return this.debug(
      'Headers already sent, ignoring content type change: %s', contentTypes[type]
    );

    this.contentType = contentTypes[type];
    this._res.setHeader('Content-Type', this.contentType);
  },

  /**
   * Add fragment of data to the queue.
   *
   * @param {String} name Pagelet name that queued the content.
   * @param {String} parent Pagelet parent that queued the content.
   * @param {Mixed} data Output to be send to the response
   * @returns {Pagelet} this
   * @api public
   */
  queue: function queue(name, parent, data) {
    this.length--;

    //
    // Object was queued, transform the response type to application/json.
    //
    if ('object' === typeof data && this._contentType !== contentTypes.json) {
      this.emit('contentType', 'json');
    }

    this._queue.push({
      parent: parent,
      name: name,
      view: data
    });

    return this;
  },

  /**
   * Joins all the data fragments in the queue.
   *
   * @return {Mixed} Object by pagelet name or HTML string
   * @api private
   */
  join: function join() {
    var pagelet = this
      , result = this._queue.map(function flatten(fragment) {
          if (!fragment.name || !fragment.view) return '';
          return fragment.view;
        });

    try {
      result = this._contentType === contentTypes.json
        ? JSON.stringify(result.shift())
        : result.join('');
    } catch (error) {
      this.emit('done', error);
      return this.debug('Captured error while stringifying JSON data %s', error);
    }

    this._queue.length = 0;
    return result;
  },

  /**
   * Flush all queued rendered pagelets to the request object.
   *
   * @returns {Pagelet} this
   * @api private
   */
  flush: function flush(done) {
    this.once('done', done);

    if (this._res.finished) {
      this.emit('done', new Error('Response was closed, unable to flush content'));
    }

    if (!this._queue.length) this.emit('done');
    var data = new Buffer(this.join(), this.charset);

    if (data.length) {
      this.debug('Writing %d bytes of %s to response', data.length, this.charset);
      this._res.write(data, this.emits('done'));
    }

    //
    // Optional write confirmation, it got added in more recent versions of
    // node, so if it's not supported we're just going to call the callback
    // our selfs.
    //
    if (this._res.write.length !== 3 || !data.length) this.emit('done');
  },

  /**
   * Reduce all elements of the current queue to one single element based on
   * the data-pagelet attribute. Only text/html content can be properly reduced.
   *
   * @returns {Bootstrap} reference to self
   * @api private
   */
  reduce: function reduce() {
    if (this._contentType !== contentTypes.html) return this;
    var tree = new Sapling(this._queue, 'name', 'parent');

    t.dfs(tree, function each(child, parent) {
      if (parent && parent.name === child.parent) [
        "data-pagelet='"+ child.name +"'",
        'data-pagelet="'+ child.name +'"',
        'data-pagelet='+ child.name,
      ].forEach(function locate(attribute) {
        var index = parent.view.indexOf(attribute)
          , id = '{id-'+ child.name +'}'
          , end;

        //
        // As multiple versions of the pagelet can be included in to one single
        // parent pagelet we need to search for multiple occurrences of the
        // `data-pagelet` attribute.
        //
        while (~index) {
          end = parent.view.indexOf('>', index);

          if (~end) {
            end += 1;
            parent.view = parent.view.slice(0, end) + id + parent.view.slice(end);
            index = end + id.length;
          }

          index = parent.view.indexOf(attribute, index + 1);
        }
      });
    });

    //
    // Walk through the tree in reversed order to replace the data
    // added in each view. This has to be done separately otherwise childs
    // at different branches might replace content in the wrong parent
    // due to name collisions.
    //
    t.dfs(tree, { order: 'post' }, function each(child, parent) {
      if (parent && parent.name === child.parent) {
        parent.view = parent.view.replace(
          new RegExp('{id-'+ child.name +'}','g'),
          child.view
        );
      }
    });

    //
    // Finally clean up the queue for unprocessed fragments. Only the root
    // element containing the content of the reduced children is allowed to
    // be written to the response. Remaining fragments would destroy the
    // HTML output.
    //
    this._queue = [{
      name: tree.name,
      view: tree.view
    }];

    return this;
  },

  /**
   * Extend the default constructor of the pagelet to set additional defaults
   * based on the provided options.
   *
   * @param {Object} options Optional options.
   * @api public
   */
  constructor: function constructor(options) {
    Pagelet.prototype.constructor.call(this, options = options || {});

    //
    // Store the provided global dependencies.
    //
    this.dependencies = this._bigpipe._compiler.page(this).concat(
      options.dependencies
    ).filter(function (what, i, arr) {
      return arr.indexOf(what) === i;
    }).join('');

    var req = options.req || {}
      , uri = req.uri || {}
      , query = req.query || {};

    //
    // Set a number of properties on the response as it is available to all pagelets.
    // This will ensure the correct amount of pagelets are processed and that the
    // entire queue is written to the client.
    //
    this._queue = [];

    //
    // Prepare several properties that are used to render the HTML fragment.
    //
    this.length = options.length || 0;
    this.child = options.child || 'root';
    this.once('contentType', this.contentTypeHeader, this);

    //
    // Set the default fallback script, see explanation above.
    //
    this.debug('Initialized in %s mode', options.mode);
    this.fallback = 'sync' === options.mode ? script : noscript.replace(
      '{path}',
      uri.pathname || 'http://localhost/'
    ).replace(
      '{query}',
      qs.stringify(this.merge({ no_pagelet_js: 1 }, query))
    );
  }
}).on(module);
<commit_msg>[fix] Re-introduce the name property<commit_after>'use strict';

var Pagelet = require('pagelet')
  , Sapling = require('sapling')
  , qs = require('querystring')
  , t = require('t');

//
// BigPipe depends heavily on the support of JavaScript in browsers as the
// rendering of the page's components is done through JavaScript. When the
// user has JavaScript disabled they will see a blank page instead. To prevent
// this from happening we're injecting a `noscript` tag in to the page which
// forces the `sync` render mode.
//
var noscript = [
  '',
  '<meta http-equiv="refresh" content="0; URL={path}?{query}">',
  ''
].join('');

//
// Also when we have JavaScript enabled make sure the user doesn't accidentally
// force them selfs in to a `sync` render mode as the URL could have been
// shared through social media.
//
var script = [
  ''
].join('');

//
// Map of available content types.
//
var contentTypes = {
  'html': 'text/html',
  'json': 'application/json'
};

//
// This basic HEAD/bootstrap pagelet can easily be extended.
// Bootstrap adds specific directives to the HEAD element, which are required
// for BigPipe to function.
//
// - Sets a default set of meta tags in the HEAD element
// - It includes the pipe.js JavaScript client and initializes it.
// - It includes "core" library files for the page (pagelet dependencies).
// - It includes "core" CSS for the page (pagelet dependencies).
// - It adds a noscript meta refresh to force a `sync` method which fully
//   renders the HTML server side.
//
// Do NOT change the name of the bootstrap pagelet or BigPipe will not
// be able to find it in the pagelet collection.
//
Pagelet.extend({
  name: 'bootstrap',
  title: 'BigPipe',
  description: 'Default description for BigPipe\'s pagelets',
  keywords: ['BigPipe', 'pagelets', 'bootstrap'],
  robots: ['index', 'follow'],
  favicon: '/favicon.ico',
  author: 'BigPipe',

  //
  // Used for proper client side library initialization. Overrules the
  // default pagelet children length getter.
  //
  length: 0,

  //
  // Set of keys used by the HTML renderer to deduce the required data.
  //
  keys: [
    'title', 'description', 'keywords', 'robots', 'favicon', 'author',
    'dependencies', 'fallback', 'charset', 'child', 'length', 'id', 'name'
  ],

  /**
   * Get the value of the child's name.
   *
   * @return {String} Child's name
   * @api private
   */
  get child() {
    return this._child;
  },

  /**
   * Set the value of the child's name, only allows strings.
   *
   * @param {String} value Child's name.
   * @api private
   */
  set child(value) {
    if ('string' !== typeof value) return;
    this._child = value;
  },

  /**
   * Render the HTML template with the data provided. Temper provides a minimal
   * templater to handle data in HTML templates. Data has to be specifically
   * provided, properties of `this` are not enumerable and would not be included.
   *
   * @returns {Pagelet} this
   * @api public
   */
  render: function render() {
    var framework = this._bigpipe._framework
      , bootstrap = this;

    //
    // Adds initial HTML headers to the queue. The first flush will
    // push out these headers immediately. If the render mode is sync
    // the headers will be injected with the other content. Since each
    // front-end framework might require custom bootstrapping, data is
    // passed to fittings, which will return valid bootstrap content.
    //
    this.debug('Queueing initial headers');
    this._queue.push({
      name: this.name,
      view: framework.get('bootstrap', this.keys.reduce(function reduce(memo, key) {
        memo[key] = bootstrap[key];
        return memo;
      }, {}))
    });

    return this;
  },

  /**
   * Change the contentType header if possible.
   *
   * @param {String} type html|json
   * @api private
   */
  contentTypeHeader: function contentTypeHeader(type) {
    if (this._res.headersSent) return this.debug(
      'Headers already sent, ignoring content type change: %s', contentTypes[type]
    );

    this.contentType = contentTypes[type];
    this._res.setHeader('Content-Type', this.contentType);
  },

  /**
   * Add fragment of data to the queue.
   *
   * @param {String} name Pagelet name that queued the content.
   * @param {String} parent Pagelet parent that queued the content.
   * @param {Mixed} data Output to be send to the response
   * @returns {Pagelet} this
   * @api public
   */
  queue: function queue(name, parent, data) {
    this.length--;

    //
    // Object was queued, transform the response type to application/json.
    //
    if ('object' === typeof data && this._contentType !== contentTypes.json) {
      this.emit('contentType', 'json');
    }

    this._queue.push({
      parent: parent,
      name: name,
      view: data
    });

    return this;
  },

  /**
   * Joins all the data fragments in the queue.
   *
   * @return {Mixed} Object by pagelet name or HTML string
   * @api private
   */
  join: function join() {
    var pagelet = this
      , result = this._queue.map(function flatten(fragment) {
          if (!fragment.name || !fragment.view) return '';
          return fragment.view;
        });

    try {
      result = this._contentType === contentTypes.json
        ? JSON.stringify(result.shift())
        : result.join('');
    } catch (error) {
      this.emit('done', error);
      return this.debug('Captured error while stringifying JSON data %s', error);
    }

    this._queue.length = 0;
    return result;
  },

  /**
   * Flush all queued rendered pagelets to the request object.
   *
   * @returns {Pagelet} this
   * @api private
   */
  flush: function flush(done) {
    this.once('done', done);

    if (this._res.finished) {
      this.emit('done', new Error('Response was closed, unable to flush content'));
    }

    if (!this._queue.length) this.emit('done');
    var data = new Buffer(this.join(), this.charset);

    if (data.length) {
      this.debug('Writing %d bytes of %s to response', data.length, this.charset);
      this._res.write(data, this.emits('done'));
    }

    //
    // Optional write confirmation, it got added in more recent versions of
    // node, so if it's not supported we're just going to call the callback
    // our selfs.
    //
    if (this._res.write.length !== 3 || !data.length) this.emit('done');
  },

  /**
   * Reduce all elements of the current queue to one single element based on
   * the data-pagelet attribute. Only text/html content can be properly reduced.
   *
   * @returns {Bootstrap} reference to self
   * @api private
   */
  reduce: function reduce() {
    if (this._contentType !== contentTypes.html) return this;
    var tree = new Sapling(this._queue, 'name', 'parent');

    t.dfs(tree, function each(child, parent) {
      if (parent && parent.name === child.parent) [
        "data-pagelet='"+ child.name +"'",
        'data-pagelet="'+ child.name +'"',
        'data-pagelet='+ child.name,
      ].forEach(function locate(attribute) {
        var index = parent.view.indexOf(attribute)
          , id = '{id-'+ child.name +'}'
          , end;

        //
        // As multiple versions of the pagelet can be included in to one single
        // parent pagelet we need to search for multiple occurrences of the
        // `data-pagelet` attribute.
        //
        while (~index) {
          end = parent.view.indexOf('>', index);

          if (~end) {
            end += 1;
            parent.view = parent.view.slice(0, end) + id + parent.view.slice(end);
            index = end + id.length;
          }

          index = parent.view.indexOf(attribute, index + 1);
        }
      });
    });

    //
    // Walk through the tree in reversed order to replace the data
    // added in each view. This has to be done separately otherwise childs
    // at different branches might replace content in the wrong parent
    // due to name collisions.
    //
    t.dfs(tree, { order: 'post' }, function each(child, parent) {
      if (parent && parent.name === child.parent) {
        parent.view = parent.view.replace(
          new RegExp('{id-'+ child.name +'}','g'),
          child.view
        );
      }
    });

    //
    // Finally clean up the queue for unprocessed fragments. Only the root
    // element containing the content of the reduced children is allowed to
    // be written to the response. Remaining fragments would destroy the
    // HTML output.
    //
    this._queue = [{
      name: tree.name,
      view: tree.view
    }];

    return this;
  },

  /**
   * Extend the default constructor of the pagelet to set additional defaults
   * based on the provided options.
   *
   * @param {Object} options Optional options.
   * @api public
   */
  constructor: function constructor(options) {
    Pagelet.prototype.constructor.call(this, options = options || {});

    //
    // Store the provided global dependencies.
    //
    this.dependencies = this._bigpipe._compiler.page(this).concat(
      options.dependencies
    ).filter(function (what, i, arr) {
      return arr.indexOf(what) === i;
    }).join('');

    var req = options.req || {}
      , uri = req.uri || {}
      , query = req.query || {};

    //
    // Set a number of properties on the response as it is available to all pagelets.
    // This will ensure the correct amount of pagelets are processed and that the
    // entire queue is written to the client.
    //
    this._queue = [];

    //
    // Prepare several properties that are used to render the HTML fragment.
    //
    this.length = options.length || 0;
    this.child = options.child || 'root';
    this.once('contentType', this.contentTypeHeader, this);

    //
    // Set the default fallback script, see explanation above.
    //
    this.debug('Initialized in %s mode', options.mode);
    this.fallback = 'sync' === options.mode ? script : noscript.replace(
      '{path}',
      uri.pathname || 'http://localhost/'
    ).replace(
      '{query}',
      qs.stringify(this.merge({ no_pagelet_js: 1 }, query))
    );
  }
}).on(module);
<|endoftext|>


<commit_before>var util = require('util');

var binding = null;
try {
	binding = require(__dirname + '/build/Debug/obj.target/isc_dhclient.node');
} catch(e) {
	if(e.code == 'MODULE_NOT_FOUND')
		binding = require(__dirname + '/build/Release/obj.target/isc_dhclient.node');
	else
		console.error("ERROR: " + util.inspect(e));
}

if(binding) {
	module.exports = binding;
} else {
	console.error("Error loading node-isc-dhclient native.");
}

module.exports.newClient = function() {
  var o = binding._newClient();

  o.setLeaseCallback = function(cb) {
    return o._setLeaseCallback(function(lease) {
  //    console.log("Got lease: " + lease);
      lease = lease.replace(/\\n/g, "\\n")
                   .replace(/\\'/g, "\\'")
                   .replace(/\\"/g, '\\"')
                   .replace(/\\&/g, "\\&")
                   .replace(/\\r/g, "\\r")
                   .replace(/\\t/g, "\\t")
                   .replace(/\\b/g, "\\b")
                   .replace(/\\f/g, "\\f");
    // remove non-printable and other non-valid JSON chars
      lease = lease.replace(/[\u0000-\u0019]+/g,"");
      var obj = null;
      try {
        obj = JSON.parse(lease);
        // console.log("valid json:");
        // console.dir(obj);
      } catch(e) {
        console.error("Invalid JSON in lease: " + util.inspect(e));
        cb(null);
      }
      if(obj) {
        cb(obj);
      }
    });
  }

  return o;
}
<commit_msg>added use strict<commit_after>'use strict';

var util = require('util');

var binding = null;
try {
	binding = require(__dirname + '/build/Debug/obj.target/isc_dhclient.node');
} catch(e) {
	if(e.code == 'MODULE_NOT_FOUND')
		binding = require(__dirname + '/build/Release/obj.target/isc_dhclient.node');
	else
		console.error("ERROR: " + util.inspect(e));
}

if(binding) {
	module.exports = binding;
} else {
	console.error("Error loading node-isc-dhclient native.");
}

module.exports.newClient = function() {
  var o = binding._newClient();

  o.setLeaseCallback = function(cb) {
    return o._setLeaseCallback(function(lease) {
  //    console.log("Got lease: " + lease);
      lease = lease.replace(/\\n/g, "\\n")
                   .replace(/\\'/g, "\\'")
                   .replace(/\\"/g, '\\"')
                   .replace(/\\&/g, "\\&")
                   .replace(/\\r/g, "\\r")
                   .replace(/\\t/g, "\\t")
                   .replace(/\\b/g, "\\b")
                   .replace(/\\f/g, "\\f");
    // remove non-printable and other non-valid JSON chars
      lease = lease.replace(/[\u0000-\u0019]+/g,"");
      var obj = null;
      try {
        obj = JSON.parse(lease);
        // console.log("valid json:");
        // console.dir(obj);
      } catch(e) {
        console.error("Invalid JSON in lease: " + util.inspect(e));
        cb(null);
      }
      if(obj) {
        cb(obj);
      }
    });
  };

  return o;
};
<|endoftext|>


<commit_before>'use strict'

/* eslint-disable no-new-func */

const common = {
  toFunction: function (validators) {
    if (!Array.isArray(validators)) {
      throw new TypeError('Validators is not an array')
    }
    // Function code
    let code = '"use strict";\nlet errors = 0;\n'

    // Here we get the validator function code
    validators.forEach((validator) => {
      // Error checking
      if (typeof validator !== 'object') {
        throw new TypeError('Validator is not an object')
      }
      if (typeof validator.parameters !== 'object') {
        throw new TypeError('validator.parameters is not an object')
      }
      if (typeof validator.function !== 'function') {
        throw new TypeError('validator.function is not a function')
      }

      // Begins a new block scope
      code += '{\n'
      // Stringify the validator function code
      const functionCode = validator.function.toString()
      // Here we remove the function declaration,
      // this works ONLY if there are not destructuring assignment as parameters.
      // Because of the lib design the validator function has never parameters,
      // so we can be "safe" about the following implementation.
      const linesOfCode = functionCode.substring(functionCode.indexOf('{') + 1, functionCode.lastIndexOf('}'))
                                    .replace(/  +/g, ' ') // eslint-disable-line
                                    .trim()
                                    .split('\n')
      const params = validator.parameters
      linesOfCode.forEach((line) => {
        for (let val in params) {
          let value
          if (typeof params[val] === 'string') {
            value = `'${params[val]}'`

          // If the variable is an object (but not an instance of RegExp) we stringify it
          } else if (typeof params[val] === 'object' && !(params[val] instanceof RegExp)) {
            value = `${JSON.stringify(params[val])}`

          // In all the other cases we add it 'as is' to the code
          } else {
            value = params[val]
          }
          // Replace $varname$ with its value
          line = line.replace(new RegExp('\\' + val.substring(0, val.length - 1) + '\\$', 'g'), value)
        }
        code += line + '\n'
      })
      // Ends the block scope
      code += '}'
    })

    // Adds the final return
    code += 'return errors === 0'
    // Generates the new Function
    return new Function('value', code)
  },

  // Thanks to: https://davidwalsh.name/javascript-arguments
  getArgs: function (func) {
    if (typeof func !== 'function') {
      throw new TypeError('func is not a function')
    }

    // First match everything inside the function argument parens.
    let args = func.toString().match(/function\s.*?\(([^)]*)\)/)[1]

    // Split the arguments string into an array comma delimited.
    return args.split(',').map(function (arg) {
      // Ensure no inline comments are parsed and trim the whitespace.
      return arg.replace(/\/\*.*\*\//, '').trim()
    }).filter(function (arg) {
      // Ensure no undefined values are added.
      return arg
    })
  },

  extend: function (tyvalValidator, func) {
    if (typeof func !== 'function') {
      throw new TypeError('func is not a function')
    }

    // Gets the parameters name
    const parametersName = this.getArgs(func)

    // Extends the passed tyval validator with a new function
    tyvalValidator[func.name] = function () {
      // gets the parameters passed as arguments
      const parametersValue = Array.prototype.slice.call(arguments)
      if (parametersName.length !== parametersValue.length) {
        throw new Error('The length of parametersName and parametersValue do not coincide')
      }

      // Instantiate the parameters object
      const parameters = {}
      for (let i = 0; i < parametersName.length; i++) {
        // Adds the parameters name: value
        parameters['$' + parametersName[i] + '$'] = parametersValue[i]
      }

      // Push the function and the generated parameters object
      tyvalValidator.validators.push({
        function: func,
        parameters: parameters
      })

      return tyvalValidator
    }
  }
}

module.exports = common
<commit_msg>Fixes<commit_after>'use strict'

/* eslint-disable no-new-func */

const common = {
  toFunction: function (validators) {
    if (!Array.isArray(validators)) {
      throw new TypeError('Validators is not an array')
    }
    // Function code
    let code = '"use strict"\nlet errors = 0\n'

    // Here we get the validator function code
    validators.forEach((validator) => {
      // Error checking
      if (typeof validator !== 'object') {
        throw new TypeError('Validator is not an object')
      }
      if (typeof validator.parameters !== 'object') {
        throw new TypeError('validator.parameters is not an object')
      }
      if (typeof validator.function !== 'function') {
        throw new TypeError('validator.function is not a function')
      }

      // Begins a new block scope
      code += '{\n'
      // Stringify the validator function code
      const functionCode = validator.function.toString()
      // Here we remove the function declaration,
      // this works ONLY if there are not destructuring assignment as parameters.
      // Because of the lib design the validator function has never parameters,
      // so we can be "safe" about the following implementation.
      const linesOfCode = functionCode.substring(functionCode.indexOf('{') + 1, functionCode.lastIndexOf('}'))
                                      .replace(/  +/g, ' ') // eslint-disable-line
                                      .trim()
                                      .split('\n')
      const params = validator.parameters
      linesOfCode.forEach((line) => {
        for (let val in params) {
          let value
          if (typeof params[val] === 'string') {
            value = `'${params[val]}'`

          // If the variable is an object (but not an instance of RegExp) we stringify it
          } else if (typeof params[val] === 'object' && !(params[val] instanceof RegExp)) {
            value = `${JSON.stringify(params[val])}`

          // In all the other cases we add it 'as is' to the code
          } else {
            value = params[val]
          }
          // Replace $varname$ with its value
          line = line.replace(new RegExp('\\' + val.substring(0, val.length - 1) + '\\$', 'g'), value)
        }
        code += line + '\n'
      })
      // Ends the block scope
      code += '}'
    })

    // Adds the final return
    code += '\nreturn errors === 0'
    // Generates the new Function
    return new Function('value', code)
  },

  // Thanks to: https://davidwalsh.name/javascript-arguments
  getArgs: function (func) {
    if (typeof func !== 'function') {
      throw new TypeError('func is not a function')
    }

    // First match everything inside the function argument parens.
    let args = func.toString().match(/function\s.*?\(([^)]*)\)/)[1]

    // Split the arguments string into an array comma delimited.
    return args.split(',').map(function (arg) {
      // Ensure no inline comments are parsed and trim the whitespace.
      return arg.replace(/\/\*.*\*\//, '').trim()
    }).filter(function (arg) {
      // Ensure no undefined values are added.
      return arg
    })
  },

  extend: function (tyvalValidator, func) {
    if (typeof func !== 'function') {
      throw new TypeError('func is not a function')
    }

    // Gets the parameters name
    const parametersName = this.getArgs(func)

    // Extends the passed tyval validator with a new function
    tyvalValidator[func.name] = function () {
      // gets the parameters passed as arguments
      const parametersValue = Array.prototype.slice.call(arguments)
      if (parametersName.length !== parametersValue.length) {
        throw new Error('The length of parametersName and parametersValue do not coincide')
      }

      // Instantiate the parameters object
      const parameters = {}
      for (let i = 0; i < parametersName.length; i++) {
        // Adds the parameters name: value
        parameters['$' + parametersName[i] + '$'] = parametersValue[i]
      }

      // Push the function and the generated parameters object
      tyvalValidator.validators.push({
        function: func,
        parameters: parameters
      })

      return tyvalValidator
    }
  }
}

module.exports = common
<|endoftext|>


<commit_before>"use strict";

/**
 * Dependencies
 **/
var io = require("socket.io"),
  ioAuth = require("socketio-auth"),
  Pubsub = require("./pubsub"),
  debug = require("debug")("lc:pubsub"),
  NATS = require("nats");

/**
 * @module LoopBack Component PubSub
 * @author Jonathan Casarrubias <http://twitter.com/johncasarrubias>
 * @description
 *
 * This module integrates LoopBack with Socket IO in order to provide
 * PubSub functionallity.
 */
module.exports = (app, options) => {

  /**
   * Set Default Options
   */
  options = Object.assign({}, {
    auth: true,
    removeApiRoot: true,
    apiRoot: app.settings.restApiRoot,
    natsUrl: process.env.NATS_URL || app.settings.natsUrl || ""
  }, options);

  debug("Options from component config:", options);

  /**
   * Set Listener waiting for Http Server
   **/
  app.on("started", start);

  /**
   * Setup Real Time Communications
   **/
  function start(server) {
    debug("RTC server listening at %s", app.get("url").replace("http", "ws"));

    // Lets create an instance of IO and reference it in app
    var socket = io(server);
    var nats   = buildNatsClient(options);

    // close the engine to let the app server stop
    app.on("stopping", () => {
      debug("Attached server is stopping, closing pubsub engines");
      if ( socket ) socket.engine.close();
      if ( nats )   nats.close();
    });

    // Add a pubsub instanceable module
    app.pubsub = new Pubsub(socket, nats, options);

    // Configure ioAuth
    if (options.auth === true) {
      debug("RTC authentication mechanism enabled");

      ioAuth(socket, {
        authenticate: (ctx, token, next) => {
          var AccessToken = app.models.AccessToken;
          //verify credentials sent by the client
          token = AccessToken.find({
            where: { id: token.id || 0, userId: token.userId || 0 }
          }, (err, tokenInstance) => {
            next(err, tokenInstance.length > 0 ? true : false);
          });
        },
        postAuthenticate: () => {
          socket.on("authentication", value => {
            debug("A user (%s) has been authenticated over web sockets", value.userId);
          });
        }
      });
    }

    socket.on("connection", connection => {
      debug("A new client connected", connection.id);
      connection.on("lb-ping", () => connection.emit("lb-pong", new Date().getTime() / 1000));
    });
  }
};

var buildNatsClient = function(options) {
  if ( options.natsUrl === "" || !options.natsUrl ) {
    return null;
  }

  var opts = {
    url: options.natsUrl,
    reconnect: true,
    maxReconnectAttempts: 30
  };

  if ( options.natsAuth ) {
    debug("Using nats authentication");
    opts.user = options.natsAuth.user;
    opts.pass = options.natsAuth.pass;
  }

  var nats = NATS.connect(opts);

  nats.on("connect", function() {
    debug("NATS connected on %s", options.natsUrl);
  });

  nats.on("reconnecting", function() {
    debug("NATS attempting reconnection to %s", options.natsUrl);
  });

  nats.on("error", function(err) {
    debug("NATS error: %s", err);

    if ( err.indexOf("ECONNREFUSED") ) {
      setTimeout(function() {
        debug("NATS attempting to re-open connection with %s", options.natsUrl)
        nats.parseOptions(opts);
        nats.initState();
        nats.createConnection();
      }, 2000)
    }
  });

  nats.on("close", function() {
    debug("NATS connection closed");

    if ( nats.closed ) return;

    debug("NATS attempting to re-open connection with %s", options.natsUrl)
    nats.parseOptions(opts);
    nats.initState();
    nats.createConnection();
  });

  nats.on("disconnect", function() {
    debug("NATS was disconnected");
  });

  nats.on("reconnecting", function() {
    debug("NATS is reconnecting");
  });

  return nats;
};
<commit_msg>move buildNatsClient inside the exported function<commit_after>"use strict";

/**
 * Dependencies
 **/
var io = require("socket.io"),
  ioAuth = require("socketio-auth"),
  Pubsub = require("./pubsub"),
  debug = require("debug")("lc:pubsub"),
  NATS = require("nats");

/**
 * @module LoopBack Component PubSub
 * @author Jonathan Casarrubias <http://twitter.com/johncasarrubias>
 * @description
 *
 * This module integrates LoopBack with Socket IO in order to provide
 * PubSub functionallity.
 */
module.exports = (app, options) => {

  /**
   * Set Default Options
   */
  options = Object.assign({}, {
    auth: true,
    removeApiRoot: true,
    apiRoot: app.settings.restApiRoot,
    natsUrl: process.env.NATS_URL || app.settings.natsUrl || ""
  }, options);

  debug("Options from component config:", options);

  /**
   * Set Listener waiting for Http Server
   **/
  app.on("started", start);

  /**
   * Setup Real Time Communications
   **/
  function start(server) {
    debug("RTC server listening at %s", app.get("url").replace("http", "ws"));

    // Lets create an instance of IO and reference it in app
    var socket = io(server);
    var nats   = buildNatsClient(options);

    // close the engine to let the app server stop
    app.on("stopping", () => {
      debug("Attached server is stopping, closing pubsub engines");
      if ( socket ) socket.engine.close();
      if ( nats )   nats.close();
    });

    // Add a pubsub instanceable module
    app.pubsub = new Pubsub(socket, nats, options);

    // Configure ioAuth
    if (options.auth === true) {
      debug("RTC authentication mechanism enabled");

      ioAuth(socket, {
        authenticate: (ctx, token, next) => {
          var AccessToken = app.models.AccessToken;
          //verify credentials sent by the client
          token = AccessToken.find({
            where: { id: token.id || 0, userId: token.userId || 0 }
          }, (err, tokenInstance) => {
            next(err, tokenInstance.length > 0 ? true : false);
          });
        },
        postAuthenticate: () => {
          socket.on("authentication", value => {
            debug("A user (%s) has been authenticated over web sockets", value.userId);
          });
        }
      });
    }

    socket.on("connection", connection => {
      debug("A new client connected", connection.id);
      connection.on("lb-ping", () => connection.emit("lb-pong", new Date().getTime() / 1000));
    });
  }

  // this will build a NATS client and return it, even if it is not connected,
  // with reconnection and persistent reopening handled via the callbacks available
  // from the NATS client itself.  Publishes will still work but will fall into
  // the ether until the connection is re-established
  var buildNatsClient = function(options) {
    if ( options.natsUrl === "" || !options.natsUrl ) {
      return null;
    }

    var opts = {
      url: options.natsUrl,
      reconnect: true,
      maxReconnectAttempts: 30
    };

    if ( options.natsAuth ) {
      debug("Using nats authentication");
      opts.user = options.natsAuth.user;
      opts.pass = options.natsAuth.pass;
    }

    var nats = NATS.connect(opts);

    nats.on("connect", function() {
      debug("NATS connected on %s", options.natsUrl);
    });

    nats.on("reconnecting", function() {
      debug("NATS attempting reconnection to %s", options.natsUrl);
    });

    nats.on("error", function(err) {
      debug("NATS error: %s", err);

      if ( err.indexOf("ECONNREFUSED") ) {
        setTimeout(function() {
          debug("NATS attempting to re-open connection with %s", options.natsUrl)
          nats.parseOptions(opts);
          nats.initState();
          nats.createConnection();
        }, 2000)
      }
    });

    nats.on("close", function() {
      debug("NATS connection closed");

      if ( nats.closed ) return;

      debug("NATS attempting to re-open connection with %s", options.natsUrl)
      nats.parseOptions(opts);
      nats.initState();
      nats.createConnection();
    });

    nats.on("disconnect", function() {
      debug("NATS was disconnected");
    });

    nats.on("reconnecting", function() {
      debug("NATS is reconnecting");
    });

    return nats;
  };
};
<|endoftext|>


<commit_before>var packet = require('dns-packet')
var dgram = require('dgram')
var thunky = require('thunky')
var events = require('events')
var os = require('os')

var noop = function () {}

module.exports = function (opts) {
  if (!opts) opts = {}

  var that = new events.EventEmitter()
  var port = typeof opts.port === 'number' ? opts.port : 5353
  var type = opts.type || 'udp4'
  var ip = opts.ip || opts.host || (type === 'udp4' ? '224.0.0.251' : null)
  var me = {address: ip, port: port}
  var memberships = {}
  var destroyed = false
  var interval = null

  if (type === 'udp6' && (!ip || !opts.interface)) {
    throw new Error('For IPv6 multicast you must specify `ip` and `interface`')
  }

  var socket = opts.socket || dgram.createSocket({
    type: type,
    reuseAddr: opts.reuseAddr !== false,
    toString: function () {
      return type
    }
  })

  socket.on('error', function (err) {
    if (err.code === 'EACCES' || err.code === 'EADDRINUSE') that.emit('error', err)
    else that.emit('warning', err)
  })

  socket.on('message', function (message, rinfo) {
    try {
      message = packet.decode(message)
    } catch (err) {
      that.emit('warning', err)
      return
    }

    that.emit('packet', message, rinfo)

    if (message.type === 'query') that.emit('query', message, rinfo)
    if (message.type === 'response') that.emit('response', message, rinfo)
  })

  socket.on('listening', function () {
    if (!port) port = me.port = socket.address().port
    if (opts.multicast !== false) {
      that.update()
      interval = setInterval(that.update, 5000)
      socket.setMulticastTTL(opts.ttl || 255)
      socket.setMulticastLoopback(opts.loopback !== false)
    }
  })

  var bind = thunky(function (cb) {
    if (!port || opts.bind === false) return cb(null)
    socket.once('error', cb)
    socket.bind(port, opts.bind || opts.interface, function () {
      socket.removeListener('error', cb)
      cb(null)
    })
  })

  bind(function (err) {
    if (err) return that.emit('error', err)
    that.emit('ready')
  })

  that.send = function (value, rinfo, cb) {
    if (typeof rinfo === 'function') return that.send(value, null, rinfo)
    if (!cb) cb = noop
    if (!rinfo) rinfo = me
    else if (!rinfo.host && !rinfo.address) rinfo.address = me.address

    bind(onbind)

    function onbind (err) {
      if (destroyed) return cb()
      if (err) return cb(err)
      var message = packet.encode(value)
      socket.send(message, 0, message.length, rinfo.port, rinfo.address || rinfo.host, cb)
    }
  }

  that.response =
  that.respond = function (res, rinfo, cb) {
    if (Array.isArray(res)) res = {answers: res}

    res.type = 'response'
    res.flags = (res.flags || 0) | packet.AUTHORITATIVE_ANSWER
    that.send(res, rinfo, cb)
  }

  that.query = function (q, type, rinfo, cb) {
    if (typeof type === 'function') return that.query(q, null, null, type)
    if (typeof type === 'object' && type && type.port) return that.query(q, null, type, rinfo)
    if (typeof rinfo === 'function') return that.query(q, type, null, rinfo)
    if (!cb) cb = noop

    if (typeof q === 'string') q = [{name: q, type: type || 'ANY'}]
    if (Array.isArray(q)) q = {type: 'query', questions: q}

    q.type = 'query'
    that.send(q, rinfo, cb)
  }

  that.destroy = function (cb) {
    if (!cb) cb = noop
    if (destroyed) return process.nextTick(cb)
    destroyed = true
    clearInterval(interval)
    socket.once('close', cb)
    socket.close()
  }

  that.update = function () {
    var ifaces = opts.interface ? [].concat(opts.interface) : allInterfaces()
    var updated = false

    for (var i = 0; i < ifaces.length; i++) {
      var addr = ifaces[i]

      if (memberships[addr]) continue
      memberships[addr] = true
      updated = true

      try {
        socket.addMembership(ip, addr)
      } catch (err) {
        that.emit('warning', err)
      }
    }

    if (!updated || !socket.setMulticastInterface) return
    socket.setMulticastInterface(opts.interface || defaultInterface())
  }

  return that
}

function defaultInterface () {
  var networks = os.networkInterfaces()
  var names = Object.keys(networks)

  for (var i = 0; i < names.length; i++) {
    var net = networks[names[i]]
    for (var j = 0; j < net.length; j++) {
      var iface = net[j]
      if (iface.family === 'IPv4' && !iface.internal) {
        if (os.platform() === 'darwin' && names[i] === 'en0') return iface.address
        return '0.0.0.0'
      }
    }
  }

  return '127.0.0.1'
}

function allInterfaces () {
  var networks = os.networkInterfaces()
  var names = Object.keys(networks)
  var res = []

  for (var i = 0; i < names.length; i++) {
    var net = networks[names[i]]
    for (var j = 0; j < net.length; j++) {
      var iface = net[j]
      if (iface.family === 'IPv4') {
        res.push(iface.address)
        // could only addMembership once per interface (https://nodejs.org/api/dgram.html#dgram_socket_addmembership_multicastaddress_multicastinterface)
        break
      }
    }
  }

  return res
}
<commit_msg>'networkInterface' event (#50)<commit_after>var packet = require('dns-packet')
var dgram = require('dgram')
var thunky = require('thunky')
var events = require('events')
var os = require('os')

var noop = function () {}

module.exports = function (opts) {
  if (!opts) opts = {}

  var that = new events.EventEmitter()
  var port = typeof opts.port === 'number' ? opts.port : 5353
  var type = opts.type || 'udp4'
  var ip = opts.ip || opts.host || (type === 'udp4' ? '224.0.0.251' : null)
  var me = {address: ip, port: port}
  var memberships = {}
  var destroyed = false
  var interval = null

  if (type === 'udp6' && (!ip || !opts.interface)) {
    throw new Error('For IPv6 multicast you must specify `ip` and `interface`')
  }

  var socket = opts.socket || dgram.createSocket({
    type: type,
    reuseAddr: opts.reuseAddr !== false,
    toString: function () {
      return type
    }
  })

  socket.on('error', function (err) {
    if (err.code === 'EACCES' || err.code === 'EADDRINUSE') that.emit('error', err)
    else that.emit('warning', err)
  })

  socket.on('message', function (message, rinfo) {
    try {
      message = packet.decode(message)
    } catch (err) {
      that.emit('warning', err)
      return
    }

    that.emit('packet', message, rinfo)

    if (message.type === 'query') that.emit('query', message, rinfo)
    if (message.type === 'response') that.emit('response', message, rinfo)
  })

  socket.on('listening', function () {
    if (!port) port = me.port = socket.address().port
    if (opts.multicast !== false) {
      that.update()
      interval = setInterval(that.update, 5000)
      socket.setMulticastTTL(opts.ttl || 255)
      socket.setMulticastLoopback(opts.loopback !== false)
    }
  })

  var bind = thunky(function (cb) {
    if (!port || opts.bind === false) return cb(null)
    socket.once('error', cb)
    socket.bind(port, opts.bind || opts.interface, function () {
      socket.removeListener('error', cb)
      cb(null)
    })
  })

  bind(function (err) {
    if (err) return that.emit('error', err)
    that.emit('ready')
  })

  that.send = function (value, rinfo, cb) {
    if (typeof rinfo === 'function') return that.send(value, null, rinfo)
    if (!cb) cb = noop
    if (!rinfo) rinfo = me
    else if (!rinfo.host && !rinfo.address) rinfo.address = me.address

    bind(onbind)

    function onbind (err) {
      if (destroyed) return cb()
      if (err) return cb(err)
      var message = packet.encode(value)
      socket.send(message, 0, message.length, rinfo.port, rinfo.address || rinfo.host, cb)
    }
  }

  that.response =
  that.respond = function (res, rinfo, cb) {
    if (Array.isArray(res)) res = {answers: res}

    res.type = 'response'
    res.flags = (res.flags || 0) | packet.AUTHORITATIVE_ANSWER
    that.send(res, rinfo, cb)
  }

  that.query = function (q, type, rinfo, cb) {
    if (typeof type === 'function') return that.query(q, null, null, type)
    if (typeof type === 'object' && type && type.port) return that.query(q, null, type, rinfo)
    if (typeof rinfo === 'function') return that.query(q, type, null, rinfo)
    if (!cb) cb = noop

    if (typeof q === 'string') q = [{name: q, type: type || 'ANY'}]
    if (Array.isArray(q)) q = {type: 'query', questions: q}

    q.type = 'query'
    that.send(q, rinfo, cb)
  }

  that.destroy = function (cb) {
    if (!cb) cb = noop
    if (destroyed) return process.nextTick(cb)
    destroyed = true
    clearInterval(interval)

    // Need to drop memberships by hand and ignore errors.
    // socket.close() does not cope with errors.
    for (var iface in memberships) {
      try {
        socket.dropMembership(ip, iface)
      } catch (e) {
        // eat it
      }
    }
    memberships = {}
    socket.close(cb)
  }

  that.update = function () {
    var ifaces = opts.interface ? [].concat(opts.interface) : allInterfaces()
    var updated = false

    for (var i = 0; i < ifaces.length; i++) {
      var addr = ifaces[i]
      if (memberships[addr]) continue

      try {
        socket.addMembership(ip, addr)
        memberships[addr] = true
        updated = true
      } catch (err) {
        that.emit('warning', err)
      }
    }

    if (updated) {
      if (socket.setMulticastInterface) {
        try {
          socket.setMulticastInterface(opts.interface || defaultInterface())
        } catch (err) {
          that.emit('warning', err)
        }
      }
      that.emit('networkInterface')
    }
  }

  return that
}

function defaultInterface () {
  var networks = os.networkInterfaces()
  var names = Object.keys(networks)

  for (var i = 0; i < names.length; i++) {
    var net = networks[names[i]]
    for (var j = 0; j < net.length; j++) {
      var iface = net[j]
      if (iface.family === 'IPv4' && !iface.internal) {
        if (os.platform() === 'darwin' && names[i] === 'en0') return iface.address
        return '0.0.0.0'
      }
    }
  }

  return '127.0.0.1'
}

function allInterfaces () {
  var networks = os.networkInterfaces()
  var names = Object.keys(networks)
  var res = []

  for (var i = 0; i < names.length; i++) {
    var net = networks[names[i]]
    for (var j = 0; j < net.length; j++) {
      var iface = net[j]
      if (iface.family === 'IPv4') {
        res.push(iface.address)
        // could only addMembership once per interface (https://nodejs.org/api/dgram.html#dgram_socket_addmembership_multicastaddress_multicastinterface)
        break
      }
    }
  }

  return res
}
<|endoftext|>


<commit_before><commit_msg>Database-level security.<commit_after><|endoftext|>


<commit_before>var Container = typeof Buffer !== "undefined" ? Buffer //in node, use buffers
		: typeof Int8Array !== "undefined" ? Int8Array //in newer browsers, use webgl int8arrays
		: function(l){ var a = new Array(l); for(var i = 0; i < l; i++) a[i]=0; }; //else, do something similar

function BitField(data){
	if(!(this instanceof BitField)) {
		return new BitField(data);
	}
	if(typeof data === "number"){
		if(data % 8 !== 0) data += 1 << 3;
		data = new Container(data >> 3);
		if(data.fill) data.fill(0); // clear node buffers of garbage
	}
	this.buffer = data;
}

BitField.prototype.get = function(i){
	var j = i >> 3;
	if (j < this.buffer.length) {
		return !!(this.buffer[j] & (128 >> (i % 8)));
	} else {
		return false;
	}
};

BitField.prototype.set = function(i, b){
	var j = i >> 3;
	if (b || arguments.length === 1){
		this._grow(j + 1);
		/* Set */
		this.buffer[j] |= 128 >> (i % 8);
	} else if (j < this.buffer.length) {
		/* Clear */
		this.buffer[j] &= ~(128 >> (i % 8));
	}
};

BitField.prototype._grow = function(length) {
	if (this.buffer.length < length) {
		var newBuffer = new Container(length);
		if (newBuffer.fill) newBuffer.fill(0);
		for(var i = 0; i < this.buffer.length; i++) {
			newBuffer[i] = this.buffer[i];
		}
		this.buffer = newBuffer;
	}
}

if(typeof module !== "undefined") module.exports = BitField;
<commit_msg>get(): use single return statement<commit_after>var Container = typeof Buffer !== "undefined" ? Buffer //in node, use buffers
		: typeof Int8Array !== "undefined" ? Int8Array //in newer browsers, use webgl int8arrays
		: function(l){ var a = new Array(l); for(var i = 0; i < l; i++) a[i]=0; }; //else, do something similar

function BitField(data){
	if(!(this instanceof BitField)) {
		return new BitField(data);
	}
	if(typeof data === "number"){
		if(data % 8 !== 0) data += 1 << 3;
		data = new Container(data >> 3);
		if(data.fill) data.fill(0); // clear node buffers of garbage
	}
	this.buffer = data;
}

BitField.prototype.get = function(i){
	var j = i >> 3;
	return (j < this.buffer.length) &&
		!!(this.buffer[j] & (128 >> (i % 8)));
};

BitField.prototype.set = function(i, b){
	var j = i >> 3;
	if (b || arguments.length === 1){
		this._grow(j + 1);
		/* Set */
		this.buffer[j] |= 128 >> (i % 8);
	} else if (j < this.buffer.length) {
		/* Clear */
		this.buffer[j] &= ~(128 >> (i % 8));
	}
};

BitField.prototype._grow = function(length) {
	if (this.buffer.length < length) {
		var newBuffer = new Container(length);
		if (newBuffer.fill) newBuffer.fill(0);
		for(var i = 0; i < this.buffer.length; i++) {
			newBuffer[i] = this.buffer[i];
		}
		this.buffer = newBuffer;
	}
}

if(typeof module !== "undefined") module.exports = BitField;
<|endoftext|>


<commit_before>var getType = require('should-type');
var util = require('./util');

function genKeysFunc(f) {
  return function(value) {
    var k = f(value);
    k.sort();
    return k;
  };
}

function Formatter(opts) {
  opts = opts || {};

  this.seen = [];
  this.keys = genKeysFunc(opts.keys === false ? Object.getOwnPropertyNames : Object.keys);

  this.maxLineLength = typeof opts.maxLineLength === 'number' ? opts.maxLineLength : 60;
  this.propSep = opts.propSep || ',';

  this.isUTCdate = !!opts.isUTCdate;
}

Formatter.prototype = {
  constructor: Formatter,

  format: function(value) {
    var t = getType(value);
    var name1 = t.type, name2 = t.type;
    if(t.cls) {
      name1 += '_' + t.cls;
      name2 += '_' + t.cls;
    }
    if(t.sub) {
      name2 += '_' + t.sub;
    }
    var f = this['_format_' + name2] || this['_format_' + name1] || this['_format_' + t.type] || this.defaultFormat;
    return f.call(this, value).trim();
  },

  _formatObject: function(value, opts) {
    opts = opts || {};
    var mainKeys = opts.keys || this.keys(value);

    var len = 0;

    var formatPropertyValue = opts.formatPropertyValue || this.formatPropertyValue;
    var formatPropertyName = opts.formatPropertyName || this.formatPropertyName;
    var keyValueSep = opts.keyValueSep || ': ';
    var keyFilter = opts.keyFilter || function() { return true; };

    this.seen.push(value);
    var keys = [];

    mainKeys.forEach(function(key) {
      if(!keyFilter(key)) return;

      var fName = formatPropertyName.call(this, key);

      var f = (fName ? fName + keyValueSep : '') + formatPropertyValue.call(this, value, key);
      len += f.length;
      keys.push(f);
    }, this);
    this.seen.pop();

    (opts.additionalProperties || []).forEach(function(keyValue) {
      var f = keyValue[0] + keyValueSep + this.format(keyValue[1]);
      len += f.length;
      keys.push(f);
    }, this);

    var prefix = opts.prefix || Formatter.constructorName(value) || '';
    if(prefix.length > 0) prefix += ' ';

    var lbracket, rbracket;
    if(Array.isArray(opts.brackets)) {
      lbracket = opts.brackets && opts.brackets[0];
      rbracket = opts.brackets && opts.brackets[1];
    } else {
      lbracket = '{';
      rbracket = '}';
    }

    var rootValue = opts.value || '';

    if(keys.length === 0)
      return rootValue || (prefix + lbracket + rbracket);

    if(len <= this.maxLineLength) {
      return prefix + lbracket + ' ' + (rootValue ? rootValue + ' ' : '') + keys.join(this.propSep + ' ') + ' ' + rbracket;
    } else {
      return prefix + lbracket + '\n' + (rootValue ? '  ' + rootValue + '\n' : '') + keys.map(util.addSpaces).join(this.propSep + '\n') + '\n' + rbracket;
    }
  },

  formatObject: function(value, prefix, props) {
    props = props || this.keys(value);

    var len = 0;

    this.seen.push(value);
    props = props.map(function(prop) {
      var f = this.formatProperty(value, prop);
      len += f.length;
      return f;
    }, this);
    this.seen.pop();

    if(props.length === 0) return '{}';

    if(len <= this.maxLineLength) {
      return '{ ' + (prefix ? prefix + ' ' : '') + props.join(this.propSep + ' ') + ' }';
    } else {
      return '{' + '\n' + (prefix ? '  ' + prefix + '\n' : '') + props.map(util.addSpaces).join(this.propSep + '\n') + '\n' + '}';
    }
  },

  formatPropertyName: function(name) {
    return name.match(/^[a-zA-Z_$][a-zA-Z_$0-9]*$/) ? name : this.format(name);
  },

  formatProperty: function(value, prop) {
    var desc = Formatter.getPropertyDescriptor(value, prop);

    var propName = this.formatPropertyName(prop);

    var propValue = desc.get && desc.set ?
      '[Getter/Setter]' : desc.get ?
      '[Getter]' : desc.set ?
      '[Setter]' : this.seen.indexOf(desc.value) >= 0 ?
      '[Circular]' :
      this.format(desc.value);

    return propName + ': ' + propValue;
  },

  formatPropertyValue: function(value, prop) {
    var desc = Formatter.getPropertyDescriptor(value, prop);

    var propValue = desc.get && desc.set ?
      '[Getter/Setter]' : desc.get ?
      '[Getter]' : desc.set ?
      '[Setter]' : this.seen.indexOf(desc.value) >= 0 ?
      '[Circular]' :
      this.format(desc.value);

    return propValue;
  }
};

Formatter.add = function add(type, cls, sub, f) {
  var args = Array.prototype.slice.call(arguments);
  f = args.pop();
  Formatter.prototype['_format_' + args.join('_')] = f;
};

Formatter.formatObjectWithPrefix = function formatObjectWithPrefix(f) {
  return function(value) {
    var prefix = f.call(this, value);
    var props = this.keys(value);
    if(props.length == 0) return prefix;
    else return this.formatObject(value, prefix, props);
  };
};

var functionNameRE = /^\s*function\s*(\S*)\s*\(/;

Formatter.functionName = function functionName(f) {
  if(f.name) {
    return f.name;
  }
  var name = f.toString().match(functionNameRE)[1];
  return name;
};

Formatter.constructorName = function(obj) {
  while (obj) {
    var descriptor = Object.getOwnPropertyDescriptor(obj, 'constructor');
    if (descriptor !== undefined &&
        typeof descriptor.value === 'function') {

        var name = Formatter.functionName(descriptor.value);
        if(name !== '') {
          return name;
        }
    }

    obj = Object.getPrototypeOf(obj);
  }
};

Formatter.getPropertyDescriptor = function(obj, value) {
  var desc;
  try {
    desc = Object.getOwnPropertyDescriptor(obj, value) || {value: obj[value]};
  } catch(e) {
    desc = {value: e};
  }
  return desc;
};

Formatter.generateFunctionForIndexedArray = function generateFunctionForIndexedArray(lengthProp, name, padding) {
  return function(value) {
    var max = this.byteArrayMaxLength || 50;
    var length = value[lengthProp];
    var formattedValues = [];
    var len = 0;
    for(var i = 0; i < max && i < length; i++) {
      var b = value[i] || 0;
      var v = util.pad0(b.toString(16), padding);
      len += v.length;
      formattedValues.push(v);
    }
    var prefix = value.constructor.name || name || '';
    if(prefix) prefix += ' ';

    if(formattedValues.length === 0)
      return prefix + '[]';

    if(len <= this.maxLineLength) {
      return prefix + '[ ' + formattedValues.join(this.propSep + ' ') + ' ' + ']';
    } else {
      return prefix + '[\n' + formattedValues.map(util.addSpaces).join(this.propSep + '\n') + '\n' + ']';
    }
  };
};

Formatter.add('undefined', function() { return 'undefined' });
Formatter.add('null', function() { return 'null' });
Formatter.add('boolean', function(value) { return value ? 'true': 'false' });
Formatter.add('symbol', function(value) { return value.toString() });

['number', 'boolean'].forEach(function(name) {
  Formatter.add('object', name, function(value) {
    return this._formatObject(value, {
      additionalProperties: [['[[PrimitiveValue]]', value.valueOf()]]
    });
  });
});

Formatter.add('object', 'string', function(value) {
  var realValue = value.valueOf();

  return this._formatObject(value, {
    keyFilter: function(key) {
      //skip useless indexed properties
      return !(key.match(/\d+/) && parseInt(key, 10) < realValue.length);
    },
    additionalProperties: [['[[PrimitiveValue]]', realValue]]
  });
});

Formatter.add('object', 'regexp', function(value) {
  return this._formatObject(value, {
    value: String(value)
  });
});

Formatter.add('number', function(value) {
  if(value === 0 && 1 / value < 0) return '-0';
  return String(value);
});

Formatter.add('string', function(value) {
  return '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
      .replace(/'/g, "\\'")
      .replace(/\\"/g, '"') + '\'';
});

Formatter.add('object', function(value) {
  return this._formatObject(value);
});

Formatter.add('object', 'arguments', function(value) {
  return this._formatObject(value, {
    prefix: 'Arguments',
    formatPropertyName: function(key) {
      if(!key.match(/\d+/)) {
        return this.formatPropertyName(key);
      }
    },
    brackets: ['[', ']']
  });
});

Formatter.add('object', 'array', function(value) {
  return this._formatObject(value, {
    formatPropertyName: function(key) {
      if(!key.match(/\d+/)) {
        return this.formatPropertyName(key);
      }
    },
    brackets: ['[', ']']
  });
});

function formatDate(value, isUTC) {
  var prefix = isUTC ? 'UTC' : '';

  var date = value['get' + prefix + 'FullYear']() +
    '-' +
    util.pad0(value['get' + prefix + 'Month']() + 1, 2) +
    '-' +
    util.pad0(value['get' + prefix + 'Date'](), 2);

  var time = util.pad0(value['get' + prefix + 'Hours'](), 2) +
    ':' +
    util.pad0(value['get' + prefix + 'Minutes'](), 2) +
    ':' +
    util.pad0(value['get' + prefix + 'Seconds'](), 2) +
    '.' +
    util.pad0(value['get' + prefix + 'Milliseconds'](), 3);

  var to = value.getTimezoneOffset();
  var absTo = Math.abs(to);
  var hours = Math.floor(absTo / 60);
  var minutes = absTo - hours * 60;
  var tzFormat = (to < 0 ? '+' : '-') + util.pad0(hours, 2) + util.pad0(minutes, 2);

  return date + ' ' + time + (isUTC ? '' : ' ' + tzFormat);
}

Formatter.add('object', 'date', function(value) {
  return this._formatObject(value, { value: formatDate(value, this.isUTCdate) });
});

Formatter.add('function', function(value) {
  return this._formatObject(value, {
    additionalProperties: [['name', Formatter.functionName(value)]]
  });
});

Formatter.add('object', 'error', function(value) {
  return this._formatObject(value, {
    prefix: value.name,
    additionalProperties: [['message', value.message]]
  });
});

Formatter.add('object', 'buffer', Formatter.generateFunctionForIndexedArray('length', 'Buffer', 2));

Formatter.add('object', 'array-buffer', Formatter.generateFunctionForIndexedArray('byteLength', 'ArrayBuffer', 2));

Formatter.add('object', 'typed-array', 'int8', Formatter.generateFunctionForIndexedArray('length', 'Int8Array', 2));
Formatter.add('object', 'typed-array', 'uint8', Formatter.generateFunctionForIndexedArray('length', 'Uint8Array', 2));
Formatter.add('object', 'typed-array', 'uint8clamped', Formatter.generateFunctionForIndexedArray('length', 'Uint8ClampedArray', 2));

Formatter.add('object', 'typed-array', 'int16', Formatter.generateFunctionForIndexedArray('length', 'Int16Array', 4));
Formatter.add('object', 'typed-array', 'uint16', Formatter.generateFunctionForIndexedArray('length', 'Uint16Array', 4));

Formatter.add('object', 'typed-array', 'int32', Formatter.generateFunctionForIndexedArray('length', 'Int32Array', 8));
Formatter.add('object', 'typed-array', 'uint32', Formatter.generateFunctionForIndexedArray('length', 'Uint32Array', 8));

//TODO add float32 and float64

Formatter.add('object', 'promise', function() {
  return '[Promise]';//TODO it could be nice to inspect its state and value
});

Formatter.add('object', 'xhr', function() {
  return '[XMLHttpRequest]';//TODO it could be nice to inspect its state
});

Formatter.add('object', 'html-element', function(value) {
  return value.outerHTML;
});

Formatter.add('object', 'html-element', '#text', function(value) {
  return value.nodeValue;
});

Formatter.add('object', 'html-element', '#document', function(value) {
  return value.documentElement.outerHTML;
});

Formatter.add('object', 'host', function() {
  return '[Host]';
});

Formatter.add('object', 'set', function(value) {
  var iter = value.values();
  var len = 0;

  this.seen.push(value);

  var props = [];

  var next = iter.next();
  while(!next.done) {
    var val = next.value;
    var f = this.format(val);
    len += f.length;
    props.push(f);

    next = iter.next();
  }

  this.seen.pop();

  if(props.length === 0) return 'Set {}';

  if(len <= this.maxLineLength) {
    return 'Set { ' + props.join(this.propSep + ' ') + ' }';
  } else {
    return 'Set {\n' + props.map(util.addSpaces).join(this.propSep + '\n') + '\n' + '}';
  }
});

Formatter.add('object', 'map', function(value) {
  var iter = value.entries();
  var len = 0;

  this.seen.push(value);

  var props = [];

  var next = iter.next();
  while(!next.done) {
    var val = next.value;
    var fK = this.format(val[0]);
    var fV = this.format(val[1]);

    var f;
    if((fK.length + fV.length + 4) <= this.maxLineLength) {
      f = fK + ' => ' + fV;
    } else {
      f = fK + ' =>\n' + fV;
    }

    len += fK.length + fV.length + 4;
    props.push(f);

    next = iter.next();
  }

  this.seen.pop();

  if(props.length === 0) return 'Map {}';

  if(len <= this.maxLineLength) {
    return 'Map { ' + props.join(this.propSep + ' ') + ' }';
  } else {
    return 'Map {\n' + props.map(util.addSpaces).join(this.propSep + '\n') + '\n' + '}';
  }
});

Formatter.prototype.defaultFormat = Formatter.prototype._format_object;

function defaultFormat(value, opts) {
  return new Formatter(opts).format(value);
}

defaultFormat.Formatter = Formatter;
module.exports = defaultFormat;
<commit_msg>Fix `Formatter.functionName` TypeError for arrow functions<commit_after>var getType = require('should-type');
var util = require('./util');

function genKeysFunc(f) {
  return function(value) {
    var k = f(value);
    k.sort();
    return k;
  };
}

function Formatter(opts) {
  opts = opts || {};

  this.seen = [];
  this.keys = genKeysFunc(opts.keys === false ? Object.getOwnPropertyNames : Object.keys);

  this.maxLineLength = typeof opts.maxLineLength === 'number' ? opts.maxLineLength : 60;
  this.propSep = opts.propSep || ',';

  this.isUTCdate = !!opts.isUTCdate;
}

Formatter.prototype = {
  constructor: Formatter,

  format: function(value) {
    var t = getType(value);
    var name1 = t.type, name2 = t.type;
    if(t.cls) {
      name1 += '_' + t.cls;
      name2 += '_' + t.cls;
    }
    if(t.sub) {
      name2 += '_' + t.sub;
    }
    var f = this['_format_' + name2] || this['_format_' + name1] || this['_format_' + t.type] || this.defaultFormat;
    return f.call(this, value).trim();
  },

  _formatObject: function(value, opts) {
    opts = opts || {};
    var mainKeys = opts.keys || this.keys(value);

    var len = 0;

    var formatPropertyValue = opts.formatPropertyValue || this.formatPropertyValue;
    var formatPropertyName = opts.formatPropertyName || this.formatPropertyName;
    var keyValueSep = opts.keyValueSep || ': ';
    var keyFilter = opts.keyFilter || function() { return true; };

    this.seen.push(value);
    var keys = [];

    mainKeys.forEach(function(key) {
      if(!keyFilter(key)) return;

      var fName = formatPropertyName.call(this, key);

      var f = (fName ? fName + keyValueSep : '') + formatPropertyValue.call(this, value, key);
      len += f.length;
      keys.push(f);
    }, this);
    this.seen.pop();

    (opts.additionalProperties || []).forEach(function(keyValue) {
      var f = keyValue[0] + keyValueSep + this.format(keyValue[1]);
      len += f.length;
      keys.push(f);
    }, this);

    var prefix = opts.prefix || Formatter.constructorName(value) || '';
    if(prefix.length > 0) prefix += ' ';

    var lbracket, rbracket;
    if(Array.isArray(opts.brackets)) {
      lbracket = opts.brackets && opts.brackets[0];
      rbracket = opts.brackets && opts.brackets[1];
    } else {
      lbracket = '{';
      rbracket = '}';
    }

    var rootValue = opts.value || '';

    if(keys.length === 0)
      return rootValue || (prefix + lbracket + rbracket);

    if(len <= this.maxLineLength) {
      return prefix + lbracket + ' ' + (rootValue ? rootValue + ' ' : '') + keys.join(this.propSep + ' ') + ' ' + rbracket;
    } else {
      return prefix + lbracket + '\n' + (rootValue ? '  ' + rootValue + '\n' : '') + keys.map(util.addSpaces).join(this.propSep + '\n') + '\n' + rbracket;
    }
  },

  formatObject: function(value, prefix, props) {
    props = props || this.keys(value);

    var len = 0;

    this.seen.push(value);
    props = props.map(function(prop) {
      var f = this.formatProperty(value, prop);
      len += f.length;
      return f;
    }, this);
    this.seen.pop();

    if(props.length === 0) return '{}';

    if(len <= this.maxLineLength) {
      return '{ ' + (prefix ? prefix + ' ' : '') + props.join(this.propSep + ' ') + ' }';
    } else {
      return '{' + '\n' + (prefix ? '  ' + prefix + '\n' : '') + props.map(util.addSpaces).join(this.propSep + '\n') + '\n' + '}';
    }
  },

  formatPropertyName: function(name) {
    return name.match(/^[a-zA-Z_$][a-zA-Z_$0-9]*$/) ? name : this.format(name);
  },

  formatProperty: function(value, prop) {
    var desc = Formatter.getPropertyDescriptor(value, prop);

    var propName = this.formatPropertyName(prop);

    var propValue = desc.get && desc.set ?
      '[Getter/Setter]' : desc.get ?
      '[Getter]' : desc.set ?
      '[Setter]' : this.seen.indexOf(desc.value) >= 0 ?
      '[Circular]' :
      this.format(desc.value);

    return propName + ': ' + propValue;
  },

  formatPropertyValue: function(value, prop) {
    var desc = Formatter.getPropertyDescriptor(value, prop);

    var propValue = desc.get && desc.set ?
      '[Getter/Setter]' : desc.get ?
      '[Getter]' : desc.set ?
      '[Setter]' : this.seen.indexOf(desc.value) >= 0 ?
      '[Circular]' :
      this.format(desc.value);

    return propValue;
  }
};

Formatter.add = function add(type, cls, sub, f) {
  var args = Array.prototype.slice.call(arguments);
  f = args.pop();
  Formatter.prototype['_format_' + args.join('_')] = f;
};

Formatter.formatObjectWithPrefix = function formatObjectWithPrefix(f) {
  return function(value) {
    var prefix = f.call(this, value);
    var props = this.keys(value);
    if(props.length == 0) return prefix;
    else return this.formatObject(value, prefix, props);
  };
};

var functionNameRE = /^\s*function\s*(\S*)\s*\(/;

Formatter.functionName = function functionName(f) {
  if(f.name) {
    return f.name;
  }
  var matches = f.toString().match(functionNameRE);
  if (matches === null) {
    // `functionNameRE` doesn't match arrow functions.
    return '';
  }
  var name = matches[1];
  return name;
};

Formatter.constructorName = function(obj) {
  while (obj) {
    var descriptor = Object.getOwnPropertyDescriptor(obj, 'constructor');
    if (descriptor !== undefined &&
        typeof descriptor.value === 'function') {

        var name = Formatter.functionName(descriptor.value);
        if(name !== '') {
          return name;
        }
    }

    obj = Object.getPrototypeOf(obj);
  }
};

Formatter.getPropertyDescriptor = function(obj, value) {
  var desc;
  try {
    desc = Object.getOwnPropertyDescriptor(obj, value) || {value: obj[value]};
  } catch(e) {
    desc = {value: e};
  }
  return desc;
};

Formatter.generateFunctionForIndexedArray = function generateFunctionForIndexedArray(lengthProp, name, padding) {
  return function(value) {
    var max = this.byteArrayMaxLength || 50;
    var length = value[lengthProp];
    var formattedValues = [];
    var len = 0;
    for(var i = 0; i < max && i < length; i++) {
      var b = value[i] || 0;
      var v = util.pad0(b.toString(16), padding);
      len += v.length;
      formattedValues.push(v);
    }
    var prefix = value.constructor.name || name || '';
    if(prefix) prefix += ' ';

    if(formattedValues.length === 0)
      return prefix + '[]';

    if(len <= this.maxLineLength) {
      return prefix + '[ ' + formattedValues.join(this.propSep + ' ') + ' ' + ']';
    } else {
      return prefix + '[\n' + formattedValues.map(util.addSpaces).join(this.propSep + '\n') + '\n' + ']';
    }
  };
};

Formatter.add('undefined', function() { return 'undefined' });
Formatter.add('null', function() { return 'null' });
Formatter.add('boolean', function(value) { return value ? 'true': 'false' });
Formatter.add('symbol', function(value) { return value.toString() });

['number', 'boolean'].forEach(function(name) {
  Formatter.add('object', name, function(value) {
    return this._formatObject(value, {
      additionalProperties: [['[[PrimitiveValue]]', value.valueOf()]]
    });
  });
});

Formatter.add('object', 'string', function(value) {
  var realValue = value.valueOf();

  return this._formatObject(value, {
    keyFilter: function(key) {
      //skip useless indexed properties
      return !(key.match(/\d+/) && parseInt(key, 10) < realValue.length);
    },
    additionalProperties: [['[[PrimitiveValue]]', realValue]]
  });
});

Formatter.add('object', 'regexp', function(value) {
  return this._formatObject(value, {
    value: String(value)
  });
});

Formatter.add('number', function(value) {
  if(value === 0 && 1 / value < 0) return '-0';
  return String(value);
});

Formatter.add('string', function(value) {
  return '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
      .replace(/'/g, "\\'")
      .replace(/\\"/g, '"') + '\'';
});

Formatter.add('object', function(value) {
  return this._formatObject(value);
});

Formatter.add('object', 'arguments', function(value) {
  return this._formatObject(value, {
    prefix: 'Arguments',
    formatPropertyName: function(key) {
      if(!key.match(/\d+/)) {
        return this.formatPropertyName(key);
      }
    },
    brackets: ['[', ']']
  });
});

Formatter.add('object', 'array', function(value) {
  return this._formatObject(value, {
    formatPropertyName: function(key) {
      if(!key.match(/\d+/)) {
        return this.formatPropertyName(key);
      }
    },
    brackets: ['[', ']']
  });
});

function formatDate(value, isUTC) {
  var prefix = isUTC ? 'UTC' : '';

  var date = value['get' + prefix + 'FullYear']() +
    '-' +
    util.pad0(value['get' + prefix + 'Month']() + 1, 2) +
    '-' +
    util.pad0(value['get' + prefix + 'Date'](), 2);

  var time = util.pad0(value['get' + prefix + 'Hours'](), 2) +
    ':' +
    util.pad0(value['get' + prefix + 'Minutes'](), 2) +
    ':' +
    util.pad0(value['get' + prefix + 'Seconds'](), 2) +
    '.' +
    util.pad0(value['get' + prefix + 'Milliseconds'](), 3);

  var to = value.getTimezoneOffset();
  var absTo = Math.abs(to);
  var hours = Math.floor(absTo / 60);
  var minutes = absTo - hours * 60;
  var tzFormat = (to < 0 ? '+' : '-') + util.pad0(hours, 2) + util.pad0(minutes, 2);

  return date + ' ' + time + (isUTC ? '' : ' ' + tzFormat);
}

Formatter.add('object', 'date', function(value) {
  return this._formatObject(value, { value: formatDate(value, this.isUTCdate) });
});

Formatter.add('function', function(value) {
  return this._formatObject(value, {
    additionalProperties: [['name', Formatter.functionName(value)]]
  });
});

Formatter.add('object', 'error', function(value) {
  return this._formatObject(value, {
    prefix: value.name,
    additionalProperties: [['message', value.message]]
  });
});

Formatter.add('object', 'buffer', Formatter.generateFunctionForIndexedArray('length', 'Buffer', 2));

Formatter.add('object', 'array-buffer', Formatter.generateFunctionForIndexedArray('byteLength', 'ArrayBuffer', 2));

Formatter.add('object', 'typed-array', 'int8', Formatter.generateFunctionForIndexedArray('length', 'Int8Array', 2));
Formatter.add('object', 'typed-array', 'uint8', Formatter.generateFunctionForIndexedArray('length', 'Uint8Array', 2));
Formatter.add('object', 'typed-array', 'uint8clamped', Formatter.generateFunctionForIndexedArray('length', 'Uint8ClampedArray', 2));

Formatter.add('object', 'typed-array', 'int16', Formatter.generateFunctionForIndexedArray('length', 'Int16Array', 4));
Formatter.add('object', 'typed-array', 'uint16', Formatter.generateFunctionForIndexedArray('length', 'Uint16Array', 4));

Formatter.add('object', 'typed-array', 'int32', Formatter.generateFunctionForIndexedArray('length', 'Int32Array', 8));
Formatter.add('object', 'typed-array', 'uint32', Formatter.generateFunctionForIndexedArray('length', 'Uint32Array', 8));

//TODO add float32 and float64

Formatter.add('object', 'promise', function() {
  return '[Promise]';//TODO it could be nice to inspect its state and value
});

Formatter.add('object', 'xhr', function() {
  return '[XMLHttpRequest]';//TODO it could be nice to inspect its state
});

Formatter.add('object', 'html-element', function(value) {
  return value.outerHTML;
});

Formatter.add('object', 'html-element', '#text', function(value) {
  return value.nodeValue;
});

Formatter.add('object', 'html-element', '#document', function(value) {
  return value.documentElement.outerHTML;
});

Formatter.add('object', 'host', function() {
  return '[Host]';
});

Formatter.add('object', 'set', function(value) {
  var iter = value.values();
  var len = 0;

  this.seen.push(value);

  var props = [];

  var next = iter.next();
  while(!next.done) {
    var val = next.value;
    var f = this.format(val);
    len += f.length;
    props.push(f);

    next = iter.next();
  }

  this.seen.pop();

  if(props.length === 0) return 'Set {}';

  if(len <= this.maxLineLength) {
    return 'Set { ' + props.join(this.propSep + ' ') + ' }';
  } else {
    return 'Set {\n' + props.map(util.addSpaces).join(this.propSep + '\n') + '\n' + '}';
  }
});

Formatter.add('object', 'map', function(value) {
  var iter = value.entries();
  var len = 0;

  this.seen.push(value);

  var props = [];

  var next = iter.next();
  while(!next.done) {
    var val = next.value;
    var fK = this.format(val[0]);
    var fV = this.format(val[1]);

    var f;
    if((fK.length + fV.length + 4) <= this.maxLineLength) {
      f = fK + ' => ' + fV;
    } else {
      f = fK + ' =>\n' + fV;
    }

    len += fK.length + fV.length + 4;
    props.push(f);

    next = iter.next();
  }

  this.seen.pop();

  if(props.length === 0) return 'Map {}';

  if(len <= this.maxLineLength) {
    return 'Map { ' + props.join(this.propSep + ' ') + ' }';
  } else {
    return 'Map {\n' + props.map(util.addSpaces).join(this.propSep + '\n') + '\n' + '}';
  }
});

Formatter.prototype.defaultFormat = Formatter.prototype._format_object;

function defaultFormat(value, opts) {
  return new Formatter(opts).format(value);
}

defaultFormat.Formatter = Formatter;
module.exports = defaultFormat;
<|endoftext|>


<commit_before><commit_msg>make symbol optional<commit_after><|endoftext|>


<commit_before>var SteamCommunity = require('steamcommunity');

module.exports = TradeOfferManager;

TradeOfferManager.ETradeOfferState = require('./resources/ETradeOfferState.js');

function TradeOfferManager(steam, domain) {
	this._steam = steam;
	this._community = new SteamCommunity();
	this._domain = domain || 'localhost';

	this._request = this._community._request; // I probably shouldn't be doing this...

	this.apiKey = null;
}

TradeOfferManager.prototype.setCookies = function(cookies, callback) {
	this._community.setCookies(cookies);
	this._checkApiKey(callback);
};

TradeOfferManager.prototype._checkApiKey = function(callback) {
	if(this.apiKey) {
		if(callback) {
			callback();
		}

		return;
	}

	this._community.getWebApiKey(this._domain, function(err, key) {
		if(err) {
			return makeAnError(new Error(err), callback);
		}

		this.apiKey = key;
		callback();
	}.bind(this));
};

function makeAnError(error, callback) {
	if(callback) {
		callback(error);
	} else {
		throw error;
	}
}

require('./webapi.js');
<commit_msg>Export SteamID<commit_after>var SteamCommunity = require('steamcommunity');

module.exports = TradeOfferManager;

TradeOfferManager.SteamID = require('steamid');
TradeOfferManager.ETradeOfferState = require('./resources/ETradeOfferState.js');

function TradeOfferManager(steam, domain) {
	this._steam = steam;
	this._community = new SteamCommunity();
	this._domain = domain || 'localhost';

	this._request = this._community._request; // I probably shouldn't be doing this...

	this.apiKey = null;
}

TradeOfferManager.prototype.setCookies = function(cookies, callback) {
	this._community.setCookies(cookies);
	this._checkApiKey(callback);
};

TradeOfferManager.prototype._checkApiKey = function(callback) {
	if(this.apiKey) {
		if(callback) {
			callback();
		}

		return;
	}

	this._community.getWebApiKey(this._domain, function(err, key) {
		if(err) {
			return makeAnError(new Error(err), callback);
		}

		this.apiKey = key;
		callback();
	}.bind(this));
};

function makeAnError(error, callback) {
	if(callback) {
		callback(error);
	} else {
		throw error;
	}
}

require('./webapi.js');
<|endoftext|>


<commit_before>"use strict";

(function(){

  var
    buf,
    bufIdx = 0,
    hexBytes = [],
    i
  ;

  // Improve memory performance by decreasing this number (>=16)
  // or improve speed by increasing this number (try 16384)
  uuid.BUFFER_SIZE = 512;

  // Binary uuids (even faster)
  uuid.bin = uuidbin;

  // Test for uuid
  uuid.test = isUUID;

  // Cache toString(16)
  // This is massively impactful on performance
  for (i = 0; i < 256; i++) {

    // This is a fast way to ensure a 2 char hex byte
    hexBytes[i] = (i + 0x100).toString(16).substr(1);
  }

  // Node & Browser support
  if ((typeof module !== 'undefined') && (typeof require === 'function')) {
    var crypto = require('crypto');
    module.exports = uuid;
  } else if (typeof window !== 'undefined') {
    window.uuid = uuid;
  }

  // Backup method
  function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
  }

  // uuid.test
  function isUUID(uuid) {
    if (typeof uuid === 'string') {
      return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(uuid);
    }
  }

  // Use best RNG as possible
  function randomBytes(n) {
    var r;
    if (typeof crypto !== 'undefined') {
      if ((typeof buf === 'undefined') || ((bufIdx + n) > uuid.BUFFER_SIZE)) {
        bufIdx = 0;
        if (crypto.getRandomValues) {
          buf = new Uint8Array(uuid.BUFFER_SIZE);
          crypto.getRandomValues(buf);
        } else if (crypto.randomBytes) {
          buf = crypto.randomBytes(uuid.BUFFER_SIZE);
        } else {
          throw new Error('Non-standard crypto library');
        }
      }
      return buf.slice(bufIdx, bufIdx += n);
    } else {
      r = [];
      for (i = 0; i < n; i++) {
        r.push(getRandomInt(0, 255));
      }
      return r;
    }
  }

  // uuid.bin
  function uuidbin() {
    var b = randomBytes(16);
    b[6] = (b[6] & 0x0f) | 0x40;
    b[8] = (b[8] & 0x3f) | 0x80;
    return b;
  }

  // String UUIDv4 (Random)
  function uuid() {
    var b = uuidbin();
    return hexBytes[b[0]] + hexBytes[b[1]] +
      hexBytes[b[2]] + hexBytes[b[3]] + '-' +
      hexBytes[b[4]] + hexBytes[b[5]] + '-' +
      hexBytes[b[6]] + hexBytes[b[7]] + '-' +
      hexBytes[b[8]] + hexBytes[b[9]] + '-' +
      hexBytes[b[10]] + hexBytes[b[11]] +
      hexBytes[b[12]] + hexBytes[b[13]] +
      hexBytes[b[14]] + hexBytes[b[15]]
    ;
  }

})();<commit_msg>Avoid redefining `crypto` (already defined in browser).<commit_after>"use strict";

(function(){

  var
    buf,
    bufIdx = 0,
    hexBytes = [],
    i
  ;

  // Improve memory performance by decreasing this number (>=16)
  // or improve speed by increasing this number (try 16384)
  uuid.BUFFER_SIZE = 512;

  // Binary uuids (even faster)
  uuid.bin = uuidbin;

  // Test for uuid
  uuid.test = isUUID;

  // Cache toString(16)
  // This is massively impactful on performance
  for (i = 0; i < 256; i++) {

    // This is a fast way to ensure a 2 char hex byte
    hexBytes[i] = (i + 0x100).toString(16).substr(1);
  }

  // Node & Browser support
  var _crypto;
  if(typeof crypto !== 'undefined') {
    _crypto = crypto;
  }
  if ((typeof module !== 'undefined') && (typeof require === 'function')) {
    _crypto = _crypto || require('crypto');
    module.exports = uuid;
  } else if (typeof window !== 'undefined') {
    window.uuid = uuid;
  }

  // Backup method
  function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
  }

  // uuid.test
  function isUUID(uuid) {
    if (typeof uuid === 'string') {
      return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(uuid);
    }
  }

  // Use best RNG as possible
  function randomBytes(n) {
    var r;
    if (typeof _crypto !== 'undefined') {
      if ((typeof buf === 'undefined') || ((bufIdx + n) > uuid.BUFFER_SIZE)) {
        bufIdx = 0;
        if (_crypto.getRandomValues) {
          buf = new Uint8Array(uuid.BUFFER_SIZE);
          _crypto.getRandomValues(buf);
        } else if (_crypto.randomBytes) {
          buf = _crypto.randomBytes(uuid.BUFFER_SIZE);
        } else {
          throw new Error('Non-standard crypto library');
        }
      }
      return buf.slice(bufIdx, bufIdx += n);
    } else {
      r = [];
      for (i = 0; i < n; i++) {
        r.push(getRandomInt(0, 255));
      }
      return r;
    }
  }

  // uuid.bin
  function uuidbin() {
    var b = randomBytes(16);
    b[6] = (b[6] & 0x0f) | 0x40;
    b[8] = (b[8] & 0x3f) | 0x80;
    return b;
  }

  // String UUIDv4 (Random)
  function uuid() {
    var b = uuidbin();
    return hexBytes[b[0]] + hexBytes[b[1]] +
      hexBytes[b[2]] + hexBytes[b[3]] + '-' +
      hexBytes[b[4]] + hexBytes[b[5]] + '-' +
      hexBytes[b[6]] + hexBytes[b[7]] + '-' +
      hexBytes[b[8]] + hexBytes[b[9]] + '-' +
      hexBytes[b[10]] + hexBytes[b[11]] +
      hexBytes[b[12]] + hexBytes[b[13]] +
      hexBytes[b[14]] + hexBytes[b[15]]
    ;
  }

})();<|endoftext|>