<commit_before>/** @jsx React.DOM */
'use strict';

var React = require('react'),
    Children = require('react/addons').Children,
    PropTypes = React.PropTypes;

/**
 * Provides a declarative way to specify `document.title` in a single-page app.
 * This component is only intended for client-side usage.
 *
 * Because it is just a React component, you can return it in `render` inside
 * your own components, and use their `props` or `state` to determine the title.
 *
 * `DocumentTitle` does not render to DOM itself, not even to a .
 * In its `render`, it simply returns the only child that was passed to it.
 * Being a container itself, it allows title nesting and specificity.

 * For example, you may put it at the very top of view hierarchy to specify the
 * default title, and then you can give some pages their own `DocumentTitle`s
 * that depend on their `props` or `state`.
 *
 * Sample code (assuming you use something like react-router):
 *
 *     var App = React.createClass({
 *       render: function () {
 *
 *         // Use "My Web App" if no child overrides this
 *
 *         return (
 *           <DocumentTitle title='My Web App'>
*              <this.props.activeRouteHandler />
 *           </DocumentTitle>
 *         );
 *       }
 *     });
 *
 *     var HomePage = React.createClass({
 *       render: function () {
 *
 *         // Use "Home" when this component is mounted
 *
 *         return (
 *           <DocumentTitle title='Home'>
 *
Home, sweet home.

 *           </DocumentTitle>
 *         );
 *       }
 *     });
 *
 *     var NewArticlePage = React.createClass({
 *       mixins: [LinkStateMixin],
 *
 *       render: function () {
 *
 *         // Update using value from state when this component is mounted
 *
 *         return (
 *           <DocumentTitle title={this.state.title || 'Untitled'}>
 *

 *
New Article

 *               <input valueLink={this.linkState('title')} />
 *

 *           </DocumentTitle>
 *         );
 *       }
 *     });
 */
var DocumentTitle = React.createClass({
  displayName: 'DocumentTitle',

  propTypes: {
    title: PropTypes.string
  },

  statics: {
    mountedInstances: [],

    rewind: function () {
      var activeInstance = DocumentTitle.getActiveInstance();
      DocumentTitle.mountedInstances.splice(0);

      if (activeInstance) {
        return activeInstance.props.title;
      }
    },

    getActiveInstance: function () {
      var length = DocumentTitle.mountedInstances.length;
      if (length > 0) {
        return DocumentTitle.mountedInstances[length - 1];
      }
    },

    updateDocumentTitle: function () {
      if (typeof document === 'undefined') {
        return;
      }

      var activeInstance = DocumentTitle.getActiveInstance();
      if (activeInstance) {
        document.title = activeInstance.props.title;
      }
    }
  },

  getDefaultProps: function () {
    return {
      title: ''
    };
  },

  isActive: function () {
    return this === DocumentTitle.getActiveInstance();
  },

  componentWillMount: function () {
    DocumentTitle.mountedInstances.push(this);
    DocumentTitle.updateDocumentTitle();
  },

  componentDidUpdate: function (prevProps) {
    if (this.isActive() && prevProps.title !== this.props.title) {
      DocumentTitle.updateDocumentTitle();
    }
  },

  componentWillUnmount: function () {
    var index = DocumentTitle.mountedInstances.indexOf(this);
    DocumentTitle.mountedInstances.splice(index, 1);
    DocumentTitle.updateDocumentTitle();
  },

  render: function () {
    if (this.props.children) {
      return Children.only(this.props.children);
    } else {
      return null;
    }
  }
});

module.exports = DocumentTitle;
<commit_msg>Remove unneeded JSX pragma and inline docs in favor of README<commit_after>'use strict';

var React = require('react'),
    Children = require('react/addons').Children,
    PropTypes = React.PropTypes;

var DocumentTitle = React.createClass({
  displayName: 'DocumentTitle',

  propTypes: {
    title: PropTypes.string
  },

  statics: {
    mountedInstances: [],

    rewind: function () {
      var activeInstance = DocumentTitle.getActiveInstance();
      DocumentTitle.mountedInstances.splice(0);

      if (activeInstance) {
        return activeInstance.props.title;
      }
    },

    getActiveInstance: function () {
      var length = DocumentTitle.mountedInstances.length;
      if (length > 0) {
        return DocumentTitle.mountedInstances[length - 1];
      }
    },

    updateDocumentTitle: function () {
      if (typeof document === 'undefined') {
        return;
      }

      var activeInstance = DocumentTitle.getActiveInstance();
      if (activeInstance) {
        document.title = activeInstance.props.title;
      }
    }
  },

  getDefaultProps: function () {
    return {
      title: ''
    };
  },

  isActive: function () {
    return this === DocumentTitle.getActiveInstance();
  },

  componentWillMount: function () {
    DocumentTitle.mountedInstances.push(this);
    DocumentTitle.updateDocumentTitle();
  },

  componentDidUpdate: function (prevProps) {
    if (this.isActive() && prevProps.title !== this.props.title) {
      DocumentTitle.updateDocumentTitle();
    }
  },

  componentWillUnmount: function () {
    var index = DocumentTitle.mountedInstances.indexOf(this);
    DocumentTitle.mountedInstances.splice(index, 1);
    DocumentTitle.updateDocumentTitle();
  },

  render: function () {
    if (this.props.children) {
      return Children.only(this.props.children);
    } else {
      return null;
    }
  }
});

module.exports = DocumentTitle;
<|endoftext|>


<commit_before>var R = require('ramda');

var curry = R.curry;
var assoc = R.assoc;
var converge = R.converge;
var compose = R.compose;
var get = R.get;
var propOf = R.propOf;
var identity = R.identity;
var map = R.map;

var isNothing = x => x === null || x === undefined;

var maybe = f => x => isNothing(f(x)) ? x : f(x);

var foreignKeyObj = (key, keyed) => obj => {
  return converge(
    assoc(key),
      compose(
        maybe(propOf(keyed)),
        get(key)),
      identity
    )(obj);
};

var foreignKey = curry((key, keyed, array) =>
  map(
    foreignKeyObj(key, keyed)
    )(array));

module.exports = foreignKey;<commit_msg>removed parameter from foreignKeyObj<commit_after>var R = require('ramda');

var curry = R.curry;
var assoc = R.assoc;
var converge = R.converge;
var compose = R.compose;
var get = R.get;
var propOf = R.propOf;
var identity = R.identity;
var map = R.map;

var isNothing = x => x === null || x === undefined;

var maybe = f => x => isNothing(f(x)) ? x : f(x);

var foreignKeyObj = (key, keyed) =>
  converge(
    assoc(key),
      compose(
        maybe(propOf(keyed)),
        get(key)),
      identity
    );

var foreignKey = curry((key, keyed, array) =>
  map(
    foreignKeyObj(key, keyed)
    )(array));

module.exports = foreignKey;<|endoftext|>


<commit_before>

var _ = require('underscore');
var async = require('async');
var influx  = require('influx');

var MongoClient = require('mongodb').MongoClient
    , Server = require('mongodb').Server;

var configuration =
{
    influxserver : {
        user        : 'root',
        password    : 'root',
        hostname    : 'localhost',
        port        : 8086
    },
    influxdb : {
        user        : 'dbuser',
        password    : '',
        hostname    : 'localhost',
        port        : 8086,
        database    : 'default'

    },
    mongodb : {
        user        : '',
        password    : '',
        hostname    : 'localhost',
        port        : 27017,
        database    : 'default'
    },
    logging : true

}

var influxServer, influxDB, mongoClient, mongodb;

var Mongo2Influx = function(options)
{

    if (options.influxdb)
        _.extend(configuration.influxdb,options.influxdb);

    if (options.influxserver)
        _.extend(configuration.influxserver,options.influxserver);

    if (options.mongodb)
        _.extend(configuration.mongodb,options.mongodb);

}

Mongo2Influx.prototype.connect = function (cb)
{

    influxServer = influx(
        configuration.influxserver.hostname,
        configuration.influxserver.port,
        configuration.influxserver.user,
        configuration.influxserver.pass,
        configuration.influxserver.database
    );

    influxDB = influx(
        configuration.influxdb.hostname,
        configuration.influxdb.port,
        configuration.influxdb.user,
        configuration.influxdb.pass,
        configuration.influxdb.database
    );

    mongoClient = new MongoClient(new Server(configuration.mongodb.hostname, configuration.mongodb.port));

    mongoClient.open(function ( err, mongoClient ) {
        if (err) {
            return cb(err);
        }
        mongodb = mongoClient.db(configuration.mongodb.database);
        if (cb) cb(null);
    });
}

Mongo2Influx.prototype.log = function ()
{
    if (configuration.logging) {
        console.log(_.values(arguments).join(' '));
    }
}

Mongo2Influx.prototype.migrate = function ( prepareFunction, options, callback )
{
    if (!mongodb)
    {
        return callback('mongodb is not connected');
    }

    if ('function' == typeof options)
        callback = options;

    if ('function' != typeof prepareFunction)
        return callback('missing prepare function');
    var self = this;

    mongodb.collections(function(err,collections)
    {
        self.log('found',collections.length,'collection');
        async.eachSeries(collections,function(collection,callbackCollections)
        {

            var collectionName = collection.collectionName;
            if ( -1 !== collectionName.indexOf('system')) return callbackCollections();
            self.log('next collection: ',collectionName);
            var startDump = new Date();
            collection.find().toArray(function(err, results) {
                if (!err && _.isArray(results))
                {
                    self.log('reading results from',collectionName,results.length,'rows, took',(new Date()-startDump),'ms');

                    var index =0;
                    async.eachLimit(results,8,function(row,cb){
                        var startMigration = new Date();
                        var data = prepareFunction(row);

                        if (!row.time) {
                            self.log('skipped row',row);
                            return cb();
                        }

                        influxDB.writePoint(collectionName, data , {pool : false}, function(err) {
                            index++;
                            if (0 == index%1000)
                            {
                                var diff = (new Date()-startMigration) / 1000;
                                var ips = 1000 / diff;
                                self.log('collection',collectionName,'item #',index,'@',ips,' inserts/sec');
                                startMigration = new Date();
                            }
                            if (cb) cb();
                        });
                    },function(err,res)
                    {
                        self.log('collection done',collectionName);
                        callbackCollections(err);
                    });
                } else {
                    self.log('error',err);
                    callbackCollections(err);
                }
            });

        },function(err)
        {
            self.log('done with everything');
        });
    });

}

module.exports = Mongo2Influx;<commit_msg>fixed ips calculation<commit_after>

var _ = require('underscore');
var async = require('async');
var influx  = require('influx');

var MongoClient = require('mongodb').MongoClient
    , Server = require('mongodb').Server;

var configuration =
{
    influxserver : {
        user        : 'root',
        password    : 'root',
        hostname    : 'localhost',
        port        : 8086
    },
    influxdb : {
        user        : 'dbuser',
        password    : '',
        hostname    : 'localhost',
        port        : 8086,
        database    : 'default'

    },
    mongodb : {
        user        : '',
        password    : '',
        hostname    : 'localhost',
        port        : 27017,
        database    : 'default'
    },
    logging : true

}

var influxServer, influxDB, mongoClient, mongodb;

var Mongo2Influx = function(options)
{

    if (options.influxdb)
        _.extend(configuration.influxdb,options.influxdb);

    if (options.influxserver)
        _.extend(configuration.influxserver,options.influxserver);

    if (options.mongodb)
        _.extend(configuration.mongodb,options.mongodb);

}

Mongo2Influx.prototype.connect = function (cb)
{

    influxServer = influx(
        configuration.influxserver.hostname,
        configuration.influxserver.port,
        configuration.influxserver.user,
        configuration.influxserver.pass,
        configuration.influxserver.database
    );

    influxDB = influx(
        configuration.influxdb.hostname,
        configuration.influxdb.port,
        configuration.influxdb.user,
        configuration.influxdb.pass,
        configuration.influxdb.database
    );

    mongoClient = new MongoClient(new Server(configuration.mongodb.hostname, configuration.mongodb.port));

    mongoClient.open(function ( err, mongoClient ) {
        if (err) {
            return cb(err);
        }
        mongodb = mongoClient.db(configuration.mongodb.database);
        if (cb) cb(null);
    });
}

Mongo2Influx.prototype.log = function ()
{
    if (configuration.logging) {
        console.log(_.values(arguments).join(' '));
    }
}

Mongo2Influx.prototype.migrate = function ( prepareFunction, options, callback )
{
    if (!mongodb)
    {
        return callback('mongodb is not connected');
    }

    if ('function' == typeof options)
        callback = options;

    if ('function' != typeof prepareFunction)
        return callback('missing prepare function');
    var self = this;

    mongodb.collections(function(err,collections)
    {
        self.log('found',collections.length,'collection');
        async.eachSeries(collections,function(collection,callbackCollections)
        {

            var collectionName = collection.collectionName;
            if ( -1 !== collectionName.indexOf('system')) return callbackCollections();
            self.log('next collection: ',collectionName);
            var startDump = new Date();
            collection.find().toArray(function(err, results) {
                if (!err && _.isArray(results))
                {
                    self.log('reading results from',collectionName,results.length,'rows, took',(new Date()-startDump),'ms');

                    var index =0;
                    var startMigration = new Date();
                    async.eachLimit(results,8,function(row,cb){
                        var data = prepareFunction(row);

                        if (!row.time) {
                            self.log('skipped row',row);
                            return cb();
                        }

                        influxDB.writePoint(collectionName, data , {pool : false}, function(err) {
                            index++;
                            if (0 == index%1000)
                            {
                                var diff = (new Date()-startMigration) / 1000;
                                var ips = Math.round(1000 / diff);
                                self.log('collection',collectionName,'item #',index,'@',ips,'inserts/sec');
                                startMigration = new Date();
                            }
                            if (cb) cb();
                        });
                    },function(err,res)
                    {
                        self.log('collection done',collectionName);
                        callbackCollections(err);
                    });
                } else {
                    self.log('error',err);
                    callbackCollections(err);
                }
            });

        },function(err)
        {
            self.log('done with everything');
        });
    });

}

module.exports = Mongo2Influx;<|endoftext|>


<commit_before>
const debug                = require('debug')('kuss:pool')
const R                    = require('ramda')
const Bluebird             = require('bluebird')
const GenericPool          = require('generic-pool')
const { FibonacciBackoff } = require('simple-backoff')

const CONFIG_PROP_SERVER    = 'server'
const CONFIG_PROP_VALIDATOR = 'validate'
const CONFIG_PROP_TEST      = 'testOnBorrow'

const EVENT_CREATE_ERROR    = 'factoryCreateError'

const DEFAULT_CONFIG = {
  max               : 10
, min               : 2
, idleTimeoutMillis : 30000
, log               : false
, testOnBorrow      : false
, logger            : console
}

function _addBackoff(factory) {
  const backoff              = new FibonacciBackoff()
  const originalCreateMethod = factory.create

  factory.create = function __run() {

    return originalCreateMethod().catch(function ___handleErrorInCreate(e) {

      const wait = backoff.next()

      debug(
        '::_addBackoff - could not create resource - waiting %d ms - %s'
      , wait
      , e.message
      )

      return Bluebird.delay(wait).throw(e)

    })

  }

  return factory

}

function _buildPoolConfig(factory, user_config) {
  const pool_config   = R.merge(DEFAULT_CONFIG, user_config)

  if (R.has(CONFIG_PROP_VALIDATOR, factory)) {
    pool_config[CONFIG_PROP_TEST] = true
  }

  debug('::_buildPoolConfig - configuration: %o', pool_config)

  return pool_config
}

function _buildFactory(builder, default_config, user_config) {
  const server_config = R.propOr({}, CONFIG_PROP_SERVER, user_config)
  const config        = R.merge(default_config, server_config)

  debug('::_buildFactory - server configuration: %o', server_config)
  debug('::_buildFactory - merged  configuration: %o', config)

  return _addBackoff( builder(config) )
}

function _initPool(builder, default_config, user_config) {
  const factory      = _buildFactory(builder, default_config, user_config)
  const pool_config  = _buildPoolConfig(factory, user_config)

  const pool    = GenericPool.createPool(factory, pool_config)
  pool.logger   = pool_config.logger

  pool.shutdown = function __shutdown() {
    return pool.drain().then(() => pool.clear())
  }

  pool.on(EVENT_CREATE_ERROR, function __poolResourceCreateError(err) {
    pool.logger.error(`Generic Pool Creation Error: ${err.message} - `, err)
    debug('::initPool - Create resource error: %s - %o', err.message, err)
  })

  return pool
}

function create(factoryBuilder, default_server_config = {}) {

  return function __createPool(user_config = {}) {
    debug('::create - user configuration: %o', user_config)

    return _initPool(factoryBuilder, default_server_config, user_config)
  }

}

module.exports = {
  create
}
<commit_msg>make sure to reset the backoff whenever a successful allocation occurs.<commit_after>
const debug                = require('debug')('kuss:pool')
const R                    = require('ramda')
const Bluebird             = require('bluebird')
const GenericPool          = require('generic-pool')
const { FibonacciBackoff } = require('simple-backoff')

const CONFIG_PROP_SERVER    = 'server'
const CONFIG_PROP_VALIDATOR = 'validate'
const CONFIG_PROP_TEST      = 'testOnBorrow'

const EVENT_CREATE_ERROR    = 'factoryCreateError'

const DEFAULT_CONFIG = {
  max               : 10
, min               : 2
, idleTimeoutMillis : 30000
, log               : false
, testOnBorrow      : false
, logger            : console
}

function _addBackoff(factory) {
  const backoff              = new FibonacciBackoff()
  const originalCreateMethod = factory.create

  factory.create = function __run() {

    return originalCreateMethod().catch(function ___handleErrorInCreate(e) {

      const wait = backoff.next()

      debug(
        '::_addBackoff - could not create resource - waiting %d ms - %s'
      , wait
      , e.message
      )

      return Bluebird.delay(wait).throw(e)

    })

    .then((resource) => {

      backoff.reset()

      return resource

    })

  }

  return factory

}

function _buildPoolConfig(factory, user_config) {
  const pool_config   = R.merge(DEFAULT_CONFIG, user_config)

  if (R.has(CONFIG_PROP_VALIDATOR, factory)) {
    pool_config[CONFIG_PROP_TEST] = true
  }

  debug('::_buildPoolConfig - configuration: %o', pool_config)

  return pool_config
}

function _buildFactory(builder, default_config, user_config) {
  const server_config = R.propOr({}, CONFIG_PROP_SERVER, user_config)
  const config        = R.merge(default_config, server_config)

  debug('::_buildFactory - server configuration: %o', server_config)
  debug('::_buildFactory - merged  configuration: %o', config)

  return _addBackoff( builder(config) )
}

function _initPool(builder, default_config, user_config) {
  const factory      = _buildFactory(builder, default_config, user_config)
  const pool_config  = _buildPoolConfig(factory, user_config)

  const pool    = GenericPool.createPool(factory, pool_config)
  pool.logger   = pool_config.logger

  pool.shutdown = function __shutdown() {
    return pool.drain().then(() => pool.clear())
  }

  pool.on(EVENT_CREATE_ERROR, function __poolResourceCreateError(err) {
    pool.logger.error(`Generic Pool Creation Error: ${err.message} - `, err)
    debug('::initPool - Create resource error: %s - %o', err.message, err)
  })

  return pool
}

function create(factoryBuilder, default_server_config = {}) {

  return function __createPool(user_config = {}) {
    debug('::create - user configuration: %o', user_config)

    return _initPool(factoryBuilder, default_server_config, user_config)
  }

}

module.exports = {
  create
}
<|endoftext|>


<commit_before>'use strict'

var Handlebars = require('handlebars')

exports.name = 'handlebars'
exports.inputFormats = ['hbs', 'handlebars']
exports.outputFormat = 'html'
exports.handlebars = Handlebars

exports.compile = function (str, options) {
  options = options || {}
  for (var partial in options.partials || {}) {
    if ({}.hasOwnProperty.call(options.partials, partial)) {
      Handlebars.registerPartial(partial, options.partials[partial])
    }
  }
  for (var helper in options.helpers || {}) {
    if ({}.hasOwnProperty.call(options.helpers, helper)) {
      Handlebars.registerHelper(helper, options.helpers[helper])
    }
  }
  for (var decorator in options.decorators || {}) {
    if ({}.hasOwnProperty.call(options.decorators, decorator)) {
      Handlebars.registerDecorator(decorator, options.decorator[decorator])
    }
  }
  return Handlebars.compile(str, options)
}
<commit_msg>1.1.0<commit_after>'use strict'

const Handlebars = require('handlebars')

exports.name = 'handlebars'
exports.inputFormats = ['hbs', 'handlebars']
exports.outputFormat = 'html'
exports.handlebars = Handlebars

exports.compile = function (str, options) {
  options = options || {}
  for (const partial in options.partials || {}) {
    if ({}.hasOwnProperty.call(options.partials, partial)) {
      Handlebars.registerPartial(partial, options.partials[partial])
    }
  }
  for (const helper in options.helpers || {}) {
    if ({}.hasOwnProperty.call(options.helpers, helper)) {
      Handlebars.registerHelper(helper, options.helpers[helper])
    }
  }
  for (const decorator in options.decorators || {}) {
    if ({}.hasOwnProperty.call(options.decorators, decorator)) {
      Handlebars.registerDecorator(decorator, options.decorator[decorator])
    }
  }
  return Handlebars.compile(str, options)
}
<|endoftext|>


<commit_before>/*!
 * Copyright 2019 Google LLC.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const glob = require('glob')
const { readFileSync, statSync } = require('fs')
const { resolve } = require('path')

const SAMPLES_DIRECTORY = process.env.SAMPLES_DIRECTORY || resolve(process.cwd(), './samples')
const REGION_START_REGEX = /\[START\s+([^\]]+)/
const REGION_END_REGEX = /\[END/

const sampleCache = new Map()
exports.loadSampleCache = function () {
  const sampleCandidates = glob.sync(`${SAMPLES_DIRECTORY}/**/*.{js,ts}`, { ignore: ['node_modules'] })
  for (const candidate of sampleCandidates) {
    const stat = statSync(candidate)
    if (!stat.isFile()) continue
    const content = readFileSync(candidate, 'utf8')
    if (REGION_START_REGEX.test(content)) {
      parseSamples(content)
    }
  }
  return sampleCache
}

function parseSamples (content) {
  let key
  let sample
  let inTag = false
  for (const line of content.split(/\r?\n/)) {
    if (inTag && REGION_END_REGEX.test(line)) {
      sampleCache.set(key, sample)
      inTag = false
    } else if (inTag) {
      sample += `${line}\n`
    } else {
      const match = line.match(REGION_START_REGEX)
      if (match) {
        key = match[1]
        sample = ''
        inTag = true
      }
    }
  }
}

exports.handlers = {
  newDoclet: e => {
    if (sampleCache.size === 0) {
      exports.loadSampleCache()
    }

    const examples = e.doclet.examples

    if (!examples) {
      return
    }

    for (const [i, example] of examples.entries()) {
      if (example.includes('region_tag')) {
        const [, tag, intro] = example.split(/\r?\n/)
        const key = tag.replace('region_tag:', '').trim()
        const sample = sampleCache.get(key)
        if (!sample) {
          console.warn(`could not find sample ${key}`)
        } else {
          examples[i] = intro ? `<caption>${intro}</caption>\n${sample}` : sample
        }
      }
    }
  }
}
<commit_msg>fix: tag issue of undefined (#11)<commit_after>/*!
 * Copyright 2019 Google LLC.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const glob = require('glob')
const { readFileSync, statSync } = require('fs')
const { resolve } = require('path')

const SAMPLES_DIRECTORY = process.env.SAMPLES_DIRECTORY || resolve(process.cwd(), './samples')
const REGION_START_REGEX = /\[START\s+([^\]]+)/
const REGION_END_REGEX = /\[END/

const sampleCache = new Map()
exports.loadSampleCache = function () {
  const sampleCandidates = glob.sync(`${SAMPLES_DIRECTORY}/**/*.{js,ts}`, { ignore: ['node_modules'] })
  for (const candidate of sampleCandidates) {
    const stat = statSync(candidate)
    if (!stat.isFile()) continue
    const content = readFileSync(candidate, 'utf8')
    if (REGION_START_REGEX.test(content)) {
      parseSamples(content)
    }
  }
  return sampleCache
}

function parseSamples (content) {
  let key
  let sample
  let inTag = false
  for (const line of content.split(/\r?\n/)) {
    if (inTag && REGION_END_REGEX.test(line)) {
      sampleCache.set(key, sample)
      inTag = false
    } else if (inTag) {
      sample += `${line}\n`
    } else {
      const match = line.match(REGION_START_REGEX)
      if (match) {
        key = match[1]
        sample = ''
        inTag = true
      }
    }
  }
}

exports.handlers = {
  newDoclet: e => {
    if (sampleCache.size === 0) {
      exports.loadSampleCache()
    }

    const examples = e.doclet.examples

    if (!examples) {
      return
    }

    for (const [i, example] of examples.entries()) {
      if (example.includes('region_tag')) {
        const [, tag, intro] = example.split(/\r|\n/)
        const key = tag.replace('region_tag:', '').trim()
        const sample = sampleCache.get(key)
        if (!sample) {
          console.warn(`could not find sample ${key}`)
        } else {
          examples[i] = intro ? `<caption>${intro}</caption>\n${sample}` : sample
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>/**
* Copyright (C) 2013-2015 David PHAM-VAN
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
**/

function CrudService($http, service) {

	var service_url = cf_options.rest_path + "/" + service;

	var onerror = function(data, status) {
	};

	this.getServiceUrl = function() {
		return service_url;
	}

	this.get_list = function (filter, page, onsuccess, onerror) {
		if (page<0) {
			onsuccess && onsuccess([], 200);
			return;
		}
		if (filter == undefined)
			filter = "";
		$http.get(service_url + "?p="+page+"&q="+filter).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess(data.list, status);
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data, status);
		});
	};

	this.get_count = function (filter, onsuccess, onerror) {
		if (filter == undefined)
			filter = "";
		$http.get(service_url + "/count?q="+filter).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess(data);
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data, status);
		});
	};

	this.add = function (data, onsuccess, onerror) {
		$http.put(service_url, data).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess(data.id);
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data);
		});
	};

	this.del = function (id, onsuccess, onerror) {
		$http.delete(service_url + "/" + id).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess();
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data);
		});
	};

	this.save = function (id, data, onsuccess, onerror) {
		$http.post(service_url + "/" + id, data).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess();
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data);
		});
	};

	this.getOne = function (id, onsuccess, onerror) {
		$http.get(service_url + "/get/" + id).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess(data, status);
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data, status);
		});
	};

	this.getNew = function (onsuccess, onerror) {
		$http.get(service_url + "/new").success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess(data, status);
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data, status);
		});
	};

	this.getForeign = function (field, onsuccess, onerror) {
		$http.get(service_url + "/foreign/" + field).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess(data, status);
			}).error(function (data, status) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			});
	};

}

function CrudController($scope, $timeout, $location, $route, CrudService, NotificationFactory) {
	this.init = function () {
		$scope.perpages = null;
		$scope.list = [];
		$scope.item = {};
		$scope.foreign = {};
		$scope.filter = "";
		$scope.pages = 0;
		$scope.count = 0;
		$scope.page = 0;
		$scope.loading = true;
	};

	this.get_list = function() {
		CrudService.get_count($scope.filter, function (count) {
			$scope.count = count.count;
			$scope.pages = count.pages;
			$scope.perpages = count.limit;
			$scope.setPage(CrudService.page || 0);
		});
	};

	$scope.go_list = function() {
		var path = (new RegExp("^/[^/]+")).exec($route.current.originalPath)[0];
		$location.path(path);
	};

	$scope.go_detail = function(id) {
		var path = (new RegExp("^/[^/]+")).exec($route.current.originalPath)[0];
		$location.path(path + "/" + id);
	};

	this.get_fiche = function(id) {
		if (!id || id=='new') {
			$scope.id = null;
			CrudService.getNew(function (data) {
				$scope.item = data.data;
				if (data.foreigns) {
					for (item in data.foreigns) {
						var name = data.foreigns[item];
						(function(name_){
							CrudService.getForeign(name, function(data) {
								$scope.foreign[name_] = data.list;
							});
						})(name);
					}
				}
				$scope.loading = false;
			}, function (data) {
				$scope.loading = false;
				NotificationFactory.error(data);
			});
		} else {
			CrudService.getOne(id, function (data) {
				$scope.id = id;
				$scope.item = data.data;
				if (data.foreigns) {
					for (item in data.foreigns) {
						var name = data.foreigns[item];
						(function(name_){
							CrudService.getForeign(name, function(data) {
								$scope.foreign[name_] = data.list;
							});
						})(name);
					}
				}
				$scope.loading = false;
			}, function (data) {
				$scope.loading = false;
				NotificationFactory.error(data);
			});
		}
	};

	$scope.del = function(id) {
		NotificationFactory.confirm("Delete the record #" + id + " ?", function () {
			CrudService.del(id, function () {
				var path = (new RegExp("^/[^/]+")).exec($route.current.originalPath)[0];
				if (path == $route.current.originalPath)
					this.get_list();
				else
					$scope.go_list();
				NotificationFactory.success("Record #"+ id +" deleted");
			}.bind(this), function (data) {
				NotificationFactory.error(data);
			});
		}.bind(this));
	}.bind(this);

	$scope.save = function(id, data) {
		$scope.loading = true;
		for (item in data) {
			if (data[item] instanceof Date) {
				data[item] = data[item].getTime()/1000;
			}
		}
		if (id) {
			CrudService.save(id, data, function () {
				$scope.go_list();
				//this.get_fiche(id);
				NotificationFactory.success("Record #"+ id +" saved");
			}.bind(this), function (data) {
				NotificationFactory.error(data);
			});
		} else {
			CrudService.add(data, function (id) {
				$scope.go_list();
				//this.get_fiche(id);
				NotificationFactory.success("New record #"+ id +" saved");
			}.bind(this), function (data) {
				$scope.loading = false;
				NotificationFactory.error(data);
			});
		}
	}.bind(this);

	$scope.getPages = function() {
		return new Array($scope.pages);
	};

	$scope.setPage = function(num) {
		if (num < 0)
			num = 0;
		if (num > $scope.pages -1)
			num = $scope.pages -1;

		$scope.loading = true;

		$scope.page = num;
		CrudService.get_list($scope.filter, $scope.page, function (data) {
			$('html,body').scrollTop(0);
			$scope.list = data;
			CrudService.page = $scope.page;
			$scope.loading = false;
		}, function (data) {
			$scope.loading = false;
			NotificationFactory.error(data);
		});
	};

	$scope.Search = function () {
		this.get_list();
	}.bind(this);
}
<commit_msg>Fix Javascript warning<commit_after>/**
* Copyright (C) 2013-2015 David PHAM-VAN
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
**/

function CrudService($http, service) {

	var service_url = cf_options.rest_path + "/" + service;

	var onerror = function(data, status) {
	};

	this.getServiceUrl = function() {
		return service_url;
	}

	this.get_list = function (filter, page, onsuccess, onerror) {
		if (page<0) {
			onsuccess && onsuccess([], 200);
			return;
		}
		if (filter == undefined)
			filter = "";
		$http.get(service_url + "?p="+page+"&q="+filter).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess(data.list, status);
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data, status);
		});
	};

	this.get_count = function (filter, onsuccess, onerror) {
		if (filter == undefined)
			filter = "";
		$http.get(service_url + "/count?q="+filter).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess(data);
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data, status);
		});
	};

	this.add = function (data, onsuccess, onerror) {
		$http.put(service_url, data).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess(data.id);
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data);
		});
	};

	this.del = function (id, onsuccess, onerror) {
		$http.delete(service_url + "/" + id).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess();
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data);
		});
	};

	this.save = function (id, data, onsuccess, onerror) {
		$http.post(service_url + "/" + id, data).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess();
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data);
		});
	};

	this.getOne = function (id, onsuccess, onerror) {
		$http.get(service_url + "/get/" + id).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess(data, status);
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data, status);
		});
	};

	this.getNew = function (onsuccess, onerror) {
		$http.get(service_url + "/new").success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess(data, status);
		}).error(function (data, status) {
			if (!restError(data, status))
				onerror && onerror(data, status);
		});
	};

	this.getForeign = function (field, onsuccess, onerror) {
		$http.get(service_url + "/foreign/" + field).success(function (data, status) {
			if (status != 200) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			} else
				onsuccess && onsuccess(data, status);
			}).error(function (data, status) {
				if (!restError(data, status))
					onerror && onerror(data, status);
			});
	};

}

function CrudController($scope, $timeout, $location, $route, CrudService, NotificationFactory) {
	this.init = function () {
		$scope.perpages = null;
		$scope.list = [];
		$scope.item = {};
		$scope.foreign = {};
		$scope.filter = "";
		$scope.pages = 0;
		$scope.count = 0;
		$scope.page = 0;
		$scope.loading = true;
	};

	this.get_list = function() {
		CrudService.get_count($scope.filter, function (count) {
			$scope.count = count.count;
			$scope.pages = count.pages;
			$scope.perpages = count.limit;
			$scope.setPage(CrudService.page || 0);
		});
	};

	$scope.go_list = function() {
		var path = (new RegExp("^/[^/]+")).exec($route.current.originalPath)[0];
		$location.path(path);
	};

	$scope.go_detail = function(id) {
		var path = (new RegExp("^/[^/]+")).exec($route.current.originalPath)[0];
		$location.path(path + "/" + id);
	};

	this.get_fiche = function(id) {
		if (!id || id=='new') {
			$scope.id = null;
			CrudService.getNew(function (data) {
				$scope.item = data.data;
				if (data.foreigns) {
					for (item in data.foreigns) {
						var name = data.foreigns[item];
						(function(name_){
							CrudService.getForeign(name, function(data) {
								$scope.foreign[name_] = data.list;
							});
						})(name);
					}
				}
				$scope.loading = false;
			}, function (data) {
				$scope.loading = false;
				NotificationFactory.error(data);
			});
		} else {
			CrudService.getOne(id, function (data) {
				$scope.id = id;
				$scope.item = data.data;
				if (data.foreigns) {
					for (item in data.foreigns) {
						var name = data.foreigns[item];
						(function(name_){
							CrudService.getForeign(name, function(data) {
								$scope.foreign[name_] = data.list;
							});
						})(name);
					}
				}
				$scope.loading = false;
			}, function (data) {
				$scope.loading = false;
				NotificationFactory.error(data);
			});
		}
	};

	$scope.del = function(id) {
		NotificationFactory.confirm("Delete the record #" + id + " ?", function () {
			CrudService.del(id, function () {
				var path = (new RegExp("^/[^/]+")).exec($route.current.originalPath)[0];
				if (path == $route.current.originalPath)
					this.get_list();
				else
					$scope.go_list();
				NotificationFactory.success("Record #"+ id +" deleted");
			}.bind(this), function (data) {
				NotificationFactory.error(data);
			});
		}.bind(this));
	}.bind(this);

	$scope.save = function(id, data) {
		$scope.loading = true;
		for (var item in data) {
			if (data[item] instanceof Date) {
				data[item] = data[item].getTime()/1000;
			}
		}
		if (id) {
			CrudService.save(id, data, function () {
				$scope.go_list();
				//this.get_fiche(id);
				NotificationFactory.success("Record #"+ id +" saved");
			}.bind(this), function (data) {
				NotificationFactory.error(data);
			});
		} else {
			CrudService.add(data, function (id) {
				$scope.go_list();
				//this.get_fiche(id);
				NotificationFactory.success("New record #"+ id +" saved");
			}.bind(this), function (data) {
				$scope.loading = false;
				NotificationFactory.error(data);
			});
		}
	}.bind(this);

	$scope.getPages = function() {
		return new Array($scope.pages);
	};

	$scope.setPage = function(num) {
		if (num < 0)
			num = 0;
		if (num > $scope.pages -1)
			num = $scope.pages -1;

		$scope.loading = true;

		$scope.page = num;
		CrudService.get_list($scope.filter, $scope.page, function (data) {
			$('html,body').scrollTop(0);
			$scope.list = data;
			CrudService.page = $scope.page;
			$scope.loading = false;
		}, function (data) {
			$scope.loading = false;
			NotificationFactory.error(data);
		});
	};

	$scope.Search = function () {
		this.get_list();
	}.bind(this);
}
<|endoftext|>


<commit_before>'use strict';

var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));
var path = require('path');
var url = require('url');
var http = require('http');
var https = require('https');
var crypto = require('crypto');

var postcss = require('postcss');

/**
 * Return `true` if the given path is http/https
 *
 * @param  {String}  filePath - path
 * @return {Boolean}
 */

function isRemotePath(filePath) {
    return /^(?:https?:)?\/\//.test(filePath);
}

/**
 * Return `true` if the given filePath is an absolute url
 *
 * @param  {String}  filePath - path
 * @return {Boolean}
 */

function isAbsolutePath(filePath) {
    return filePath.indexOf('/') === 0;
}

/**
 * Whether or not the url should be inluded
 *
 * @param  {Object} meta - url meta info
 * @param  {Object} opts - options
 * @return {Boolean}
 */

function validUrl(meta, opts) {
    // ignore hashes or data uris
    if (meta.value.indexOf('data:') === 0 || meta.value.indexOf('#') === 0) {
        return false;
    }

    if (!opts.absolutePath && isAbsolutePath(meta.value)) {
        return false;
    }

    // do not handle the http/https urls if `includeRemote` is false
    if (!opts.includeRemote && isRemotePath(meta.value)) {
        return false;
    }

    return true;
}

/**
 * Get all `url()`s, and return the meta info
 *
 * @param  {String} value - decl.value
 * @param  {Object} opts  - options
 * @return {Array}        - the urls
 */

function getUrls(value, opts) {
    var reg = /url\((\s*)(['"]?)(.+?)\2(\s*)\)/g;
    var match;
    var urls = [];

    while ((match = reg.exec(value)) !== null) {
        var meta = {
            source: match[0],
            before: match[1],
            quote: match[2],
            value: match[3],
            after: match[4]
        };
        if (validUrl(meta, opts)) {
            urls.push(meta);
        }
    }
    return urls;
}

/**
 * Get the absolute path of the url, relative to the basePath
 *
 * @param  {String} str          - the url
 * @param  {String} relativePath - the relative path
 * @param  {String} absolutePath - the absolute path
 * @return {String}              - the full path to the file
 */

function getResourcePath(str, relativePath, absolutePath) {
    var pathname = url.parse(str).pathname;
    var filePath;

    if (isRemotePath(str)) {
        filePath = str;
    } else if (isAbsolutePath(str)) {
        filePath = path.join(absolutePath, pathname);
    } else {
        filePath = path.resolve(relativePath, pathname);
    }
    return Promise.resolve(filePath);
}

/**
 * Get the hash value of the remote resource
 *
 * @param  {String} file - the remote path
 * @return {Promise}     - the Promise
 */

function getRemoteFileHash(file) {
    return new Promise(function (resolve, reject) {
        var client = /^https/.test(file) ? https : http;
        client.get(file, function (res) {
            var md5 = crypto.createHash('md5');

            res.on('data', function (chunk) {
                md5.update(chunk);
            });

            res.on('end', function () {
                resolve(md5.digest('hex'));
            });
        }).on('error', reject);
    });
}

/**
 * Get the hash value of the local resource
 *
 * @param  {String} file - the local path
 * @return {Promise}     - the Promise
 */

function getLocalFileHash(file) {
    return fs.readFileAsync(file).then(function (contents) {
        return crypto.createHash('md5').update(contents).digest('hex');
    });
}

/**
 * Get the hash function
 *
 * @param  {Object} opts - the options
 * @return {Function}    - the hash function
 */

function getHash(opts) {
    /**
     * Get the hash of the given path
     *
     * @param  {String} filePath - the file path
     * @return {Promise}         - the Promise
     */

    return function hashFunction(filePath) {
        if (typeof opts.hashFunction === 'function') {
            return opts.hashFunction(filePath, path.basename(filePath));
        }
        if (isRemotePath(filePath)) {
            return getRemoteFileHash(filePath);
        }
        return getLocalFileHash(filePath);
    };
}

/**
 * Generate a url() creator based on the url meta info and the options.
 * The creator receive a hash as its parameter
 *
 * @param  {Object} meta - the url meta info
 * @param  {Object} opts - the options
 * @return {Function}    - the url creator
 */

function createUrl(meta, opts) {
    return function (hash) {
        meta.value = opts.replacer(meta.value, hash);
        return 'url(' +
            meta.before +
            meta.quote +
            meta.value +
            meta.quote +
            meta.after +
        ')';
    };
}

/**
 * Generate a default replacer based on the hashLength parameter
 *
 * @param  {Number} hashLength - the hash length
 * @return {Function}          - the replacer function
 */

function defaultReplacer(hashLength) {
    hashLength = Math.max(0, hashLength || 10);

    return function (str, hash) {
        var urlObj = url.parse(str, true);
        var length = Math.min(hashLength, hash.length);

        urlObj.query.v = hash.slice(0, length);
        delete urlObj.search;

        return url.format(urlObj);
    };
}

/**
 * Process the single `url()` pattern
 *
 * @param  {String} relativePath - the relativePath relative to
 * @param  {Object} opts         - the options
 * @return {Promise}             - the Promise
 */

function processUrl(relativePath, opts) {
    return function (meta) {
        return getResourcePath(meta.value, relativePath, opts.absolutePath)
            .then(getHash(opts))
            .then(createUrl(meta, opts))
            .then(function (newUrl) {
                meta.newUrl = newUrl;
                return meta;
            });
    };
}

/**
 * Replace the raw value's `url()` segment to the new value
 *
 * @param  {String} raw - the raw value
 * @return {String}     - the new value
 */

function repalceUrls(raw) {
    return function (urls) {
        urls.forEach(function (item) {
            raw = raw.replace(item.source, item.newUrl);
        });

        return raw;
    };
}

/**
 * The error handler
 *
 * @param  {Object} result - the postcss result object
 * @param  {Object} decl   - the postcss declaration
 * @return {Function}      - the error handler
 */

function handleError(result, decl) {
    return function (err) {
        result.warn(err.message || err, {node: decl});
    };
}

/**
 * Process one declaration
 *
 * @param  {Object} result - the postcss result object
 * @param  {Object} decl   - the postcss declaration
 * @param  {String} from   - source
 * @param  {Object} opts   - the plugin options
 * @return {Promise}       - the Promise
 */

function processDecl(result, decl, from, opts) {
    var inputfile = decl.source && decl.source.input && decl.source.input.file;
    var dirname = inputfile ? path.dirname(inputfile) : path.dirname(from);
    var relativePath = opts.basePath || opts.relativePath || dirname;

    return Promise.map(
            getUrls(decl.value, opts),
            processUrl(relativePath, opts)
        )
        .then(repalceUrls(decl.value))
        .then(function (newValue) {
            decl.value = newValue;
        })
        .catch(handleError(result, decl));
}

module.exports = postcss.plugin('postcss-urlrev', function (opts) {
    opts = opts || {};
    opts.replacer = opts.replacer || defaultReplacer(opts.hashLength);

    return function (css, result) {
        var from = result.opts.from ?
            path.resolve(result.opts.from) :
            '.';

        var actions = [];
        css.walkDecls(function (decl) {
            if (decl.value && decl.value.indexOf('url(') > -1) {
                actions.push(processDecl(result, decl, from, opts));
            }
        });

        return Promise.all(actions);
    };
});
<commit_msg>Improve absolute path test<commit_after>'use strict';

var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));
var path = require('path');
var url = require('url');
var http = require('http');
var https = require('https');
var crypto = require('crypto');

var postcss = require('postcss');

/**
 * Return `true` if the given path is http/https
 *
 * @param  {String}  filePath - path
 * @return {Boolean}
 */

function isRemotePath(filePath) {
    return /^(?:https?:)?\/\//.test(filePath);
}

function normalizeUrl(url) {
    return /^\/\//.test(url) ? 'http:' + url : url;
}

/**
 * Return `true` if the given filePath is an absolute url
 *
 * @param  {String}  filePath - path
 * @return {Boolean}
 */

function isAbsolutePath(filePath) {
    return /^\/(?!\/)/.test(filePath);
}

/**
 * Whether or not the url should be inluded
 *
 * @param  {Object} meta - url meta info
 * @param  {Object} opts - options
 * @return {Boolean}
 */

function validUrl(meta, opts) {
    // ignore hashes or data uris
    if (meta.value.indexOf('data:') === 0 || meta.value.indexOf('#') === 0) {
        return false;
    }

    if (!opts.absolutePath && isAbsolutePath(meta.value)) {
        return false;
    }

    // do not handle the http/https urls if `includeRemote` is false
    if (!opts.includeRemote && isRemotePath(meta.value)) {
        return false;
    }

    return true;
}

/**
 * Get all `url()`s, and return the meta info
 *
 * @param  {String} value - decl.value
 * @param  {Object} opts  - options
 * @return {Array}        - the urls
 */

function getUrls(value, opts) {
    var reg = /url\((\s*)(['"]?)(.+?)\2(\s*)\)/g;
    var match;
    var urls = [];

    while ((match = reg.exec(value)) !== null) {
        var meta = {
            source: match[0],
            before: match[1],
            quote: match[2],
            value: match[3],
            after: match[4]
        };
        if (validUrl(meta, opts)) {
            urls.push(meta);
        }
    }
    return urls;
}

/**
 * Get the absolute path of the url, relative to the basePath
 *
 * @param  {String} str          - the url
 * @param  {String} relativePath - the relative path
 * @param  {String} absolutePath - the absolute path
 * @return {String}              - the full path to the file
 */

function getResourcePath(str, relativePath, absolutePath) {
    var pathname = url.parse(str).pathname;
    var filePath;

    if (isRemotePath(str)) {
        filePath = str;
    } else if (isAbsolutePath(str)) {
        filePath = path.join(absolutePath, pathname);
    } else {
        filePath = path.resolve(relativePath, pathname);
    }
    return Promise.resolve(filePath);
}

/**
 * Get the hash value of the remote resource
 *
 * @param  {String} file - the remote path
 * @return {Promise}     - the Promise
 */

function getRemoteFileHash(file) {
    return new Promise(function (resolve, reject) {
        var client = /^https/.test(file) ? https : http;
        client.get(normalizeUrl(file), function (res) {
            var md5 = crypto.createHash('md5');

            res.on('data', function (chunk) {
                md5.update(chunk);
            });

            res.on('end', function () {
                resolve(md5.digest('hex'));
            });
        }).on('error', reject);
    });
}

/**
 * Get the hash value of the local resource
 *
 * @param  {String} file - the local path
 * @return {Promise}     - the Promise
 */

function getLocalFileHash(file) {
    return fs.readFileAsync(file).then(function (contents) {
        return crypto.createHash('md5').update(contents).digest('hex');
    });
}

/**
 * Get the hash function
 *
 * @param  {Object} opts - the options
 * @return {Function}    - the hash function
 */

function getHash(opts) {
    /**
     * Get the hash of the given path
     *
     * @param  {String} filePath - the file path
     * @return {Promise}         - the Promise
     */

    return function hashFunction(filePath) {
        if (typeof opts.hashFunction === 'function') {
            return opts.hashFunction(filePath, path.basename(filePath));
        }
        if (isRemotePath(filePath)) {
            return getRemoteFileHash(filePath);
        }
        return getLocalFileHash(filePath);
    };
}

/**
 * Generate a url() creator based on the url meta info and the options.
 * The creator receive a hash as its parameter
 *
 * @param  {Object} meta - the url meta info
 * @param  {Object} opts - the options
 * @return {Function}    - the url creator
 */

function createUrl(meta, opts) {
    return function (hash) {
        meta.value = opts.replacer(meta.value, hash);
        return 'url(' +
            meta.before +
            meta.quote +
            meta.value +
            meta.quote +
            meta.after +
        ')';
    };
}

/**
 * Generate a default replacer based on the hashLength parameter
 *
 * @param  {Number} hashLength - the hash length
 * @return {Function}          - the replacer function
 */

function defaultReplacer(hashLength) {
    hashLength = Math.max(0, hashLength || 10);

    return function (str, hash) {
        var urlObj = url.parse(str, true);
        var length = Math.min(hashLength, hash.length);

        urlObj.query.v = hash.slice(0, length);
        delete urlObj.search;

        return url.format(urlObj);
    };
}

/**
 * Process the single `url()` pattern
 *
 * @param  {String} relativePath - the relativePath relative to
 * @param  {Object} opts         - the options
 * @return {Promise}             - the Promise
 */

function processUrl(relativePath, opts) {
    return function (meta) {
        return getResourcePath(meta.value, relativePath, opts.absolutePath)
            .then(getHash(opts))
            .then(createUrl(meta, opts))
            .then(function (newUrl) {
                meta.newUrl = newUrl;
                return meta;
            });
    };
}

/**
 * Replace the raw value's `url()` segment to the new value
 *
 * @param  {String} raw - the raw value
 * @return {String}     - the new value
 */

function repalceUrls(raw) {
    return function (urls) {
        urls.forEach(function (item) {
            raw = raw.replace(item.source, item.newUrl);
        });

        return raw;
    };
}

/**
 * The error handler
 *
 * @param  {Object} result - the postcss result object
 * @param  {Object} decl   - the postcss declaration
 * @return {Function}      - the error handler
 */

function handleError(result, decl) {
    return function (err) {
        result.warn(err.message || err, {node: decl});
    };
}

/**
 * Process one declaration
 *
 * @param  {Object} result - the postcss result object
 * @param  {Object} decl   - the postcss declaration
 * @param  {String} from   - source
 * @param  {Object} opts   - the plugin options
 * @return {Promise}       - the Promise
 */

function processDecl(result, decl, from, opts) {
    var inputfile = decl.source && decl.source.input && decl.source.input.file;
    var dirname = inputfile ? path.dirname(inputfile) : path.dirname(from);
    var relativePath = opts.basePath || opts.relativePath || dirname;

    return Promise.map(
            getUrls(decl.value, opts),
            processUrl(relativePath, opts)
        )
        .then(repalceUrls(decl.value))
        .then(function (newValue) {
            decl.value = newValue;
        })
        .catch(handleError(result, decl));
}

module.exports = postcss.plugin('postcss-urlrev', function (opts) {
    opts = opts || {};
    opts.replacer = opts.replacer || defaultReplacer(opts.hashLength);

    return function (css, result) {
        var from = result.opts.from ?
            path.resolve(result.opts.from) :
            '.';

        var actions = [];
        css.walkDecls(function (decl) {
            if (decl.value && decl.value.indexOf('url(') > -1) {
                actions.push(processDecl(result, decl, from, opts));
            }
        });

        return Promise.all(actions);
    };
});
<|endoftext|>


<commit_before>
/*!
 * Copyright(c) Thomas Blobaum
 * MIT Licensed
 */

var mongoose = require('mongoose')

function shim(data) {
  if (!data) return null
  if (data instanceof Array) {
    return data.map(function(doc) {
      return doc.toObject()
    })
  }
  return data.toObject()
}

function rest (schema, options) {
  options = options || {}

  var pagination = options.pagination || {}

  schema.static({
    get: get
  , post: update
  , put: update
  , del: del
  , search: search
  , bulk: search
  , controller: controller
  })

  if (!schema.statics.paginate) {
    schema.plugin(require('./pagination'), pagination)
  }

  function get (id, fn) {
    this.findById(id, function (err, doc) {
      fn(err, shim(doc))
    })
  }

  function update (data, fn) {
    var query = {}
    if (data._id) {
      query._id = data._id
      delete data._id
    }
    this.update(query, data, {
      upsert: true
    }, function (err, doc, blah, wtf) {
      if (err || !doc) return fn(err, false)
      fn(null, true)
    })
  }

  function del (id, fn) {
    this.findById(id, function (err, doc) {
      if (err || !doc) return fn(err, false)
      doc.remove(function (err, doc) {
        if (err) return fn(err, false)
        fn(null, true)
      })
    })
  }

  function search (query, fn) {
    var query = query || {}
      , limit = query.limit
      , page = query.page

    delete query.limit
    delete query.page

    this.paginate({
      query: query
    , limit: limit
    , page: page
    }, function (err, docs, total, pages, current) {
      fn(err, shim(docs))
    })
  }

  function controller () {
    ;['get'
    , 'post'
    , 'put'
    , 'del'
    , 'search'
    , 'bulk'
    ].forEach(function(method) {
      this[method] = schema.statics[method]
    })
  }
}

module.exports = rest
<commit_msg>Removing debug code<commit_after>
/*!
 * Copyright(c) Thomas Blobaum
 * MIT Licensed
 */

var mongoose = require('mongoose')

function shim(data) {
  if (!data) return null
  if (data instanceof Array) {
    return data.map(function(doc) {
      return doc.toObject()
    })
  }
  return data.toObject()
}

function rest (schema, options) {
  options = options || {}

  var pagination = options.pagination || {}

  schema.static({
    get: get
  , post: update
  , put: update
  , del: del
  , search: search
  , bulk: search
  , controller: controller
  })

  if (!schema.statics.paginate) {
    schema.plugin(require('./pagination'), pagination)
  }

  function get (id, fn) {
    this.findById(id, function (err, doc) {
      fn(err, shim(doc))
    })
  }

  function update (data, fn) {
    var query = {}
    data._id && (query._id = data._id)
    delete data._id

    this.update(query, data, {
      upsert: true
    }, function (err, count) {
      if (err || !count) return fn(err, false)
      fn(null, true)
    })
  }

  function del (id, fn) {
    this.findById(id, function (err, doc) {
      if (err || !doc) return fn(err, false)
      doc.remove(function (err, doc) {
        if (err) return fn(err, false)
        fn(null, true)
      })
    })
  }

  function search (query, fn) {
    var query = query || {}
      , limit = query.limit
      , page = query.page

    delete query.limit
    delete query.page

    this.paginate({
      query: query
    , limit: limit
    , page: page
    }, function (err, docs) {
      fn(err, shim(docs))
    })
  }

  function controller () {
    ;['get'
    , 'post'
    , 'put'
    , 'del'
    , 'search'
    , 'bulk'
    ].forEach(function(method) {
      this[method] = schema.statics[method]
    })
  }
}

module.exports = rest
<|endoftext|>


<commit_before>(function() {
	'use strict';

	var fetchUrl = require('fetch').fetchUrl,
		qs = require('qs'),
		log = require(__dirname + '/log'),
		util = require('util'),
		EventEmitter= require('events').EventEmitter,
		urllib = require('url'),
		userAgent = require(__dirname + '/userAgent'),
		_ = require('lodash'),
		fs = require('fs'),
		async = require('async'),
		FormData = require('form-data'),
		requestRate = 5;

	module.exports = {
		get: request.bind(this, 'GET'),
		post: request.bind(this, 'POST'),
		put: request.bind(this, 'PUT'),
		del: request.bind(this, 'DELETE')
	};

	var requestQueue = async.queue(function(task, callback) {
		fetchUrl(task.url, task.requestOptions, callback);
	}, requestRate);

	function request(method, url, options) {
		return new Request(method, url, options);
	}

	function Request(method, url, options) {
		EventEmitter.call(this);

		var query,
			payload,
			headers = {},
			requestOptions;

		this.options = options || {};
		this.options.method = this.options.method || method || 'GET';

		if(this.options.query) {
			query = typeof this.options.query == 'string' ? this.options.query : qs.stringify(this.options.query);
			url += (url.match(/\?/) ? '&' : '?') + query;
		}

		this.url = urllib.parse(url);

		if (this.options.multipart) {
			var form = new FormData();

			_.each(this.options.data, function(value, inputName) {
				if(inputName === 'file_path' && fs.existsSync(value)) {
					var parts = value.split(/[\/\\]/);
					var fileName = parts[parts.length - 1];
					form.append('file', fs.readFileSync(value), fileName);
				} else {
					form.append(inputName, value);
				}
			});

			headers = form.getHeaders(headers);
			payload = form.getBuffer();
		}
		else if (this.options.data) {
			if (typeof this.options.data == 'string') {
				payload = new Buffer(this.options.data, this.options.encoding || 'utf-8');
			}
			else if (this.options.json) {
				payload = JSON.stringify(this.options.data);
			}
			else {
				payload = qs.stringify(this.options.data);
			}
			headers['content-type'] = this.options.json ? 'application/json' : 'application/x-www-form-urlencoded';
		}

		requestOptions = {
			method: method,
			maxResponseLength: 10 * 1024 * 1024,
			payload: payload,
			headers: headers,
			disableDecoding: true,
			userAgent: userAgent,
			agent: false,
			asyncDnsLoookup: process.env.PIPEDRIVE_API_DNS_LOOKUP == '1' ? true : false,
			timeout: 10 * 1000,
			rejectUnauthorized: process.env.PIPEDRIVE_API_HOST == 'api.pipedrive.com' ? true : false
		};

		log('Adding API request to queue: ' + JSON.stringify(_.extend(_.omit(requestOptions, this.options.multipart ? ['payload'] : []), { url: url }), null, 4));

		requestQueue.push({ url: url, requestOptions: requestOptions }, (function(err, meta, body) {
			if (!meta) {
				meta = {};
			}
			meta.statusCode = meta && meta.status || 500;
			meta.responseHeaders = meta && meta.responseHeaders || {};

			this.response = {
				statusCode: meta.statusCode,
				rawEncoded: body,
				req: this.options,
				headers: meta.responseHeaders,
				_error: err
			};

			// Apply rate limiting with linear backoff
			if (meta.responseHeaders['x-ratelimit-reset'] && meta.responseHeaders['x-ratelimit-limit'] && meta.responseHeaders['x-ratelimit-remaining']) {
				requestRate = parseInt(meta.responseHeaders['x-ratelimit-limit'], 10) - parseInt(meta.responseHeaders['x-ratelimit-remaining'], 10);

				// If less than 10 requests are left, spread them out across the remaining seconds until next rate limit reset
				if (parseInt(meta.responseHeaders['x-ratelimit-remaining'], 10) < 10) {
					requestRate = parseInt(meta.responseHeaders['x-ratelimit-reset']) * 1000 / parseInt(meta.responseHeaders['x-ratelimit-remaining'], 10);
				}
			}

			log('Handling API response: ' + JSON.stringify(_.extend(_.omit(this.response, ['rawEncoded']), { req: { url: url, method: method }, body: body && body.toString() || '' }), null, 4));

			return this.emit('complete', body && body.toString() || '', this.response);
		}).bind(this));
	}

	util.inherits(Request, EventEmitter);

})();<commit_msg>GRAL-826 Whitespace tweak as requested<commit_after>(function() {
	'use strict';

	var fetchUrl = require('fetch').fetchUrl,
		qs = require('qs'),
		log = require(__dirname + '/log'),
		util = require('util'),
		EventEmitter= require('events').EventEmitter,
		urllib = require('url'),
		userAgent = require(__dirname + '/userAgent'),
		_ = require('lodash'),
		fs = require('fs'),
		async = require('async'),
		FormData = require('form-data'),
		requestRate = 5;

	module.exports = {
		get: request.bind(this, 'GET'),
		post: request.bind(this, 'POST'),
		put: request.bind(this, 'PUT'),
		del: request.bind(this, 'DELETE')
	};

	var requestQueue = async.queue(function(task, callback) {
		fetchUrl(task.url, task.requestOptions, callback);
	}, requestRate);

	function request(method, url, options) {
		return new Request(method, url, options);
	}

	function Request(method, url, options) {
		EventEmitter.call(this);

		var query,
			payload,
			headers = {},
			requestOptions;

		this.options = options || {};
		this.options.method = this.options.method || method || 'GET';

		if(this.options.query) {
			query = typeof this.options.query == 'string' ? this.options.query : qs.stringify(this.options.query);
			url += (url.match(/\?/) ? '&' : '?') + query;
		}

		this.url = urllib.parse(url);

		if (this.options.multipart) {
			var form = new FormData();

			_.each(this.options.data, function(value, inputName) {
				if (inputName === 'file_path' && fs.existsSync(value)) {
					var parts = value.split(/[\/\\]/);
					var fileName = parts[parts.length - 1];
					form.append('file', fs.readFileSync(value), fileName);
				} else {
					form.append(inputName, value);
				}
			});

			headers = form.getHeaders(headers);
			payload = form.getBuffer();
		}
		else if (this.options.data) {
			if (typeof this.options.data == 'string') {
				payload = new Buffer(this.options.data, this.options.encoding || 'utf-8');
			}
			else if (this.options.json) {
				payload = JSON.stringify(this.options.data);
			}
			else {
				payload = qs.stringify(this.options.data);
			}
			headers['content-type'] = this.options.json ? 'application/json' : 'application/x-www-form-urlencoded';
		}

		requestOptions = {
			method: method,
			maxResponseLength: 10 * 1024 * 1024,
			payload: payload,
			headers: headers,
			disableDecoding: true,
			userAgent: userAgent,
			agent: false,
			asyncDnsLoookup: process.env.PIPEDRIVE_API_DNS_LOOKUP == '1' ? true : false,
			timeout: 10 * 1000,
			rejectUnauthorized: process.env.PIPEDRIVE_API_HOST == 'api.pipedrive.com' ? true : false
		};

		log('Adding API request to queue: ' + JSON.stringify(_.extend(_.omit(requestOptions, this.options.multipart ? ['payload'] : []), { url: url }), null, 4));

		requestQueue.push({ url: url, requestOptions: requestOptions }, (function(err, meta, body) {
			if (!meta) {
				meta = {};
			}
			meta.statusCode = meta && meta.status || 500;
			meta.responseHeaders = meta && meta.responseHeaders || {};

			this.response = {
				statusCode: meta.statusCode,
				rawEncoded: body,
				req: this.options,
				headers: meta.responseHeaders,
				_error: err
			};

			// Apply rate limiting with linear backoff
			if (meta.responseHeaders['x-ratelimit-reset'] && meta.responseHeaders['x-ratelimit-limit'] && meta.responseHeaders['x-ratelimit-remaining']) {
				requestRate = parseInt(meta.responseHeaders['x-ratelimit-limit'], 10) - parseInt(meta.responseHeaders['x-ratelimit-remaining'], 10);

				// If less than 10 requests are left, spread them out across the remaining seconds until next rate limit reset
				if (parseInt(meta.responseHeaders['x-ratelimit-remaining'], 10) < 10) {
					requestRate = parseInt(meta.responseHeaders['x-ratelimit-reset']) * 1000 / parseInt(meta.responseHeaders['x-ratelimit-remaining'], 10);
				}
			}

			log('Handling API response: ' + JSON.stringify(_.extend(_.omit(this.response, ['rawEncoded']), { req: { url: url, method: method }, body: body && body.toString() || '' }), null, 4));

			return this.emit('complete', body && body.toString() || '', this.response);
		}).bind(this));
	}

	util.inherits(Request, EventEmitter);

})();<|endoftext|>


<commit_before>/* eslint-env node, browser */
'use strict'

module.exports = require('./Combokeys')
<commit_msg>git rm index.js: no need for it<commit_after><|endoftext|>


<commit_before>var lerp = require('lerp-array');

function interpolateArrays(arrays, t) {
    if (t >= 1) {
        return arrays[arrays.length - 1];
    }
    if (arrays.length == 1) {
        return arrays[0];
    }
    var numStops = arrays.length - 1;
    var stopF = t * numStops;
    var stop = Math.floor(stopF);
    var k = stopF - stop;
    return lerp(arrays[stop], arrays[stop+1], k);
}

module.exports = interpolateArrays;
<commit_msg>Add out parameter to avoid GC garbage<commit_after>var lerp = require('lerp-array');

function interpolateArrays(arrays, t, out) {
    if (t >= 1) {
        return arrays[arrays.length - 1];
    }
    if (arrays.length == 1) {
        return arrays[0];
    }
    var numStops = arrays.length - 1;
    var stopF = t * numStops;
    var stop = Math.floor(stopF);
    var k = stopF - stop;
    return lerp(arrays[stop], arrays[stop+1], k, out);
}

module.exports = interpolateArrays;
<|endoftext|>


<commit_before>'use strict';

var from         = require('es5-ext/array/from')
  , primitiveSet = require('es5-ext/object/primitive-set')
  , value        = require('es5-ext/object/valid-value')
  , callable     = require('es5-ext/object/valid-callable')
  , d            = require('d')
  , eolSet       = require('./lib/ws-eol')
  , wsSet        = require('./lib/ws')

  , hasOwnProperty = Object.prototype.hasOwnProperty
  , preRegExpSet = primitiveSet.apply(null, from(';{=([,<>+-*/%&|^!~?:}'))
  , nonNameSet = primitiveSet.apply(null, from(';{=([,<>+-*/%&|^!~?:})]'))

  , move, startCollect, endCollect, collectNest
  , $ws, $common, $string, $comment, $multiComment, $regExp

  , i, char, line, columnIndex, afterWs, previousChar
  , nest, nestedTokens, results
  , userCode, userTriggerChar, userCallback

  , quote
  , collectIndex, data, nestRelease;

move = function (j) {
	if (!char) return;
	if (i >= j) return;
	while (i !== j) {
		if (!char) return;
		if (hasOwnProperty.call(wsSet, char)) {
			if (hasOwnProperty.call(eolSet, char)) {
				columnIndex = i;
				++line;
			}
		} else {
			previousChar = char;
		}
		char = userCode[++i];
	}
};

startCollect = function (oldNestRelease) {
	if (collectIndex != null) nestedTokens.push([data, collectIndex, oldNestRelease]);
	data = { point: i + 1, line: line, column: i + 1 - columnIndex };
	collectIndex = i;
};

endCollect = function () {
	var previous;
	data.raw = userCode.slice(collectIndex, i);
	results.push(data);
	if (nestedTokens.length) {
		previous = nestedTokens.pop();
		data = previous[0];
		collectIndex = previous[1];
		nestRelease = previous[2];
		return;
	}
	data = null;
	collectIndex = null;
	nestRelease = null;
};

collectNest = function () {
	var old = nestRelease;
	nestRelease = nest;
	++nest;
	move(i + 1);
	startCollect(old);
	return $ws;
};

$common = function () {
	if ((char === '\'') || (char === '"')) {
		quote = char;
		char = userCode[++i];
		return $string;
	}
	if (char === '(') {
		++nest;
	} else if (char === ')') {
		if (nestRelease === --nest) endCollect();
	} else if (char === '{') {
		++nest;
	} else if (char === '}') {
		if (nestRelease === --nest) endCollect();
	} else if (char === '/') {
		if (hasOwnProperty.call(preRegExpSet, previousChar)) {
			char = userCode[++i];
			return $regExp;
		}
	}
	if ((char !== userTriggerChar) || (previousChar && !afterWs &&
			!hasOwnProperty.call(nonNameSet, previousChar))) {
		previousChar = char;
		char = userCode[++i];
		return $ws;
	}

	return userCallback(i, previousChar);
};

$comment = function () {
	while (true) {
		if (!char) return;
		if (hasOwnProperty.call(eolSet, char)) {
			columnIndex = i + 1;
			++line;
			return;
		}
		char = userCode[++i];
	}
};

$multiComment = function () {
	while (true) {
		if (!char) return;
		if (char === '*') {
			char = userCode[++i];
			if (!char) return;
			if (char === '/') return;
		}
		if (hasOwnProperty.call(eolSet, char)) {
			columnIndex = i + 1;
			++line;
		}
		char = userCode[++i];
	}
};

$ws = function () {
	var next;
	while (true) {
		if (!char) return;
		if (hasOwnProperty.call(wsSet, char)) {
			afterWs = true;
			if (hasOwnProperty.call(eolSet, char)) {
				columnIndex = i + 1;
				++line;
			}
		} else if (char === '/') {
			next = userCode[i + 1];
			if (next === '/') {
				char = userCode[i += 2];
				afterWs = true;
				$comment();
			} else if (next === '*') {
				char = userCode[i += 2];
				afterWs = true;
				$multiComment();
			} else {
				break;
			}
		} else {
			break;
		}
		char = userCode[++i];
	}
	return $common;
};

$string = function () {
	while (true) {
		if (!char) return;
		if (char === quote) {
			char = userCode[++i];
			previousChar = quote;
			return $ws;
		}
		if (char === '\\') {
			if (hasOwnProperty.call(eolSet, userCode[++i])) {
				columnIndex = i + 1;
				++line;
			}
		}
		char = userCode[++i];
	}
};

$regExp = function () {
	while (true) {
		if (!char) return;
		if (char === '/') {
			previousChar = '/';
			char = userCode[++i];
			return $ws;
		}
		if (char === '\\') ++i;
		char = userCode[++i];
	}
};

module.exports = exports = function (code, triggerChar, callback) {
	var state;

	userCode = String(value(code));
	userTriggerChar = String(value(triggerChar));
	if (userTriggerChar.length !== 1) {
		throw new TypeError(userTriggerChar + " should be one character long string");
	}
	if (hasOwnProperty.call(nonNameSet, userTriggerChar)) {
		throw new TypeError("Trigger char must not be one of operator chars");
	}
	userCallback = callable(callback);
	i = 0;
	char = userCode[i];
	line = 1;
	columnIndex = 0;
	afterWs = false;
	previousChar = null;
	nest = 0;
	nestedTokens = [];
	results = [];
	exports.forceStop = false;
	state = $ws;
	while (state) state = state();
	return results;
};

Object.defineProperties(exports, {
	$ws: d($ws),
	$common: d($common),
	collectNest: d(collectNest),
	move: d(move),
	index: d.gs(function () { return i; }),
	line: d.gs(function () { return line; }),
	columnIndex: d.gs(function () { return columnIndex; }),
	next: d(function (step) {
		if (!char) return;
		move(i + (step || 1));
		return $ws();
	}),
	resume: d(function () { return $common; })
});
<commit_msg>Allow operator chars as triggers<commit_after>'use strict';

var from         = require('es5-ext/array/from')
  , primitiveSet = require('es5-ext/object/primitive-set')
  , value        = require('es5-ext/object/valid-value')
  , callable     = require('es5-ext/object/valid-callable')
  , d            = require('d')
  , eolSet       = require('./lib/ws-eol')
  , wsSet        = require('./lib/ws')

  , hasOwnProperty = Object.prototype.hasOwnProperty
  , preRegExpSet = primitiveSet.apply(null, from(';{=([,<>+-*/%&|^!~?:}'))
  , nonNameSet = primitiveSet.apply(null, from(';{=([,<>+-*/%&|^!~?:})]'))

  , move, startCollect, endCollect, collectNest
  , $ws, $common, $string, $comment, $multiComment, $regExp

  , i, char, line, columnIndex, afterWs, previousChar
  , nest, nestedTokens, results
  , userCode, userTriggerChar, isUserTriggerOperatorChar, userCallback

  , quote
  , collectIndex, data, nestRelease;

move = function (j) {
	if (!char) return;
	if (i >= j) return;
	while (i !== j) {
		if (!char) return;
		if (hasOwnProperty.call(wsSet, char)) {
			if (hasOwnProperty.call(eolSet, char)) {
				columnIndex = i;
				++line;
			}
		} else {
			previousChar = char;
		}
		char = userCode[++i];
	}
};

startCollect = function (oldNestRelease) {
	if (collectIndex != null) nestedTokens.push([data, collectIndex, oldNestRelease]);
	data = { point: i + 1, line: line, column: i + 1 - columnIndex };
	collectIndex = i;
};

endCollect = function () {
	var previous;
	data.raw = userCode.slice(collectIndex, i);
	results.push(data);
	if (nestedTokens.length) {
		previous = nestedTokens.pop();
		data = previous[0];
		collectIndex = previous[1];
		nestRelease = previous[2];
		return;
	}
	data = null;
	collectIndex = null;
	nestRelease = null;
};

collectNest = function () {
	var old = nestRelease;
	nestRelease = nest;
	++nest;
	move(i + 1);
	startCollect(old);
	return $ws;
};

$common = function () {
	if ((char === '\'') || (char === '"')) {
		quote = char;
		char = userCode[++i];
		return $string;
	}
	if (char === '(') {
		++nest;
	} else if (char === ')') {
		if (nestRelease === --nest) endCollect();
	} else if (char === '{') {
		++nest;
	} else if (char === '}') {
		if (nestRelease === --nest) endCollect();
	} else if (char === '/') {
		if (hasOwnProperty.call(preRegExpSet, previousChar)) {
			char = userCode[++i];
			return $regExp;
		}
	}
	if ((char !== userTriggerChar) || (!isUserTriggerOperatorChar &&  previousChar && !afterWs &&
			!hasOwnProperty.call(nonNameSet, previousChar))) {
		previousChar = char;
		char = userCode[++i];
		return $ws;
	}

	return userCallback(i, previousChar);
};

$comment = function () {
	while (true) {
		if (!char) return;
		if (hasOwnProperty.call(eolSet, char)) {
			columnIndex = i + 1;
			++line;
			return;
		}
		char = userCode[++i];
	}
};

$multiComment = function () {
	while (true) {
		if (!char) return;
		if (char === '*') {
			char = userCode[++i];
			if (!char) return;
			if (char === '/') return;
		}
		if (hasOwnProperty.call(eolSet, char)) {
			columnIndex = i + 1;
			++line;
		}
		char = userCode[++i];
	}
};

$ws = function () {
	var next;
	while (true) {
		if (!char) return;
		if (hasOwnProperty.call(wsSet, char)) {
			afterWs = true;
			if (hasOwnProperty.call(eolSet, char)) {
				columnIndex = i + 1;
				++line;
			}
		} else if (char === '/') {
			next = userCode[i + 1];
			if (next === '/') {
				char = userCode[i += 2];
				afterWs = true;
				$comment();
			} else if (next === '*') {
				char = userCode[i += 2];
				afterWs = true;
				$multiComment();
			} else {
				break;
			}
		} else {
			break;
		}
		char = userCode[++i];
	}
	return $common;
};

$string = function () {
	while (true) {
		if (!char) return;
		if (char === quote) {
			char = userCode[++i];
			previousChar = quote;
			return $ws;
		}
		if (char === '\\') {
			if (hasOwnProperty.call(eolSet, userCode[++i])) {
				columnIndex = i + 1;
				++line;
			}
		}
		char = userCode[++i];
	}
};

$regExp = function () {
	while (true) {
		if (!char) return;
		if (char === '/') {
			previousChar = '/';
			char = userCode[++i];
			return $ws;
		}
		if (char === '\\') ++i;
		char = userCode[++i];
	}
};

module.exports = exports = function (code, triggerChar, callback) {
	var state;

	userCode = String(value(code));
	userTriggerChar = String(value(triggerChar));
	if (userTriggerChar.length !== 1) {
		throw new TypeError(userTriggerChar + " should be one character long string");
	}
	userCallback = callable(callback);
	isUserTriggerOperatorChar = hasOwnProperty.call(nonNameSet, userTriggerChar);
	i = 0;
	char = userCode[i];
	line = 1;
	columnIndex = 0;
	afterWs = false;
	previousChar = null;
	nest = 0;
	nestedTokens = [];
	results = [];
	exports.forceStop = false;
	state = $ws;
	while (state) state = state();
	return results;
};

Object.defineProperties(exports, {
	$ws: d($ws),
	$common: d($common),
	collectNest: d(collectNest),
	move: d(move),
	index: d.gs(function () { return i; }),
	line: d.gs(function () { return line; }),
	columnIndex: d.gs(function () { return columnIndex; }),
	next: d(function (step) {
		if (!char) return;
		move(i + (step || 1));
		return $ws();
	}),
	resume: d(function () { return $common; })
});
<|endoftext|>


<commit_before>var deadline = 0, retry_interval = 0;
var ti;

function insert(parent, child) {
  var existing = parent.children();
  var before = null;
  existing.each(function () {
    var jq = $(this);
    if (jq.attr('name') < child.attr('name')) {
      before = jq;
    }
  });
  if (before === null) {
    parent.prepend(child);
  } else {
    before.after(child);
  }
}

function apply(ev) {
  var parts = ev.Path.split("/")
  if (parts.length < 2) {
    return
  }
  parts = parts.slice(1); // omit leading empty string
  var dir_parts = parts.slice(0, parts.length - 1);
  var dir = $('#root');
  for (var i = 0; i < dir_parts.length; i++) {
    var part = dir_parts[i];
    var next = dir.find('> dl > div[name="'+part+'"] > dd');
    if (next.length < 1) {
      var div = $('
').attr('name', part);
      var dd = $('
');
      div.append($('
').text(part+'/')).append(dd);
      insert(dir.children('dl'), div);
      dd.append('
').append('

');
      next = dd;
    }
    dir = next;
  }

  var basename = parts[parts.length - 1];
  var entry = dir.find('tr[name="'+basename+'"]');
  if (entry.length < 1) {
    var tr = $('
').attr('name', basename);
    insert(dir.children('table').children('tbody'), tr);
    tr.append($('').text(basename)).
      append('').
      append('').
      append('');
    entry = tr;
  }
  entry.children('td.rev').text('('+ev.Rev+')');
  entry.children('td.body').text(ev.Body);
  entry.addClass('new');

  // Kick off the transition in a bit.
  setTimeout(function() { entry.removeClass('new') }, 550);
}

function time_interval(s) {
  if (s < 120) return Math.ceil(s) + 's';
  if (s < 7200) return Math.round(s/60) + 'm';
  return Math.round(s/3600) + 'h';
}

function countdown() {
  var body = $('body');
  var eta = (deadline - new Date().getTime())/1000;
  if (eta < 0) {
    body.removeClass('waiting');
    open();
  } else {
    $('#retrymsg').text("retrying in " + time_interval(eta));
    body.addClass('waiting');
    ti = setTimeout(countdown, Math.max(100, eta*9));
  }
}

function retry() {
  deadline = ((new Date()).getTime()) + retry_interval * 1000;
  retry_interval += (retry_interval + 5) * (Math.random() + .5);
  countdown();
}

function open() {
  var body = $('body');
  var status = $('#status');
  status.text("connecting");
  var ws = new WebSocket("ws://"+location.host+"/$events"+path);
  ws.onmessage = function (ev) {
    var jev = JSON.parse(ev.data);
    apply(jev);
  };
  ws.onopen = function(ev) {
    if (retry_interval > 0) {
      body.addClass('wereback');
      setTimeout(function () { body.removeClass('wereback') }, 8000);
    }
    retry_interval = 0;
    status.text('open')
    body.addClass('open').removeClass('loading closed error');
    $('#root > dl > *, #root > table > tbody > *').remove();
  };
  ws.onclose = function(ev) {
    status.text('closed')
    body.addClass('closed').removeClass('loading open error wereback');
    retry();
  };
  ws.onerror = function(ev) {
    status.text('error ' + ev)
    body.addClass('error').removeClass('loading open closed wereback');
    retry();
  };
}

function dr() {
  $('#trynow').click(function() {
    clearTimeout(ti);
    deadline = 0;
    countdown();
  });

  if ("WebSocket" in window) {
    open();
  } else {
    $('#status').text("no websockets");
    $('body').addClass('error nows').removeClass('loading open closed wereback');
  }
}

function jerr() {
  const m = 'could not load jquery (is your network link down?)';
  document.getElementById('status').innerText = m;
  document.getElementsByTagName('body')[0].className = 'error';
}
<commit_msg>web: clarify missing websockets error message<commit_after>var deadline = 0, retry_interval = 0;
var ti;

function insert(parent, child) {
  var existing = parent.children();
  var before = null;
  existing.each(function () {
    var jq = $(this);
    if (jq.attr('name') < child.attr('name')) {
      before = jq;
    }
  });
  if (before === null) {
    parent.prepend(child);
  } else {
    before.after(child);
  }
}

function apply(ev) {
  var parts = ev.Path.split("/")
  if (parts.length < 2) {
    return
  }
  parts = parts.slice(1); // omit leading empty string
  var dir_parts = parts.slice(0, parts.length - 1);
  var dir = $('#root');
  for (var i = 0; i < dir_parts.length; i++) {
    var part = dir_parts[i];
    var next = dir.find('> dl > div[name="'+part+'"] > dd');
    if (next.length < 1) {
      var div = $('
').attr('name', part);
      var dd = $('
');
      div.append($('
').text(part+'/')).append(dd);
      insert(dir.children('dl'), div);
      dd.append('
').append('

');
      next = dd;
    }
    dir = next;
  }

  var basename = parts[parts.length - 1];
  var entry = dir.find('tr[name="'+basename+'"]');
  if (entry.length < 1) {
    var tr = $('
').attr('name', basename);
    insert(dir.children('table').children('tbody'), tr);
    tr.append($('').text(basename)).
      append('').
      append('').
      append('');
    entry = tr;
  }
  entry.children('td.rev').text('('+ev.Rev+')');
  entry.children('td.body').text(ev.Body);
  entry.addClass('new');

  // Kick off the transition in a bit.
  setTimeout(function() { entry.removeClass('new') }, 550);
}

function time_interval(s) {
  if (s < 120) return Math.ceil(s) + 's';
  if (s < 7200) return Math.round(s/60) + 'm';
  return Math.round(s/3600) + 'h';
}

function countdown() {
  var body = $('body');
  var eta = (deadline - new Date().getTime())/1000;
  if (eta < 0) {
    body.removeClass('waiting');
    open();
  } else {
    $('#retrymsg').text("retrying in " + time_interval(eta));
    body.addClass('waiting');
    ti = setTimeout(countdown, Math.max(100, eta*9));
  }
}

function retry() {
  deadline = ((new Date()).getTime()) + retry_interval * 1000;
  retry_interval += (retry_interval + 5) * (Math.random() + .5);
  countdown();
}

function open() {
  var body = $('body');
  var status = $('#status');
  status.text("connecting");
  var ws = new WebSocket("ws://"+location.host+"/$events"+path);
  ws.onmessage = function (ev) {
    var jev = JSON.parse(ev.data);
    apply(jev);
  };
  ws.onopen = function(ev) {
    if (retry_interval > 0) {
      body.addClass('wereback');
      setTimeout(function () { body.removeClass('wereback') }, 8000);
    }
    retry_interval = 0;
    status.text('open')
    body.addClass('open').removeClass('loading closed error');
    $('#root > dl > *, #root > table > tbody > *').remove();
  };
  ws.onclose = function(ev) {
    status.text('closed')
    body.addClass('closed').removeClass('loading open error wereback');
    retry();
  };
  ws.onerror = function(ev) {
    status.text('error ' + ev)
    body.addClass('error').removeClass('loading open closed wereback');
    retry();
  };
}

function dr() {
  $('#trynow').click(function() {
    clearTimeout(ti);
    deadline = 0;
    countdown();
  });

  if ("WebSocket" in window) {
    open();
  } else {
    $('#status').text("your browser does not provide websockets");
    $('body').addClass('error nows').removeClass('loading open closed wereback');
  }
}

function jerr() {
  const m = 'could not load jquery (is your network link down?)';
  document.getElementById('status').innerText = m;
  document.getElementsByTagName('body')[0].className = 'error';
}
<|endoftext|>