<commit_before>var fs = require('graceful-fs');
var jph = require('json-parse-helpfulerror');
var path = require('path');
var steno = require('steno');

module.exports = function(dbDir) {
  'use strict';

  if (!dbDir || typeof dbDir !== 'string') {
    throw new Error("Must provide a directory.");
  }

  var cacheObject = {};
  var checksums = {};

  try {
    fs.statSync(dbDir);
  } catch (err) {
    if (err && err.code === 'ENOENT') {
      fs.mkdirSync(dbDir);
    }
  }

  fs.readdirSync(dbDir).filter(function(file) {
    return file.indexOf('.json') >= 0 && file.indexOf('~') < 0;
  }).forEach(function(file) {
    var fileDir = path.join(dbDir, file);
    var fileName = file.slice(0, -5);
    var data = (fs.readFileSync(fileDir, 'utf-8') || '').trim();

    try {
      cacheObject[fileName] = jph.parse(data);
      checksums[fileName] = JSON.stringify(cacheObject[fileName]);
    } catch (e) {
      if (e instanceof SyntaxError) e.message = 'Malformed JSON in file: ' + file + '\n' + e.message;
      throw e;
    }
  });

  function save() {
    for (var file in cacheObject) {
      var jsonData = JSON.stringify(cacheObject[file]);

      if (jsonData === checksums[file]) continue;

      checksums[file] = jsonData;
      write(file, cacheObject[file]);
    }
  }

  function write(file, json, cb) {
    var fileDir = path.join(dbDir, file + '.json');
    steno.writeFile(fileDir, JSON.stringify(json, null, 2), function(err) {
      if (err) throw err;
    });
  }

  function db(file) {
    if (!cacheObject[file]) cacheObject[file] = {};

    // methods
    return {
      get: function(prop, defaultValue) {
        var value = cacheObject[file][prop];

        return typeof value === 'undefined' || typeof value === 'null'
          ? defaultValue
          : value;
      },

      set: function(prop, value) {
        cacheObject[file][prop] = value;
        save();
        return this;
      },

      object: function() {
        return cacheObject[file];
      }
    };
  }

  db.save = save;

  return db;
};
<commit_msg>Fix lint errors<commit_after>var fs = require('graceful-fs');
var jph = require('json-parse-helpfulerror');
var path = require('path');
var steno = require('steno');

module.exports = function(dbDir) {
  'use strict';

  if (!dbDir || typeof dbDir !== 'string') {
    throw new Error("Must provide a directory.");
  }

  var cacheObject = {};
  var checksums = {};

  try {
    fs.statSync(dbDir);
  } catch (err) {
    if (err && err.code === 'ENOENT') {
      fs.mkdirSync(dbDir);
    }
  }

  fs.readdirSync(dbDir).filter(function(file) {
    return file.indexOf('.json') >= 0 && file.indexOf('~') < 0;
  }).forEach(function(file) {
    var fileDir = path.join(dbDir, file);
    var fileName = file.slice(0, -5);
    var data = (fs.readFileSync(fileDir, 'utf-8') || '').trim();

    try {
      cacheObject[fileName] = jph.parse(data);
      checksums[fileName] = JSON.stringify(cacheObject[fileName]);
    } catch (e) {
      if (e instanceof SyntaxError) e.message = 'Malformed JSON in file: ' + file + '\n' + e.message;
      throw e;
    }
  });

  function save() {
    for (var file in cacheObject) {
      var jsonData = JSON.stringify(cacheObject[file]);

      if (jsonData === checksums[file]) continue;

      checksums[file] = jsonData;
      write(file, cacheObject[file]);
    }
  }

  function write(file, json, cb) {
    var fileDir = path.join(dbDir, file + '.json');
    steno.writeFile(fileDir, JSON.stringify(json, null, 2), function(err) {
      if (err) throw err;
    });
  }

  function db(file) {
    if (!cacheObject[file]) cacheObject[file] = {};

    // methods
    return {
      get: function(prop, defaultValue) {
        var value = cacheObject[file][prop];

        return typeof value === 'undefined' ? defaultValue : value;
      },

      set: function(prop, value) {
        cacheObject[file][prop] = value;
        save();
        return this;
      },

      object: function() {
        return cacheObject[file];
      }
    };
  }

  db.save = save;

  return db;
};
<|endoftext|>


<commit_before>var express = require('express');
var ConnectionPool = require('./lib/droonga-protocol/connection-pool').ConnectionPool;
var httpAdapter = require('./lib/adapter/http');
var socketIoAdapter = require('./lib/adapter/socket.io');
var dashboardUI = require('./lib/ui/dashboard');
var ConsoleLogger = require('./lib/console-logger').ConsoleLogger;

function droonga(application, params) {
  params = params || {};

  params.logger = params.logger || new ConsoleLogger();

  params.connectionPool = params.connectionPool || new ConnectionPool(params);
  var connectionPool = params.connectionPool;

  params.prefix = params.prefix || '';
  params.prefix = params.prefix.replace(/\/$/, '');

  httpAdapter.register(application, params);

  if (params.server) {
    socketIoAdapter.register(application, params.server, params);
    params.server.on('error', function(error) {
      connectionPool.closeAll();
    });
    params.server.on('close', function() {
      // The connection can be mocked/stubbed. We don't need to close
      // such a fake connection.
      if (typeof connectionPool.closeAll == 'function')
        connectionPool.closeAll();
    });
  }

  dashboardUI.register(application, params);

  application.connectionPool = connectionPool;
}

exports.initialize = droonga;
express.application.droonga = function(params) {
  droonga(this, params);
};

require('./lib/adapter/api').exportTo(exports);

exports.command = require('./lib/adapter/command');
exports.Cache = require('./lib/cache');
exports.middleware = {
  cacheStatistics: require('./lib/middleware/cache-statistics'),
  cache: require('./lib/middleware/cache')
};
<commit_msg>Synchronize hostNames automatically<commit_after>var express = require('express');
var ConnectionPool = require('./lib/droonga-protocol/connection-pool').ConnectionPool;
var httpAdapter = require('./lib/adapter/http');
var socketIoAdapter = require('./lib/adapter/socket.io');
var dashboardUI = require('./lib/ui/dashboard');
var ConsoleLogger = require('./lib/console-logger').ConsoleLogger;

function droonga(application, params) {
  params = params || {};

  params.logger = params.logger || new ConsoleLogger();

  params.connectionPool = params.connectionPool || new ConnectionPool(params);
  var connectionPool = params.connectionPool;

  params.prefix = params.prefix || '';
  params.prefix = params.prefix.replace(/\/$/, '');

  httpAdapter.register(application, params);

  if (params.server) {
    socketIoAdapter.register(application, params.server, params);
    params.server.on('error', function(error) {
      if (typeof connectionPool.closeAll == 'function')
        connectionPool.closeAll();
      if (typeof connectionPool.stopSyncHostNamesFromCluster == 'function')
        connectionPool.stopSyncHostNamesFromCluster();
    });
    params.server.on('close', function() {
      if (typeof connectionPool.closeAll == 'function')
        connectionPool.closeAll();
      if (typeof connectionPool.stopSyncHostNamesFromCluster == 'function')
        connectionPool.stopSyncHostNamesFromCluster();
    });
  }

  dashboardUI.register(application, params);

  application.connectionPool = connectionPool;

  if (params.syncHostNames &&
      typeof connectionPool.startSyncHostNamesFromCluster == 'function')
    connectionPool.startSyncHostNamesFromCluster();
}

exports.initialize = droonga;
express.application.droonga = function(params) {
  droonga(this, params);
};

require('./lib/adapter/api').exportTo(exports);

exports.command = require('./lib/adapter/command');
exports.Cache = require('./lib/cache');
exports.middleware = {
  cacheStatistics: require('./lib/middleware/cache-statistics'),
  cache: require('./lib/middleware/cache')
};
<|endoftext|>


<commit_before>/* global define */
;(function (root, factory) {
  if (typeof define === 'function' && define.amd) define(factory)
  else if (typeof exports === 'object') module.exports = factory()
  else {
    if (window.jQuery) window.jQuery.behavior = factory()
    else root.behavior = factory()
  }
}(this, function ($) {

  // Initializer registry.
  var handlers = behavior.handlers = []
  var selectors = behavior.selectors = {}
  var id = 0

  behavior.selectify = selectify
  behavior.reset = reset

  // Use jQuery (or a jQuery-like) when available. This will allow
  // the use of jQuery selectors.
  behavior.$ = window.jQuery || window.Zepto || window.Ender

  return behavior

  /**
   * Adds a behavior, or triggers behaviors.
   *
   * When no parameters are passed, it triggers all behaviors. When one
   * parameter is passed, it triggers the given behavior. Otherwise, it adds a
   * behavior.
   *
   *     // define a behavior
   *     $.behavior('.select-box', function () {
   *       $(this).on('...')
   *     })
   *
   *     // define a behavior with exit
   *     $.behavior('.select-box', function () {
   *       $(document).on('...')
   *     }, function () {
   *       $(document).off('...')
   *     })
   *
   *     // retrigger a behavior
   *     $.behavior('.select-box')
   *
   *     // retriggers all behaviors
   *     $.behavior()
   */

  function behavior (selector, init, exit) {
    // trigger all behaviors on $.behavior(). Also account for cases such as
    // $($.behavior), where it's triggered with an event object.
    if (arguments.length === 0 || selector === $ || selector.target) {
      return trigger()
    }

    // account for `@role` selectors and such
    selector = behavior.selectify(selector)

    // trigger with $.behavior(selector)
    if (arguments.length === 1) return trigger(selector)

    // keep track of dom elements loaded for this behavior
    var loaded = []
    var key = '__behavior:' + slugify(selector)

    register(selector, function () {
      // clean up old ones
      for (var i = 0, len = loaded.length; i < len; i++) {
        var element = loaded[i]
        if (element && !isAttached(element)) {
          loaded[i] = undefined
          if (exit && exit.call(element, element[key]) !== false) {
            delete element[key]
          }
        }
      }

      // initialize new ones
      each(selector, function () {
        var options = { id: 'b' + id }
        if (!this[key] && init.call(this, options) !== false) {
          this[key] = options
          id++
          loaded.push(this)
        }
      })
    })

    // allow $.behavior().behavior() chain
    return this
  }

  /**
   * Clears all behaviors. Useful for tests.
   * This will NOT call exit handlers.
   */

  function reset () {
    handlers = behavior.handlers = []
    selectors = behavior.selectors = {}
  }

  /**
   * Internal: check if an element is still attached to its document.
   */

  function isAttached (el) {
    while (el) {
      if (el === document.documentElement) return true
      el = el.parentElement
    }
  }

  /**
   * Internal: reimplementation of `$('...').each()`. If jQuery is available,
   * use it (I guess to preserve IE compatibility and to enable special jQuery
   * attribute selectors).
   */

  function each (selector, fn) {
    if (behavior.$) return behavior.$(selector).each(fn)

    var list = document.querySelectorAll(selector)
    for (var i = 0, len = list.length; i < len; i++) {
      fn.apply(list[i])
    }
  }

  /**
   * Internal: registers a behavior handler for a selector.
   */

  function register (selector, fn) {
    if (!selectors[selector]) selectors[selector] = []
    selectors[selector].push(fn)
    handlers.push(fn)
  }

  /**
   * Internal: triggers behaviors for a selector or for all.
   *
   *     trigger()
   *     trigger('.js-button')
   */

  function trigger (selector) {
    var list

    if (selector) {
      list = selectors[selector] || []
    } else {
      list = handlers
    }

    for (var i = 0, len = list.length; i < len; i++) {
      list[i].call(this)
    }
  }

  /**
   * Internal: Converts `@role` to `[role~="role"]` if needed. You can override
   * this by reimplementing `behavior.selectify`.
   *
   *     selectify('@hi')   //=> '[role="hi"]'
   *     selectify('.btn')  //=> '.btn'
   */

  function selectify (selector) {
    if (selector[0] === '@') {
      return '[role~="' + selector.substr(1).replace(/"/g, '\\"') + '"]'
    }
    return selector
  }

  /**
   * Internal: Neutralizes a string so that it can be used as an event tag. You
   * may override this by reimplementing `behavior.slugify`.
   *
   *     slugify('[role="hi"]')  //=> "_5Brole_3D_22hi_22_5D"
   */

  function slugify (str) {
    return encodeURIComponent(str).replace(/[^a-zA-Z0-9]/g, '_')
  }

}))
<commit_msg>Update IIFE prefix<commit_after>/* global define */
void (function (root, factory) {
  if (typeof define === 'function' && define.amd) define(factory)
  else if (typeof exports === 'object') module.exports = factory()
  else {
    if (window.jQuery) window.jQuery.behavior = factory()
    else root.behavior = factory()
  }
}(this, function ($) {

  // Initializer registry.
  var handlers = behavior.handlers = []
  var selectors = behavior.selectors = {}
  var id = 0

  behavior.selectify = selectify
  behavior.reset = reset

  // Use jQuery (or a jQuery-like) when available. This will allow
  // the use of jQuery selectors.
  behavior.$ = window.jQuery || window.Zepto || window.Ender

  return behavior

  /**
   * Adds a behavior, or triggers behaviors.
   *
   * When no parameters are passed, it triggers all behaviors. When one
   * parameter is passed, it triggers the given behavior. Otherwise, it adds a
   * behavior.
   *
   *     // define a behavior
   *     $.behavior('.select-box', function () {
   *       $(this).on('...')
   *     })
   *
   *     // define a behavior with exit
   *     $.behavior('.select-box', function () {
   *       $(document).on('...')
   *     }, function () {
   *       $(document).off('...')
   *     })
   *
   *     // retrigger a behavior
   *     $.behavior('.select-box')
   *
   *     // retriggers all behaviors
   *     $.behavior()
   */

  function behavior (selector, init, exit) {
    // trigger all behaviors on $.behavior(). Also account for cases such as
    // $($.behavior), where it's triggered with an event object.
    if (arguments.length === 0 || selector === $ || selector.target) {
      return trigger()
    }

    // account for `@role` selectors and such
    selector = behavior.selectify(selector)

    // trigger with $.behavior(selector)
    if (arguments.length === 1) return trigger(selector)

    // keep track of dom elements loaded for this behavior
    var loaded = []
    var key = '__behavior:' + slugify(selector)

    register(selector, function () {
      // clean up old ones
      for (var i = 0, len = loaded.length; i < len; i++) {
        var element = loaded[i]
        if (element && !isAttached(element)) {
          loaded[i] = undefined
          if (exit && exit.call(element, element[key]) !== false) {
            delete element[key]
          }
        }
      }

      // initialize new ones
      each(selector, function () {
        var options = { id: 'b' + id }
        if (!this[key] && init.call(this, options) !== false) {
          this[key] = options
          id++
          loaded.push(this)
        }
      })
    })

    // allow $.behavior().behavior() chain
    return this
  }

  /**
   * Clears all behaviors. Useful for tests.
   * This will NOT call exit handlers.
   */

  function reset () {
    handlers = behavior.handlers = []
    selectors = behavior.selectors = {}
  }

  /**
   * Internal: check if an element is still attached to its document.
   */

  function isAttached (el) {
    while (el) {
      if (el === document.documentElement) return true
      el = el.parentElement
    }
  }

  /**
   * Internal: reimplementation of `$('...').each()`. If jQuery is available,
   * use it (I guess to preserve IE compatibility and to enable special jQuery
   * attribute selectors).
   */

  function each (selector, fn) {
    if (behavior.$) return behavior.$(selector).each(fn)

    var list = document.querySelectorAll(selector)
    for (var i = 0, len = list.length; i < len; i++) {
      fn.apply(list[i])
    }
  }

  /**
   * Internal: registers a behavior handler for a selector.
   */

  function register (selector, fn) {
    if (!selectors[selector]) selectors[selector] = []
    selectors[selector].push(fn)
    handlers.push(fn)
  }

  /**
   * Internal: triggers behaviors for a selector or for all.
   *
   *     trigger()
   *     trigger('.js-button')
   */

  function trigger (selector) {
    var list

    if (selector) {
      list = selectors[selector] || []
    } else {
      list = handlers
    }

    for (var i = 0, len = list.length; i < len; i++) {
      list[i].call(this)
    }
  }

  /**
   * Internal: Converts `@role` to `[role~="role"]` if needed. You can override
   * this by reimplementing `behavior.selectify`.
   *
   *     selectify('@hi')   //=> '[role="hi"]'
   *     selectify('.btn')  //=> '.btn'
   */

  function selectify (selector) {
    if (selector[0] === '@') {
      return '[role~="' + selector.substr(1).replace(/"/g, '\\"') + '"]'
    }
    return selector
  }

  /**
   * Internal: Neutralizes a string so that it can be used as an event tag. You
   * may override this by reimplementing `behavior.slugify`.
   *
   *     slugify('[role="hi"]')  //=> "_5Brole_3D_22hi_22_5D"
   */

  function slugify (str) {
    return encodeURIComponent(str).replace(/[^a-zA-Z0-9]/g, '_')
  }

}))
<|endoftext|>


<commit_before>'use strict'

const gcloud = require('google-cloud')
const Promise = require('bluebird')
const redis = require('redis')
const request = require('request')

Promise.promisifyAll(redis.RedisClient.prototype)
Promise.promisifyAll(redis.Multi.prototype)

class RedisLocalStore {
  constructor (config, options) {
    this.options = options
    this.client = redis.createClient(config.connection)
  }

  get (key) {
    return this.client.getAsync(key).then(result => {
      if (result) {
        return result
      }
      return null
    })
  }

  set (key, value, ttl = 60) {
    this.client.setAsync(key, value, 'EX', ttl)
  }
}

class GoogleCloudCache {
  constructor (config, localStore) {
    this.store = localStore
    this.storage = gcloud.storage(config.connection)
    this.uploads = {}

    this.bucketName = config.options.bucket
    this.bucket = this.storage.bucket(this.bucketName)
  }

  get (key) {
    return this.store.get(key).then(result => {
      if (result) {
        return result
      }
      return null
    })
  }

  set (key, uri, ttl = 60) {
    return this._write(key, uri).then(cacheUri => {
      this.store.set(key, cacheUri, ttl)
      return cacheUri
    })
  }

  _write (key, uri) {
    if (this.uploads[key] === undefined) {
      this.uploads[key] = true
      const name = Buffer.from(uri).toString('base64')
      const file = this.bucket.file(name)
      return new Promise((resolve, reject) => {
        request(uri)
        .pipe(file.createWriteStream())
        .on('error', err => {
          reject(err)
          delete this.uploads[key]
        })
        .on('finish', () => {
          resolve(`https://storage.googleapis.com/${this.bucketName}/${name}`)
          delete this.uploads[key]
        })
      })
    }
    return null
  }
}

module.exports = (config = {}) => {
  if (!config.store || !config.cache) {
    throw new Error('invalid local or remote configuration')
  }

  let store
  switch (config.store.client) {
    case 'redis':
      store = new RedisLocalStore(config.store)
      break
    default:
      return Promise.reject(new Error('unknown store client type'))
  }

  let cache
  if (config.cache.client === 'gcloud') {
    cache = new GoogleCloudCache(config.cache, store)
  } else {
    return Promise.reject(new Error('unknown cache client type'))
  }

  return Promise.resolve(cache)
}
<commit_msg>remove 'use strict'<commit_after>const gcloud = require('google-cloud')
const Promise = require('bluebird')
const redis = require('redis')
const request = require('request')

Promise.promisifyAll(redis.RedisClient.prototype)
Promise.promisifyAll(redis.Multi.prototype)

class RedisLocalStore {
  constructor (config, options) {
    this.options = options
    this.client = redis.createClient(config.connection)
  }

  get (key) {
    return this.client.getAsync(key).then(result => {
      if (result) {
        return result
      }
      return null
    })
  }

  set (key, value, ttl = 60) {
    this.client.setAsync(key, value, 'EX', ttl)
  }
}

class GoogleCloudCache {
  constructor (config, localStore) {
    this.store = localStore
    this.storage = gcloud.storage(config.connection)
    this.uploads = {}

    this.bucketName = config.options.bucket
    this.bucket = this.storage.bucket(this.bucketName)
  }

  get (key) {
    return this.store.get(key).then(result => {
      if (result) {
        return result
      }
      return null
    })
  }

  set (key, uri, ttl = 60) {
    return this._write(key, uri).then(cacheUri => {
      this.store.set(key, cacheUri, ttl)
      return cacheUri
    })
  }

  _write (key, uri) {
    if (this.uploads[key] === undefined) {
      this.uploads[key] = true
      const name = Buffer.from(uri).toString('base64')
      const file = this.bucket.file(name)
      return new Promise((resolve, reject) => {
        request(uri)
        .pipe(file.createWriteStream())
        .on('error', err => {
          reject(err)
          delete this.uploads[key]
        })
        .on('finish', () => {
          resolve(`https://storage.googleapis.com/${this.bucketName}/${name}`)
          delete this.uploads[key]
        })
      })
    }
    return null
  }
}

module.exports = (config = {}) => {
  if (!config.store || !config.cache) {
    throw new Error('invalid local or remote configuration')
  }

  let store
  switch (config.store.client) {
    case 'redis':
      store = new RedisLocalStore(config.store)
      break
    default:
      return Promise.reject(new Error('unknown store client type'))
  }

  let cache
  if (config.cache.client === 'gcloud') {
    cache = new GoogleCloudCache(config.cache, store)
  } else {
    return Promise.reject(new Error('unknown cache client type'))
  }

  return Promise.resolve(cache)
}
<|endoftext|>


<commit_before>module.exports = function (stylecow) {

	stylecow.addTask({
		disable: {
			firefox: 3.6,
			explorer: 9.0,
			safari: 5.0,
			opera: 11.6,
			ios: 4.0
		},

		//Set the default value of a rem (16px)
		RootBefore: function (root) {
			root.setData('rem', 16);
		},

		//Changes the default value on :root or html selectors
		RuleBefore: function (rule) {
			if (rule.hasChild({type: 'Selector', string: [':root', 'html']})) {
				rule.children({type: 'Declaration', name: 'font-size'}).forEach(function (declaration) {
					rule.ancestor({type: 'Root'}).setData('rem', toPixels(declaration.getValue().join(', ')));
				});
			}
		},

		//Add the fallback
		Declaration: function (declaration) {
			var value = declaration.getValue().join(', ');

			if (value.indexOf('rem') === -1) {
				return false;
			}

			declaration.cloneBefore().setValue(value.replace(/([0-9\.]+)rem/, function (match) {
				if (match[0] === '.') {
					match = '0' + match;
				}

				return (declaration.getData('rem') * parseFloat(match, 10)) + 'px';
			}));
		}
	});
};

function toPixels (value) {
	if (value[0] === '.') {
		value = '0' + value;
	}

	if (value.indexOf('px') !== -1) {
		return parseInt(value, 10);
	}

	if (value.indexOf('em') !== -1) {
		return parseFloat(value, 10) * 16;
	}

	if (value.indexOf('pt') !== -1) {
		return parseFloat(value, 10) * 14;
	}

	if (value.indexOf('%') !== -1) {
		return parseFloat(value, 10)/100 * 16;
	}

	return 16;
};
<commit_msg>changes for the new api in stylecow<commit_after>module.exports = function (stylecow) {

	stylecow.addTask({
		disable: {
			firefox: 3.6,
			explorer: 9.0,
			safari: 5.0,
			opera: 11.6,
			ios: 4.0
		},

		//Set the default value of a rem (16px)
		RootBefore: function (root) {
			root.setData('rem', 16);
		},

		//Changes the default value on :root or html selectors
		RuleBefore: function (rule) {
			if (rule.hasChild({type: 'Selector', string: [':root', 'html']})) {
				rule.children({type: 'Declaration', name: 'font-size'}).forEach(function (declaration) {
					rule.parent({type: 'Root'}).setData('rem', toPixels(declaration.getContent().join(', ')));
				});
			}
		},

		//Add the fallback
		Declaration: function (declaration) {
			var value = declaration.getContent().join(', ');

			if (value.indexOf('rem') === -1) {
				return false;
			}

			declaration.cloneBefore().setContent(value.replace(/([0-9\.]+)rem/, function (match) {
				if (match[0] === '.') {
					match = '0' + match;
				}

				return (declaration.getData('rem') * parseFloat(match, 10)) + 'px';
			}));
		}
	});
};

function toPixels (value) {
	if (value[0] === '.') {
		value = '0' + value;
	}

	if (value.indexOf('px') !== -1) {
		return parseInt(value, 10);
	}

	if (value.indexOf('em') !== -1) {
		return parseFloat(value, 10) * 16;
	}

	if (value.indexOf('pt') !== -1) {
		return parseFloat(value, 10) * 14;
	}

	if (value.indexOf('%') !== -1) {
		return parseFloat(value, 10)/100 * 16;
	}

	return 16;
};
<|endoftext|>


<commit_before>'use strict';
module.exports = {
	parserOptions: {
		ecmaFeatures: {
			jsx: true
		}
	},
	plugins: [
		'react'
	],
	rules: {
		'react/forbid-component-props': 2,
		'react/no-danger': 2,
		'react/no-danger-with-children': 2,
		'react/no-deprecated': 2,
		'react/no-did-update-set-state': 2,
		'react/no-direct-mutation-state': 2,
		'react/no-find-dom-node': 2,
		'react/no-is-mounted': 2,
		'react/no-render-return-value': 2,
		'react/no-string-refs': 2,
		'react/no-unknown-property': 2,
		'react/no-unused-prop-types': 2,
		'react/prop-types': 2,
		'react/react-in-jsx-scope': 2,
		'react/self-closing-comp': 2,
		'react/jsx-boolean-value': 2,
		'react/jsx-closing-bracket-location': [2, 'props-aligned'],
		'react/jsx-curly-spacing': [2, 'never'],
		'react/jsx-equals-spacing': [2, 'never'],
		'react/jsx-first-prop-new-line': [2, 'multiline'],
		'react/jsx-handler-names': 2,
		'react/jsx-indent': [2, 'tab'],
		'react/jsx-indent-props': [2, 'tab'],
		'react/jsx-key': 2,
		'react/jsx-no-bind': 2,
		'react/jsx-no-comment-textnodes': 2,
		'react/jsx-no-duplicate-props': [2, {ignoreCase: true}],
		'react/jsx-no-target-blank': 2,
		'react/jsx-no-undef': 2,
		'react/jsx-pascal-case': 2,
		'react/jsx-space-before-closing': [2, 'never'],
		'react/jsx-uses-react': 2,
		'react/jsx-uses-vars': 2,
		'react/jsx-wrap-multilines': 2
	}
};
<commit_msg>add `style-prop-object` rule<commit_after>'use strict';
module.exports = {
	parserOptions: {
		ecmaFeatures: {
			jsx: true
		}
	},
	plugins: [
		'react'
	],
	rules: {
		'react/forbid-component-props': 2,
		'react/no-danger': 2,
		'react/no-danger-with-children': 2,
		'react/no-deprecated': 2,
		'react/no-did-update-set-state': 2,
		'react/no-direct-mutation-state': 2,
		'react/no-find-dom-node': 2,
		'react/no-is-mounted': 2,
		'react/no-render-return-value': 2,
		'react/no-string-refs': 2,
		'react/no-unknown-property': 2,
		'react/no-unused-prop-types': 2,
		'react/prop-types': 2,
		'react/react-in-jsx-scope': 2,
		'react/self-closing-comp': 2,
		'react/style-prop-object': 2,
		'react/jsx-boolean-value': 2,
		'react/jsx-closing-bracket-location': [2, 'props-aligned'],
		'react/jsx-curly-spacing': [2, 'never'],
		'react/jsx-equals-spacing': [2, 'never'],
		'react/jsx-first-prop-new-line': [2, 'multiline'],
		'react/jsx-handler-names': 2,
		'react/jsx-indent': [2, 'tab'],
		'react/jsx-indent-props': [2, 'tab'],
		'react/jsx-key': 2,
		'react/jsx-no-bind': 2,
		'react/jsx-no-comment-textnodes': 2,
		'react/jsx-no-duplicate-props': [2, {ignoreCase: true}],
		'react/jsx-no-target-blank': 2,
		'react/jsx-no-undef': 2,
		'react/jsx-pascal-case': 2,
		'react/jsx-space-before-closing': [2, 'never'],
		'react/jsx-uses-react': 2,
		'react/jsx-uses-vars': 2,
		'react/jsx-wrap-multilines': 2
	}
};
<|endoftext|>


<commit_before>$('.words').on('keyup change', function() {
  var text = $(this).val();
  var color = textToColor(text);
  var colorString = "rgb(" + color.join(", ") + ")";
  var hexString = rgbToHex(color[0], color[1], color[2]).toUpperCase();

  $('.rgb-color').text(colorString);
  $('.hex-color').text(hexString);
  $('body').css('background-color', colorString);
  location.hash = "t=" + text;
});

$(window).on('hashchange', function() {
  var parsedHash = /t\=([^&]*)/.exec(location.hash);
  var text = parsedHash[1] || "";
  $('.words').val(text).change();
}).trigger('hashchange');

$('.words').change();

function textToColor(text) {
  var color = [255, 255, 255];

  var thirdTextLength = text.length / 3;
  for (var color_i = 0; color_i < color.length; color_i++) {
    for (var i = color_i * thirdTextLength; i < (color_i + 1) * thirdTextLength; i++) {
      var char = text.charCodeAt(i);
      color[color_i] = Math.floor(color[color_i] + char * 7 / 4 + 32) % 255;
    }
  }

  return color;
}

function componentToHex(c) {
  var hex = c.toString(16);
  return hex.length == 1 ? "0" + hex : hex;
}

function rgbToHex(r, g, b) {
  return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
<commit_msg>Decoding URLs<commit_after>$('.words').on('keyup change', function() {
  var text = $(this).val();
  var color = textToColor(text);
  var colorString = "rgb(" + color.join(", ") + ")";
  var hexString = rgbToHex(color[0], color[1], color[2]).toUpperCase();

  $('.rgb-color').text(colorString);
  $('.hex-color').text(hexString);
  $('body').css('background-color', colorString);
  location.hash = "t=" + text;
});

$(window).on('hashchange', function() {
  var parsedHash = /t\=([^&]*)/.exec(location.hash);
  var text = decodeURIComponent(parsedHash[1] || "");
  $('.words').val(text).change();
}).trigger('hashchange');

$('.words').change();

function textToColor(text) {
  var color = [255, 255, 255];

  var thirdTextLength = text.length / 3;
  for (var color_i = 0; color_i < color.length; color_i++) {
    for (var i = color_i * thirdTextLength; i < (color_i + 1) * thirdTextLength; i++) {
      var char = text.charCodeAt(i);
      color[color_i] = Math.floor(color[color_i] + char * 7 / 4 + 32) % 255;
    }
  }

  return color;
}

function componentToHex(c) {
  var hex = c.toString(16);
  return hex.length == 1 ? "0" + hex : hex;
}

function rgbToHex(r, g, b) {
  return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
<|endoftext|>


<commit_before>module.exports = {
  env: {
    browser: true,
    commonjs: true,
    es6: true
  },
  extends: 'eslint:recommended',
  ecmaFeatures: {
    jsx: true,
  },
  globals: {},
  plugins: [
    'react'
  ],
  rules: {
    'array-bracket-spacing': ['error', 'never'],
    'arrow-parens': ['error', 'as-needed'],
    'comma-spacing': ['error', {
      before: false,
      after: true,
    }],
    'computed-property-spacing': ['error', 'never'],
    'comma-dangle': ['error', 'always-multiline'],
    'eqeqeq': ['error', 'allow-null'],
    'indent': ['error', 2, {SwitchCase: 1}],
    'jsx-quotes': ['error', 'prefer-double'],
    'key-spacing': ['error', {
      beforeColon: false,
      afterColon: true,
    }],
    'keyword-spacing': ['error', {before: true, after: true}],
    'linebreak-style': ['error', 'unix'],
    'max-len': [1, 80, 2, {
      'ignorePattern': '^import\\s.+\\sfrom\\s.+;$',
      'ignoreUrls': true
    }],
    'no-case-declarations': 0,
    'no-debugger': 'error',
    'no-trailing-spaces': 'error',
    'no-undef': 'error',
    'no-unreachable': 'error',
    'no-unused-vars': ['error', {args: 'none'}],
    'object-curly-spacing': ['error', 'never'],
    'quotes': ['error', 'single', 'avoid-escape'],
    'react/jsx-uses-react': 'error',
    'react/jsx-uses-vars': 'error',
    'react/react-in-jsx-scope': 'error',
    'react/jsx-closing-bracket-location': ['error', {
      'nonEmpty': 'after-props',
      'selfClosing': 'tag-aligned',
    }],
    'react/jsx-no-undef': 'error',
    'react/jsx-key': 1,
    'react/jsx-sort-props': ['error', {ignoreCase: true}],
    'react/no-direct-mutation-state': 'error',
    'semi': ['error', 'always'],
    'semi-spacing': ['error', {
      before: false,
      after: true,
    }],
    'space-before-function-paren': ['error', 'never'],
    'space-in-parens': ['error', 'never'],
    'yoda': ['error', 'never'],
  },
};<commit_msg>Add `space-before-blocks` rule<commit_after>module.exports = {
  env: {
    browser: true,
    commonjs: true,
    es6: true
  },
  extends: 'eslint:recommended',
  ecmaFeatures: {
    jsx: true,
  },
  globals: {},
  plugins: [
    'react'
  ],
  rules: {
    'array-bracket-spacing': ['error', 'never'],
    'arrow-parens': ['error', 'as-needed'],
    'comma-spacing': ['error', {
      before: false,
      after: true,
    }],
    'computed-property-spacing': ['error', 'never'],
    'comma-dangle': ['error', 'always-multiline'],
    'eqeqeq': ['error', 'allow-null'],
    'indent': ['error', 2, {SwitchCase: 1}],
    'jsx-quotes': ['error', 'prefer-double'],
    'key-spacing': ['error', {
      beforeColon: false,
      afterColon: true,
    }],
    'keyword-spacing': ['error', {before: true, after: true}],
    'linebreak-style': ['error', 'unix'],
    'max-len': [1, 80, 2, {
      'ignorePattern': '^import\\s.+\\sfrom\\s.+;$',
      'ignoreUrls': true
    }],
    'no-case-declarations': 0,
    'no-debugger': 'error',
    'no-trailing-spaces': 'error',
    'no-undef': 'error',
    'no-unreachable': 'error',
    'no-unused-vars': ['error', {args: 'none'}],
    'object-curly-spacing': ['error', 'never'],
    'quotes': ['error', 'single', 'avoid-escape'],
    'react/jsx-uses-react': 'error',
    'react/jsx-uses-vars': 'error',
    'react/react-in-jsx-scope': 'error',
    'react/jsx-closing-bracket-location': ['error', {
      'nonEmpty': 'after-props',
      'selfClosing': 'tag-aligned',
    }],
    'react/jsx-no-undef': 'error',
    'react/jsx-key': 1,
    'react/jsx-sort-props': ['error', {ignoreCase: true}],
    'react/no-direct-mutation-state': 'error',
    'semi': ['error', 'always'],
    'semi-spacing': ['error', {
      before: false,
      after: true,
    }],
    'space-before-blocks': 'error',
    'space-before-function-paren': ['error', 'never'],
    'space-in-parens': ['error', 'never'],
    'yoda': ['error', 'never'],
  },
};<|endoftext|>


<commit_before>'use strict'

var fs = require('fs')
var path = require('path')
var util = require('util')
var http = require('http')
var debug = require('debug')('followers')
var patterns = require('patterns')()
var request = require('request')
var csv = require('csv-parser')
var pkg = require('./package')

var env = process.env.NODE_ENV || 'development'
var userAgent = pkg.name + '/' + pkg.version
var css = fs.readFileSync(path.join(__dirname, 'style.css'))
var head = '<!doctype html><meta charset=utf-8><title>GitHub followers</title>
'
var top10k = []

debug('Loading top 10k Github users')
fs.createReadStream(path.join(__dirname, 'top-10K.csv'))
  .pipe(csv())
  .on('data', function (data) {
    top10k.push(data.login)
  })
  .on('end', function () {
    debug('Finished loading top 10k Github users')
  })

patterns.add('GET /', function (req, res) {
  res.end(head + '<input type=text name=username id=username placeholder="Enter GitHub username"><button onclick="window.location = document.getElementById(\'username\').value">Submit</button>')
})

var userDiv = function (login, avatar, rank) {
  return util.format('
%s%s
', avatar, login, login, rank)
}

patterns.add('GET /{username}', function (req, res) {
  var username = req.params.username
  var opts = {
    uri: 'https://api.github.com/users/' + username + '/followers',
    json: true,
    headers: {
      'User-Agent': userAgent
    }
  }

  request(opts, function (err, response, data) {
    if (err) {
      res.writeHead(500)
      res.end(err.message)
      return
    }
    if (!Array.isArray(data)) {
      res.writeHead(404)
      res.end()
      return
    }

    var rank = top10k.indexOf(username)
    rank = rank === -1 ? 'no rank' : rank + 1

    var body = [head]
    body.push(userDiv(username, 'https://github.com/' + username + '.png', rank))
    body.push('
Top Github followers
')
    body.push('
These people follow ' + username + ' and are all among the top 10k most active Github users in the world
')
    body.push('
')

    data
      .filter(function (user) {
        return ~top10k.indexOf(user.login)
      })
      .sort(function (a, b) {
        a = top10k.indexOf(a.login)
        b = top10k.indexOf(b.login)
        return a - b
      })
      .forEach(function (user) {
        var rank = top10k.indexOf(user.login)
        body.push(userDiv(user.login, user.avatar_url, rank))
      })

    body.push('
')
    body.push('')
    body.push('
')
    body = body.join('\n')

    res.writeHead(200, {
      'Content-Type': 'text/html',
      'Content-Length': Buffer.byteLength(body)
    })
    res.end(body)
  })
})

var server = http.createServer(function (req, res) {
  var ptn = req.method + ' ' + req.url
  debug(ptn)
  var match = patterns.match(ptn)

  if (!match) {
    res.writeHead(404)
    res.end()
    return
  }

  var fn = match.value
  req.params = match.params
  fn(req, res)
})

server.listen(process.env.PORT, function () {
  debug('Server listening on port ' + server.address().port)
})
<commit_msg>Show form on result page as well<commit_after>'use strict'

var fs = require('fs')
var path = require('path')
var util = require('util')
var http = require('http')
var debug = require('debug')('followers')
var patterns = require('patterns')()
var request = require('request')
var csv = require('csv-parser')
var pkg = require('./package')

var env = process.env.NODE_ENV || 'development'
var userAgent = pkg.name + '/' + pkg.version
var css = fs.readFileSync(path.join(__dirname, 'style.css'))
var head = '<!doctype html><meta charset=utf-8><title>GitHub followers</title>
'
var top10k = []

debug('Loading top 10k Github users')
fs.createReadStream(path.join(__dirname, 'top-10K.csv'))
  .pipe(csv())
  .on('data', function (data) {
    top10k.push(data.login)
  })
  .on('end', function () {
    debug('Finished loading top 10k Github users')
  })

var form = function (login, avatar, rank) {
  return '<form onsubmit="window.location = document.getElementById(\'username\').value; return false"><input type=text name=username id=username placeholder="Enter GitHub username"> <input type=submit value=View></form>'
}

var userDiv = function (login, avatar, rank) {
  return util.format('
%s%s
', avatar, login, login, rank)
}

patterns.add('GET /', function (req, res) {
  res.end(head + form())
})

patterns.add('GET /{username}', function (req, res) {
  var username = req.params.username
  var opts = {
    uri: 'https://api.github.com/users/' + username + '/followers',
    json: true,
    headers: {
      'User-Agent': userAgent
    }
  }

  request(opts, function (err, response, data) {
    if (err) {
      res.writeHead(500)
      res.end(err.message)
      return
    }
    if (!Array.isArray(data)) {
      res.writeHead(404)
      res.end()
      return
    }

    var rank = top10k.indexOf(username)
    rank = rank === -1 ? 'no rank' : rank + 1

    var body = [head]
    body.push(userDiv(username, 'https://github.com/' + username + '.png', rank))
    body.push('
Top Github followers
')
    body.push('
These people follow ' + username + ' and are all among the top 10k most active Github users in the world
')
    body.push('
')

    data
      .filter(function (user) {
        return ~top10k.indexOf(user.login)
      })
      .sort(function (a, b) {
        a = top10k.indexOf(a.login)
        b = top10k.indexOf(b.login)
        return a - b
      })
      .forEach(function (user) {
        var rank = top10k.indexOf(user.login)
        body.push(userDiv(user.login, user.avatar_url, rank))
      })

    body.push('
')
    body.push(form())
    body.push('
')
    body.push('')
    body = body.join('\n')

    res.writeHead(200, {
      'Content-Type': 'text/html',
      'Content-Length': Buffer.byteLength(body)
    })
    res.end(body)
  })
})

var server = http.createServer(function (req, res) {
  var ptn = req.method + ' ' + req.url
  debug(ptn)
  var match = patterns.match(ptn)

  if (!match) {
    res.writeHead(404)
    res.end()
    return
  }

  var fn = match.value
  req.params = match.params
  fn(req, res)
})

server.listen(process.env.PORT, function () {
  debug('Server listening on port ' + server.address().port)
})
<|endoftext|>


<commit_before>var postcss = require('postcss'),
    resolvedNestedSelector = require('postcss-resolve-nested-selector'),
    assign = require('object-assign'),
    escRgx = require('escape-string-regexp');

module.exports = postcss.plugin('postcss-nested-ancestors', function (opts) {
    opts = assign({
        placeholder: '^&',
        replaceDeclarations: false
    }, opts);

    // Advanced options
    opts = assign({
        levelSymbol: opts.levelSymbol || opts.placeholder.charAt(0),
        parentSymbol: opts.parentSymbol || opts.placeholder.charAt(1)
    }, opts);

    // Gets all ancestors placeholder recurrencies: ^&, ^^&, ^^^&, [...]
    var placeholderRegex = new RegExp(
            // eslint-disable-next-line max-len
            '(' + escRgx(opts.levelSymbol) + ')+(' + escRgx(opts.parentSymbol) + ')',
            'g'
        );

    /**
     * Climb up PostCSS node parent stack
     * @param  {Object} node            PostCSS node object
     * @param  {Number} nestingLevel    Number of parent to climb
     * @return {Object|false}           Parent PostCSS node or false if no matching parent
     */
    function getParentNodeAtLevel(node, nestingLevel) {
        var currentNode = node;
        nestingLevel = nestingLevel || 1;

        for (var i = 0; i < nestingLevel; i++) {
            if (currentNode.parent.type === 'root') {
                return false;
            } else {
                currentNode = currentNode.parent;
            }
        }
        return currentNode;
    }

    /**
     * Given a PostCSS object and the level of a parent rule,
     * return the selector of the matching parent rule
     *
     * @param  {Object} node            PostCSS Node object
     * @param  {Number} nestingLevel    Ancestor nesting depth (0 = &, 1 = ^&, ...)
     * @param  {Object} result          PostCSS Result object
     * @return {Array}                  Array of ancestor selectors
     */
    function getParentSelectorsAtLevel(node, nestingLevel, result) {
        nestingLevel = nestingLevel || 1;

        // Get parent PostCSS node object at requested nesting level
        var parentNodeAtLevel = getParentNodeAtLevel(node, nestingLevel + 1);

        // Iterate each matching parent node selectors and resolve them
        if (parentNodeAtLevel && parentNodeAtLevel.selectors) {
            return parentNodeAtLevel.selectors
                .map(function (selector) {
                    // Resolve parent selectors for each node
                    return resolvedNestedSelector(selector, parentNodeAtLevel);
                })
                .reduce(function (a, b) {
                    // Flatten array of arrays
                    return a.concat(b);
                });
        } else {
            // Set a warning no matching parent node found
            node.warn(result, 'Parent selector exceeds current stack.');
            return [''];
        }
    }

    /**
     * Given an ancestor placeholder and the PostCSS node object,
     * returns the corresponding parent selectors
     * calculated from the provided PostCSS node object.
     *
     * @param  {String} placeholder     Ancestor placeholder (eg.^^&)
     * @param  {Object} node            PostCSS Node object
     * @param  {Object} result          PostCSS Result object
     * @return {Array}                  Array of ancestor selectors
     */
    function getMatchingParentSelectors(placeholder, node, result) {
        return getParentSelectorsAtLevel(
            node,
            // Get how many level symbols ("^") has current placeholder
            placeholder.lastIndexOf(opts.levelSymbol) / opts.levelSymbol.length  + 1,
            result
        );
    }

    /**
     * Given a selector string and its PostCSS node object,
     * return a string rapresenting the provided selector
     * with ancestor placeholder replaced with actual parent selectors
     *
     * @param  {Array} selectors    Array of CSS selectors / strings
     * @param  {Object} node        a PostCSS Node object
     * @param  {Object} result      a PostCSS Result object
     * @return {String}             Array of Arrays of CSS selectors
     */
    function replacePlaceholders(selectors, node, result) {
        // Parse each singular selector
        const resolvedSelectors = selectors.map(function (selector) {

            // Look for ancestor placeholders into selector (eg. ^^&-foo)
            const placeholder = selector.match(placeholderRegex);

            // Ancestor placeholder found! (eg. ^^&):
            if (placeholder) {
                /*
                 * Get an array of parent selectors build from found placeholder
                 * (eg. ['.ancestor-1, '.ancestor-2'])
                 */
                // eslint-disable-next-line max-len
                const parentSelectors = getMatchingParentSelectors(placeholder[0], node, result);

                /*
                 * Replace original selector string with an array of updated selectors.
                 * The ancestor placeholder (^^&) found in original selector (^^&-foo)
                 * is replaced by just generated parent selectors.
                 * (eg. '^^&-foo' --> ['.ancestor-1-foo, '.ancestor-2-foo'])
                 */
                return parentSelectors.map(function (parentSelector) {
                    return selector.replace(placeholder[0], parentSelector);
                });
            }

            return selector;
        });
        return resolvedSelectors;
    }

    var process = function (node, result) {
        // Replace parents placeholders in each rule selector
        node.walkRules( function (rule) {
            rule.selectors = replacePlaceholders(rule.selectors, rule, result);
        });

        // Replace parents placeholders in each rule declaration value
        if (opts.replaceDeclarations) {
            node.walkDecls( function (decl) {
                decl.value = decl.value.replace(placeholderRegex, function (placeholder) {
                    // Get parent selectors array and join it as a comma separated string
                    return getMatchingParentSelectors(placeholder, decl, result).join();
                });
            });
        }
    };

    return function (root, result) {
        process(root, result);
    };
});
<commit_msg>Rename "replaceSelectorsPlaceholders" method to "getReplacedSelectors"<commit_after>var postcss = require('postcss'),
    resolvedNestedSelector = require('postcss-resolve-nested-selector'),
    assign = require('object-assign'),
    escRgx = require('escape-string-regexp');

module.exports = postcss.plugin('postcss-nested-ancestors', function (opts) {
    opts = assign({
        placeholder: '^&',
        replaceDeclarations: false
    }, opts);

    // Advanced options
    opts = assign({
        levelSymbol: opts.levelSymbol || opts.placeholder.charAt(0),
        parentSymbol: opts.parentSymbol || opts.placeholder.charAt(1)
    }, opts);

    // Gets all ancestors placeholder recurrencies: ^&, ^^&, ^^^&, [...]
    var placeholderRegex = new RegExp(
            // eslint-disable-next-line max-len
            '(' + escRgx(opts.levelSymbol) + ')+(' + escRgx(opts.parentSymbol) + ')',
            'g'
        );

    /**
     * Climb up PostCSS node parent stack
     * @param  {Object} node            PostCSS node object
     * @param  {Number} nestingLevel    Number of parent to climb
     * @return {Object|false}           Parent PostCSS node or false if no matching parent
     */
    function getParentNodeAtLevel(node, nestingLevel) {
        var currentNode = node;
        nestingLevel = nestingLevel || 1;

        for (var i = 0; i < nestingLevel; i++) {
            if (currentNode.parent.type === 'root') {
                return false;
            } else {
                currentNode = currentNode.parent;
            }
        }
        return currentNode;
    }

    /**
     * Given a PostCSS object and the level of a parent rule,
     * return the selector of the matching parent rule
     *
     * @param  {Object} node            PostCSS Node object
     * @param  {Number} nestingLevel    Ancestor nesting depth (0 = &, 1 = ^&, ...)
     * @param  {Object} result          PostCSS Result object
     * @return {Array}                  Array of ancestor selectors
     */
    function getParentSelectorsAtLevel(node, nestingLevel, result) {
        nestingLevel = nestingLevel || 1;

        // Get parent PostCSS node object at requested nesting level
        var parentNodeAtLevel = getParentNodeAtLevel(node, nestingLevel + 1);

        // Iterate each matching parent node selectors and resolve them
        if (parentNodeAtLevel && parentNodeAtLevel.selectors) {
            return parentNodeAtLevel.selectors
                .map(function (selector) {
                    // Resolve parent selectors for each node
                    return resolvedNestedSelector(selector, parentNodeAtLevel);
                })
                .reduce(function (a, b) {
                    // Flatten array of arrays
                    return a.concat(b);
                });
        } else {
            // Set a warning no matching parent node found
            node.warn(result, 'Parent selector exceeds current stack.');
            return [''];
        }
    }

    /**
     * Given an ancestor placeholder and the PostCSS node object,
     * returns the corresponding parent selectors
     * calculated from the provided PostCSS node object.
     *
     * @param  {String} placeholder     Ancestor placeholder (eg.^^&)
     * @param  {Object} node            PostCSS Node object
     * @param  {Object} result          PostCSS Result object
     * @return {Array}                  Array of ancestor selectors
     */
    function getMatchingParentSelectors(placeholder, node, result) {
        return getParentSelectorsAtLevel(
            node,
            // Get how many level symbols ("^") has current placeholder
            placeholder.lastIndexOf(opts.levelSymbol) / opts.levelSymbol.length  + 1,
            result
        );
    }

    /**
     * Given a PostCSS node object,
     * generate an array of selector from provided PostCSS node selectors
     * in which ancestor placeholders are replaced with actual matching parent selectors.
     *
     * In case of multiple parent selectors, the returning selectors array will
     * contain more items then the original one.
     *
     * @param  {Array} selectors    Array of CSS selectors / strings
     * @param  {Object} node        a PostCSS Node object
     * @param  {Object} result      a PostCSS Result object
     * @return {String}             Array of Arrays of CSS selectors
     */
    function getReplacedSelectors(node, result) {
        // Parse each singular selector
        const resolvedSelectors = node.selectors.map(function (selector) {

            // Look for ancestor placeholders into selector (eg. ^^&-foo)
            const placeholder = selector.match(placeholderRegex);

            // Ancestor placeholder found! (eg. ^^&):
            if (placeholder) {
                /*
                 * Get an array of parent selectors build from found placeholder
                 * (eg. ['.ancestor-1, '.ancestor-2'])
                 */
                // eslint-disable-next-line max-len
                const parentSelectors = getMatchingParentSelectors(placeholder[0], node, result);

                /*
                 * Replace original selector string with an array of updated selectors.
                 * The ancestor placeholder (^^&) found in original selector (^^&-foo)
                 * is replaced by just generated parent selectors.
                 * (eg. '^^&-foo' --> ['.ancestor-1-foo, '.ancestor-2-foo'])
                 */
                return parentSelectors.map(function (parentSelector) {
                    return selector.replace(placeholder[0], parentSelector);
                });
            }

            return selector;
        });
        return resolvedSelectors;
    }

    var process = function (node, result) {
        // Replace parents placeholders in each rule selector
        node.walkRules( function (rule) {
            rule.selectors = getReplacedSelectors(rule, result);
        });

        // Replace parents placeholders in each rule declaration value
        if (opts.replaceDeclarations) {
            node.walkDecls( function (decl) {
                decl.value = decl.value.replace(placeholderRegex, function (placeholder) {
                    // Get parent selectors array and join it as a comma separated string
                    return getMatchingParentSelectors(placeholder, decl, result).join();
                });
            });
        }
    };

    return function (root, result) {
        process(root, result);
    };
});
<|endoftext|>


<commit_before>const cheerio = require("cheerio");
const request = require("request");
const MongoClient = require("mongodb").MongoClient;
const moment = require("moment");
const async = require("async");

const mongodbUrl = "mongodb://localhost:27017/npm";

// STORE RECENTLY UPDATED
function storeRecentlyUpdated() {
    console.log(new Date(), "storeRecentlyUpdated()");
    var packages = [];

    // fetch recently updated
    request("https://www.npmjs.com/browse/updated", (error, response, body) => {
        // the request has a valid response
        if (response && response.statusCode === 200 && response.body) {
            // parse html with cheerio
            var $ = cheerio.load(response.body);

            $("a[class='name']").each((i, a) => {
                var href = $(a).attr("href");
                if (href.indexOf("/package/") === 0) {
                    packages.push(href.replace("/package/", ""));
                }
            });
        }

        // store in mongodb
        // open mongodb connection
        MongoClient.connect(mongodbUrl, (err, db) => {
            var collection = db.collection("packages");

            // insert each package
            async.each(
                packages,
                (p, done) => {
                    collection.insert(
                        {
                            _id: p,
                            upt: new Date()
                        },
                        (err, result) => {
                            return done();
                        }
                    );
                },
                err => {
                    db.close();
                }
            );
        });
    });
}

// download newly updated packages every minute
setInterval(storeRecentlyUpdated, 60000);
storeRecentlyUpdated();

// CHECK NEXT PACKAGE
function checkNextPackage(callback) {
    MongoClient.connect(mongodbUrl, (err, db) => {
        var downloadsCol = db.collection("downloads");
        var packagesCol = db.collection("packages");

        // find some packages
        packagesCol
            .find({
                upt: {
                    $lt: moment().utc().subtract(1, "h").toDate()
                }
            })
            .sort(["upt", 1])
            .limit(1)
            .toArray(function(err, packages) {
                if (err) return callback(err);

                var pkg = packages[0];

                // download the npm download counts for today
                request(
                    "https://www.npmjs.com/package/" + pkg._id,
                    (error, response, body) => {
                        // the request has a valid response
                        if (
                            response &&
                            response.statusCode === 200 &&
                            response.body
                        ) {
                            // parse html with cheerio
                            var $ = cheerio.load(response.body);

                            var count = $(".daily-downloads")
                                .text()
                                .replace(/[^\d]/g, "");

                            // store download count
                            downloadsCol.updateOne(
                                {
                                    _id: {
                                        pkg: pkg._id,
                                        date: moment().startOf("day").toDate()
                                    }
                                },
                                {
                                    $set: {
                                        dl: parseInt(count)
                                    }
                                },
                                {
                                    upsert: true
                                }
                            );

                            // update the update date on the package
                            packagesCol.updateOne(
                                {
                                    _id: pkg._id
                                },
                                {
                                    $set: {
                                        upt: new Date()
                                    }
                                }
                            );

                            // download package config
                            request(
                                "https://unpkg.com/" +
                                    pkg._id +
                                    "/package.json",
                                (error, response, body) => {
                                    var packagejson = null;
                                    if (!error && response.statusCode === 200) {
                                        packagejson = JSON.parse(body);
                                    }

                                    if (packagejson !== null) {
                                        collection.updateOne(
                                            {
                                                _id: pkg._id
                                            },
                                            {
                                                $set: {
                                                    desc: packagejson.description,
                                                    ver: packagejson.version,
                                                    keys: packagejson.keywords
                                                },
                                                $unset: {
                                                    pkg: true
                                                }
                                            },
                                            (err, result) => {
                                                // store dependencies
                                                if (
                                                    "dependencies" in
                                                    packagejson
                                                ) {
                                                    for (var d in Object.keys(
                                                        packagejson.dependencies
                                                    )) {
                                                        collection.insert(
                                                            {
                                                                _id: Object.keys(
                                                                    packagejson.dependencies
                                                                )[d],
                                                                upt: new Date()
                                                            },
                                                            (err, result) => {}
                                                        );
                                                    }
                                                }
                                            }
                                        );
                                    }
                                }
                            );

                            console.log(
                                new Date(),
                                "checkNextPackage(" + pkg._id + ") -> ",
                                parseInt(count)
                            );
                        } else if (response.statusCode === 404) {
                            // remove the package, because it apparently does not exist anymore
                            packagesCol.deleteOne({
                                _id: pkg._id
                            });
                        }

                        return callback();
                    }
                );
            });
    });
}

async.forever(checkNextPackage, err => {
    console.error(err);
});
<commit_msg>packagesCol fix<commit_after>const cheerio = require("cheerio");
const request = require("request");
const MongoClient = require("mongodb").MongoClient;
const moment = require("moment");
const async = require("async");

const mongodbUrl = "mongodb://localhost:27017/npm";

// STORE RECENTLY UPDATED
function storeRecentlyUpdated() {
    console.log(new Date(), "storeRecentlyUpdated()");
    var packages = [];

    // fetch recently updated
    request("https://www.npmjs.com/browse/updated", (error, response, body) => {
        // the request has a valid response
        if (response && response.statusCode === 200 && response.body) {
            // parse html with cheerio
            var $ = cheerio.load(response.body);

            $("a[class='name']").each((i, a) => {
                var href = $(a).attr("href");
                if (href.indexOf("/package/") === 0) {
                    packages.push(href.replace("/package/", ""));
                }
            });
        }

        // store in mongodb
        // open mongodb connection
        MongoClient.connect(mongodbUrl, (err, db) => {
            var collection = db.collection("packages");

            // insert each package
            async.each(
                packages,
                (p, done) => {
                    collection.insert(
                        {
                            _id: p,
                            upt: new Date()
                        },
                        (err, result) => {
                            return done();
                        }
                    );
                },
                err => {
                    db.close();
                }
            );
        });
    });
}

// download newly updated packages every minute
setInterval(storeRecentlyUpdated, 60000);
storeRecentlyUpdated();

// CHECK NEXT PACKAGE
function checkNextPackage(callback) {
    MongoClient.connect(mongodbUrl, (err, db) => {
        var downloadsCol = db.collection("downloads");
        var packagesCol = db.collection("packages");

        // find some packages
        packagesCol
            .find({
                upt: {
                    $lt: moment().utc().subtract(1, "h").toDate()
                }
            })
            .sort(["upt", 1])
            .limit(1)
            .toArray(function(err, packages) {
                if (err) return callback(err);

                var pkg = packages[0];

                // download the npm download counts for today
                request(
                    "https://www.npmjs.com/package/" + pkg._id,
                    (error, response, body) => {
                        // the request has a valid response
                        if (
                            response &&
                            response.statusCode === 200 &&
                            response.body
                        ) {
                            // parse html with cheerio
                            var $ = cheerio.load(response.body);

                            var count = $(".daily-downloads")
                                .text()
                                .replace(/[^\d]/g, "");

                            // store download count
                            downloadsCol.updateOne(
                                {
                                    _id: {
                                        pkg: pkg._id,
                                        date: moment().startOf("day").toDate()
                                    }
                                },
                                {
                                    $set: {
                                        dl: parseInt(count)
                                    }
                                },
                                {
                                    upsert: true
                                }
                            );

                            // update the update date on the package
                            packagesCol.updateOne(
                                {
                                    _id: pkg._id
                                },
                                {
                                    $set: {
                                        upt: new Date()
                                    }
                                }
                            );

                            // download package config
                            request(
                                "https://unpkg.com/" +
                                    pkg._id +
                                    "/package.json",
                                (error, response, body) => {
                                    var packagejson = null;
                                    if (!error && response.statusCode === 200) {
                                        packagejson = JSON.parse(body);
                                    }

                                    if (packagejson !== null) {
                                        packagesCol.updateOne(
                                            {
                                                _id: pkg._id
                                            },
                                            {
                                                $set: {
                                                    desc: packagejson.description,
                                                    ver: packagejson.version,
                                                    keys: packagejson.keywords
                                                },
                                                $unset: {
                                                    pkg: true
                                                }
                                            },
                                            (err, result) => {
                                                // store dependencies
                                                if (
                                                    "dependencies" in
                                                    packagejson
                                                ) {
                                                    for (var d in Object.keys(
                                                        packagejson.dependencies
                                                    )) {
                                                        packagesCol.insert(
                                                            {
                                                                _id: Object.keys(
                                                                    packagejson.dependencies
                                                                )[d],
                                                                upt: new Date()
                                                            },
                                                            (err, result) => {}
                                                        );
                                                    }
                                                }
                                            }
                                        );
                                    }
                                }
                            );

                            console.log(
                                new Date(),
                                "checkNextPackage(" + pkg._id + ") -> ",
                                parseInt(count)
                            );
                        } else if (response.statusCode === 404) {
                            // remove the package, because it apparently does not exist anymore
                            packagesCol.deleteOne({
                                _id: pkg._id
                            });
                        }

                        return callback();
                    }
                );
            });
    });
}

async.forever(checkNextPackage, err => {
    console.error(err);
});
<|endoftext|>


<commit_before>'use strict'

var debug = require('debug')('monster-drift')
delete process.env.DEBUG // hackrf doesn't like this flag

var fs = require('fs')
var devices = require('hackrf')()

var signal = {
  f: fs.readFileSync('./recordings/car-f.raw'),
  b: fs.readFileSync('./recordings/car-b.raw'),
  l: fs.readFileSync('./recordings/car-r.raw'),
  r: fs.readFileSync('./recordings/car-l.raw'),
  fr: fs.readFileSync('./recordings/car-fl.raw'),
  fl: fs.readFileSync('./recordings/car-fr.raw'),
  br: fs.readFileSync('./recordings/car-bl.raw'),
  bl: fs.readFileSync('./recordings/car-br.raw')
}
signal.f.name = 'forward'
signal.b.name = 'backward'
signal.l.name = 'left'
signal.r.name = 'right'
signal.fr.name = 'forward/right'
signal.fl.name = 'forward/left'
signal.br.name = 'backward/right'
signal.bl.name = 'backward/left'

module.exports = MonsterDrift

function MonsterDrift (opts) {
  if (!(this instanceof MonsterDrift)) return new MonsterDrift()
  if (!opts) opts = {}

  this._freq = opts.freq || 27e6
  this._index = 0
  this._stream = null
  this._stopIn = opts.stop || null
  this._stopTimer = null

  this._device = devices.open(opts.id || 0)
  this._device.setTxGain(opts.gain || 40) // TX VGA (IF) gain, 0-47 dB in 1 dB steps
  this._device.setFrequency(this._freq)
}

MonsterDrift.prototype.turn180 = function (cb) {
  var self = this
  this.forward()
  setTimeout(function () {
    self.right()
    setTimeout(function () {
      self.backwardLeft()
      setTimeout(function () {
        self.backward()
        if (cb) setTimeout(cb, 1000)
      }, 100)
    }, 125)
  }, 1000)
}

MonsterDrift.prototype.start = function () {
  var self = this
  debug('starting')
  this._device.startTx(function (buf, cb) {
    var i
    if (self._stream) {
      for (i = 0; i < buf.length; i++) {
        buf[i] = self._stream[self._index++]
        if (self._index === self._stream.length) self._index = 0
      }
    } else {
      for (i = 0; i < buf.length; i++) buf[i] = 0
    }
    cb()
  })
}

MonsterDrift.prototype.stop = function (cb) {
  if (!this._stream) return
  debug('stopping')
  this._stream = null
  this._device.stopTx(function () {
    debug('stopped!')
    if (cb) cb()
  })
}

MonsterDrift.prototype.close = function (cb) {
  var self = this
  this._device.stopTx(function () {
    self._device.close(cb)
  })
}

MonsterDrift.prototype.left = function () {
  this._drive(signal.l)
}

MonsterDrift.prototype.right = function () {
  this._drive(signal.r)
}

MonsterDrift.prototype.forward = function () {
  this._drive(signal.f)
}

MonsterDrift.prototype.forwardRight = function () {
  this._drive(signal.fr)
}

MonsterDrift.prototype.forwardLeft = function () {
  this._drive(signal.fl)
}

MonsterDrift.prototype.backward = function () {
  this._drive(signal.b)
}

MonsterDrift.prototype.backwardRight = function () {
  this._drive(signal.br)
}

MonsterDrift.prototype.backwardLeft = function () {
  this._drive(signal.bl)
}

MonsterDrift.prototype._drive = function (s) {
  debug(s.name)
  if (this._stopTimer) clearTimeout(this._stopTimer)
  if (this._stream === s) return
  else if (!this._stream) this.start()

  debug('new direction')
  this._index = 0
  this._stream = s

  if (this._stopIn) {
    var self = this
    this._stopTimer = setTimeout(function () {
      self.stop()
    }, this._stopIn)
  }
}
<commit_msg>Use stop function when closing<commit_after>'use strict'

var debug = require('debug')('monster-drift')
delete process.env.DEBUG // hackrf doesn't like this flag

var fs = require('fs')
var devices = require('hackrf')()

var signal = {
  f: fs.readFileSync('./recordings/car-f.raw'),
  b: fs.readFileSync('./recordings/car-b.raw'),
  l: fs.readFileSync('./recordings/car-r.raw'),
  r: fs.readFileSync('./recordings/car-l.raw'),
  fr: fs.readFileSync('./recordings/car-fl.raw'),
  fl: fs.readFileSync('./recordings/car-fr.raw'),
  br: fs.readFileSync('./recordings/car-bl.raw'),
  bl: fs.readFileSync('./recordings/car-br.raw')
}
signal.f.name = 'forward'
signal.b.name = 'backward'
signal.l.name = 'left'
signal.r.name = 'right'
signal.fr.name = 'forward/right'
signal.fl.name = 'forward/left'
signal.br.name = 'backward/right'
signal.bl.name = 'backward/left'

module.exports = MonsterDrift

function MonsterDrift (opts) {
  if (!(this instanceof MonsterDrift)) return new MonsterDrift()
  if (!opts) opts = {}

  this._freq = opts.freq || 27e6
  this._index = 0
  this._stream = null
  this._stopIn = opts.stop || null
  this._stopTimer = null

  this._device = devices.open(opts.id || 0)
  this._device.setTxGain(opts.gain || 40) // TX VGA (IF) gain, 0-47 dB in 1 dB steps
  this._device.setFrequency(this._freq)
}

MonsterDrift.prototype.turn180 = function (cb) {
  var self = this
  this.forward()
  setTimeout(function () {
    self.right()
    setTimeout(function () {
      self.backwardLeft()
      setTimeout(function () {
        self.backward()
        if (cb) setTimeout(cb, 1000)
      }, 100)
    }, 125)
  }, 1000)
}

MonsterDrift.prototype.start = function () {
  var self = this
  debug('starting')
  this._device.startTx(function (buf, cb) {
    var i
    if (self._stream) {
      for (i = 0; i < buf.length; i++) {
        buf[i] = self._stream[self._index++]
        if (self._index === self._stream.length) self._index = 0
      }
    } else {
      for (i = 0; i < buf.length; i++) buf[i] = 0
    }
    cb()
  })
}

MonsterDrift.prototype.stop = function (cb) {
  if (!this._stream) return
  debug('stopping')
  this._stream = null
  this._device.stopTx(function () {
    debug('stopped!')
    if (cb) cb()
  })
}

MonsterDrift.prototype.close = function (cb) {
  var self = this
  this.stop(function () {
    self._device.close(cb)
  })
}

MonsterDrift.prototype.left = function () {
  this._drive(signal.l)
}

MonsterDrift.prototype.right = function () {
  this._drive(signal.r)
}

MonsterDrift.prototype.forward = function () {
  this._drive(signal.f)
}

MonsterDrift.prototype.forwardRight = function () {
  this._drive(signal.fr)
}

MonsterDrift.prototype.forwardLeft = function () {
  this._drive(signal.fl)
}

MonsterDrift.prototype.backward = function () {
  this._drive(signal.b)
}

MonsterDrift.prototype.backwardRight = function () {
  this._drive(signal.br)
}

MonsterDrift.prototype.backwardLeft = function () {
  this._drive(signal.bl)
}

MonsterDrift.prototype._drive = function (s) {
  debug(s.name)
  if (this._stopTimer) clearTimeout(this._stopTimer)
  if (this._stream === s) return
  else if (!this._stream) this.start()

  debug('new direction')
  this._index = 0
  this._stream = s

  if (this._stopIn) {
    var self = this
    this._stopTimer = setTimeout(function () {
      self.stop()
    }, this._stopIn)
  }
}
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';

import {
   View,
   StyleSheet,
   TouchableOpacity,
   Animated,
   Platform,
   BackAndroid
} from 'react-native'

class Modal extends Component {
   constructor() {
      super();

      this.state = {
         opacity: new Animated.Value(0),
         scale: new Animated.Value(0.8),
         offset: new Animated.Value(0)
      };
   }
   componentWillReceiveProps(props) {
      if (props.open && props.children !== this.state.children) {
         this.setState({children: props.children});
      }
      if (props.animationDuration === 0)
         this.state.scale.setValue(1);
      else
         this.state.scale.setValue(this.props.open? 1 : 0.8);

      if (props.open !== this.props.open) {
         if (props.open)
            this.open();
         else
            this.close();
      }

      if (props.offset !== this.props.offset) {
         this.animateOffset(props.offset);
      }
   }
   componentDidMount() {
      if (Platform.OS === 'android') {
         BackAndroid.addEventListener('hardwareBackPress', () => {
            if (this.state.open) {
               this.close();
               return true;
            }
            return false;
         });
      }
   }
   setPhase(toValue) {
      if (this.state.open != toValue) {
         const {animationDuration, animationTension} = this.props;
         if (animationDuration === 0)
           this.state.opacity.setValue(toValue);
         else {
           Animated.timing(
              this.state.opacity,
              {
                 toValue,
                 duration: animationDuration
              }
           ).start();

           Animated.spring(
              this.state.scale,
              {
                 toValue: toValue ? 1 : 0.8,
                 tension: animationTension
              }
           ).start();
         }

         setTimeout(() => {
            if (toValue)
               this.props.modalDidOpen();
            else {
               this.setState({open: false, children: undefined});
               this.props.modalDidClose();
            }
         }, animationDuration);
      }
   }
   render() {
      const {opacity, open, scale, offset, children} = this.state;
      let containerStyles = [styles.absolute, styles.container, this.props.containerStyle];

      if (!this.state.open) {
        containerStyles.push(styles.hidden);
      }

      return (
         <View
         pointerEvents={open ? 'auto' : 'none'}
         style={containerStyles}>
            <TouchableOpacity
            style={styles.absolute}
            disabled={!this.props.closeOnTouchOutside}
            onPress={this.close.bind(this)}
            activeOpacity={0.75}>
               <Animated.View style={{flex: 1, opacity, backgroundColor: this.props.overlayBackground}} />
            </TouchableOpacity>
            <Animated.View
               style={[
                  styles.defaultModalStyle,
                  this.props.modalStyle,
                  {opacity, transform: [{scale}, {translateY: offset}]}
               ]}>
               {children}
            </Animated.View>
         </View>
      );
   }
   open() {
      this.setState({open: true});
      this.setPhase(1);
   }
   close() {
      this.setPhase(0);
   }
   animateOffset(offset) {
      Animated.spring(
         this.state.offset,
         {toValue: offset}
      ).start();
   }
}

Modal.propTypes = {
   open: PropTypes.bool,
   offset: PropTypes.number,
   overlayBackground: PropTypes.string,
   animationDuration: PropTypes.number,
   animationTension: PropTypes.number,
   modalDidOpen: PropTypes.func,
   modalDidClose: PropTypes.func,
   closeOnTouchOutside: PropTypes.bool,
};

Modal.defaultProps = {
   open: false,
   offset: 0,
   overlayBackground: 'rgba(0, 0, 0, 0.75)',
   animationDuration: 200,
   animationTension: 40,
   modalDidOpen: () => undefined,
   modalDidClose: () => undefined,
   closeOnTouchOutside: true,
};

const styles = StyleSheet.create({
   absolute: {
      position: 'absolute',
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      backgroundColor: 'rgba(0, 0, 0, 0)'
   },
   container: {
      justifyContent: 'center'
   },
   defaultModalStyle: {
      borderRadius: 2,
      margin: 20,
      padding: 10,
      backgroundColor: '#F5F5F5'
   },
   hidden: {
      top: -10000,
      left: 0,
      height: 0,
      width: 0
   }
});

export default Modal;
<commit_msg>update Pull request<commit_after>import React, { Component, PropTypes } from 'react';

import {
   View,
   StyleSheet,
   TouchableOpacity,
   Animated,
   Platform,
   BackAndroid
} from 'react-native'

class Modal extends Component {
   constructor() {
      super();

      this.state = {
         opacity: new Animated.Value(0),
         scale: new Animated.Value(0.8),
         offset: new Animated.Value(0)
      };
   }
   componentWillReceiveProps(props) {
      if (props.open && props.children !== this.state.children) {
         this.setState({children: props.children});
      }
      if (props.animationDuration === 0){
         this.state.scale.setValue(1);
      } else {
         this.state.scale.setValue(this.props.open ? 1 : 0.8);
      }
      if (props.open !== this.props.open) {
         if (props.open)
            this.open();
         else
            this.close();
      }

      if (props.offset !== this.props.offset) {
         this.animateOffset(props.offset);
      }
   }
   componentDidMount() {
      if (Platform.OS === 'android') {
         BackAndroid.addEventListener('hardwareBackPress', () => {
            if (this.state.open) {
               this.close();
               return true;
            }
            return false;
         });
      }
   }
   setPhase(toValue) {
      if (this.state.open != toValue) {
         const {animationDuration, animationTension} = this.props;
         if (animationDuration === 0){
           this.state.opacity.setValue(toValue);
         } else {
           Animated.timing(
              this.state.opacity,
              {
                 toValue,
                 duration: animationDuration
              }
           ).start();

           Animated.spring(
              this.state.scale,
              {
                 toValue: toValue ? 1 : 0.8,
                 tension: animationTension
              }
           ).start();
         }

         setTimeout(() => {
            if (toValue)
               this.props.modalDidOpen();
            else {
               this.setState({open: false, children: undefined});
               this.props.modalDidClose();
            }
         }, animationDuration);
      }
   }
   render() {
      const {opacity, open, scale, offset, children} = this.state;
      let containerStyles = [styles.absolute, styles.container, this.props.containerStyle];

      if (!this.state.open) {
        containerStyles.push(styles.hidden);
      }

      return (
         <View
         pointerEvents={open ? 'auto' : 'none'}
         style={containerStyles}>
            <TouchableOpacity
            style={styles.absolute}
            disabled={!this.props.closeOnTouchOutside}
            onPress={this.close.bind(this)}
            activeOpacity={0.75}>
               <Animated.View style={{flex: 1, opacity, backgroundColor: this.props.overlayBackground}} />
            </TouchableOpacity>
            <Animated.View
               style={[
                  styles.defaultModalStyle,
                  this.props.modalStyle,
                  {opacity, transform: [{scale}, {translateY: offset}]}
               ]}>
               {children}
            </Animated.View>
         </View>
      );
   }
   open() {
      this.setState({open: true});
      this.setPhase(1);
   }
   close() {
      this.setPhase(0);
   }
   animateOffset(offset) {
      Animated.spring(
         this.state.offset,
         {toValue: offset}
      ).start();
   }
}

Modal.propTypes = {
   open: PropTypes.bool,
   offset: PropTypes.number,
   overlayBackground: PropTypes.string,
   animationDuration: PropTypes.number,
   animationTension: PropTypes.number,
   modalDidOpen: PropTypes.func,
   modalDidClose: PropTypes.func,
   closeOnTouchOutside: PropTypes.bool,
};

Modal.defaultProps = {
   open: false,
   offset: 0,
   overlayBackground: 'rgba(0, 0, 0, 0.75)',
   animationDuration: 200,
   animationTension: 40,
   modalDidOpen: () => undefined,
   modalDidClose: () => undefined,
   closeOnTouchOutside: true,
};

const styles = StyleSheet.create({
   absolute: {
      position: 'absolute',
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      backgroundColor: 'rgba(0, 0, 0, 0)'
   },
   container: {
      justifyContent: 'center'
   },
   defaultModalStyle: {
      borderRadius: 2,
      margin: 20,
      padding: 10,
      backgroundColor: '#F5F5F5'
   },
   hidden: {
      top: -10000,
      left: 0,
      height: 0,
      width: 0
   }
});

export default Modal;
<|endoftext|>


<commit_before>/*
	TODO :
		parsing
			from DOM
				still data-*
			from String 				OK

		if('!initialised', ..., ...)

		integrate filters and expressions

		request and c3po

		model validation + .disabled

		route

		views pool

		collection filtering view 				OK

		.client( t1, t2, ...)
		.server(t1, t2, ...)

		promise management : catch end render / load

		mount/umount event 						OK

		EAch : children  : place els in Virtual Node (could be many)
			==> is natural : no need... each node has it's own dom element    	OK
		//______________________
		y.dependent('bloupi', 'foo', function(bloupi, foo){});

		==> a dependent function should only be a value in context.data
			that is registred to dependencies (as a Interpolable)

		y.applyToDOM(node | selector, template)		==> apply template on dom element (select it if selector)

		eventListeners : click(addUser(user)) : should retrieve user before feeding addUser

*/

//____________________________________________________ YAMVISH

var utils = require('./lib/utils');

var y = function(t) {
	return new y.Template(t);
};
y.isServer = utils.isServer;
y.utils = utils;
y.Context = require('./lib/context');
y.Template = require('./lib/template');
y.PureNode = require('./lib/pure-node');
y.Virtual = require('./lib/virtual');
y.Container = require('./lib/container');
y.View = require('./lib/view');
y.c3po = require('./plugins/c3po-bridge');
y.rql = require('./plugins/rql-array');
require('./plugins/rql');

var interpolable = require('./lib/interpolable');
y.interpolable = interpolable.interpolable;
y.Interpolable = interpolable.Interpolable;

// parsers
y.dom = require('./lib/parsers/dom-to-template');
y.html = require('./lib/parsers/html-to-template');
y.expression = require('./lib/parsers/expression');
y.elenpi = require('elenpi');

//________________________________________________ END VIEW

y.mainContext = null;
y.components = {};
y.addComponent = function(name, template /* or view instance */ ) {
	y.components[name] = template;
};

module.exports = y;
<commit_msg>working on TODO in index.js<commit_after>/*
	TODO :
		parsing
			from DOM
				still data-*
			from String 				OK

		 .disabled

		if('!initialised', ..., ...) 		// almost done

		integrate filters and expressions

		request and c3po-bridge 			OK

		model validation

		route

		views pool

		collection filtering view 				OK

		.client( t1, t2, ...)
		.server(t1, t2, ...)

		promise management : catch end render / load

		mount/umount event 						OK

		EAch : children  : place els in Virtual Node (could be many)
			==> is natural : no need... each node has it's own dom element    	OK
		//______________________
		y.dependent('bloupi', 'foo', function(bloupi, foo){});

		==> a dependent function should only be a value in context.data
			that is registred to dependencies (as a Interpolable)

		y.applyToDOM(node | selector, template)		==> apply template on dom element (select it if selector)

		eventListeners : click(addUser(user)) : should retrieve user before feeding addUser

	Parser :
		split html texts in static/interpolable atoms
		interpret with new Function() to allow complexe expression

	Should :

		rename _yamvish_binds in _binds 					OK
		rename all privates vars with _*

		for each template handler :
		add args in queue (through done) and place inner functions outside : no more closure

	Context with * 					OK

		could register to path.*
		and receive the * as key  +  value
		then items[key].reset(value)

	Eacher :

		hybrid structure ?												OK
			virtual that could contains real DOM node in childNodes

		associate to real DOMNode that execute 'each' the virtual node that hold children  		OK

		==> maybe introduce special token/tag/comment for each/filter/sort
			=> it resolves the html/js template equivalence
		e.g.

			<div ...>
				<h1>...</h1>
				<each:users filter="name" sort="lastname">

				</each>
				...
				<each:events>

				</each>
				...
				<todo-list:todoId  />
			</div>

	ES5/6

		arrows everywhere

		arguments manip

		simple interpolation

		classes

		...

 */

//____________________________________________________ YAMVISH

var utils = require('./lib/utils');

var y = function(t) {
	return new y.Template(t);
};
y.isServer = utils.isServer;
y.utils = utils;
y.Context = require('./lib/context');
y.Template = require('./lib/template');
y.PureNode = require('./lib/pure-node');
y.Virtual = require('./lib/virtual');
y.Container = require('./lib/container');
y.View = require('./lib/view');
y.c3po = require('./plugins/c3po-bridge');
y.rql = require('./plugins/rql-array');
require('./plugins/rql');

var interpolable = require('./lib/interpolable');
y.interpolable = interpolable.interpolable;
y.Interpolable = interpolable.Interpolable;

// parsers
y.dom = require('./lib/parsers/dom-to-template');
y.html = require('./lib/parsers/html-to-template');
y.expression = require('./lib/parsers/expression');
y.elenpi = require('elenpi');

//________________________________________________ END VIEW

y.mainContext = null;
y.components = {};
y.addComponent = function(name, template /* or view instance */ ) {
	y.components[name] = template;
};

module.exports = y;
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var through = require('through');
var Core = require('css-modules-loader-core');
var FileSystemLoader = require('css-modules-loader-core/lib/file-system-loader');
var assign = require('object-assign');
var stringHash = require('string-hash');

/*
  Custom `generateScopedName` function for `postcss-modules-scope`.
  Appends a hash of the css source.
*/
function createScopedNameFunc (plugin) {
  var orig = plugin.generateScopedName;
  return function (name, path, css) {
    var hash = stringHash(css).toString(36).substr(0, 5);
    return orig.apply(plugin, arguments) + '___' + hash;
  }
};

var cssExt = /\.css$/;
module.exports = function (browserify, options) {
  options = options || {};

  var cssOutFilename = options.output || options.o;
  if (!cssOutFilename) {
    throw new Error('css-modulesify needs the --output / -o option (path to output css file)');
  }

  // PostCSS plugins passed to FileSystemLoader
  var plugins = options.use || options.u;
  if (!plugins) {
    plugins = Core.defaultPlugins;
  } else {
    if (typeof plugins === 'string') {
      plugins = [ plugins ];
    }

    plugins = plugins.map(function requirePlugin (name) {
      // assume objects are already required plugins
      if (typeof name === 'object') {
        return name;
      }

      var plugin = require(name);

      // custom scoped name generation
      if (name === 'postcss-modules-scope') {
        options[name].generateScopedName = createScopedNameFunc(plugin);
      }

      if (name in options) {
        plugin = plugin(options[name]);
      } else {
        plugin = plugin.postcss || plugin();
      }

      return plugin;
    });
  }

  // keep track of css files visited
  var filenames = [];

  // keep track of all tokens so we can avoid duplicates
  var tokensByFile = {};

  // keep track of all source files for later builds: when
  // using watchify, not all files will be caught on subsequent
  // bundles
  var sourceByFile = {};

  browserify.transform(function transform (filename) {
    // only handle .css files
    if (!cssExt.test(filename)) {
      return through();
    }

    // collect visited filenames
    filenames.push(filename);

    return through(function noop () {}, function end () {
      var self = this;

      var loader = new FileSystemLoader(path.dirname(filename), plugins);

      // pre-populate the loader's tokensByFile
      loader.tokensByFile = tokensByFile;

      loader.fetch(path.basename(filename), '/').then(function (tokens) {
        var output = "module.exports = " + JSON.stringify(tokens);

        assign(tokensByFile, loader.tokensByFile);

        // store this file's source to be written out to disk later
        sourceByFile[filename] = loader.finalSource;

        self.queue(output);
        self.queue(null);
      }, function (err) {
        console.error(err);
      });
    });
  });

  // wrap the `bundle` function
  var bundle = browserify.bundle;
  browserify.bundle = function (opts, cb) {
    // reset the `tokensByFile` cache
    tokensByFile = {};

    // call the original
    var stream = bundle.apply(browserify, arguments);

    // close the css stream
    stream.on('end', function () {
      // Combine the collected sources into a single CSS file
      var css = Object.keys(sourceByFile).map(function(file) {
        return sourceByFile[file];
      }).join('\n');

      fs.writeFile(cssOutFilename, css, function(err) {
        if (err) console.error(err);
      });
    });

    return stream;
  };

  return browserify;
};
<commit_msg>ensure options object is initialized<commit_after>var fs = require('fs');
var path = require('path');
var through = require('through');
var Core = require('css-modules-loader-core');
var FileSystemLoader = require('css-modules-loader-core/lib/file-system-loader');
var assign = require('object-assign');
var stringHash = require('string-hash');

/*
  Custom `generateScopedName` function for `postcss-modules-scope`.
  Appends a hash of the css source.
*/
function createScopedNameFunc (plugin) {
  var orig = plugin.generateScopedName;
  return function (name, path, css) {
    var hash = stringHash(css).toString(36).substr(0, 5);
    return orig.apply(plugin, arguments) + '___' + hash;
  }
};

var cssExt = /\.css$/;
module.exports = function (browserify, options) {
  options = options || {};

  var cssOutFilename = options.output || options.o;
  if (!cssOutFilename) {
    throw new Error('css-modulesify needs the --output / -o option (path to output css file)');
  }

  // PostCSS plugins passed to FileSystemLoader
  var plugins = options.use || options.u;
  if (!plugins) {
    plugins = Core.defaultPlugins;
  } else {
    if (typeof plugins === 'string') {
      plugins = [ plugins ];
    }

    plugins = plugins.map(function requirePlugin (name) {
      // assume objects are already required plugins
      if (typeof name === 'object') {
        return name;
      }

      var plugin = require(name);

      // custom scoped name generation
      if (name === 'postcss-modules-scope') {
        options[name] = options[name] || {};
        options[name].generateScopedName = createScopedNameFunc(plugin);
      }

      if (name in options) {
        plugin = plugin(options[name]);
      } else {
        plugin = plugin.postcss || plugin();
      }

      return plugin;
    });
  }

  // keep track of css files visited
  var filenames = [];

  // keep track of all tokens so we can avoid duplicates
  var tokensByFile = {};

  // keep track of all source files for later builds: when
  // using watchify, not all files will be caught on subsequent
  // bundles
  var sourceByFile = {};

  browserify.transform(function transform (filename) {
    // only handle .css files
    if (!cssExt.test(filename)) {
      return through();
    }

    // collect visited filenames
    filenames.push(filename);

    return through(function noop () {}, function end () {
      var self = this;

      var loader = new FileSystemLoader(path.dirname(filename), plugins);

      // pre-populate the loader's tokensByFile
      loader.tokensByFile = tokensByFile;

      loader.fetch(path.basename(filename), '/').then(function (tokens) {
        var output = "module.exports = " + JSON.stringify(tokens);

        assign(tokensByFile, loader.tokensByFile);

        // store this file's source to be written out to disk later
        sourceByFile[filename] = loader.finalSource;

        self.queue(output);
        self.queue(null);
      }, function (err) {
        console.error(err);
      });
    });
  });

  // wrap the `bundle` function
  var bundle = browserify.bundle;
  browserify.bundle = function (opts, cb) {
    // reset the `tokensByFile` cache
    tokensByFile = {};

    // call the original
    var stream = bundle.apply(browserify, arguments);

    // close the css stream
    stream.on('end', function () {
      // Combine the collected sources into a single CSS file
      var css = Object.keys(sourceByFile).map(function(file) {
        return sourceByFile[file];
      }).join('\n');

      fs.writeFile(cssOutFilename, css, function(err) {
        if (err) console.error(err);
      });
    });

    return stream;
  };

  return browserify;
};
<|endoftext|>