<commit_before>var _ = require('lodash')
var types = require('./types')
var introspect = require('introspect')

var ERRORS = exports.ERRORS = {
	MISSING_REQUIRED_FIELD: 'missing required field',
	INVALID_VALUE: 'invalid value'
}

var PLATFORM = {
	POSTGRES: 1,
	REDSHIFT: 2
}

Object.keys(PLATFORM).forEach(function(k){
	exports[k] = PLATFORM[k]
})

exports.object = function (obj, metadata, opts) {
	var errors = []
	var platform = opts && opts.platform

	_.forEach(metadata, function (fieldMetadata, field) {

		var value = obj[field]

		// we might miss zeros here, so
		if (value === undefined || value === null) {
			if (fieldMetadata.required) {
				errors.push({
					field: field,
					error: ERRORS.MISSING_REQUIRED_FIELD
				})
			}

			return
		}

		var validator = validatorFor(fieldMetadata, platform)

		if (!validator.isValidValue(value)) {
			errors.push({
				field: field,
				error: ERRORS.INVALID_VALUE
			})
		}
	})

	return errors
}

function validatorFor (fieldMetadata, platform) {
	if (!platform) platform = PLATFORM.POSTGRES

	var type = fieldMetadata.type
	var validators = platformValidators(platform)

	if (type in validators) {
		var validator = validators[type]

		if (typeof validator === 'function') {
			// Has user-specified type options(s)
			var options = _.values(_.pick(fieldMetadata, introspect(validator)))
			validator = validator.apply(null, options)
		}

		return validator
	}

	throw new Error('missing validator for type ' + type)
}

/*
	these are validators that can be reused
*/
var staticValidators = {}
var platformAgnostic = {
	boolean:     new types.Boolean(),
	char:        types.Char,
	int2:        new types.Integer('16bit'),
	int4:        new types.Integer('32bit'),
	int8:        new types.Integer('64bit'),
	serial:      new types.Integer('serial'),
	bigserial:   new types.Integer('bigserial'),
	timestamp:   new types.Timestamp(),
	date:        new types.Date(),
	time:        new types.Time()
}

var ALIAS = {
	smallint:    'int2',
	integer:     'int4',
	bigint:      'int8',
	varchar:     'char',
	numeric:     'decimal',
	float4:      'real',
	float8:      'double_precision',
	timestamptz: 'timestamp',
	timetz:      'time'
}

function platformValidators(platform) {
	if (staticValidators[platform]) return staticValidators[platform]

	var validators = staticValidators[platform] = _.assign({}, platformAgnostic)

	if (platform === PLATFORM.POSTGRES) {
		var Decimal = validators.decimal = types.postgres.Decimal
	} else if (platform === PLATFORM.REDSHIFT) {
		Decimal = validators.decimal = types.redshift.Decimal
	} else {
		throw new Error('Invalid platform: ' + platform)
	}

	// Inexact. Maximum precision is advisory and *at least* 6.
	validators.real = new Decimal(null, null, '128bit')

	// Inexact. Maximum precision is advisory and *at least* 15.
	validators.double_precision = new Decimal(null, null, '1024bit')

	if (platform === PLATFORM.POSTGRES) {
		validators.float = types.postgres.Float.factory(validators)
	} else {
		validators.float = validators.double_precision
	}

	for(var alias in ALIAS) {
		validators[alias] = validators[ALIAS[alias]]
	}

	staticValidators[platform] = validators
	return validators
}

exports.validatorFor = validatorFor
<commit_msg>bpchar alias<commit_after>var _ = require('lodash')
var types = require('./types')
var introspect = require('introspect')

var ERRORS = exports.ERRORS = {
	MISSING_REQUIRED_FIELD: 'missing required field',
	INVALID_VALUE: 'invalid value'
}

var PLATFORM = {
	POSTGRES: 1,
	REDSHIFT: 2
}

Object.keys(PLATFORM).forEach(function(k){
	exports[k] = PLATFORM[k]
})

exports.object = function (obj, metadata, opts) {
	var errors = []
	var platform = opts && opts.platform

	_.forEach(metadata, function (fieldMetadata, field) {

		var value = obj[field]

		// we might miss zeros here, so
		if (value === undefined || value === null) {
			if (fieldMetadata.required) {
				errors.push({
					field: field,
					error: ERRORS.MISSING_REQUIRED_FIELD
				})
			}

			return
		}

		var validator = validatorFor(fieldMetadata, platform)

		if (!validator.isValidValue(value)) {
			errors.push({
				field: field,
				error: ERRORS.INVALID_VALUE
			})
		}
	})

	return errors
}

function validatorFor (fieldMetadata, platform) {
	if (!platform) platform = PLATFORM.POSTGRES

	var type = fieldMetadata.type
	var validators = platformValidators(platform)

	if (type in validators) {
		var validator = validators[type]

		if (typeof validator === 'function') {
			// Has user-specified type options(s)
			var options = _.values(_.pick(fieldMetadata, introspect(validator)))
			validator = validator.apply(null, options)
		}

		return validator
	}

	throw new Error('missing validator for type ' + type)
}

/*
	these are validators that can be reused
*/
var staticValidators = {}
var platformAgnostic = {
	boolean:     new types.Boolean(),
	char:        types.Char,
	int2:        new types.Integer('16bit'),
	int4:        new types.Integer('32bit'),
	int8:        new types.Integer('64bit'),
	serial:      new types.Integer('serial'),
	bigserial:   new types.Integer('bigserial'),
	timestamp:   new types.Timestamp(),
	date:        new types.Date(),
	time:        new types.Time()
}

var ALIAS = {
	smallint:    'int2',
	integer:     'int4',
	bigint:      'int8',
	varchar:     'char',
	numeric:     'decimal',
	float4:      'real',
	float8:      'double_precision',
	timestamptz: 'timestamp',
	timetz:      'time',
	bpchar:      'char'
}

function platformValidators(platform) {
	if (staticValidators[platform]) return staticValidators[platform]

	var validators = staticValidators[platform] = _.assign({}, platformAgnostic)

	if (platform === PLATFORM.POSTGRES) {
		var Decimal = validators.decimal = types.postgres.Decimal
	} else if (platform === PLATFORM.REDSHIFT) {
		Decimal = validators.decimal = types.redshift.Decimal
	} else {
		throw new Error('Invalid platform: ' + platform)
	}

	// Inexact. Maximum precision is advisory and *at least* 6.
	validators.real = new Decimal(null, null, '128bit')

	// Inexact. Maximum precision is advisory and *at least* 15.
	validators.double_precision = new Decimal(null, null, '1024bit')

	if (platform === PLATFORM.POSTGRES) {
		validators.float = types.postgres.Float.factory(validators)
	} else {
		validators.float = validators.double_precision
	}

	for(var alias in ALIAS) {
		validators[alias] = validators[ALIAS[alias]]
	}

	staticValidators[platform] = validators
	return validators
}

exports.validatorFor = validatorFor
<|endoftext|>


<commit_before>function createAmplifier(startValue, duration) {
  var amplifier = audio.createGain();
  decay(amplifier.gain, startValue, duration);
  return amplifier;
};

function chain() {
  for (var i = 0; i < arguments.length - 1; i++) {
    arguments[i].connect(arguments[i + 1]);
  }
};

function decay(item, startValue, duration) {
  item.setValueAtTime(startValue, audio.currentTime);
  item.exponentialRampToValueAtTime(0.01, audio.currentTime + duration);
};

function createSineWave(duration) {
  var oscillator = audio.createOscillator();
  oscillator.type = "sine";

  oscillator.start(audio.currentTime);
  oscillator.stop(audio.currentTime + duration);

  return oscillator;
};

function note(frequency) {
  return function() {
    var duration = 0.5;
    var sineWave = createSineWave(duration);
    sineWave.frequency.value = frequency;
    chain(sineWave,
          createAmplifier(1, duration),
          audio.destination);
  };
};

function kick() {
  var duration = 1;
  var sineWave = createSineWave(duration);
  decay(sineWave.frequency, 160, duration);
  chain(sineWave,
        createAmplifier(1, duration),
        audio.destination);
};

function buttonPosition(column, row) {
  return {
    x: BUTTON_SIZE / 2 + column * BUTTON_SIZE * 1.5,
    y: BUTTON_SIZE / 2 + row * BUTTON_SIZE * 1.5
  };
};

function isPointInButton(p, column, row) {
  var b = buttonPosition(column, row);
  return !(p.x < b.x ||
           p.y < b.y ||
           p.x > b.x + BUTTON_SIZE ||
           p.y > b.y + BUTTON_SIZE);
};

function createTrack(playSound) {
  var steps = [];
  for (var i = 0; i < 16; i++) {
    steps.push(false);
  }

  return { steps: steps, playSound: playSound };
};

function drawTracks(screen, data) {
  data.tracks.forEach(function(track, row) {
    track.steps.forEach(function(on, column) {
      drawButton(screen, column, row, on ? "gold" : "lightgray");
    });
  });
};

function drawButton(screen, column, row, color) {
  var position = buttonPosition(column, row);
  screen.fillStyle = color;
  screen.fillRect(position.x, position.y, BUTTON_SIZE, BUTTON_SIZE);
};

var data = {
  step: 0,
  tracks: [createTrack(note(880)),
           createTrack(note(659)),
           createTrack(note(587)),
           createTrack(note(523)),
           createTrack(note(440)),
           createTrack(kick)]
};

var BUTTON_SIZE = 25;
var audio = new window.AudioContext();
var screen = document.getElementById("screen").getContext("2d");

// update

setInterval(function update() {
  data.step = (data.step + 1) % data.tracks[0].steps.length;

  data.tracks
    .filter(function(track) { return track.steps[data.step]; })
    .forEach(function(track) { track.playSound(); })
}, 100);

// draw

(function draw() {
  screen.clearRect(0, 0, screen.canvas.width, screen.canvas.height);
  drawTracks(screen, data);
  drawButton(screen, data.step, data.tracks.length, "deeppink");

  requestAnimationFrame(draw);
})();

// handle events

(function setupButtonClicking() {
  window.addEventListener("click", function(e) {
    var click = { x: e.clientX, y: e.clientY };
    data.tracks.forEach(function(track, row) {
      track.steps.forEach(function(on, column) {
        if (isPointInButton(click, column, row)) {
          track.steps[column] = !on;
        }
      });
    });
  });
})();
<commit_msg>remove redundant references to window<commit_after>function createAmplifier(startValue, duration) {
  var amplifier = audio.createGain();
  decay(amplifier.gain, startValue, duration);
  return amplifier;
};

function chain() {
  for (var i = 0; i < arguments.length - 1; i++) {
    arguments[i].connect(arguments[i + 1]);
  }
};

function decay(item, startValue, duration) {
  item.setValueAtTime(startValue, audio.currentTime);
  item.exponentialRampToValueAtTime(0.01, audio.currentTime + duration);
};

function createSineWave(duration) {
  var oscillator = audio.createOscillator();
  oscillator.type = "sine";

  oscillator.start(audio.currentTime);
  oscillator.stop(audio.currentTime + duration);

  return oscillator;
};

function note(frequency) {
  return function() {
    var duration = 0.5;
    var sineWave = createSineWave(duration);
    sineWave.frequency.value = frequency;
    chain(sineWave,
          createAmplifier(1, duration),
          audio.destination);
  };
};

function kick() {
  var duration = 1;
  var sineWave = createSineWave(duration);
  decay(sineWave.frequency, 160, duration);
  chain(sineWave,
        createAmplifier(1, duration),
        audio.destination);
};

function buttonPosition(column, row) {
  return {
    x: BUTTON_SIZE / 2 + column * BUTTON_SIZE * 1.5,
    y: BUTTON_SIZE / 2 + row * BUTTON_SIZE * 1.5
  };
};

function isPointInButton(p, column, row) {
  var b = buttonPosition(column, row);
  return !(p.x < b.x ||
           p.y < b.y ||
           p.x > b.x + BUTTON_SIZE ||
           p.y > b.y + BUTTON_SIZE);
};

function createTrack(playSound) {
  var steps = [];
  for (var i = 0; i < 16; i++) {
    steps.push(false);
  }

  return { steps: steps, playSound: playSound };
};

function drawTracks(screen, data) {
  data.tracks.forEach(function(track, row) {
    track.steps.forEach(function(on, column) {
      drawButton(screen, column, row, on ? "gold" : "lightgray");
    });
  });
};

function drawButton(screen, column, row, color) {
  var position = buttonPosition(column, row);
  screen.fillStyle = color;
  screen.fillRect(position.x, position.y, BUTTON_SIZE, BUTTON_SIZE);
};

var data = {
  step: 0,
  tracks: [createTrack(note(880)),
           createTrack(note(659)),
           createTrack(note(587)),
           createTrack(note(523)),
           createTrack(note(440)),
           createTrack(kick)]
};

var BUTTON_SIZE = 25;
var audio = new AudioContext();
var screen = document.getElementById("screen").getContext("2d");

// update

setInterval(function update() {
  data.step = (data.step + 1) % data.tracks[0].steps.length;

  data.tracks
    .filter(function(track) { return track.steps[data.step]; })
    .forEach(function(track) { track.playSound(); })
}, 100);

// draw

(function draw() {
  screen.clearRect(0, 0, screen.canvas.width, screen.canvas.height);
  drawTracks(screen, data);
  drawButton(screen, data.step, data.tracks.length, "deeppink");

  requestAnimationFrame(draw);
})();

// handle events

(function setupButtonClicking() {
  addEventListener("click", function(e) {
    var click = { x: e.clientX, y: e.clientY };
    data.tracks.forEach(function(track, row) {
      track.steps.forEach(function(on, column) {
        if (isPointInButton(click, column, row)) {
          track.steps[column] = !on;
        }
      });
    });
  });
})();
<|endoftext|>


<commit_before>/**
 * Super-Duper Simple Express
 * Instantiate an express object, and handle `GET /`.
 */

'use strict';

let express = require('express');
let path = require('path');
let ejs = require('ejs');
let request = require('request');
let githubApi = require('./config/githubApi.json');
const app = express();

const github_client_id = process.env.GITHUB_CLIENT_ID || '';
const github_client_secret = process.env.GITHUB_CLIENT_SECRET || '';
const tokenPayload = {
  "client_id": github_client_id,
  "client_secret": github_client_secret
};
const requestAccessTokenOptions = {
  url: githubApi.tokenUrl,
  method: 'POST',
  json: true,
  headers: {
    Accept: 'application/json'
  }
};

githubApi.githubAuthUrl += '?client_id=' + github_client_id

app.use(express.static(path.join(__dirname, 'public')));
app.engine('ejs', ejs.renderFile);

app.get('/', function (req, res) {
  let query = req.query;
  let code = query.code || '';
  if (code) {
    let payload = Object.assign({}, tokenPayload, { code });
    let opts = Object.assign({}, requestAccessTokenOptions, { body: payload});
    return request(opts, function (error, response, body) {
      if (!error && response.statusCode == 200) {
        console.log(body); // Print the google web page.
      }
      console.log(body);
      res.render('index.ejs', githubApi);
    });
  }
  res.render('index.ejs', githubApi);
});

let port = process.env.PORT || 5000;
app.listen(port, function () {
  console.log(`OctoShelf, http://localhost:${port}/`);
});<commit_msg>Annnd now we have an access token :)<commit_after>/**
 * Super-Duper Simple Express
 * Instantiate an express object, and handle `GET /`.
 */

'use strict';

let express = require('express');
let path = require('path');
let ejs = require('ejs');
let request = require('request');
let githubApi = require('./config/githubApi.json');
const app = express();

const github_client_id = process.env.GITHUB_CLIENT_ID || '';
const github_client_secret = process.env.GITHUB_CLIENT_SECRET || '';
const tokenPayload = {
  "client_id": github_client_id,
  "client_secret": github_client_secret
};
const requestAccessTokenOptions = {
  url: githubApi.githubTokenUrl,
  method: 'POST',
  json: true,
  headers: {
    Accept: 'application/json'
  }
};

githubApi.githubAuthUrl += '?client_id=' + github_client_id

app.use(express.static(path.join(__dirname, 'public')));
app.engine('ejs', ejs.renderFile);

app.get('/', function (req, res) {
  let query = req.query;
  let code = query.code || '';
  if (code) {
    let payload = Object.assign({}, tokenPayload, { code });
    let opts = Object.assign({}, requestAccessTokenOptions, { body: payload});
    return request(opts, function (error, response, body) {
      if (!error && response.statusCode == 200) {
        githubApi.accessToken = body.access_token;
      }
      res.render('index.ejs', githubApi);
    });
  }
  res.render('index.ejs', githubApi);
});

let port = process.env.PORT || 5000;
app.listen(port, function () {
  console.log(`OctoShelf, http://localhost:${port}/`);
});<|endoftext|>


<commit_before>// Generated by CoffeeScript 2.4.1
// Mixin definition
var indexOf = [].indexOf;
export default {
  // Public interface
  props: {
    // Add listeners and check if in viewport immediately
    inViewportActive: {
      type: Boolean,
      default: true
    },
    // Only update once by default. The assumption is that it will be used for
    // one-time buildins
    inViewportOnce: {
      type: Boolean,
      default: false
    },
    // The IntersectionObserver root margin adds offsets to when the now and
    // fully get updated
    inViewportRootMargin: {
      type: Number | String,
      default: void 0
    },
    // Specify the IntersectionObserver root to use.
    inViewportRoot: {
      type: String | Function | Object,
      default: void 0
    },
    // The IntersectionObserver threshold defines the intersection ratios that
    // fire the observer callback
    inViewportThreshold: {
      type: Number | Array,
      default: function () {
        return [0, 1 // Fire on enter/leave and fully enter/leave
        ];
      }
    }
  },
  // Bindings that are used by the host component
  data: function () {
    return {
      inViewport: {
        // Public props
        now: null,
        // Is in viewport
        fully: null,
        // Is fully in viewport
        above: null,
        // Is partially or fully above the viewport
        below: null,
        // Is partially or fully below the viewport
        // Internal props
        listening: false,
        maxThreshold: 1
      }
    };
  },
  // Lifecycle hooks
  mounted: function () {
    return this.$nextTick(this.inViewportInit);
  },
  destroyed: function () {
    return this.removeInViewportHandlers();
  },
  computed: {
    // Add the maxThreshold to the @inViewportThreshold prop so that the handler
    // is fired for elements that are talled than the viewport
    inViewportThresholdWithMax: function () {
      var ref, threshold; // Support number and array thresholds

      threshold = typeof this.inViewportThreshold === 'object' ? this.inViewportThreshold : [this.inViewportThreshold]; // Add only if not already in the threshold list

      if (ref = this.inViewport.maxThreshold, indexOf.call(threshold, ref) >= 0) {
        return threshold;
      } else {
        return threshold.concat(this.inViewport.maxThreshold);
      }
    }
  },
  // Watch props and data
  watch: {
    // Add or remove event handlers handlers
    inViewportActive: function (active) {
      if (active) {
        return this.addInViewportHandlers();
      } else {
        return this.removeInViewportHandlers();
      }
    },
    // If any of the Observer options change, re-init
    inViewportRootMargin: function () {
      return this.reInitInViewportMixin();
    },
    inViewportRoot: function () {
      return this.reInitInViewportMixin();
    },
    inViewportThresholdWithMax: function () {
      return this.reInitInViewportMixin();
    }
  },
  // Public API
  methods: {
    // Re-init
    reInitInViewportMixin: function () {
      this.removeInViewportHandlers();
      return this.inViewportInit();
    },
    // Instantiate
    inViewportInit: function () {
      if (this.inViewportActive) {
        return this.addInViewportHandlers();
      }
    },
    // Add listeners
    addInViewportHandlers: function () {
      // Don't add twice
      if (this.inViewport.listening) {
        return;
      }

      this.inViewport.listening = true; // Create IntersectionObserver instance

      this.inViewportObserver = new IntersectionObserver(this.updateInViewport, {
        root: function () {
          switch (typeof this.inViewportRoot) {
            case 'function':
              return this.inViewportRoot();

            case 'string':
              return document.querySelector(this.inViewportRoot);

            case 'object':
              return this.inViewportRoot;
            // Expects to be a DOMElement

            default:
              return void 0;
          }
        }.call(this),
        rootMargin: this.inViewportRootMargin,
        threshold: this.inViewportThresholdWithMax
      }); // Start listening

      return this.inViewportObserver.observe(this.$el);
    },
    // Remove listeners
    removeInViewportHandlers: function () {
      var ref; // Don't remove twice

      if (!this.inViewport.listening) {
        return;
      }

      this.inViewport.listening = false; // Destroy instance, which also removes listeners

      if ((ref = this.inViewportObserver) != null) {
        ref.disconnect();
      }

      return delete this.inViewportObserver;
    },
    // Handle state changes from scrollMonitor.  There should only ever be one
    // entry
    updateInViewport: function ([entry]) {
      // Get the maximum threshold ratio, which is less than 1 when the
      // element is taller than the viewport
      this.inViewport.maxThreshold = Math.min(1, entry.rootBounds.height / entry.boundingClientRect.height); // Update state values. It was necessary to include "or equal to" here
      // because the threshold trigger fires when the sites may equal each other.
      // Without this, the appeared stuck when the two tops (for instance) were
      // exactly equal.

      this.inViewport.now = entry.isIntersecting;
      this.inViewport.fully = entry.intersectionRatio >= this.inViewport.maxThreshold;
      this.inViewport.above = entry.boundingClientRect.top <= entry.rootBounds.top;
      this.inViewport.below = entry.boundingClientRect.bottom >= entry.rootBounds.bottom;

      if (this.inViewportOnce && this.inViewport.now) {
        // If set to update "once", remove listeners if in viewport
        return this.removeInViewportHandlers();
      }
    }
  }
};<commit_msg>New build<commit_after>"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

// Generated by CoffeeScript 2.4.1
// Mixin definition
var indexOf = [].indexOf;
var _default2 = {
  // Public interface
  props: {
    // Add listeners and check if in viewport immediately
    inViewportActive: {
      type: Boolean,
      default: true
    },
    // Only update once by default. The assumption is that it will be used for
    // one-time buildins
    inViewportOnce: {
      type: Boolean,
      default: false
    },
    // The IntersectionObserver root margin adds offsets to when the now and
    // fully get updated
    inViewportRootMargin: {
      type: Number | String,
      default: void 0
    },
    // Specify the IntersectionObserver root to use.
    inViewportRoot: {
      type: String | Function | Object,
      default: void 0
    },
    // The IntersectionObserver threshold defines the intersection ratios that
    // fire the observer callback
    inViewportThreshold: {
      type: Number | Array,
      default: function _default() {
        return [0, 1 // Fire on enter/leave and fully enter/leave
        ];
      }
    }
  },
  // Bindings that are used by the host component
  data: function data() {
    return {
      inViewport: {
        // Public props
        now: null,
        // Is in viewport
        fully: null,
        // Is fully in viewport
        above: null,
        // Is partially or fully above the viewport
        below: null,
        // Is partially or fully below the viewport
        // Internal props
        listening: false,
        maxThreshold: 1
      }
    };
  },
  // Lifecycle hooks
  mounted: function mounted() {
    return this.$nextTick(this.inViewportInit);
  },
  destroyed: function destroyed() {
    return this.removeInViewportHandlers();
  },
  computed: {
    // Add the maxThreshold to the @inViewportThreshold prop so that the handler
    // is fired for elements that are talled than the viewport
    inViewportThresholdWithMax: function inViewportThresholdWithMax() {
      var ref, threshold; // Support number and array thresholds

      threshold = _typeof(this.inViewportThreshold) === 'object' ? this.inViewportThreshold : [this.inViewportThreshold]; // Add only if not already in the threshold list

      if (ref = this.inViewport.maxThreshold, indexOf.call(threshold, ref) >= 0) {
        return threshold;
      } else {
        return threshold.concat(this.inViewport.maxThreshold);
      }
    }
  },
  // Watch props and data
  watch: {
    // Add or remove event handlers handlers
    inViewportActive: function inViewportActive(active) {
      if (active) {
        return this.addInViewportHandlers();
      } else {
        return this.removeInViewportHandlers();
      }
    },
    // If any of the Observer options change, re-init.
    inViewportRootMargin: function inViewportRootMargin() {
      return this.reInitInViewportMixin();
    },
    inViewportRoot: function inViewportRoot() {
      return this.reInitInViewportMixin();
    },
    inViewportThresholdWithMax: function inViewportThresholdWithMax(now, old) {
      if (now.toString() !== old.toString()) {
        // In IE, this is kept getting retriggered, to doing a manual comparison
        // of old and new before deciding whether to take action.
        return this.reInitInViewportMixin();
      }
    }
  },
  // Public API
  methods: {
    // Re-init
    reInitInViewportMixin: function reInitInViewportMixin() {
      this.removeInViewportHandlers();
      return this.inViewportInit();
    },
    // Instantiate
    inViewportInit: function inViewportInit() {
      if (this.inViewportActive) {
        return this.addInViewportHandlers();
      }
    },
    // Add listeners
    addInViewportHandlers: function addInViewportHandlers() {
      // Don't add twice
      if (this.inViewport.listening) {
        return;
      }

      this.inViewport.listening = true; // Create IntersectionObserver instance

      this.inViewportObserver = new IntersectionObserver(this.updateInViewport, {
        root: function () {
          switch (_typeof(this.inViewportRoot)) {
            case 'function':
              return this.inViewportRoot();

            case 'string':
              return document.querySelector(this.inViewportRoot);

            case 'object':
              return this.inViewportRoot;
            // Expects to be a DOMElement

            default:
              return void 0;
          }
        }.call(this),
        rootMargin: this.inViewportRootMargin,
        threshold: this.inViewportThresholdWithMax
      }); // Start listening

      return this.inViewportObserver.observe(this.$el);
    },
    // Remove listeners
    removeInViewportHandlers: function removeInViewportHandlers() {
      var ref; // Don't remove twice

      if (!this.inViewport.listening) {
        return;
      }

      this.inViewport.listening = false; // Destroy instance, which also removes listeners

      if ((ref = this.inViewportObserver) != null) {
        ref.disconnect();
      }

      return delete this.inViewportObserver;
    },
    // Handle state changes from scrollMonitor.  There should only ever be one
    // entry
    updateInViewport: function updateInViewport(_ref) {
      var _ref2 = _slicedToArray(_ref, 1),
          entry = _ref2[0];

      // Get the maximum threshold ratio, which is less than 1 when the
      // element is taller than the viewport
      this.inViewport.maxThreshold = Math.min(1, entry.rootBounds.height / entry.boundingClientRect.height); // Update state values. It was necessary to include "or equal to" here
      // because the threshold trigger fires when the sites may equal each other.
      // Without this, the appeared stuck when the two tops (for instance) were
      // exactly equal.

      this.inViewport.now = entry.isIntersecting;
      this.inViewport.fully = entry.intersectionRatio >= this.inViewport.maxThreshold;
      this.inViewport.above = entry.boundingClientRect.top <= entry.rootBounds.top;
      this.inViewport.below = entry.boundingClientRect.bottom >= entry.rootBounds.bottom;

      if (this.inViewportOnce && this.inViewport.now) {
        // If set to update "once", remove listeners if in viewport
        return this.removeInViewportHandlers();
      }
    }
  }
};
exports.default = _default2;<|endoftext|>


<commit_before>var Gesso = require('gesso');
var helpers = require('./helpers');

var game = new Gesso();
var gravity = 0.3;
var seaLevel = 80;
var player = null;
var rocks = [];
var frameCount = 0;
var highScore = 0;
var highScoreTime = 0;
var highScoreMaxTime = 60;
var particles = [];
var endGameParticleCount = 100;
var bottomLeeway = 60;
var bubbles = [];

function newGame() {
  player = {
    playing: false,
    x: 100,
    y: 200,
    sy: 1,
    velocity: -10,
    jumpVelocity: 8,
    terminalVelocity: 7,
    score: 0
  };
}

function endGame() {
  if (!player) {
    return;
  }

  // Set the new high score, animating it, if the record was broken
  if (player.score > highScore) {
    highScore = player.score;
    highScoreTime = highScoreMaxTime;
  }

  // Explode
  for (var index = 0; index < endGameParticleCount; index++) {
    var angle = helpers.randInt(0, 360);
    var velocity = helpers.randInt(10, 20);
    particles.push({
      x: player.x,
      y: player.y,
      vx: Math.cos(angle * Math.PI / 180) * velocity - 6,
      vy: Math.sin(angle * Math.PI / 180) * velocity
    });
  }

  // Set to not playing
  player = null;
}

function newBubble(probability) {
  if (player && helpers.randInt(1, probability) === 1) {
    bubbles.push({x: player.x, y: player.y, r: helpers.randInt(2, 4)});
  }
}

Gesso.getCanvas().addEventListener('mousedown', function (e) {
  e.preventDefault();

  // Create new player, if not currently playing
  if (!player) {
    newGame();
    return false;
  }

  // Swim / jump
  if (player.y > seaLevel) {
    player.velocity = -player.jumpVelocity;
    player.sy = 1.6;
    newBubble(10);
  }

  return false;
});

game.update(function () {
  frameCount += 1;

  // Update rocks
  for (var r = 0; r < rocks.length; r++) {
    rocks[r].x -= 5;
    // Delete rock when out of bounds
    if (rocks[r].x + rocks[r].width < 0) {
      rocks.splice(r, 1);
      r--;
    }
  }

  // Create a new rock
  // TODO: Difficulty
  // TODO: Top / bottom pattern
  if (frameCount % 100 === 0) {
    rocks.push({
      x: game.width,
      y: helpers.randInt(50, game.height),
      width: helpers.randInt(100, 150),
      height: helpers.randInt(200, 300)
    });
  }

  // Update bubbles
  for (var b = 0; b < bubbles.length; b++) {
    bubbles[b].x -= 3;
    if (helpers.randInt(1, 3) === 1) {
      bubbles[b].x -= 1;
    }
    if (helpers.randInt(1, 5)) {
      bubbles[b].y += helpers.randInt(-3, 1);
    }
    // Delete bubble when out of bounds
    if (bubbles[b].x + bubbles[b].r < 0 || bubbles[b].y <= seaLevel) {
      bubbles.splice(b, 1);
      b--;
    }
  }
  // Randomly add a new bubble
  if (player) {
    newBubble(100);
  }
  // Check for rock / bubble collisions
  for (r = 0; r < rocks.length; r++) {
    for (b = 0; b < bubbles.length; b++) {
      if (helpers.intersected({x: bubbles[b].x, y: bubbles[b].y, width: bubbles[b].r, height: bubbles[b].r}, rocks[r])) {
        bubbles.splice(b, 1);
        b--;
      }
    }
  }

  // Update particles
  for (var p = 0; p < particles.length; p++) {
    particles[p].x -= particles[p].vx;
    particles[p].y -= particles[p].vy;
    // Delete particle when out of bounds
    if (particles[p].x + 3 < 0 || particles[p].y + 3 < 0 ||
        particles[p].x - 3 > game.width || particles[p].y - 3 > game.height + bottomLeeway) {
      particles.splice(p, 1);
      p--;
    }
  }

  if (highScoreTime > 0) {
    highScoreTime -= 1;
  }

  // Skip player logic if not currently playing
  if (!player) {
    return;
  }

  // Check for collisions
  for (r = 0; r < rocks.length; r++) {
    if (helpers.intersected({x: player.x, y: player.y, width: 20, height: 10}, rocks[r])) {
      endGame();
      return;
    }
  }

  // Update player
  if (frameCount % 6 === 0) {
    player.score += 100;
  }
  if (player.sy > 1) {
    player.sy -= 0.1;
  }
  if (player.best && player.score > player.best) {
    player.best = player.score;
  }
  player.velocity += gravity;
  if (player.velocity > player.terminalVelocity) {
    player.velocity = player.terminalVelocity;
  }
  player.y += player.velocity;
  if (player.y >= game.height + bottomLeeway) {
    endGame();
    return;
  }
});

game.render(function (ctx) {
  // Draw background
  ctx.fillStyle = '#ece';
  ctx.fillRect(0, 0, game.width, game.height);

  // Draw sky
  var grd = ctx.createLinearGradient(game.width / 2, 0.000, game.width / 2, seaLevel);
  grd.addColorStop(0.000, '#80befc');
  grd.addColorStop(1.000, '#cbcfed');
  ctx.fillStyle = grd;
  ctx.fillRect(0, 0, game.width, seaLevel);

  // Draw water
  grd = ctx.createLinearGradient(game.width / 2, seaLevel, game.width / 2, game.height - seaLevel);
  grd.addColorStop(0.000, '#7EBDFC');
  grd.addColorStop(0.100, '#007fff');
  grd.addColorStop(1.000, '#003f7f');
  ctx.fillStyle = grd;
  ctx.fillRect(0, seaLevel, game.width, game.height - seaLevel);

  // Water lighting (note: coordinates are off, but the mistake looks better)
  grd = ctx.createLinearGradient(0, 0, game.width, game.height - seaLevel);
  grd.addColorStop(0.000, 'rgba(0, 127, 255, 0.200)');
  grd.addColorStop(0.100, 'rgba(255, 255, 255, 0.200)');
  grd.addColorStop(0.200, 'rgba(0, 127, 255, 0.200)');
  grd.addColorStop(0.500, 'rgba(255, 255, 255, 0.200)');
  grd.addColorStop(0.600, 'rgba(0, 127, 255, 0.200)');
  grd.addColorStop(0.800, 'rgba(255, 255, 255, 0.200)');
  grd.addColorStop(1.000, 'rgba(0, 127, 255, 0.200)');
  ctx.fillStyle = grd;
  ctx.fillRect(0, seaLevel, game.width, game.height - seaLevel);

  // Draw bubbles
  for (var b = 0; b < bubbles.length; b++) {
    helpers.fillCircle(ctx, bubbles[b].x, bubbles[b].y, bubbles[b].r, 'rgba(255, 255, 255, 0.8)');
  }

  // Draw rocks
  for (var r = 0; r < rocks.length; r++) {
    ctx.fillStyle = '#5d4';
    ctx.fillRect(rocks[r].x, rocks[r].y, rocks[r].width, rocks[r].height);
  }

  // Draw particles
  for (var p = 0; p < particles.length; p++) {
    helpers.fillCircle(ctx, particles[p].x, particles[p].y, 3, '#ff4');
  }

  // Draw score
  if (player || highScore) {
    ctx.font = 'bold 24px sans-serif';
    ctx.textAlign = 'right';
    helpers.outlineText(ctx, 'Score: ' + (player ? player.score : 0), game.width - 30, 32, '#333', '#fff');
  }
  if (highScore) {
    ctx.font = 'bold 24px sans-serif';
    helpers.outlineText(ctx, 'Best: ' + highScore, game.width - 30, 64, '#333', '#fff');
    if (highScoreTime > 0) {
      var offset = (highScoreTime) * 2;
      var fade = (highScoreTime / highScoreMaxTime * 2);
      ctx.font = 'bold ' + (24 + offset) + 'px sans-serif';
      ctx.fillStyle = 'rgba(255, 255, 255, ' + fade + ')';
      ctx.fillText('Best: ' + highScore, game.width - 30 + (offset * 0.25), 64 + (offset * 1.5));
    }
  }

  if (player) {
    // Draw player
    helpers.fillEllipse(ctx, player.x, player.y, 10, 2, player.sy, '#ff4');
    helpers.fillCircle(ctx, player.x + 5, player.y - 2, 3, '#330');
  }

  // Draw water depth gradient
  grd = ctx.createLinearGradient(game.width / 2, seaLevel, game.width / 2, game.height);
  grd.addColorStop(0.000, 'rgba(0, 127, 255, 0.100)');
  grd.addColorStop(0.700, 'rgba(0, 63, 127, 0.100)');
  grd.addColorStop(1.000, 'rgba(0, 63, 127, 0.500)');
  ctx.fillStyle = grd;
  ctx.fillRect(0, seaLevel, game.width, game.height - seaLevel);

  if (!player) {
    // Draw pre-game text
    if ((frameCount % 120 > 5 && frameCount % 120 < 20) || frameCount % 120 > 25) {
      ctx.font = 'bold 64px sans-serif';
      ctx.textAlign = 'center';
      if (highScore) {
        helpers.outlineText(ctx, 'Game over!', (game.width / 2), (game.height / 2) - 30, '#333', '#fff');
        helpers.outlineText(ctx, 'Click again!', (game.width / 2), (game.height / 2) + 40, '#333', '#fff');
      } else {
        helpers.outlineText(ctx, 'Click to start!', (game.width / 2), (game.height / 2), '#333', '#fff');
      }
    }
  }
});

// TODO: Delete this
game.run();

// TODO: Get the runtime to expose this object through a gesso.current global
module.exports = game;
<commit_msg>Add splash effect.<commit_after>var Gesso = require('gesso');
var helpers = require('./helpers');

var game = new Gesso();
var gravity = 0.3;
var seaLevel = 80;
var player = null;
var rocks = [];
var frameCount = 0;
var highScore = 0;
var highScoreTime = 0;
var highScoreMaxTime = 60;
var particles = [];
var endGameParticleCount = 100;
var bottomLeeway = 60;
var bubbles = [];
var splash = [];

function newGame() {
  player = {
    playing: false,
    x: 100,
    y: 200,
    sy: 1,
    velocity: -10,
    jumpVelocity: 8,
    terminalVelocity: 7,
    score: 0
  };
}

function endGame() {
  if (!player) {
    return;
  }

  // Set the new high score, animating it, if the record was broken
  if (player.score > highScore) {
    highScore = player.score;
    highScoreTime = highScoreMaxTime;
  }

  // Explode
  for (var index = 0; index < endGameParticleCount; index++) {
    var angle = helpers.randInt(0, 360);
    var velocity = helpers.randInt(10, 20);
    particles.push({
      x: player.x,
      y: player.y,
      vx: Math.cos(angle * Math.PI / 180) * velocity - 6,
      vy: Math.sin(angle * Math.PI / 180) * velocity
    });
  }

  // Set to not playing
  player = null;
}

function newSplash() {
  for (var s = 0; s < 20; s++) {
    var ax = Math.random() * 4 - 3;
    var ay = -(Math.random() * 2 + 1);
    splash.push({x: player.x + ax, y: seaLevel, vx: ax, vy: ay, r: helpers.randInt(1, 2)});
  }
}

function newBubble(probability) {
  if (player && helpers.randInt(1, probability) === 1) {
    bubbles.push({x: player.x, y: player.y, r: helpers.randInt(2, 4)});
  }
}

Gesso.getCanvas().addEventListener('mousedown', function (e) {
  e.preventDefault();

  // Create new player, if not currently playing
  if (!player) {
    newGame();
    return false;
  }

  // Swim / jump
  if (player.y > seaLevel) {
    player.velocity = -player.jumpVelocity;
    player.sy = 1.6;
    newBubble(10);
  }

  return false;
});

game.update(function () {
  frameCount += 1;

  // Update rocks
  for (var r = 0; r < rocks.length; r++) {
    rocks[r].x -= 5;
    // Delete rock when out of bounds
    if (rocks[r].x + rocks[r].width < 0) {
      rocks.splice(r, 1);
      r--;
    }
  }

  // Create a new rock
  // TODO: Difficulty
  // TODO: Top / bottom pattern
  if (frameCount % 100 === 0) {
    rocks.push({
      x: game.width,
      y: helpers.randInt(50, game.height),
      width: helpers.randInt(100, 150),
      height: helpers.randInt(200, 300)
    });
  }

  // Update bubbles
  for (var b = 0; b < bubbles.length; b++) {
    bubbles[b].x -= 3;
    if (helpers.randInt(1, 3) === 1) {
      bubbles[b].x -= 1;
    }
    if (helpers.randInt(1, 5)) {
      bubbles[b].y += helpers.randInt(-3, 1);
    }
    // Delete bubble when out of bounds
    if (bubbles[b].x + bubbles[b].r < 0 || bubbles[b].y <= seaLevel) {
      bubbles.splice(b, 1);
      b--;
    }
  }
  // Randomly add a new bubble
  if (player) {
    newBubble(100);
  }
  // Check for rock / bubble collisions
  for (r = 0; r < rocks.length; r++) {
    for (b = 0; b < bubbles.length; b++) {
      if (helpers.intersected({x: bubbles[b].x, y: bubbles[b].y, width: bubbles[b].r, height: bubbles[b].r}, rocks[r])) {
        bubbles.splice(b, 1);
        b--;
      }
    }
  }

  // Update splash
  for (var s = 0; s < splash.length; s++) {
    splash[s].x += splash[s].vx;
    splash[s].y += splash[s].vy;
    splash[s].vy += gravity;
    // Delete splash
    if (splash[s].y > seaLevel) {
      splash.splice(s, 1);
      s--;
    }
  }

  // Update particles
  for (var p = 0; p < particles.length; p++) {
    particles[p].x -= particles[p].vx;
    particles[p].y -= particles[p].vy;
    // Delete particle when out of bounds
    if (particles[p].x + 3 < 0 || particles[p].y + 3 < 0 ||
        particles[p].x - 3 > game.width || particles[p].y - 3 > game.height + bottomLeeway) {
      particles.splice(p, 1);
      p--;
    }
  }

  if (highScoreTime > 0) {
    highScoreTime -= 1;
  }

  // Skip player logic if not currently playing
  if (!player) {
    return;
  }

  // Check for collisions
  for (r = 0; r < rocks.length; r++) {
    if (helpers.intersected({x: player.x, y: player.y, width: 20, height: 10}, rocks[r])) {
      endGame();
      return;
    }
  }

  // Update player
  if (frameCount % 6 === 0) {
    player.score += 100;
  }
  if (player.sy > 1) {
    player.sy -= 0.1;
  }
  if (player.best && player.score > player.best) {
    player.best = player.score;
  }
  player.velocity += gravity;
  if (player.velocity > player.terminalVelocity) {
    player.velocity = player.terminalVelocity;
  }
  player.y += player.velocity;
  if (player.y >= game.height + bottomLeeway) {
    endGame();
    return;
  }
  if ((player.y - player.velocity >= seaLevel && player.y < seaLevel) ||
      (player.y - player.velocity <= seaLevel && player.y > seaLevel)) {
    newSplash();
  }
});

game.render(function (ctx) {
  // Draw background
  ctx.fillStyle = '#ece';
  ctx.fillRect(0, 0, game.width, game.height);

  // Draw sky
  var grd = ctx.createLinearGradient(game.width / 2, 0.000, game.width / 2, seaLevel);
  grd.addColorStop(0.000, '#80befc');
  grd.addColorStop(1.000, '#cbcfed');
  ctx.fillStyle = grd;
  ctx.fillRect(0, 0, game.width, seaLevel);

  // Draw water
  grd = ctx.createLinearGradient(game.width / 2, seaLevel, game.width / 2, game.height - seaLevel);
  grd.addColorStop(0.000, '#7EBDFC');
  grd.addColorStop(0.100, '#007fff');
  grd.addColorStop(1.000, '#003f7f');
  ctx.fillStyle = grd;
  ctx.fillRect(0, seaLevel, game.width, game.height - seaLevel);

  // Water lighting (note: coordinates are off, but the mistake looks better)
  grd = ctx.createLinearGradient(0, 0, game.width, game.height - seaLevel);
  grd.addColorStop(0.000, 'rgba(0, 127, 255, 0.200)');
  grd.addColorStop(0.100, 'rgba(255, 255, 255, 0.200)');
  grd.addColorStop(0.200, 'rgba(0, 127, 255, 0.200)');
  grd.addColorStop(0.500, 'rgba(255, 255, 255, 0.200)');
  grd.addColorStop(0.600, 'rgba(0, 127, 255, 0.200)');
  grd.addColorStop(0.800, 'rgba(255, 255, 255, 0.200)');
  grd.addColorStop(1.000, 'rgba(0, 127, 255, 0.200)');
  ctx.fillStyle = grd;
  ctx.fillRect(0, seaLevel, game.width, game.height - seaLevel);

  // Draw splash
  for (var s = 0; s < splash.length; s++) {
    helpers.fillCircle(ctx, splash[s].x, splash[s].y, splash[s].r, '#7EBDFC');
  }

  // Draw bubbles
  for (var b = 0; b < bubbles.length; b++) {
    helpers.fillCircle(ctx, bubbles[b].x, bubbles[b].y, bubbles[b].r, 'rgba(255, 255, 255, 0.8)');
  }

  // Draw rocks
  for (var r = 0; r < rocks.length; r++) {
    ctx.fillStyle = '#5d4';
    ctx.fillRect(rocks[r].x, rocks[r].y, rocks[r].width, rocks[r].height);
  }

  // Draw particles
  for (var p = 0; p < particles.length; p++) {
    helpers.fillCircle(ctx, particles[p].x, particles[p].y, 3, '#ff4');
  }

  // Draw score
  if (player || highScore) {
    ctx.font = 'bold 24px sans-serif';
    ctx.textAlign = 'right';
    helpers.outlineText(ctx, 'Score: ' + (player ? player.score : 0), game.width - 30, 32, '#333', '#fff');
  }
  if (highScore) {
    ctx.font = 'bold 24px sans-serif';
    helpers.outlineText(ctx, 'Best: ' + highScore, game.width - 30, 64, '#333', '#fff');
    if (highScoreTime > 0) {
      var offset = (highScoreTime) * 2;
      var fade = (highScoreTime / highScoreMaxTime * 2);
      ctx.font = 'bold ' + (24 + offset) + 'px sans-serif';
      ctx.fillStyle = 'rgba(255, 255, 255, ' + fade + ')';
      ctx.fillText('Best: ' + highScore, game.width - 30 + (offset * 0.25), 64 + (offset * 1.5));
    }
  }

  if (player) {
    // Draw player
    helpers.fillEllipse(ctx, player.x, player.y, 10, 2, player.sy, '#ff4');
    helpers.fillCircle(ctx, player.x + 5, player.y - 2, 3, '#330');
  }

  // Draw water depth gradient
  grd = ctx.createLinearGradient(game.width / 2, seaLevel, game.width / 2, game.height);
  grd.addColorStop(0.000, 'rgba(0, 127, 255, 0.100)');
  grd.addColorStop(0.700, 'rgba(0, 63, 127, 0.100)');
  grd.addColorStop(1.000, 'rgba(0, 63, 127, 0.500)');
  ctx.fillStyle = grd;
  ctx.fillRect(0, seaLevel, game.width, game.height - seaLevel);

  if (!player) {
    // Draw pre-game text
    if ((frameCount % 120 > 5 && frameCount % 120 < 20) || frameCount % 120 > 25) {
      ctx.font = 'bold 64px sans-serif';
      ctx.textAlign = 'center';
      if (highScore) {
        helpers.outlineText(ctx, 'Game over!', (game.width / 2), (game.height / 2) - 30, '#333', '#fff');
        helpers.outlineText(ctx, 'Click again!', (game.width / 2), (game.height / 2) + 40, '#333', '#fff');
      } else {
        helpers.outlineText(ctx, 'Click to start!', (game.width / 2), (game.height / 2), '#333', '#fff');
      }
    }
  }
});

// TODO: Delete this
game.run();

// TODO: Get the runtime to expose this object through a gesso.current global
module.exports = game;
<|endoftext|>


<commit_before>var es = require('event-stream');
var rs = require('replacestream');
var stream = require('stream');

module.exports = function(search, replacement) {
  var doReplace = function(file, callback) {
    var isRegExp = search instanceof RegExp;
    var isStream = file.contents instanceof stream.Readable;
    var isBuffer = file.contents instanceof Buffer;

    if (isRegExp && isStream) {
      return callback(new Error('gulp-replace: Cannot do regexp replace on a stream'), file);
    }

    if (!isRegExp && typeof replacement === 'function') {
      return callback(new Error('gulp-replace: Cannot do string replace with a function as replacement value'), file);
    }

    if (isStream) {
      file.contents = file.contents.pipe(rs(search, replacement));
      callback(null, file);
    }
    else if (isBuffer) {
      if (isRegExp) {
        file.contents = new Buffer(String(file.contents).replace(search, replacement));
      }
      else {
        file.contents = new Buffer(String(file.contents).split(search).join(replacement));
      }
      callback(null, file);
    }
    else {
      callback(null, file);
    }
  };

  return es.map(doReplace);
};
<commit_msg>Use ducktyping to detect streams, return early instead of else<commit_after>var es = require('event-stream');
var rs = require('replacestream');
var stream = require('stream');

module.exports = function(search, replacement) {
  var doReplace = function(file, callback) {
    var isRegExp = search instanceof RegExp;
    var isStream = file.contents && typeof file.contents.on === 'function' && typeof file.contents.pipe === 'function';
    var isBuffer = file.contents instanceof Buffer;

    if (isRegExp && isStream) {
      return callback(new Error('gulp-replace: Cannot do regexp replace on a stream'), file);
    }

    if (!isRegExp && typeof replacement === 'function') {
      return callback(new Error('gulp-replace: Cannot do string replace with a function as replacement value'), file);
    }

    if (isStream) {
      file.contents = file.contents.pipe(rs(search, replacement));
      return callback(null, file);
    }

    if (isBuffer) {
      if (isRegExp) {
        file.contents = new Buffer(String(file.contents).replace(search, replacement));
      }
      else {
        file.contents = new Buffer(String(file.contents).split(search).join(replacement));
      }
      return callback(null, file);
    }

    callback(null, file);
  };

  return es.map(doReplace);
};
<|endoftext|>


<commit_before>'use strict';

require('@babel/register');
require('@babel/polyfill');
const express = require('express');
const path = require('path');
const app = express();

if (process.env.NODE_ENV === 'production') {
  app.use(express.static(path.resolve(__dirname, 'build')));
  app.get('*', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
  });
  require('greenlock-express')
    .create({
      version: 'draft-12',
      configDir: '~/.config/acme',
      server: 'https://acme-v02.api.letsencrypt.org/directory',
      approveDomains: function approveDomains(opts, certs, cb) {
        if (certs) {
          opts.domains = certs.altnames;
        } else {
          opts.email = 'mikey1384@gmail.com';
          opts.agreeTos = true;
        }

        cb(null, { options: opts, certs });
      },
      app: app
    })
    .listen(80, 443);
} else {
  const server = require('./webpack/webpack.dev').default(app);
  server.use(express.static(path.resolve(__dirname, './public')));
  const http = require('http');
  const DEV_PORT = process.env.PORT;

  http.createServer(server).listen(DEV_PORT, function() {
    console.log('Server listening on port:', DEV_PORT);
  });
}
<commit_msg>minor fix<commit_after>'use strict';

require('@babel/register');
require('@babel/polyfill');
const express = require('express');
const path = require('path');
const app = express();

if (process.env.NODE_ENV !== 'development') {
  app.use(express.static(path.resolve(__dirname, 'build')));
  app.get('*', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
  });
  require('greenlock-express')
    .create({
      version: 'draft-12',
      configDir: '~/.config/acme',
      server: 'https://acme-v02.api.letsencrypt.org/directory',
      approveDomains: function approveDomains(opts, certs, cb) {
        if (certs) {
          opts.domains = certs.altnames;
        } else {
          opts.email = 'mikey1384@gmail.com';
          opts.agreeTos = true;
        }

        cb(null, { options: opts, certs });
      },
      app: app
    })
    .listen(80, 443);
} else {
  const server = require('./webpack/webpack.dev').default(app);
  server.use(express.static(path.resolve(__dirname, './public')));
  const http = require('http');
  const DEV_PORT = process.env.PORT;

  http.createServer(server).listen(DEV_PORT, function() {
    console.log('Server listening on port:', DEV_PORT);
  });
}
<|endoftext|>


<commit_before>var util = require('derby/node_modules/racer/lib/util');
var defaultFns = require('derby/node_modules/racer/lib/Model/defaultFns');

// Before 1.0
// TODO: Add to proper repo with proper README and so forth
// TODO: Review current way of including/requiring racer files (above)
// TODO: Review for memory leaks / proper cleanup (still pretty sure this is not fully complete)
// TODO: Review for server vs client use; compared with filter for how each view (and query?) can be processed server-side and sent along and revived client side (still pretty sure this is also not fully complete)
// TODO: Review for ensuring data is kept up to date properly (on all kinds of changes) and that all events are properly propagated (and so forth) - including for queries
// TODO: Review current limitation of only being able to use named functions
// TODO: Throw errors where appropriate (it's severely lacking atm and a lot of use-errors will just cause random JS errors)
// TODO: Properly comment everyting, in particular the public-facing methods should be properly commented
// TODO: Ensure consistency with README / the docs. Read through and check what else needs to be changed.
// Post 1.0
// TODO: Check/test performance
// TODO: Implement subscribe/fetch
// TODO: Review if this should'nt be broken into several files
// TODO: Review the naming of "query" - it is in conflict with creating queries
// TODO: Write tests
// TODO: Long-term - think about if it's possible to hook in this to happen server-side constantly for specific apps (efficiently creating a cached version of the emitted data/refs/paths)
module.exports = function(racer) {
  var Model = racer.Model;

  Model.INITS.push(function(model) {
    model.root._views = new Views(model);
    model.on('all', viewListener);
    function viewListener(segments, eventArgs) {
      var pass = eventArgs[eventArgs.length - 1];
      var map = model.root._views.fromMap;
      for (var path in map) {
        var view = map[path];
        if (pass.$view === view) continue;
        if (util.mayImpact(view.segments, segments)) {
          var type = eventArgs.shift();

          function add(view, id, value) {
            var emit = getEmit(view, id);
            view.viewFn(emit, value, id);
          }

          function del(view, id) {
            view._delete(id);
          }

          var subSegments = segments.slice(view.segments.length);

          var id  = subSegments.shift();
          var value = eventArgs.shift();
          var previous = eventArgs.shift();

          if(type === 'change') {
            // TODO: FIXME
            if(!subSegments.length) {
              if(subSegments.length || (typeof value !== undefined && typeof previous !== undefined)) {
                // Change (= delete + add)
                del(view, id);
                add(view, id, value);
              } else if(value === undefined) {
                del(view, id);
              } else {
                add(view, id, value);
              }
            }
          } else if(type === 'load') {
            add(view, id, value);
          } else if(type === 'unload') {
            del(view, id);
          }
        }
      }
    }
  });

  Model.prototype.view = function() {
    var args = Array.prototype.slice.call(arguments);
    var fn = args.pop();
    var path = this.path(args.shift());
    return this.root._views.add(path, fn);
  };

  // Hook into filters's functionality for removing filters to also remove views
  // Save the original filter fn
  Model.prototype.___removeAllFilters = Model.prototype._removeAllFilters;

  // Create a new one which calls the fn both for filters and views
  Model.prototype._removeAllFilters = function () {
    this.___removeAllFilters.call(this, arguments);
    this._removeAllViews.call(this, arguments);
  };

  // Redo it for the non-internal fn
  Model.prototype.__removeAllFilters = Model.prototype.removeAllFilters;

  Model.prototype.removeAllFilters = function () {
    this.__removeAllFilters.call(this, arguments);
    this.removeAllViews.call(this, arguments);
  };

  // Back to the view specific code
  Model.prototype.removeAllViews = function(subpath) {
    var segments = this._splitPath(subpath);
    this._removeAllViews(segments);
  };
  Model.prototype._removeAllViews = function(segments) {
    var views = this.root._views.fromMap;
    for (var from in views) {
      if (util.contains(segments, views[from].fromSegments)) {
        views[from].destroy();
      }
    }
  };
}

function FromMap() {}
function Views(model) {
  this.model = model;
  this.fromMap = new FromMap();
}

Views.prototype.add = function(path, viewFn) {
  return new View(this, path, viewFn);
};

Views.prototype.toJSON = function() {
  var out = [];
  for (var from in this.fromMap) {
    var view = this.fromMap[from];
    // Don't try to bundle if functions were passed directly instead of by name
    if (!view.bundle) continue;
    var args = [from, view.path, view.viewName];
    out.push(args);
  }
  return out;
};

function View(views, path, viewName) {
  this.views = views;
  this.model = views.model.pass({$view: this});
  this.path = path;
  this.segments = path.split('.');
  this.viewName = viewName;
  this.bundle = true;
  this.viewFn = this.model.root._namedFns[this.viewName] || defaultFns[this.viewName];

  var segments = ['$views', this.viewName, path.replace(/\./g, '|')];
  // Parent path for all ids for all queries based upon this view
  this.querySegments = segments.slice(0);
  this.querySegments.splice(2, 0, 'queries');
  // Keeps the order of all keys
  this.keysSegments = segments.slice(0);
  this.keysSegments.splice(2, 0, 'keys');
  // Hashmap mapping keys to the value of each emitted path
  this.pathsSegments = segments.slice(0);
  this.pathsSegments.splice(2, 0, 'paths');
  // Keeps track of all keys related a specific id, on the structure of: {<id>: [<key1_of_id>, <key2_of_id>, ...], ...}
  this.idsSegments = segments.slice(0);
  this.idsSegments.splice(2, 0, 'ids');
  // Ensure paths and ids is a hash
  this.model.root._set(this.pathsSegments, {});
  this.model.root._set(this.idsSegments, {});

  this.initialized = false;
  this.from = null;
  this.fromSegments = null;
  this.fromMap = new FromMap();
}

View.prototype.get = function() {
  // Ensure initialized
  this._init();

  return this.model.root._get(this.pathsSegments);
};

View.prototype.ref = function(from) {
  // Ensure initialized
  this._init();

  from = this.model.path(from);
  this.from = from;
  this.fromSegments = from.split('.');

  // FIXME: This is not appropriate - the whole thing with the FromMap is over-used for our purposes
  this.views.fromMap[from] = this;
  return this.model.root.ref(from, this.pathsSegments.join('.'));
};

View.prototype.query = function (start, end) {
  // Ensure initialized
  this._init();

  return new Query(this.model, this, start, end);
};

// Duplicate naming for more Derby-aligned naming
View.prototype.refList = View.prototype.query;

function Query(model, view, start, end) {
  this.model = model;
  this.view = view;
  this.start = start;
  this.end = end;
  this.idsSegments = null;
  this.from = null;
  this.fromSegments = null;
}

Query.prototype.ref = function(from) {
  from = this.model.path(from);
  this.from = from;
  this.fromSegments = from.split('.');
  this.view.fromMap[from] = this;
  this.idsSegments = this.view.querySegments.concat(from.replace(/\./g, '|'));
  var path = this._getPath();
  this.update();
  return this.model.root.refList(from, path, this.idsSegments.join('.'));
};

Query.prototype._getPath = function() {
  var start = this.view._insertPosition(this.start);
  var end = this.view._insertPosition(this.end, {upperBound: true});

  if(end < start) throw new Error("Can't currently handle empty queries");

  var id = this.model._get(this.view.keysSegments.concat(start));
  var ref = this.model.root._refs.fromMap[this.view.pathsSegments.concat(id).join('.')];
  var segments = ref.toSegments.slice(0);
  segments.pop();

  return segments.join('.');
};

Query.prototype.ids = function () {
  var start = this.view._insertPosition(this.start);
  var end = this.view._insertPosition(this.end, {upperBound: true});
  var keys = this.model._get(this.view.keysSegments);
  var keys = keys.slice(start, end);
  var ids = keys.map(function (key) {
    return this.model._get(this.view.pathsSegments.concat(key)).id;
  }, this);

  return ids;
};

Query.prototype.update = function(pass) {
  var ids = this.ids();
  this.model.pass(pass, true)._setArrayDiff(this.idsSegments, ids);
};

// TODO: Implement
View.prototype.subscribe = function () {

};

// TODO: Implement
View.prototype.fetch = function () {

};

// TODO: Review this - including properly cleaning up all related queries
View.prototype.destroy = function() {
  delete this.views.fromMap[this.from];

  // this.model._removeRef(this.idsSegments);
  // this.model._del(this.idsSegments);

  if(!this.initialized) return;
  this.model._del(this.keysSegments);
  this.model._del(this.pathsSegments);
  this.model._del(this.idsSegments);
};

View.prototype._init = function () {
  // Only initialize once
  if(this.initialized) return;
  this.initialized = true;

  var data = this.model.root._get(this.segments);
  if(!data) return;

  var ids = Object.keys(data);

  for(var i = 0, len = ids.length; i < len; i++) {
    var id = ids[i];
    var obj = data[id];
    var emit = getEmit(this, id);

    this.viewFn(emit, obj, id);
  }
};

View.prototype._delete = function (id) {
  // TODO: Check if we need to go to root here - I dont think so
  var keys = this.model.root._get(this.idsSegments.concat(id))

  if(typeof keys !== 'undefined') {
    for(var i = 0, len = keys.length; i < len; i++) {
      var key = keys[i];
      var position = this._insertPosition(key);

      this.model.root._remove(this.keysSegments, position, 1);

      var refSegments = this.pathsSegments.concat(key);
      this.model.root._removeRef(refSegments, refSegments.join('.'));
    }
  }
  this.model._del(this.idsSegments.concat(id));
};

View.prototype._insert = function (key) {
  var position = this._insertPosition(key);
  this.model._insert(this.keysSegments, position, key);
};

View.prototype._insertPosition = function (key, options) {
  var keys = this.model.root._get(this.keysSegments);
  if(!keys) return 0;
  var len = keys.length;
  var lower = 0;
  var upper = len;
  var done = false;
  var pos;
  var options = options || {};

  while(!done) {
    pos = parseInt((upper + lower) / 2);

    if(pos === lower || pos === upper) {
      done = true;
      continue;
    }

    if(keys[pos] > key) {
      upper = pos;
    } else {
      lower = pos;
    }
  }

  if((pos == 0 && keys[pos] > key) || (!(options && options.upperBound) && keys[pos] === key)) pos--;

  return ++pos;
};

function getEmit(view, id) {
  return function ret(key, path) {
    view.model.root.ref(view.pathsSegments.concat(key).join('.'), path);
    view.model._push(view.idsSegments.concat(id), key);
    view._insert(key);
  }
}
<commit_msg>fix for change events<commit_after>var util = require('derby/node_modules/racer/lib/util');
var defaultFns = require('derby/node_modules/racer/lib/Model/defaultFns');

// Before 1.0
// TODO: Add to proper repo with proper README and so forth
// TODO: Review current way of including/requiring racer files (above)
// TODO: Review for memory leaks / proper cleanup (still pretty sure this is not fully complete)
// TODO: Review for server vs client use; compared with filter for how each view (and query?) can be processed server-side and sent along and revived client side (still pretty sure this is also not fully complete)
// TODO: Review for ensuring data is kept up to date properly (on all kinds of changes) and that all events are properly propagated (and so forth) - including for queries
// TODO: Review current limitation of only being able to use named functions
// TODO: Throw errors where appropriate (it's severely lacking atm and a lot of use-errors will just cause random JS errors)
// TODO: Properly comment everyting, in particular the public-facing methods should be properly commented
// TODO: Ensure consistency with README / the docs. Read through and check what else needs to be changed.
// Post 1.0
// TODO: Check/test performance
// TODO: Implement subscribe/fetch
// TODO: Review if this should'nt be broken into several files
// TODO: Review the naming of "query" - it is in conflict with creating queries
// TODO: Write tests
// TODO: Long-term - think about if it's possible to hook in this to happen server-side constantly for specific apps (efficiently creating a cached version of the emitted data/refs/paths)
module.exports = function(racer) {
  var Model = racer.Model;

  Model.INITS.push(function(model) {
    model.root._views = new Views(model);
    model.on('all', viewListener);
    function viewListener(segments, eventArgs) {
      var pass = eventArgs[eventArgs.length - 1];
      var map = model.root._views.fromMap;
      for (var path in map) {
        var view = map[path];
        if (pass.$view === view) continue;
        if (util.mayImpact(view.segments, segments)) {
          var type = eventArgs.shift();

          function add(view, id, value) {
            var emit = getEmit(view, id);
            view.viewFn(emit, value, id);
          }

          function del(view, id) {
            view._delete(id);
          }

          var subSegments = segments.slice(view.segments.length);

          var id  = subSegments.shift();
          var value = eventArgs.shift();
          var previous = eventArgs.shift();

          if(type === 'change') {
            // TODO: FIXME
            if(!subSegments.length) {
              if(subSegments.length || (typeof value !== 'undefined' && typeof previous !== 'undefined')) {
                // Change (= delete + add)
                del(view, id);
                add(view, id, value);
              } else if(value === undefined) {
                del(view, id);
              } else {
                add(view, id, value);
              }
            }
          } else if(type === 'load') {
            add(view, id, value);
          } else if(type === 'unload') {
            del(view, id);
          }
        }
      }
    }
  });

  Model.prototype.view = function() {
    var args = Array.prototype.slice.call(arguments);
    var fn = args.pop();
    var path = this.path(args.shift());
    return this.root._views.add(path, fn);
  };

  // Hook into filters's functionality for removing filters to also remove views
  // Save the original filter fn
  Model.prototype.___removeAllFilters = Model.prototype._removeAllFilters;

  // Create a new one which calls the fn both for filters and views
  Model.prototype._removeAllFilters = function () {
    this.___removeAllFilters.call(this, arguments);
    this._removeAllViews.call(this, arguments);
  };

  // Redo it for the non-internal fn
  Model.prototype.__removeAllFilters = Model.prototype.removeAllFilters;

  Model.prototype.removeAllFilters = function () {
    this.__removeAllFilters.call(this, arguments);
    this.removeAllViews.call(this, arguments);
  };

  // Back to the view specific code
  Model.prototype.removeAllViews = function(subpath) {
    var segments = this._splitPath(subpath);
    this._removeAllViews(segments);
  };
  Model.prototype._removeAllViews = function(segments) {
    var views = this.root._views.fromMap;
    for (var from in views) {
      if (util.contains(segments, views[from].fromSegments)) {
        views[from].destroy();
      }
    }
  };
}

function FromMap() {}
function Views(model) {
  this.model = model;
  this.fromMap = new FromMap();
}

Views.prototype.add = function(path, viewFn) {
  return new View(this, path, viewFn);
};

Views.prototype.toJSON = function() {
  var out = [];
  for (var from in this.fromMap) {
    var view = this.fromMap[from];
    // Don't try to bundle if functions were passed directly instead of by name
    if (!view.bundle) continue;
    var args = [from, view.path, view.viewName];
    out.push(args);
  }
  return out;
};

function View(views, path, viewName) {
  this.views = views;
  this.model = views.model.pass({$view: this});
  this.path = path;
  this.segments = path.split('.');
  this.viewName = viewName;
  this.bundle = true;
  this.viewFn = this.model.root._namedFns[this.viewName] || defaultFns[this.viewName];

  var segments = ['$views', this.viewName, path.replace(/\./g, '|')];
  // Parent path for all ids for all queries based upon this view
  this.querySegments = segments.slice(0);
  this.querySegments.splice(2, 0, 'queries');
  // Keeps the order of all keys
  this.keysSegments = segments.slice(0);
  this.keysSegments.splice(2, 0, 'keys');
  // Hashmap mapping keys to the value of each emitted path
  this.pathsSegments = segments.slice(0);
  this.pathsSegments.splice(2, 0, 'paths');
  // Keeps track of all keys related a specific id, on the structure of: {<id>: [<key1_of_id>, <key2_of_id>, ...], ...}
  this.idsSegments = segments.slice(0);
  this.idsSegments.splice(2, 0, 'ids');
  // Ensure paths and ids is a hash
  this.model.root._set(this.pathsSegments, {});
  this.model.root._set(this.idsSegments, {});

  this.initialized = false;
  this.from = null;
  this.fromSegments = null;
  this.fromMap = new FromMap();
}

View.prototype.get = function() {
  // Ensure initialized
  this._init();

  return this.model.root._get(this.pathsSegments);
};

View.prototype.ref = function(from) {
  // Ensure initialized
  this._init();

  from = this.model.path(from);
  this.from = from;
  this.fromSegments = from.split('.');

  // FIXME: This is not appropriate - the whole thing with the FromMap is over-used for our purposes
  this.views.fromMap[from] = this;
  return this.model.root.ref(from, this.pathsSegments.join('.'));
};

View.prototype.query = function (start, end) {
  // Ensure initialized
  this._init();

  return new Query(this.model, this, start, end);
};

// Duplicate naming for more Derby-aligned naming
View.prototype.refList = View.prototype.query;

function Query(model, view, start, end) {
  this.model = model;
  this.view = view;
  this.start = start;
  this.end = end;
  this.idsSegments = null;
  this.from = null;
  this.fromSegments = null;
}

Query.prototype.ref = function(from) {
  from = this.model.path(from);
  this.from = from;
  this.fromSegments = from.split('.');
  this.view.fromMap[from] = this;
  this.idsSegments = this.view.querySegments.concat(from.replace(/\./g, '|'));
  var path = this._getPath();
  this.update();
  return this.model.root.refList(from, path, this.idsSegments.join('.'));
};

Query.prototype._getPath = function() {
  var start = this.view._insertPosition(this.start);
  var end = this.view._insertPosition(this.end, {upperBound: true});

  if(end < start) throw new Error("Can't currently handle empty queries");

  var id = this.model._get(this.view.keysSegments.concat(start));
  var ref = this.model.root._refs.fromMap[this.view.pathsSegments.concat(id).join('.')];
  var segments = ref.toSegments.slice(0);
  segments.pop();

  return segments.join('.');
};

Query.prototype.ids = function () {
  var start = this.view._insertPosition(this.start);
  var end = this.view._insertPosition(this.end, {upperBound: true});
  var keys = this.model._get(this.view.keysSegments);
  var keys = keys.slice(start, end);
  var ids = keys.map(function (key) {
    return this.model._get(this.view.pathsSegments.concat(key)).id;
  }, this);

  return ids;
};

Query.prototype.update = function(pass) {
  var ids = this.ids();
  this.model.pass(pass, true)._setArrayDiff(this.idsSegments, ids);
};

// TODO: Implement
View.prototype.subscribe = function () {

};

// TODO: Implement
View.prototype.fetch = function () {

};

// TODO: Review this - including properly cleaning up all related queries
View.prototype.destroy = function() {
  delete this.views.fromMap[this.from];

  // this.model._removeRef(this.idsSegments);
  // this.model._del(this.idsSegments);

  if(!this.initialized) return;
  this.model._del(this.keysSegments);
  this.model._del(this.pathsSegments);
  this.model._del(this.idsSegments);
};

View.prototype._init = function () {
  // Only initialize once
  if(this.initialized) return;
  this.initialized = true;

  var data = this.model.root._get(this.segments);
  if(!data) return;

  var ids = Object.keys(data);

  for(var i = 0, len = ids.length; i < len; i++) {
    var id = ids[i];
    var obj = data[id];
    var emit = getEmit(this, id);

    this.viewFn(emit, obj, id);
  }
};

View.prototype._delete = function (id) {
  // TODO: Check if we need to go to root here - I dont think so
  var keys = this.model.root._get(this.idsSegments.concat(id))

  if(typeof keys !== 'undefined') {
    for(var i = 0, len = keys.length; i < len; i++) {
      var key = keys[i];
      var position = this._insertPosition(key);

      this.model.root._remove(this.keysSegments, position, 1);

      var refSegments = this.pathsSegments.concat(key);
      this.model.root._removeRef(refSegments, refSegments.join('.'));
    }
  }
  this.model._del(this.idsSegments.concat(id));
};

View.prototype._insert = function (key) {
  var position = this._insertPosition(key);
  this.model._insert(this.keysSegments, position, key);
};

View.prototype._insertPosition = function (key, options) {
  var keys = this.model.root._get(this.keysSegments);
  if(!keys) return 0;
  var len = keys.length;
  var lower = 0;
  var upper = len;
  var done = false;
  var pos;
  var options = options || {};

  while(!done) {
    pos = parseInt((upper + lower) / 2);

    if(pos === lower || pos === upper) {
      done = true;
      continue;
    }

    if(keys[pos] > key) {
      upper = pos;
    } else {
      lower = pos;
    }
  }

  if((pos == 0 && keys[pos] > key) || (!(options && options.upperBound) && keys[pos] === key)) pos--;

  return ++pos;
};

function getEmit(view, id) {
  return function ret(key, path) {
    view.model.root.ref(view.pathsSegments.concat(key).join('.'), path);
    view.model._push(view.idsSegments.concat(id), key);
    view._insert(key);
  }
}
<|endoftext|>


<commit_before>'use strict';

var csslint = require('csslint').CSSLint;
var Filter = require('broccoli-filter');
var path = require('path');
var chalk = require('chalk');
var fs = require('fs');
var findup = require('findup-sync');
var mkdirp = require('mkdirp');

CSSLinter.prototype = Object.create(Filter.prototype);
CSSLinter.prototype.constructor = CSSLinter;

function CSSLinter(inputTree, options) {
  if (!(this instanceof CSSLinter)) {
    return new CSSLinter(inputTree, options);
  }

  options = options || {};

  this.inputTree = inputTree;
  this.log = true;

  for (var key in options) {
    if (options.hasOwnProperty(key)) {
      this[key] = options[key]
    }
  }
};

CSSLinter.prototype.extensions = ['css'];

CSSLinter.prototype.write = function (readTree, destDir) {
  var self = this
  self._errors = [];

  return readTree(this.inputTree).then(function (srcDir) {
    if (!self.csslintrc) {
      var csslintrcPath = self.csslintrcPath || path.join(srcDir, self.csslintrcRoot || '');
      self.csslintrc = self.getConfig(csslintrcPath);
    }

    return Filter.prototype.write.call(self, readTree, destDir)
  })
  .finally(function() {
    if (self._errors.length > 0) {
      var label = ' Files with CSSLint Errors';
      console.log('\n' + self._errors.join('\n'));
      console.log(chalk.yellow('===== ' + self._errors.length + label + '\n'));
    }
  });
}

CSSLinter.prototype.processString = function (content, relativePath) {

  var filesToExclude =  this.csslintrc['exclude-list'];

  if(filesToExclude && filesToExclude.indexOf(relativePath) !== -1) {
    return;
  }

  var report = csslint.verify(content, this.csslintrc);
  var errors = this.processMessages(relativePath, report.messages);

  if (report.messages.length > 0) {
    this.logError(errors);
  }
};

CSSLinter.prototype.processMessages = function (file, messages) {
  var len = messages.length

  if (len == 0) {
    return '';
  }

  var messageStr = messages.map(function(message, i) {
    return file + ': line ' + message.line + ', col ' + message.col + ', ' + message.message;
  }).join();

  return messageStr + '\n' + len + ' error' + ((len === 1) ? '' : 's');
}

CSSLinter.prototype.logError = function(message, color) {
  color = color || 'red';
  this._errors.push(chalk[color](message) + "\n");
};

CSSLinter.prototype.getConfig = function(rootPath) {
  if (!rootPath) { rootPath = process.cwd(); }

  var ruleset = {};
  var lintOptions = {};

  var csslintrc = findup('.csslintrc', { cwd: rootPath, nocase: true });

  if (csslintrc) {
    var config = fs.readFileSync(csslintrc, { encoding: 'utf8' });

    try {
      lintOptions = JSON.parse(this.stripComments(config));
    } catch (e) {
      console.error(chalk.red('Error occured parsing .csslintrc.'));
      console.error(e.stack);

      return null;
    }
  }

  csslint.getRules().forEach(function(rule) {
    ruleset[rule.id] = 1;
  });

  for (var rule in lintOptions) {
    if (!lintOptions[rule]) {
      delete ruleset[rule];
    }
    else {
      ruleset[rule] = lintOptions[rule];
    }
  }

  return ruleset;
};

CSSLinter.prototype.stripComments = function(string) {
  string = string || '';

  string = string.replace(/\/\*(?:(?!\*\/)[\s\S])*\*\//g, '');
  string = string.replace(/\/\/[^\n\r]*/g, ''); // Everything after '//'

  return string;
};

module.exports = CSSLinter;
<commit_msg>Fixed excluded files from returning undefined<commit_after>'use strict';

var csslint = require('csslint').CSSLint;
var Filter = require('broccoli-filter');
var path = require('path');
var chalk = require('chalk');
var fs = require('fs');
var findup = require('findup-sync');
var mkdirp = require('mkdirp');

CSSLinter.prototype = Object.create(Filter.prototype);
CSSLinter.prototype.constructor = CSSLinter;

function CSSLinter(inputTree, options) {
  if (!(this instanceof CSSLinter)) {
    return new CSSLinter(inputTree, options);
  }

  options = options || {};

  this.inputTree = inputTree;
  this.log = true;

  for (var key in options) {
    if (options.hasOwnProperty(key)) {
      this[key] = options[key]
    }
  }
};

CSSLinter.prototype.extensions = ['css'];

CSSLinter.prototype.write = function (readTree, destDir) {
  var self = this
  self._errors = [];

  return readTree(this.inputTree).then(function (srcDir) {
    if (!self.csslintrc) {
      var csslintrcPath = self.csslintrcPath || path.join(srcDir, self.csslintrcRoot || '');
      self.csslintrc = self.getConfig(csslintrcPath);
    }

    return Filter.prototype.write.call(self, readTree, destDir)
  })
  .finally(function() {
    if (self._errors.length > 0) {
      var label = ' Files with CSSLint Errors';
      console.log('\n' + self._errors.join('\n'));
      console.log(chalk.yellow('===== ' + self._errors.length + label + '\n'));
    }
  });
}

CSSLinter.prototype.processString = function (content, relativePath) {

  var filesToExclude =  this.csslintrc['exclude-list'];

  if(filesToExclude && filesToExclude.indexOf(relativePath) !== -1) {
    return content;
  }

  var report = csslint.verify(content, this.csslintrc);
  var errors = this.processMessages(relativePath, report.messages);

  if (report.messages.length > 0) {
    this.logError(errors);
  }
};

CSSLinter.prototype.processMessages = function (file, messages) {
  var len = messages.length

  if (len == 0) {
    return '';
  }

  var messageStr = messages.map(function(message, i) {
    return file + ': line ' + message.line + ', col ' + message.col + ', ' + message.message;
  }).join();

  return messageStr + '\n' + len + ' error' + ((len === 1) ? '' : 's');
}

CSSLinter.prototype.logError = function(message, color) {
  color = color || 'red';
  this._errors.push(chalk[color](message) + "\n");
};

CSSLinter.prototype.getConfig = function(rootPath) {
  if (!rootPath) { rootPath = process.cwd(); }

  var ruleset = {};
  var lintOptions = {};

  var csslintrc = findup('.csslintrc', { cwd: rootPath, nocase: true });

  if (csslintrc) {
    var config = fs.readFileSync(csslintrc, { encoding: 'utf8' });

    try {
      lintOptions = JSON.parse(this.stripComments(config));
    } catch (e) {
      console.error(chalk.red('Error occured parsing .csslintrc.'));
      console.error(e.stack);

      return null;
    }
  }

  csslint.getRules().forEach(function(rule) {
    ruleset[rule.id] = 1;
  });

  for (var rule in lintOptions) {
    if (!lintOptions[rule]) {
      delete ruleset[rule];
    }
    else {
      ruleset[rule] = lintOptions[rule];
    }
  }

  return ruleset;
};

CSSLinter.prototype.stripComments = function(string) {
  string = string || '';

  string = string.replace(/\/\*(?:(?!\*\/)[\s\S])*\*\//g, '');
  string = string.replace(/\/\/[^\n\r]*/g, ''); // Everything after '//'

  return string;
};

module.exports = CSSLinter;
<|endoftext|>


<commit_before>'use strict';

// Options:
//
// area <AREA>           Portion of the page to analyze (top,left,bottom,right).
//                       Example: "269.875,12.75,790.5,561". Default is entire page.
//
// columns <COLUMNS>     X coordinates of column boundaries. Example "10.1,20.2,30.3"
//
// debug                 Print detected table areas instead ofprocessing.
//
// guess                 Guess the portion of the page to analyze per page.
//
// silent                Suppress all stderr output.
//
// noSpreadsheet        Force PDF not to be extracted using spreadsheet-style extraction
//                      (if there are ruling lines separating each cell, as in a PDF of an Excel spreadsheet)
//
// pages <PAGES>        Comma separated list of ranges, or all.
//                      Examples: pages: "1-3,5-7", pages: "3" or pages: "all". Default is pages: "1"
//
// spreadsheet          Force PDF to be extracted using spreadsheet-style extraction
//                      (if there are ruling lines separating each cell, as in a PDF
//                        of an Excel spreadsheet)
//
// password <PASSWORD>  Password to decrypt document. Default is empty
//
// useLineReturns       Use embedded line returns in cells. (Only in spreadsheet mode.)

// const tabula = require('tabula-js');

// tabula.streamCsv('pathToPDF');
// tabula.extractCsv('pathToPDF', cb);

const path          = require('path')
    , spawn         = require('child_process').spawn
    , EventEmitter  = require('events').EventEmitter
    , _             = require('lodash')
    , h             = require('highland');

function TabulaCommand(pdfPath, commandArgs){
  EventEmitter.call(this);
  this._build(pdfPath, commandArgs);
}

util.inherits(TabulaCommand, EventEmitter)

TabulaCommand.prototype.run = function () {
  this.process = spawn('java', this.args);

  this.process.stdout.on('data', data => this.emit('data', data.toString()));
  this.process.stderr.on('data', data => {
    const msg = data.toString();
    if(/error/i.test(msg)){ return this.emit('error', new Error(`tabula-java ${msg}`)); }
  });

  this.process.on('close', (code) => {
    this.emit('data', h.nil);
    this.emit('close', code);
  });
  this.process.on('error', (err) => this.emit('error', err));
  return this;
};

TabulaCommand.prototype._build = function (pdfPath, commandArgs) {
  this.args = ['-jar', path.join(__dirname, 'lib', 'tabula-java.jar')];
  this.args = this.args.concat(_.toPairs(_.mapKeys(commandArgs, (value, key) => `--${_.kebabCase(key)}`)));
  this.args = this.args.concat([pdfPath]);
  this.args = _.flatten(this.args);
  return this;
};

module.exports = Tabula;

function Tabula(pdfPath, options) {
  if (!(this instanceof Tabula)) return new Tabula(pdfPath, options);
  this.pdfPath = pdfPath;
  this.options = options;
}

Tabula.prototype.streamCsv = function () {
  const cmd = new TabulaCommand(this.pdfPath, this.options).run();
  const dataStream = h('data', cmd);
  const errorStream = h('error', cmd);

  this.stream = h.concat(errorStream, dataStream);
  return this.stream
  .doto(data => console.log('INCOMING -> ', data))
  .stopOnError(e => console.error(e));
};
<commit_msg>Csv streaming complete.<commit_after>'use strict';

// Options:
//
// area <AREA>           Portion of the page to analyze (top,left,bottom,right).
//                       Example: "269.875,12.75,790.5,561". Default is entire page.
//
// columns <COLUMNS>     X coordinates of column boundaries. Example "10.1,20.2,30.3"
//
// debug                 Print detected table areas instead ofprocessing.
//
// guess                 Guess the portion of the page to analyze per page.
//
// silent                Suppress all stderr output.
//
// noSpreadsheet        Force PDF not to be extracted using spreadsheet-style extraction
//                      (if there are ruling lines separating each cell, as in a PDF of an Excel spreadsheet)
//
// pages <PAGES>        Comma separated list of ranges, or all.
//                      Examples: pages: "1-3,5-7", pages: "3" or pages: "all". Default is pages: "1"
//
// spreadsheet          Force PDF to be extracted using spreadsheet-style extraction
//                      (if there are ruling lines separating each cell, as in a PDF
//                        of an Excel spreadsheet)
//
// password <PASSWORD>  Password to decrypt document. Default is empty
//
// useLineReturns       Use embedded line returns in cells. (Only in spreadsheet mode.)

// const tabula = require('tabula-js');

// tabula.streamCsv('pathToPDF');
// tabula.extractCsv('pathToPDF', cb);

const path          = require('path')
    , spawn         = require('child_process').spawn
    , EventEmitter  = require('events').EventEmitter
    , _             = require('lodash')
    , h             = require('highland');

function TabulaCommand(pdfPath, commandArgs){
  EventEmitter.call(this);
  this._build(pdfPath, commandArgs);
}

util.inherits(TabulaCommand, EventEmitter)

TabulaCommand.prototype.run = function () {
  this.process = spawn('java', this.args);

  this.process.stdout.on('data', data => this.emit('data', data.toString()));
  this.process.stderr.on('data', data => {
    const msg = data.toString();
    if(/error/i.test(msg)){ return this.emit('error', new Error(`tabula-java ${msg}`)); }
  });

  this.process.on('close', (code) => {
    this.emit('data', h.nil);
    this.emit('close', code);
  });
  this.process.on('error', (err) => this.emit('error', err));
  return this;
};

TabulaCommand.prototype._build = function (pdfPath, commandArgs) {
  this.args = ['-jar', path.join(__dirname, 'lib', 'tabula-java.jar')];
  this.args = this.args.concat(_.toPairs(_.mapKeys(commandArgs, (value, key) => `--${_.kebabCase(key)}`)));
  this.args = this.args.concat([pdfPath]);
  this.args = _.flatten(this.args);
  return this;
};

module.exports = Tabula;

function Tabula(pdfPath, options) {
  if (!(this instanceof Tabula)) return new Tabula(pdfPath, options);
  this.pdfPath = pdfPath;
  this.options = options;
}

Tabula.prototype.streamCsv = function () {
  const cmd = new TabulaCommand(this.pdfPath, this.options).run();
  const dataStream = h('data', cmd);
  const errorStream = h('error', cmd);

  return h.concat(errorStream, dataStream).stopOnError(e => console.error(e));
};
<|endoftext|>


<commit_before>var twitter = require('twitter');
var request = require('request');

var client = new twitter({
    consumer_key: process.env.TWITTER_CONSUMER_KEY,
    consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
    access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
    access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET
});

randomNum = Math.floor(Math.random() * (10 - 1) + 1)

if (randomNum <= 3) {
    var options = {
        url : process.env.OFFICE_API_URL,
        headers: {
            "token": process.env.OFFICE_API_TOKEN
        }
    };

    request(options, function(error, response, data) {
        if(error) {
            console.log(error);
        }

        if (!error && response.statusCode == 200) {
            body = JSON.parse(data)
            tweet = body.quote.quote

            client.post('statuses/update', {status: tweet},  function(error, tweet, response) {
                if(error) {
                    console.log(error);
                }

                console.log(tweet);
                console.log(response);
            });
        }
    });
}
<commit_msg>adding log for when not posting<commit_after>var twitter = require('twitter');
var request = require('request');

var client = new twitter({
    consumer_key: process.env.TWITTER_CONSUMER_KEY,
    consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
    access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
    access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET
});

randomNum = Math.floor(Math.random() * (10 - 1) + 1)

if (randomNum <= 3) {
    var options = {
        url : process.env.OFFICE_API_URL,
        headers: {
            "token": process.env.OFFICE_API_TOKEN
        }
    };

    request(options, function(error, response, data) {
        if(error) {
            console.log(error);
        }

        if (!error && response.statusCode == 200) {
            body = JSON.parse(data)
            tweet = body.quote.quote

            client.post('statuses/update', {status: tweet},  function(error, tweet, response) {
                if(error) {
                    console.log(error);
                }

                console.log(tweet);
                console.log(response);
            });
        }
    });
} else {
    console.log("number was too low, don't want to truly post ever hour")
}
<|endoftext|>


<commit_before>/*!
 * morgan
 * Copyright(c) 2013 TJ Holowaychuk
 * Copyright(c) 2014 Jonathan Ong
 * MIT Licensed
 */

/**
 * Parse the Authorization header field of `req`.
 *
 * @param {object} req
 * @return {object} with .name and .pass
 * @public
 */

module.exports = function(req){
  req = req.req || req;

  var auth = req.headers.authorization;
  if (!auth) return;

  // malformed
  var parts = auth.split(' ');
  if ('basic' != parts[0].toLowerCase()) return;
  if (!parts[1]) return;
  auth = parts[1];

  // credentials
  auth = new Buffer(auth, 'base64').toString();
  auth = auth.match(/^([^:]*):(.*)$/);
  if (!auth) return;

  return { name: auth[1], pass: auth[2] };
};
<commit_msg>Rearrange exports<commit_after>/*!
 * morgan
 * Copyright(c) 2013 TJ Holowaychuk
 * Copyright(c) 2014 Jonathan Ong
 * MIT Licensed
 */

/**
 * Module exports.
 * @public
 */

module.exports = auth

/**
 * Parse the Authorization header field of a request.
 *
 * @param {object} req
 * @return {object} with .name and .pass
 * @public
 */

function auth(req) {
  req = req.req || req;

  var auth = req.headers.authorization;
  if (!auth) return;

  // malformed
  var parts = auth.split(' ');
  if ('basic' != parts[0].toLowerCase()) return;
  if (!parts[1]) return;
  auth = parts[1];

  // credentials
  auth = new Buffer(auth, 'base64').toString();
  auth = auth.match(/^([^:]*):(.*)$/);
  if (!auth) return;

  return { name: auth[1], pass: auth[2] };
}
<|endoftext|>


<commit_before>const EventEmitter = require('events');
const DHT = require('bittorrent-dht')
const crypto = require('crypto');
const WebTorrent = require('webtorrent')
const ChunkStore = require('memory-chunk-store')

const defaults = {}
defaults.timeout = 5000
defaults.btConcurrency = 200
defaults.dhtConcurrency = 30

class Sniffer extends EventEmitter {

  constructor(options) {
    super()

    this.options = Object.assign({}, defaults, options)

    this.bt = new WebTorrent({maxConns: 1})

    this.bt.on('error', (error) => {
      console.error(error.message);
    })

    const locks = new Set

    const dht = new DHT({concurrency: this.options.dhtConcurrency});
    this.dht = dht
    dht.on('announce_peer', (infoHash, peer) => {
      if (this.bt.torrents.length >= this.options.btConcurrency) {
        //console.log('bt client is busy, drop peer');
        return
      }
      const lock = infoHash.toString('hex')
      if (locks.has(lock)) {
        return
      }
      locks.add(lock)
      this._ignore(infoHash, (drop) => {
        //console.log(this.bt.torrents.length);
        if (drop) {
          return locks.delete(lock)
        }
        //const torrent = this.bt.add(infoHash, {store})
        const torrent = this.bt.add(infoHash, { store: ChunkStore })

        const timeout = setTimeout(() => {
          if (!this.bt.get(torrent)) {
            return
          }
          this.bt.remove(torrent)
        }, this.options.timeout);

        torrent.addPeer(`${peer.host}:${peer.port}`)
        torrent.once('metadata', () => {
          clearTimeout(timeout)
          this.bt.remove(torrent)
          torrent.done = true
          this.emit('metadata', torrent)
        })
        torrent.once('close', () => locks.delete(lock))
      })
    })

    const rpc = dht._rpc
    rpc.on('ping', (olders, newer) => {
      //for (const older of olders) {
        //rpc.nodes.remove(older.id)
      //}
      rpc.clear()
    })
    dht.on('node', (node) => this.makeNeighbor(node))
  }

  makeNeighbor(node, id) {
    const rpc = this.dht._rpc
    // prevent memleak
    if (rpc.pending.length) {
      return
    }
    const query = {
      t: crypto.randomBytes(4),
      y: 'q',
      q: 'find_node',
      a: {
        id: id || Buffer.concat([node.id.slice(0, 10), rpc.id.slice(10)]),
        target: crypto.randomBytes(20)
      }
    };
    rpc.query(node, query)
  }

  ignore(callback) {
    this._ignore = callback;
  };

  start(...args) {
    this.dht.listen(...args)

    setInterval(() => {
      const rpc = this.dht._rpc
      rpc.bootstrap.forEach((node) => this.makeNeighbor(node, rpc.id))
    }, 1000)
  };

}

Sniffer.defaults = defaults

module.exports = Sniffer;
<commit_msg>Fix memleak<commit_after>const EventEmitter = require('events');
const DHT = require('bittorrent-dht')
const crypto = require('crypto');
const WebTorrent = require('webtorrent')
const ChunkStore = require('memory-chunk-store')

const defaults = {}
defaults.timeout = 5000
defaults.btConcurrency = 200
defaults.dhtConcurrency = 30

class Sniffer extends EventEmitter {

  constructor(options) {
    super()

    this.options = Object.assign({}, defaults, options)

    this.bt = new WebTorrent({
      maxConns: 1,
      dht: false,
      tracker: false
      //dht: {
        //maxTables: 1,
        //maxValues: 1,
        //maxPeers: 1
      //}
    })

    this.bt.on('error', (error) => {
      console.error(error.message);
    })

    const locks = new Set

    const dht = new DHT({
      concurrency: this.options.dhtConcurrency,
      maxTables: 1,
      maxValues: 1,
      maxPeers: 1
    });
    this.dht = dht
    dht.on('announce_peer', (infoHash, peer) => {
      if (this.bt.torrents.length >= this.options.btConcurrency) {
        //console.log('bt client is busy, drop peer');
        return
      }
      const lock = infoHash.toString('hex')
      if (locks.has(lock)) {
        return
      }
      locks.add(lock)
      this._ignore(infoHash, (drop) => {
        //console.log(this.bt.torrents.length);
        if (drop) {
          return locks.delete(lock)
        }
        //const torrent = this.bt.add(infoHash, {store})
        const torrent = this.bt.add(infoHash, { store: ChunkStore })

        const timeout = setTimeout(() => {
          if (!this.bt.get(torrent)) {
            return
          }
          this.bt.remove(torrent)
        }, this.options.timeout);

        torrent.addPeer(`${peer.host}:${peer.port}`)
        torrent.once('metadata', () => {
          clearTimeout(timeout)
          this.bt.remove(torrent)
          torrent.done = true
          this.emit('metadata', torrent)
        })
        torrent.once('close', () => {
          locks.delete(lock)
        })
      })
    })

    const rpc = dht._rpc
    rpc.on('ping', (olders, newer) => {
      for (const older of olders) {
        rpc.nodes.remove(older.id)
      }
      //rpc.clear()
    })
    dht.on('node', (node) => this.makeNeighbor(node))
  }

  makeNeighbor(node, id) {
    const rpc = this.dht._rpc
    // prevent memleak
    if (rpc.pending.length) {
      return
    }
    const query = {
      t: crypto.randomBytes(4),
      y: 'q',
      q: 'find_node',
      a: {
        id: id || Buffer.concat([node.id.slice(0, 10), rpc.id.slice(10)]),
        target: crypto.randomBytes(20)
      }
    };
    rpc.query(node, query)
  }

  ignore(callback) {
    this._ignore = callback;
  };

  start(...args) {
    this.dht.listen(...args)

    setInterval(() => {
      const rpc = this.dht._rpc
      rpc.bootstrap.forEach((node) => this.makeNeighbor(node, rpc.id))
    }, 1000)
  };

}

Sniffer.defaults = defaults

module.exports = Sniffer;
<|endoftext|>