<commit_before>var postcss = require('postcss');
var find = require('array-find');
var referenceableNodes = [];

module.exports = postcss.plugin('postcss-reference', function (opts) {
    opts = opts || {
        debug: false
    };

    // Work with options here

    var referenceRules = [];
    var findReferenceableRules = function findReferenceableRules(css) {

        // Walk through list of rules in @reference blocks, push them into the
        // referenceRules array and then remove them from the AST so they don't
        // get output to the compiled CSS unless matched.
        css.walkAtRules('reference', function(atRule) {

            atRule.walkRules(function(rule) {
                referenceRules.push(rule);
            });

            atRule.remove();
        });
    };

    var findReferences = function findReferences(css) {

        // Now that our @reference blocks have been processed
        // Walk through our rules looking for @references declarations
        css.walkRules(function(rule) {

            // TODO :: if rule's selector has a pseudoclass, prepend matches to
            // the rule

            rule.walk(function(node) {

                if (node.type === 'atrule' &&
                    node.name === 'references') {

                    // extract our @references() contents and split selectors into an array
                    var terms = node.params.replace('(', '').replace(')', '').split(',');

                    // check our reference array for any of our terms
                    var matches = matchReferences(referenceRules, terms);

                    // if referenced and referencing rules have declarations
                    // with of same property, defer to the referencing rule
                    rule.walkDecls(function(decl) {
                        matches.decls.forEach(function(match, d, matchedDecls) {
                            if (decl.prop === match.prop) {
                                matchedDecls.splice(d, 1);
                            }
                        });
                    });

                    for (var m in matches.decls) {
                        rule.insertBefore(node, matches.decls[m]);
                    }

                    if (matches.relationships.length) {
                        // sort relationships alphabetically in descending order so
                        // they will properly append after the original rule
                        matches.relationships.sort(function (a, b) {

                            if (a < b) {
                                return 1;
                            }
                            if (a > b) {
                                return -1;
                            }
                            // a must be equal to b
                            return 0;
                        });

                        matches.relationships.forEach(function(newRule) {
                            css.insertAfter(rule, newRule);
                        });
                    }

                    node.remove();
                }
            });
        });
    };

    var matchReferences = function matchReferences(referenceRules, terms) {
        var matches = {
            decls: [],
            relationships: []
        };

        referenceRules.forEach(function (reference, index, references) {
            // make sure any comma separated selector lists are broken out into an array
            var refSelectors = reference.selectors;

            refSelectors.forEach(function(refSelector, sindex, refSelectors) {

                terms.forEach(function(term, tindex, terms) {
                    var flagAll = (term.indexOf(" all") !== -1);
                    var tmpSelectorsArray = refSelectors;
                    // strip " all" from term now that flag is set
                    term = term.replace(" all", '');

                    // clean any whitespaces which might surround commas
                    term = term.trim();

                    // strip out selectors from list that don't start with current term
                    if (tmpSelectorsArray.length > 1 && tmpSelectorsArray.indexOf(term) !== -1) {
                        for (var i = 0; i < tmpSelectorsArray.length; i++){
                            var cleanSelector = tmpSelectorsArray[i].trim();
                        	if (cleanSelector.indexOf(term) !== 0) {
                                tmpSelectorsArray.splice(i, 1);
                            }
                        }

                        // then if we had to splice any selectors out of our
                        // reference's selector list, reassemble the array back to a string
                        refSelector = tmpSelectorsArray.join();
                    }

                    if (term === refSelector) {
                        extractMatchingDecls(matches.decls, reference);
                    } else if (reference.selector.indexOf(term) === 0 && flagAll) {
                        console.log(reference.selector + " is related to " + term);
                        // if the it's not an explicit match, but the 'all' flag is set
                        // and the selector describes a relationships to the term, gather
                        // those references for our matches array
                        // i.e. prevent matches with .button like .button-primary, but allow
                        // matches like .button .primary, .button.primary, or .button > .primary
                        var safeChars = [" ", ".", "#", "+", "~", ">", ":"];

                        if (reference.selector.length > term.length &&
                            reference.selector.charAt(term.length + 1).indexOf(safeChars)) {
                                extractMatchingRelationships(matches.relationships, reference);
                        }
                    }
                });
            });
        });

        return matches;
    };

    var findDuplicates = function findDuplicates(matchArray, node, childParam) {
        var dup = null;

        find(matchArray, function(match, index, array) {
            if (match[childParam] === node[childParam]) {
                dup = index;
            }
        });

        return dup;
    };

    var extractMatchingDecls = function extractMatchingDecls(matchArray, rule) {

        rule.walkDecls(function(decl) {
            var dup = null;

            // check for duplicates in our list of matches
            dup = findDuplicates(matchArray, decl, "prop");

            if (dup !== null) {
                // if it's a dupe, replace existing rule
                matchArray[dup].replaceWith(decl);
            } else {
                // otherwise add to the declarations list
                matchArray.push(decl);
            }
        });
    };

    var extractMatchingRelationships = function extractMatchingRelationships(matchArray, rule) {

        matchArray.forEach(function(match) {
            var dup = null;

            dup = findDuplicates(matchArray, rule, "selector");

            if (dup !== null) {
                // TODO :: instead of replacing the rule outright, create mergeDuplicates
                // function to to compare rules with matching selector names and run
                // findDuplicates on their declarations
                // matchArray[dup].replaceWith(rule);

                // walk through each decl in rule and discard all matching decls
                // from dup before merging remaining decls
                rule.walkDecls(function(decl) {
                    var dupDecl = findDuplicates(matchArray[dup].nodes, rule.nodes[decl], "prop");

                    matchArray[dup].nodes[dupDecl].remove();
                });
            } else {
                // otherwise add to the declarations list
                matchArray.push(rule);
            }
        });
    };

    return function (css, result) {
        findReferenceableRules(css);
        findReferences(css);
        console.log(css);
    };
});
<commit_msg>unfurled a few reusable functions out of the nested loops<commit_after>var postcss = require('postcss');
var find = require('array-find');
var referenceableNodes = [];

module.exports = postcss.plugin('postcss-reference', function (opts) {
    opts = opts || {
        debug: false
    };

    // Work with options here

    var referenceRules = [];
    var findReferenceableRules = function findReferenceableRules(css) {
        // Walk through list of rules in @reference blocks, push them into the
        // referenceRules array and then remove them from the AST so they don't
        // get output to the compiled CSS unless matched.
        css.walkAtRules('reference', function(atRule) {

            atRule.walkRules(function(rule) {
                referenceRules.push(rule);
            });

            atRule.remove();
        });
    };

    var findReferences = function findReferences(css) {
        // Now that our @reference blocks have been processed
        // Walk through our rules looking for @references declarations
        css.walkRules(function(rule) {
            // TODO :: if rule's selector has a pseudoclass, prepend matches to
            // the rule

            rule.walk(function(node) {

                if (node.type === 'atrule' &&
                    node.name === 'references') {

                    // extract our @references() contents and split selectors into an array
                    var terms = node.params.replace('(', '').replace(')', '').split(',');

                    // check our reference array for any of our terms
                    var matches = matchReferences(referenceRules, terms);

                    // if referenced and referencing rules have declarations
                    // with of same property, defer to the referencing rule
                    rule.walkDecls(function(decl) {
                        matches.decls.forEach(function(match, d, matchedDecls) {
                            if (decl.prop === match.prop) {
                                matchedDecls.splice(d, 1);
                            }
                        });
                    });

                    for (var m in matches.decls) {
                        rule.insertBefore(node, matches.decls[m]);
                    }

                    if (matches.relationships.length) {
                        // sort relationships alphabetically in descending order so
                        // they will properly append after the original rule
                        matches.relationships.sort(function (a, b) {

                            if (a < b) {
                                return 1;
                            }
                            if (a > b) {
                                return -1;
                            }
                            // a must be equal to b
                            return 0;
                        });

                        matches.relationships.forEach(function(newRule) {
                            css.insertAfter(rule, newRule);
                        });
                    }

                    node.remove();
                }
            });
        });
    };

    var testRelationExistsIn = function testSelectorExistsIn(item, array, prop) {
        var value = false;

        array.forEach(function (obj) {
            if (item.indexOf(obj[prop]) === 0) {
                value = true;
            }
        });

        return value;
    };

    var matchReferences = function matchReferences(referenceRules, terms) {
        var matches = {
            decls: [],
            relationships: []
        };

        // terms and params are a string at this point.  Convert to an array of
        // well defined objects for cleaner processing
        processedTerms = [];

        terms.forEach(function(term) {
            var obj = {
                name: null,
                all: false
            };

            obj.all = (term.indexOf(" all") !== -1);
            // strip out any params from term now that flags are set
            // (only 'all' for now)
            term = term.replace(" all", '');

            // clean any whitespaces which might surround commas after param
            // extraction and assign the term to obj.name
            obj.name = term.trim();

            processedTerms.push(obj);
        });

        referenceRules.forEach(function (reference, index, references) {
            // Strip out any selectors in our current reference rule which don't match
            // any of our requested terms
            var matchedRefSelectors = [];

            reference.selectors.filter(function(ref) {
                var hasRelation = testRelationExistsIn(ref, processedTerms, "name");

                if (hasRelation) {
                    matchedRefSelectors.push(ref.trim());
                }
            });

            matchedRefSelectors.forEach(function(refSelector, sindex, refSelectors) {

                processedTerms.forEach(function(term, tindex, terms) {
                    // var flagAll = (term.indexOf(" all") !== -1);
                    var tmpSelectorsArray = refSelectors;

                    // if it's an exact match...
                    if (term.name === refSelector) {
                        // just merge up the declarations of the successfully
                        // referenced rule
                        extractMatchingDecls(matches.decls, reference);

                    } else if (reference.selector.indexOf(term.name) === 0 && term.all) {
                        // otherwise, if the it's not an explicit match, but the 'all' flag is set
                        // and the selector describes a relationships to the term, gather
                        // those references for our matches array
                        // i.e. prevent matches with .button like .button-primary, but allow
                        // matches like .button .primary, .button.primary, or .button > .primary
                        var safeChars = [" ", ".", "#", "+", "~", ">", ":"];

                        if (reference.selector.length > term.name.length &&
                            safeChars.indexOf(reference.selector.charAt(term.name.length)) === 0) {
                                extractMatchingRelationships(matches.relationships, reference);
                        }
                    }
                });
            });
        });

        return matches;
    };

    var findDuplicates = function findDuplicates(matchArray, node, childParam) {
        var dup = null;

        find(matchArray, function(match, index, array) {
            if (match[childParam] === node[childParam]) {
                dup = index;
            }
        });

        return dup;
    };

    var extractMatchingDecls = function extractMatchingDecls(matchArray, rule) {

        rule.walkDecls(function(decl) {
            var dup = null;

            // check for duplicates in our list of matches
            dup = findDuplicates(matchArray, decl, "prop");

            if (dup !== null) {
                // if it's a dupe, replace existing rule
                matchArray[dup].replaceWith(decl);
            } else {
                // otherwise add to the declarations list
                matchArray.push(decl);
            }
        });
    };

    var extractMatchingRelationships = function extractMatchingRelationships(matchArray, rule) {

        if (!matchArray.length) {
            matchArray.push(rule);
        } else {
            matchArray.forEach(function(match) {
                var dup = null;

                dup = findDuplicates(matchArray, rule, "selector");

                if (dup !== null) {
                    // walk through each decl in rule and discard all matching decls
                    // from dup before merging remaining decls
                    rule.walkDecls(function(decl) {
                        var dupDecl = findDuplicates(matchArray[dup].nodes, rule.nodes[decl], "prop");

                        matchArray[dup].nodes[dupDecl].remove();
                    });
                } else {
                    // otherwise add to the declarations list
                    matchArray.push(rule);
                }
            });
        }
    };

    return function (css, result) {
        findReferenceableRules(css);
        findReferences(css);
    };
});
<|endoftext|>


<commit_before>'use strict';

var del = require('del');
var gulp = require('gulp');
var maven = require('gulp-maven-deploy');
var path = require('path');
var runSequence = require('run-sequence');

module.exports.registerTasks = function(opt_options) {
	var options = opt_options || {};
	options.artifactIdPrefix = options.artifactIdPrefix || 'com.liferay.webjars.';
	options.artifactSrc = options.artifactSrc || ['**/*', '!node_modules/', '!node_modules/**'];
	options.packageJsonPath = path.resolve(options.packageJsonPath || 'package.json');
	options.repositories = options.repositores || {
		releases: [
			{
				'id': 'liferay-nexus-ce',
				'url': 'https://repository.liferay.com/nexus/content/repositories/liferay-releases-ce/'
			}
		],
		snapshots: [
			{
				'id': 'liferay-nexus-ce',
				'url': 'https://repository.liferay.com/nexus/content/repositories/liferay-releases-ce/'
			}
		]
	};

	var getFinalName = function(config) {
		return getName() + '-' + getVersion(config);
	};

	var getName = function() {
		return options.artifactName || require(options.packageJsonPath).name;
	};

	var getVersion = function(config) {
		var version = require(options.packageJsonPath).version;

		return (config && config.snapshot) ? version + '-SNAPSHOT' : version;
	};

	gulp.task('clean-maven-dist', function(callback) {
		del('maven-dist').then(function() {
			callback();
		});
	});

	gulp.task('prepare-maven-snapshot', function() {
		return gulp.src(options.artifactSrc)
			.pipe(gulp.dest(
				path.join('maven-dist/META-INF/resources/webjars', getName(), getVersion({snapshot: true}))
		));
	});

	gulp.task('install-maven-snapshot', function() {
		var snapshotConfig = { snapshot: true };

		return gulp.src('.')
			.pipe(maven.install({
				'config': {
					'artifactId': options.artifactIdPrefix + getName(),
					'buildDir': 'maven-dist',
					'finalName': getFinalName(snapshotConfig),
					'groupId': 'com.liferay.webjars',
					'type': 'jar',
					'version': getVersion(snapshotConfig)
				}
		}));
	});

	gulp.task('prepare-maven-artifact', function() {
		return gulp.src(options.artifactSrc)
			.pipe(gulp.dest(
				path.join('maven-dist/META-INF/resources/webjars', getName(), getVersion())
		));
	});

	gulp.task('publish-maven-artifact', function() {
		return gulp.src('.')
			.pipe(maven.deploy({
				'config': {
					'artifactId': options.artifactIdPrefix + getName(),
					'buildDir': 'maven-dist',
					'finalName': getFinalName(),
					'groupId': 'com.liferay.webjars',
					'type': 'jar',
					'version': getVersion(),
					'repositories': options.repositories.releases
				}
		}));
	});

	gulp.task('publish-maven-snapshot', function() {
		var snapshotConfig = { snapshot: true };

		return gulp.src('.')
			.pipe(maven.deploy({
				'config': {
					'artifactId': options.artifactIdPrefix + getName(),
					'buildDir': 'maven-dist',
					'finalName': getFinalName(snapshotConfig),
					'groupId': 'com.liferay.webjars',
					'type': 'jar',
					'version': getVersion(snapshotConfig),
					'repositories': options.repositories.snapshots
				}
		}));
	});

	gulp.task('maven-install', function(done) {
		runSequence('prepare-maven-snapshot', 'install-maven-snapshot', 'clean-maven-dist', done);
	});

	gulp.task('maven-publish', function(done) {
		runSequence('prepare-maven-artifact', 'publish-maven-artifact', 'clean-maven-dist', done);
	});

	gulp.task('maven-publish-snapshot', function(done) {
		runSequence('prepare-maven-snapshot', 'publish-maven-snapshot', 'clean-maven-dist', done);
	});
};
<commit_msg>Fix snapshots repo id and url<commit_after>'use strict';

var del = require('del');
var gulp = require('gulp');
var maven = require('gulp-maven-deploy');
var path = require('path');
var runSequence = require('run-sequence');

module.exports.registerTasks = function(opt_options) {
	var options = opt_options || {};
	options.artifactIdPrefix = options.artifactIdPrefix || 'com.liferay.webjars.';
	options.artifactSrc = options.artifactSrc || ['**/*', '!node_modules/', '!node_modules/**'];
	options.packageJsonPath = path.resolve(options.packageJsonPath || 'package.json');
	options.repositories = options.repositores || {
		releases: [
			{
				'id': 'liferay-nexus-ce',
				'url': 'https://repository.liferay.com/nexus/content/repositories/liferay-releases-ce/'
			}
		],
		snapshots: [
			{
				'id': 'liferay-nexus-snapshots-ce',
				'url': 'https://repository.liferay.com/nexus/content/repositories/liferay-snapshots-ce/'
			}
		]
	};

	var getFinalName = function(config) {
		return getName() + '-' + getVersion(config);
	};

	var getName = function() {
		return options.artifactName || require(options.packageJsonPath).name;
	};

	var getVersion = function(config) {
		var version = require(options.packageJsonPath).version;

		return (config && config.snapshot) ? version + '-SNAPSHOT' : version;
	};

	gulp.task('clean-maven-dist', function(callback) {
		del('maven-dist').then(function() {
			callback();
		});
	});

	gulp.task('prepare-maven-snapshot', function() {
		return gulp.src(options.artifactSrc)
			.pipe(gulp.dest(
				path.join('maven-dist/META-INF/resources/webjars', getName(), getVersion({snapshot: true}))
		));
	});

	gulp.task('install-maven-snapshot', function() {
		var snapshotConfig = { snapshot: true };

		return gulp.src('.')
			.pipe(maven.install({
				'config': {
					'artifactId': options.artifactIdPrefix + getName(),
					'buildDir': 'maven-dist',
					'finalName': getFinalName(snapshotConfig),
					'groupId': 'com.liferay.webjars',
					'type': 'jar',
					'version': getVersion(snapshotConfig)
				}
		}));
	});

	gulp.task('prepare-maven-artifact', function() {
		return gulp.src(options.artifactSrc)
			.pipe(gulp.dest(
				path.join('maven-dist/META-INF/resources/webjars', getName(), getVersion())
		));
	});

	gulp.task('publish-maven-artifact', function() {
		return gulp.src('.')
			.pipe(maven.deploy({
				'config': {
					'artifactId': options.artifactIdPrefix + getName(),
					'buildDir': 'maven-dist',
					'finalName': getFinalName(),
					'groupId': 'com.liferay.webjars',
					'type': 'jar',
					'version': getVersion(),
					'repositories': options.repositories.releases
				}
		}));
	});

	gulp.task('publish-maven-snapshot', function() {
		var snapshotConfig = { snapshot: true };

		return gulp.src('.')
			.pipe(maven.deploy({
				'config': {
					'artifactId': options.artifactIdPrefix + getName(),
					'buildDir': 'maven-dist',
					'finalName': getFinalName(snapshotConfig),
					'groupId': 'com.liferay.webjars',
					'type': 'jar',
					'version': getVersion(snapshotConfig),
					'repositories': options.repositories.snapshots
				}
		}));
	});

	gulp.task('maven-install', function(done) {
		runSequence('prepare-maven-snapshot', 'install-maven-snapshot', 'clean-maven-dist', done);
	});

	gulp.task('maven-publish', function(done) {
		runSequence('prepare-maven-artifact', 'publish-maven-artifact', 'clean-maven-dist', done);
	});

	gulp.task('maven-publish-snapshot', function(done) {
		runSequence('prepare-maven-snapshot', 'publish-maven-snapshot', 'clean-maven-dist', done);
	});
};
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';

var fs          = require('fs');
var merge       = require('merge');
var mergeTrees  = require('broccoli-merge-trees');
var flatiron    = require('broccoli-flatiron');
var Funnel      = require('broccoli-funnel');
var SVGOptmizer = require('./svg-optimizer');

module.exports = {
  name: 'ember-inline-svg',

  options: function() {
    return merge(true, {}, {
      paths:   ['public'],
      optimize: { /* svgo defaults */ }
    }, this.app.options.svg || {});
  },

  svgPaths: function() {
    if (this.isDevelopingAddon()) {
      return ['tests/dummy/public'];
    }
    return this.options().paths;
  },

  optimizeSVGs: function(tree) {
    var config = this.options().optimize;
    if (!config) {
      return tree;
    }

    return new SVGOptmizer(tree, {svgoConfig: config});
  },

  treeForApp: function(tree) {
    var svgs = mergeTrees(this.svgPaths().filter(function(path) {
      return fs.existsSync(path);
    }));

    svgs = new Funnel(svgs, {
      include: [new RegExp(/\.svg$/)]
    });

    svgs = this.optimizeSVGs(svgs);

    svgs = flatiron(svgs, {
      outputFile: 'svgs.js',
      trimExtensions: true
    });

    return mergeTrees([tree, svgs]);
  }
};
<commit_msg>Nested Addon Usage<commit_after>/* jshint node: true */
'use strict';

var fs          = require('fs');
var merge       = require('merge');
var mergeTrees  = require('broccoli-merge-trees');
var flatiron    = require('broccoli-flatiron');
var Funnel      = require('broccoli-funnel');
var SVGOptmizer = require('./svg-optimizer');

module.exports = {
  name: 'ember-inline-svg',

  included: function(app) {
    if (app.app) {
      app = app.app;
    }
    this.app = app;
  },

  options: function() {
    return merge(true, {}, {
      paths:   ['public'],
      optimize: { /* svgo defaults */ }
    }, this.app.options.svg || {});
  },

  svgPaths: function() {
    if (this.isDevelopingAddon()) {
      return ['tests/dummy/public'];
    }
    return this.options().paths;
  },

  optimizeSVGs: function(tree) {
    var config = this.options().optimize;
    if (!config) {
      return tree;
    }

    return new SVGOptmizer(tree, {svgoConfig: config});
  },

  treeForApp: function(tree) {
    var svgs = mergeTrees(this.svgPaths().filter(function(path) {
      return fs.existsSync(path);
    }));

    svgs = new Funnel(svgs, {
      include: [new RegExp(/\.svg$/)]
    });

    svgs = this.optimizeSVGs(svgs);

    svgs = flatiron(svgs, {
      outputFile: 'svgs.js',
      trimExtensions: true
    });

    return mergeTrees([tree, svgs]);
  }
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

var
  clipboard = require('copy-paste'),
  request   = require('request');

var
  FAILURE_EXIT = 1,
  SUCCESS_EXIT = 1;

var options = {
  url: 'http://www.lgtm.in/g',
  method: 'GET',
  json: true
};

request(options, function (error, response, json) {
  if (error) {
    console.log("Error:", error);
    return 1;
  }
  var lgtm = "![LGTM]("+ json.imageUrl +")";
  return clipboard.copy(lgtm);
});
<commit_msg>Add log to see if it's working or not<commit_after>#!/usr/bin/env node
'use strict';

var
  clipboard = require('copy-paste'),
  request   = require('request');

var
  FAILURE_EXIT = 1,
  SUCCESS_EXIT = 1;

var options = {
  url: 'http://www.lgtm.in/g',
  method: 'GET',
  json: true
};

request(options, function (error, response, json) {
  if (error) {
    console.log("Error:", error);
    return 1;
  }
  var lgtm = "![LGTM]("+ json.imageUrl +")";
  console.log(lgtm);
  return clipboard.copy(lgtm);
});
<|endoftext|>


<commit_before>var _ = fis.util;

exports.name = 'inspect [media name]';
exports.desc = 'inspect the result of fis.match ';
exports.options = {
  '-h, --help': 'print this help message',
  '--files'   : 'specify files to be inspected.'
};

exports.run = function(argv, cli) {
  if (argv.h || argv.help) {
    return cli.help(exports.name, exports.options);
  }

  // 如果指定了 media 值
  if (argv._[1]) {
    process.env.NODE_ENV = argv._[1];
  }

  var specified = argv.files;
  var pattern = fis.media().get('project.files');

  if (specified && typeof specified === 'string' && specified !== '::package') {
    pattern = specified.split(/\s*,\s*/);
  }

  var files = fis.project.getSourceByPatterns(pattern);
  var stream = process.stdout;
  var matches = fis.media().getSortedMatches();

  function inspect(value) {
    if (Array.isArray(value)) {
      return '[' + value.map(function(value) {
        if (value && value.__plugin) {
          return ('[plugin `' + value.__plugin + '`]').cyan;
        }

        return value;
      }).join(', ') + ']';
    } else if (value && value.__plugin) {
      return ('[plugin `' + value.__plugin + '`]').cyan;
    }

    return value;
  }

  function output(entry, data) {
    var str = '\n ~ '.bold.yellow;
    var flag = false;

    str += entry + '\n';

    Object.keys(data).forEach(function(key) {
      if (/^__(.*)Index$/.test(key) && RegExp.$1.substr(-1) !== 'F') {
        var propKey = RegExp.$1;
        flag = true;
        str += ' -- ' + propKey + ' ' + inspect(data[propKey]) + ' `' + (matches[data[key]].raw + '').blue + '`   (' + data[key] + 'th)\n';
      }
    });

    if (!flag) {
      str += ' -- empty';
    }
    console.log(str);
  }

  Object.keys(files).forEach(function(subpath) {
    var file = files[subpath];

    output(file.subpath, file);
  });

  var packager = _.applyMatches('::packager', matches, ['prepackager', 'packager', 'spriter', 'postpackager']);
  output('::packager', packager);
};
<commit_msg>update<commit_after>var _ = fis.util;

exports.name = 'inspect [media name]';
exports.desc = 'inspect the result of fis.match ';
exports.options = {
  '-h, --help': 'print this help message',
  '--files'   : 'specify files to be inspected.'
};

exports.run = function(argv, cli) {
  if (argv.h || argv.help) {
    return cli.help(exports.name, exports.options);
  }

  // 如果指定了 media 值
  if (argv._[1]) {
    process.env.NODE_ENV = argv._[1];
  }

  var specified = argv.files;
  var pattern = fis.media().get('project.files');

  if (specified && typeof specified === 'string' && specified !== '::package') {
    pattern = specified.split(/\s*,\s*/);
  }

  var files = fis.project.getSourceByPatterns(pattern);
  var stream = process.stdout;
  var matches = fis.media().getSortedMatches();

  function inspect(value) {
    if (Array.isArray(value)) {
      return '[' + value.map(function(value, _index) {
        if (value && value.__plugin) {
          return ('[plugin `' + value.__plugin + '`]').cyan;
        } else if (fis.util.is(value, 'Function')) {
          return funcToString(value, _index);
        }
        return value;
      }).join(', ') + ']';
    } else if (value && value.__plugin) {
      return ('[plugin `' + funcToString(value.__plugin) + '`]').cyan;
    } else if (fis.util.is(value, 'Function')) {
      return funcToString(value);
    }

    return value;
  }
  function funcToString(fn, _index) {
    if (!fis.util.is(fn, 'Function')) {
      return fn;
    }
    var match = fn.toString().match(/^function\s*(\w+)?\s*\(([, \w]*)\)/);
    if (match) {
      return 'function'+ RegExp.$1 +' (' + RegExp.$2 + ') { ... }'
    }
    return fn;
  }

  function output(entry, data) {
    var str = '\n ~ '.bold.yellow;
    var flag = false;

    str += entry + '\n';

    Object.keys(data).forEach(function(key) {
      if (/^__(.*)Index$/.test(key) && RegExp.$1.substr(-1) !== 'F') {
        var propKey = RegExp.$1;
        flag = true;
        str += ' -- ' + propKey + ' ' + inspect(data[propKey]) + ' `' + (matches[data[key]].raw + '').blue + '`   (' + data[key] + 'th)\n';
      }
    });

    if (!flag) {
      str += ' -- empty';
    }
    console.log(str);
  }

  Object.keys(files).forEach(function(subpath) {
    var file = files[subpath];

    output(file.subpath, file);
  });

  var packager = _.applyMatches('::package', matches, ['prepackager', 'packager', 'spriter', 'postpackager']);
  output('::package', packager);
};
<|endoftext|>


<commit_before>'use strict';

const buscacursos = require('buscacursos-uc');
const MySet = require("collections/set");
const async = require('async');

const util = require('./lib/util');
const generator = require('./lib/initials-generator');

function all(callback) {
  getValidTwoInitials((err, r2s) => {
    if (err) return callback(err);
    r2s = r2s.map(r => r.initials);
    getValidThreeInitials(r2s, (err, r3s) => {
      if (err) return callback(err);
      r3s = r3s.map(r => r.initials);
      deepSearch(r3s, callback);
    });
  });
}

function getValidTwoInitials(callback) {
  let twoInitials = generator(2);
  util.tryInitials(twoInitials, 5, callback);
}

function getValidThreeInitials(twoInitials, callback) {
  const three = new MySet();
  twoInitials.forEach(a => {
    twoInitials.forEach(b => {
      if (a[1] === b[0]) {
        three.add(`${a[0]}${a[1]}${b[1]}`);
      }
    });
  });

  util.tryInitials(three.toArray(), 5, callback);
}

function deepSearch(threeInitials, callback) {
  async.mapLimit(threeInitials, 5, recursiveHandler, function(err, results) {
    if (err) callback(err);
    else callback(null, util.flatten(results));
  });
}

function recursiveHandler(initials, callback) {
  const newInitials = [
    initials + '0',
    initials + '1',
    initials + '2',
    initials + '3'
  ];
  buscacursos.fetch(util.querizer(initials)).then(courses => {
    // console.log(temp, courses.length);
    if (courses.length >= 50) {
      async.mapLimit(newInitials, newInitials.length, recursiveHandler, function(err, r2) {
        callback(err, r2);
      });
    } else {
      callback(null, courses);
    }
  }).catch(err => callback(err));
}

exports.generator = generator;
exports.getValidTwoInitials = getValidTwoInitials;
exports.getValidThreeInitials = getValidThreeInitials;
exports.deepSearch = deepSearch;
exports.all = all;
exports.initials = require('./initials');
<commit_msg>add more cases to deep search<commit_after>'use strict';

const buscacursos = require('buscacursos-uc');
const MySet = require("collections/set");
const async = require('async');

const util = require('./lib/util');
const generator = require('./lib/initials-generator');

function all(callback) {
  getValidTwoInitials((err, r2s) => {
    if (err) return callback(err);
    r2s = r2s.map(r => r.initials);
    getValidThreeInitials(r2s, (err, r3s) => {
      if (err) return callback(err);
      r3s = r3s.map(r => r.initials);
      deepSearch(r3s, callback);
    });
  });
}

function getValidTwoInitials(callback) {
  let twoInitials = generator(2);
  util.tryInitials(twoInitials, 5, callback);
}

function getValidThreeInitials(twoInitials, callback) {
  const three = new MySet();
  twoInitials.forEach(a => {
    twoInitials.forEach(b => {
      if (a[1] === b[0]) {
        three.add(`${a[0]}${a[1]}${b[1]}`);
      }
    });
  });

  util.tryInitials(three.toArray(), 5, callback);
}

function deepSearch(threeInitials, callback) {
  async.mapLimit(threeInitials, 5, recursiveHandler, function(err, results) {
    if (err) callback(err);
    else callback(null, util.flatten(results));
  });
}

function recursiveHandler(initials, callback) {
  buscacursos.fetch(util.querizer(initials)).then(courses => {
    // console.log(initials, courses.length);
    if (courses.length >= 50) {
      const newInitials = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(n => initials + n);
      async.mapLimit(newInitials, newInitials.length, recursiveHandler, function(err, r2) {
        callback(err, r2);
      });
    } else {
      callback(null, courses);
    }
  }).catch(err => callback(err));
}

exports.generator = generator;
exports.getValidTwoInitials = getValidTwoInitials;
exports.getValidThreeInitials = getValidThreeInitials;
exports.deepSearch = deepSearch;
exports.all = all;
exports.initials = require('./initials');
<|endoftext|>


<commit_before>var AWS = require('aws-sdk');
var ffmpeg = require('fluent-ffmpeg');
var q = require('q');
var fs = require('fs');
var path = require('path');
var mime = require('mime');
var gm = require('gm')
          .subClass({imageMagick: true});
var mkdirp = require('mkdirp');
var zlib = require('zlib');

var proc = require('child_process');

process.env['PATH'] = process.env['PATH'] + ':/tmp/:' + process.env['LAMBDA_TASK_ROOT']

var tmpPrefix;
var pathToBash;
var handleS3Event;

if (!process.env.NODE_ENV || process.env.NODE_ENV != 'testing') {
  //production
  tmpPrefix = '/tmp/';
  pathToBash = '/tmp/gif2mp4';
  handleS3Event = require('handle-s3-event');
} else {
  //local
  tmpPrefix = './';
  pathToBash = './bin/gif2mp4';
  handleS3Event = require('./local_modules/handle-s3-event');
}

var s3 = new AWS.S3();

exports.handler = function(event, context) {
  process.env['FFMPEG_PATH'] = '/tmp/ffmpeg';
  process.env['FFPROBE_PATH'] = '/tmp/ffprobe';

  var promises = [];

  if (!process.env.NODE_ENV || process.env.NODE_ENV != 'testing') {
    promises.push(function() {
      return q.Promise(function(resolve, reject, notify) {
        console.log('Manipulating binaries.');
        proc.exec(
          'rm /tmp/*; cp /var/task/ffmpeg /tmp/.; chmod 755 /tmp/ffmpeg; cp /var/task/gif2mp4 /tmp/.; chmod 755 /tmp/gif2mp4;',
          function (error, stdout, stderr) {
            if (error) {
              reject(error)
            } else {
              resolve()
            }
          }
        )
      });

    })
  }

  promises.push(handleS3Event(event))

  promises.push(function(options) {
    return q.Promise(function(resolve, reject) {
      console.log('Pulling .gif from S3.');
      options.gifPath = '/tmp/' + options.srcKey;
      var params = {Bucket: options.srcBucket, Key: options.srcKey};
      var file = require('fs').createWriteStream(options.gifPath);
      var s3Req = s3.getObject(params)
      s3Req.on('complete', function() {
        resolve(options);
      })
      s3Req.on('error', function(err) {
        reject(err);
      });
      s3Req.createReadStream().pipe(file)
    })
  });

  promises.push(function(options) {
    return q.Promise(function(resolve, reject) {
      console.log('Launching script.');

      var child = proc.spawn(pathToBash, [options.gifPath]);
      child.stdout.on('data', function (data) {
        console.log("stdout: " + data);
      });
      child.stderr.on('data', function (data) {
        console.log("stderr: " + data);
      });
      child.on('exit', function (code) {
        if (code != 0) {
          reject(new Error('spawn script err'));
        } else {
          resolve(options);
        }
      });
    });
  });

  promises.push(function(options) {
    var def = q.defer();
    console.log('Ready for upload.');
    options.mp4Path = '/tmp/' + path.basename(options.gifPath, '.gif') + '.mp4';

    var params = {
      Bucket: options.srcBucket,
      Key: path.basename(options.mp4Path),
      ContentType: mime.lookup(options.mp4Path)
    }

    var body = fs.createReadStream(options.mp4Path)
    var s3obj = new AWS.S3({params: params});
    s3obj.upload({Body: body})
      .on('httpUploadProgress', function(evt) {
        console.log('Upload progress: ' + (100 * evt.loaded / evt.total));
      })
      .send(function(err, data) {
        if (err) {
          def.reject(err);
        } else {
          console.log('Successful conversion and upload.');
          def.resolve(options);
        }
      });
    return def.promise;
  });

  promises.push(function(options) {
    var def = q.defer();
    console.log('Finished.');
    context.done();
    def.resolve();
    return def.promise;
  });

  promises.reduce(q.when, q())
    .fail(function(err){
      console.log('Promise rejected with err:');
      context.done(err);
    });
};
<commit_msg>clarifies src/dest s3 Keys<commit_after>var AWS = require('aws-sdk');
var ffmpeg = require('fluent-ffmpeg');
var q = require('q');
var fs = require('fs');
var path = require('path');
var mime = require('mime');
var gm = require('gm')
          .subClass({imageMagick: true});
var mkdirp = require('mkdirp');
var zlib = require('zlib');

var proc = require('child_process');

process.env['PATH'] = process.env['PATH'] + ':/tmp/:' + process.env['LAMBDA_TASK_ROOT']

var tmpPrefix;
var pathToBash;
var handleS3Event;

if (!process.env.NODE_ENV || process.env.NODE_ENV != 'testing') {
  //production
  tmpPrefix = '/tmp/';
  pathToBash = '/tmp/gif2mp4';
  handleS3Event = require('handle-s3-event');
} else {
  //local
  tmpPrefix = './';
  pathToBash = './bin/gif2mp4';
  handleS3Event = require('./local_modules/handle-s3-event');
}

var s3 = new AWS.S3();

exports.handler = function(event, context) {
  process.env['FFMPEG_PATH'] = '/tmp/ffmpeg';
  process.env['FFPROBE_PATH'] = '/tmp/ffprobe';

  var promises = [];

  if (!process.env.NODE_ENV || process.env.NODE_ENV != 'testing') {
    promises.push(function() {
      return q.Promise(function(resolve, reject, notify) {
        console.log('Manipulating binaries.');
        proc.exec(
          'rm /tmp/*; cp /var/task/ffmpeg /tmp/.; chmod 755 /tmp/ffmpeg; cp /var/task/gif2mp4 /tmp/.; chmod 755 /tmp/gif2mp4;',
          function (error, stdout, stderr) {
            if (error) {
              reject(error)
            } else {
              resolve()
            }
          }
        )
      });

    })
  }

  promises.push(handleS3Event(event))

  promises.push(function(options) {
    return q.Promise(function(resolve, reject) {
      console.log('Pulling .gif from S3.');
      options.gifPath = '/tmp/' + path.basename(options.srcKey);
      var params = {Bucket: options.srcBucket, Key: options.srcKey};
      var file = require('fs').createWriteStream(options.gifPath);
      var s3Req = s3.getObject(params)
      s3Req.on('complete', function() {
        resolve(options);
      })
      s3Req.on('error', function(err) {
        reject(err);
      });
      s3Req.createReadStream().pipe(file)
    })
  });

  promises.push(function(options) {
    return q.Promise(function(resolve, reject) {
      console.log('Launching script.');

      var child = proc.spawn(pathToBash, [options.gifPath]);
      child.stdout.on('data', function (data) {
        console.log("stdout: " + data);
      });
      child.stderr.on('data', function (data) {
        console.log("stderr: " + data);
      });
      child.on('exit', function (code) {
        if (code != 0) {
          reject(new Error('spawn script err'));
        } else {
          resolve(options);
        }
      });
    });
  });

  promises.push(function(options) {
    var def = q.defer();
    console.log('Ready for upload.');
    options.mp4Path = '/tmp/' + path.basename(options.gifPath, '.gif') + '.mp4';

    var params = {
      Bucket: options.srcBucket,
      Key: path.dirname(options.srcKey) + "/" + path.basename(options.mp4Path),
      ContentType: mime.lookup(options.mp4Path)
    }

    var body = fs.createReadStream(options.mp4Path)
    var s3obj = new AWS.S3({params: params});
    s3obj.upload({Body: body})
      .on('httpUploadProgress', function(evt) {
        console.log('Upload progress: ' + (100 * evt.loaded / evt.total));
      })
      .send(function(err, data) {
        if (err) {
          def.reject(err);
        } else {
          console.log('Successful conversion and upload.');
          def.resolve(options);
        }
      });
    return def.promise;
  });

  promises.push(function(options) {
    var def = q.defer();
    console.log('Finished.');
    context.done();
    def.resolve();
    return def.promise;
  });

  promises.reduce(q.when, q())
    .fail(function(err){
      console.log('Promise rejected with err:');
      context.done(err);
    });
};
<|endoftext|>


<commit_before>'use strict'

var http = require('http')
var util = require('util')
var events = require('events')
var OpbeatHttpClient = require('opbeat-http-client')
var ReleaseTracker = require('opbeat-release-tracker')
var config = require('./lib/config')
var parsers = require('./lib/parsers')
var request = require('./lib/request')
var connect = require('./lib/middleware/connect')

var userAgent = 'opbeat-nodejs/' + require('./package').version

var Client = function (opts) {
  if (!(this instanceof Client)) return new Client(opts)

  var client = this

  opts = config(opts)
  this.appId = opts.appId
  this.organizationId = opts.organizationId
  this.secretToken = opts.secretToken
  this.active = opts.active
  this.clientLogLevel = opts.clientLogLevel
  this.logger = opts.logger
  this.hostname = opts.hostname
  this.stackTraceLimit = opts.stackTraceLimit
  this.captureExceptions = opts.captureExceptions
  this.exceptionLogLevel = opts.exceptionLogLevel
  this.filter = opts.filter
  this._ff_captureFrame = opts._ff_captureFrame

  connect = connect.bind(this)
  this.middleware = { connect: connect, express: connect }

  if (!this.active) {
    this.logger.info('Opbeat logging is disabled for now')
    return
  } else if (!this.appId || !this.organizationId || !this.secretToken) {
    this.logger.info('[WARNING] Opbeat logging is disabled. To enable, specify organization id, app id and secret token')
    this.active = false
    return
  }

  this._httpClient = OpbeatHttpClient({
    appId: this.appId,
    organizationId: this.organizationId,
    secretToken: this.secretToken,
    userAgent: userAgent
  })

  Error.stackTraceLimit = this.stackTraceLimit
  if (this.captureExceptions) this.handleUncaughtExceptions()

  this.on('error', this._internalErrorLogger)
  this.on('logged', function (url) {
    client.logger.info('Opbeat logged error successfully at ' + url)
  })
}
util.inherits(Client, events.EventEmitter)

Client.prototype._internalErrorLogger = function (err) {
  this.logger.info('Could not notify Opbeat!')
  this.logger.error(err.stack)
}

Client.prototype.captureError = function (err, data, cb) {
  var client = this
  var captureTime = new Date()

  if (typeof data === 'function') {
    cb = data
    data = {}
  } else if (!data) {
    data = {}
  } else if (data.request instanceof http.IncomingMessage) {
    data.http = parsers.parseRequest(data.request)
  }
  delete data.request

  var level = this.exceptionLogLevel || 'error'
  level = level === 'warning' ? 'warn' : level

  if (!util.isError(err)) {
    var isMessage = true
    var customCulprit = 'culprit' in data
    parsers.parseMessage(err, data)
    this.logger[level](data.message)
    err = new Error(data.message)
  } else if (this._ff_captureFrame && !err.uncaught) {
    var captureFrameError = new Error()
  }

  parsers.parseError(err, data, function (data) {
    if (isMessage) {
      // Messages shouldn't have an exception and the algorithm for finding the
      // culprit might show the Opbeat client and we don't want that
      delete data.exception
      if (!customCulprit) delete data.culprit
      data.stacktrace.frames.shift()
    } else {
      client.logger[level](err.stack)
    }

    var done = function () {
      data.stacktrace.frames.reverse() // opbeat expects frames in reverse order
      data.machine = { hostname: client.hostname }
      data.extra = data.extra || {}
      data.extra.node = process.version
      data.timestamp = captureTime.toISOString()

      if (client.filter) data = client.filter(err, data)
      if (client.active) request.error(client, data, cb)
    }

    if (captureFrameError && !data.stacktrace.frames.some(function (frame) { return frame.in_app })) {
      // prepare to add a top frame to the stack trace specifying the location
      // where captureError was called from. This can make it easier to debug
      // async stack traces.
      parsers.parseError(captureFrameError, {}, function (result) {
        // ignore the first frame as it will be the opbeat module
        data.stacktrace.frames.unshift(result.stacktrace.frames[1])
        done()
      })
    } else {
      done()
    }
  })
}

// The optional callback will be called with the error object after the
// error have been logged to Opbeat. If no callback have been provided
// we will automatically terminate the process, so if you provide a
// callback you must remember to terminate the process manually.
Client.prototype.handleUncaughtExceptions = function (cb) {
  var client = this

  if (this._uncaughtExceptionListener) process.removeListener('uncaughtException', this._uncaughtExceptionListener)

  this._uncaughtExceptionListener = function (err) {
    client.logger.debug('Opbeat caught unhandled exception')

    // Since we exit the node-process we cannot guarantee that the
    // listeners will be called, so to ensure a uniform result,
    // we'll remove all event listeners if an uncaught exception is
    // found
    client.removeAllListeners()
    // But make sure emitted errors doesn't cause yet another uncaught
    // exception
    client.on('error', client._internalErrorLogger)

    err.uncaught = true

    var data = {
      level: client.exceptionLogLevel
    }
    client.captureError(err, data, function (opbeatErr, url) {
      if (opbeatErr) {
        client.logger.info('Could not notify Opbeat!')
        client.logger.error(opbeatErr.stack)
      } else {
        client.logger.info('Opbeat logged error successfully at ' + url)
      }
      cb ? cb(err, url) : process.exit(1)
    })
  }

  process.on('uncaughtException', this._uncaughtExceptionListener)
}

Client.prototype.trackRelease = function (data, cb) {
  if (data.path) {
    this.logger.warn('Detected use of deprecated path option to trackRelease function!')
    if (!data.cwd) data.cwd = data.path
  }
  if (!this._releaseTracker) this._releaseTracker = ReleaseTracker(this._httpClient)
  var client = this
  this._releaseTracker(data, function (err) {
    if (cb) cb(err)
    if (err) client.emit('error', err)
  })
}

Client.prototype.trackDeployment = Client.prototype.trackRelease

module.exports = Client
<commit_msg>Output stack trace ASAP<commit_after>'use strict'

var http = require('http')
var util = require('util')
var events = require('events')
var OpbeatHttpClient = require('opbeat-http-client')
var ReleaseTracker = require('opbeat-release-tracker')
var config = require('./lib/config')
var parsers = require('./lib/parsers')
var request = require('./lib/request')
var connect = require('./lib/middleware/connect')

var userAgent = 'opbeat-nodejs/' + require('./package').version

var Client = function (opts) {
  if (!(this instanceof Client)) return new Client(opts)

  var client = this

  opts = config(opts)
  this.appId = opts.appId
  this.organizationId = opts.organizationId
  this.secretToken = opts.secretToken
  this.active = opts.active
  this.clientLogLevel = opts.clientLogLevel
  this.logger = opts.logger
  this.hostname = opts.hostname
  this.stackTraceLimit = opts.stackTraceLimit
  this.captureExceptions = opts.captureExceptions
  this.exceptionLogLevel = opts.exceptionLogLevel
  this.filter = opts.filter
  this._ff_captureFrame = opts._ff_captureFrame

  connect = connect.bind(this)
  this.middleware = { connect: connect, express: connect }

  if (!this.active) {
    this.logger.info('Opbeat logging is disabled for now')
    return
  } else if (!this.appId || !this.organizationId || !this.secretToken) {
    this.logger.info('[WARNING] Opbeat logging is disabled. To enable, specify organization id, app id and secret token')
    this.active = false
    return
  }

  this._httpClient = OpbeatHttpClient({
    appId: this.appId,
    organizationId: this.organizationId,
    secretToken: this.secretToken,
    userAgent: userAgent
  })

  Error.stackTraceLimit = this.stackTraceLimit
  if (this.captureExceptions) this.handleUncaughtExceptions()

  this.on('error', this._internalErrorLogger)
  this.on('logged', function (url) {
    client.logger.info('Opbeat logged error successfully at ' + url)
  })
}
util.inherits(Client, events.EventEmitter)

Client.prototype._internalErrorLogger = function (err) {
  this.logger.info('Could not notify Opbeat!')
  this.logger.error(err.stack)
}

Client.prototype.captureError = function (err, data, cb) {
  var client = this
  var captureTime = new Date()

  if (typeof data === 'function') {
    cb = data
    data = {}
  } else if (!data) {
    data = {}
  } else if (data.request instanceof http.IncomingMessage) {
    data.http = parsers.parseRequest(data.request)
  }
  delete data.request

  var level = this.exceptionLogLevel || 'error'
  level = level === 'warning' ? 'warn' : level

  if (!util.isError(err)) {
    var isMessage = true
    var customCulprit = 'culprit' in data
    parsers.parseMessage(err, data)
    this.logger[level](data.message)
    err = new Error(data.message)
  } else if (this._ff_captureFrame && !err.uncaught) {
    var captureFrameError = new Error()
  }

  if (!isMessage) client.logger[level](err.stack)

  parsers.parseError(err, data, function (data) {
    if (isMessage) {
      // Messages shouldn't have an exception and the algorithm for finding the
      // culprit might show the Opbeat client and we don't want that
      delete data.exception
      if (!customCulprit) delete data.culprit
      data.stacktrace.frames.shift()
    }

    var done = function () {
      data.stacktrace.frames.reverse() // opbeat expects frames in reverse order
      data.machine = { hostname: client.hostname }
      data.extra = data.extra || {}
      data.extra.node = process.version
      data.timestamp = captureTime.toISOString()

      if (client.filter) data = client.filter(err, data)
      if (client.active) request.error(client, data, cb)
    }

    if (captureFrameError && !data.stacktrace.frames.some(function (frame) { return frame.in_app })) {
      // prepare to add a top frame to the stack trace specifying the location
      // where captureError was called from. This can make it easier to debug
      // async stack traces.
      parsers.parseError(captureFrameError, {}, function (result) {
        // ignore the first frame as it will be the opbeat module
        data.stacktrace.frames.unshift(result.stacktrace.frames[1])
        done()
      })
    } else {
      done()
    }
  })
}

// The optional callback will be called with the error object after the
// error have been logged to Opbeat. If no callback have been provided
// we will automatically terminate the process, so if you provide a
// callback you must remember to terminate the process manually.
Client.prototype.handleUncaughtExceptions = function (cb) {
  var client = this

  if (this._uncaughtExceptionListener) process.removeListener('uncaughtException', this._uncaughtExceptionListener)

  this._uncaughtExceptionListener = function (err) {
    client.logger.debug('Opbeat caught unhandled exception')

    // Since we exit the node-process we cannot guarantee that the
    // listeners will be called, so to ensure a uniform result,
    // we'll remove all event listeners if an uncaught exception is
    // found
    client.removeAllListeners()
    // But make sure emitted errors doesn't cause yet another uncaught
    // exception
    client.on('error', client._internalErrorLogger)

    err.uncaught = true

    var data = {
      level: client.exceptionLogLevel
    }
    client.captureError(err, data, function (opbeatErr, url) {
      if (opbeatErr) {
        client.logger.info('Could not notify Opbeat!')
        client.logger.error(opbeatErr.stack)
      } else {
        client.logger.info('Opbeat logged error successfully at ' + url)
      }
      cb ? cb(err, url) : process.exit(1)
    })
  }

  process.on('uncaughtException', this._uncaughtExceptionListener)
}

Client.prototype.trackRelease = function (data, cb) {
  if (data.path) {
    this.logger.warn('Detected use of deprecated path option to trackRelease function!')
    if (!data.cwd) data.cwd = data.path
  }
  if (!this._releaseTracker) this._releaseTracker = ReleaseTracker(this._httpClient)
  var client = this
  this._releaseTracker(data, function (err) {
    if (cb) cb(err)
    if (err) client.emit('error', err)
  })
}

Client.prototype.trackDeployment = Client.prototype.trackRelease

module.exports = Client
<|endoftext|>


<commit_before>var util = require('util');
var hark = require('hark');
var webrtc = require('webrtcsupport');
var getUserMedia = require('getusermedia');
var getScreenMedia = require('getscreenmedia');
var WildEmitter = require('wildemitter');
var GainController = require('mediastream-gain');
var mockconsole = require('mockconsole');

function LocalMedia(opts) {
    WildEmitter.call(this);

    var config = this.config = {
        autoAdjustMic: false,
        detectSpeakingEvents: true,
        media: {
            audio: true,
            video: true
        },
        logger: mockconsole
    };

    var item;
    for (item in opts) {
        this.config[item] = opts[item];
    }

    this.logger = config.logger;
    this._log = this.logger.log.bind(this.logger, 'LocalMedia:');
    this._logerror = this.logger.error.bind(this.logger, 'LocalMedia:');

    this.screenSharingSupport = webrtc.screenSharing;

    this.localStreams = [];
    this.localScreens = [];

    if (!webrtc.support) {
        this._logerror('Your browser does not support local media capture.');
    }
}

util.inherits(LocalMedia, WildEmitter);

LocalMedia.prototype.start = function (mediaConstraints, cb) {
    var self = this;
    var constraints = mediaConstraints || this.config.media;

    getUserMedia(constraints, function (err, stream) {
        if (!err) {
            if (constraints.audio && self.config.detectSpeakingEvents) {
                self.setupAudioMonitor(stream);
            }
            self.localStreams.push(stream);

            if (self.config.autoAdjustMic) {
                self.gainController = new GainController(stream);
                // start out somewhat muted if we can track audio
                self.setMicIfEnabled(0.5);
            }

            // TODO: might need to migrate to the video tracks onended
            // FIXME: firefox does not seem to trigger this...
            stream.onended = function () {
                /*
                var idx = self.localStreams.indexOf(stream);
                if (idx > -1) {
                    self.localScreens.splice(idx, 1);
                }
                self.emit('localStreamStopped', stream);
                */
            };

            self.emit('localStream', stream);
        }
        if (cb) {
            return cb(err, stream);
        }
    });
};

LocalMedia.prototype.stop = function (stream) {
    var self = this;
    // FIXME: duplicates cleanup code until fixed in FF
    if (stream) {
        stream.stop();
        self.emit('localStreamStopped', stream);
        var idx = self.localStreams.indexOf(stream);
        if (idx > -1) {
            self.localStreams = self.localStreams.splice(idx, 1);
        }
    } else {
        this.localStreams.forEach(function (stream) {
            stream.stop();
            self.emit('localStreamStopped', stream);
        });
        this.localStreams = [];
    }
};

LocalMedia.prototype.startScreenShare = function (cb) {
    var self = this;
    getScreenMedia(function (err, stream) {
        if (!err) {
            self.localScreens.push(stream);

            // TODO: might need to migrate to the video tracks onended
            // Firefox does not support .onended but it does not support
            // screensharing either
            stream.onended = function () {
                var idx = self.localScreens.indexOf(stream);
                if (idx > -1) {
                    self.localScreens.splice(idx, 1);
                }
                self.emit('localScreenStopped', stream);
            };
            self.emit('localScreen', stream);
        }

        // enable the callback
        if (cb) {
            return cb(err, stream);
        }
    });
};

LocalMedia.prototype.stopScreenShare = function (stream) {
    if (stream) {
        stream.stop();
    } else {
        this.localScreens.forEach(function (stream) {
            stream.stop();
        });
        this.localScreens = [];
    }
};

// Audio controls
LocalMedia.prototype.mute = function () {
    this._audioEnabled(false);
    this.hardMuted = true;
    this.emit('audioOff');
};

LocalMedia.prototype.unmute = function () {
    this._audioEnabled(true);
    this.hardMuted = false;
    this.emit('audioOn');
};

LocalMedia.prototype.setupAudioMonitor = function (stream) {
    this._log('Setup audio');
    var audio = hark(stream);
    var self = this;
    var timeout;

    audio.on('speaking', function () {
        self.emit('speaking');
        if (self.hardMuted) {
            return;
        }
        self.setMicIfEnabled(1);
    });

    audio.on('stopped_speaking', function () {
        if (timeout) {
            clearTimeout(timeout);
        }

        timeout = setTimeout(function () {
            self.emit('stoppedSpeaking');
            if (self.hardMuted) {
                return;
            }
            self.setMicIfEnabled(0.5);
        }, 1000);
    });
    audio.on('volume_change', function (volume, treshold) {
        self.emit('volumeChange', volume, treshold);
    });
};

// We do this as a seperate method in order to
// still leave the "setMicVolume" as a working
// method.
LocalMedia.prototype.setMicIfEnabled = function (volume) {
    if (!this.config.autoAdjustMic) {
        return;
    }
    this.gainController.setGain(volume);
};

// Video controls
LocalMedia.prototype.pauseVideo = function () {
    this._videoEnabled(false);
    this.emit('videoOff');
};
LocalMedia.prototype.resumeVideo = function () {
    this._videoEnabled(true);
    this.emit('videoOn');
};

// Combined controls
LocalMedia.prototype.pause = function () {
    this._audioEnabled(false);
    this.pauseVideo();
};
LocalMedia.prototype.resume = function () {
    this._audioEnabled(true);
    this.resumeVideo();
};

// Internal methods for enabling/disabling audio/video
LocalMedia.prototype._audioEnabled = function (bool) {
    // work around for chrome 27 bug where disabling tracks
    // doesn't seem to work (works in canary, remove when working)
    this.setMicIfEnabled(bool ? 1 : 0);
    this.localStreams.forEach(function (stream) {
        stream.getAudioTracks().forEach(function (track) {
            track.enabled = !!bool;
        });
    });
};
LocalMedia.prototype._videoEnabled = function (bool) {
    this.localStreams.forEach(function (stream) {
        stream.getVideoTracks().forEach(function (track) {
            track.enabled = !!bool;
        });
    });
};

// check if all audio streams are enabled
LocalMedia.prototype.isAudioEnabled = function () {
    var enabled = true;
    this.localStreams.forEach(function (stream) {
        stream.getAudioTracks().forEach(function (track) {
            enabled = enabled && track.enabled;
        });
    });
    return enabled;
};

// check if all video streams are enabled
LocalMedia.prototype.isVideoEnabled = function () {
    var enabled = true;
    this.localStreams.forEach(function (stream) {
        stream.getVideoTracks().forEach(function (track) {
            enabled = enabled && track.enabled;
        });
    });
    return enabled;
};

// Backwards Compat
LocalMedia.prototype.startLocalMedia = LocalMedia.prototype.start;
LocalMedia.prototype.stopLocalMedia = LocalMedia.prototype.stop;

// fallback for old .localStream behaviour
Object.defineProperty(LocalMedia.prototype, 'localStream', {
    get: function () {
        return this.localStreams.length > 0 ? this.localStreams[0] : null;
    }
});
// fallback for old .localScreen behaviour
Object.defineProperty(LocalMedia.prototype, 'localScreen', {
    get: function () {
        return this.localScreens.length > 0 ? this.localScreens[0] : null;
    }
});

module.exports = LocalMedia;
<commit_msg>Pass options to hark<commit_after>var util = require('util');
var hark = require('hark');
var webrtc = require('webrtcsupport');
var getUserMedia = require('getusermedia');
var getScreenMedia = require('getscreenmedia');
var WildEmitter = require('wildemitter');
var GainController = require('mediastream-gain');
var mockconsole = require('mockconsole');

function LocalMedia(opts) {
    WildEmitter.call(this);

    var config = this.config = {
        autoAdjustMic: false,
        detectSpeakingEvents: true,
        media: {
            audio: true,
            video: true
        },
        logger: mockconsole
    };

    var item;
    for (item in opts) {
        this.config[item] = opts[item];
    }

    this.logger = config.logger;
    this._log = this.logger.log.bind(this.logger, 'LocalMedia:');
    this._logerror = this.logger.error.bind(this.logger, 'LocalMedia:');

    this.screenSharingSupport = webrtc.screenSharing;

    this.localStreams = [];
    this.localScreens = [];

    if (!webrtc.support) {
        this._logerror('Your browser does not support local media capture.');
    }
}

util.inherits(LocalMedia, WildEmitter);

LocalMedia.prototype.start = function (mediaConstraints, cb) {
    var self = this;
    var constraints = mediaConstraints || this.config.media;

    getUserMedia(constraints, function (err, stream) {
        if (!err) {
            if (constraints.audio && self.config.detectSpeakingEvents) {
                self.setupAudioMonitor(stream, self.config.harkOptions);
            }
            self.localStreams.push(stream);

            if (self.config.autoAdjustMic) {
                self.gainController = new GainController(stream);
                // start out somewhat muted if we can track audio
                self.setMicIfEnabled(0.5);
            }

            // TODO: might need to migrate to the video tracks onended
            // FIXME: firefox does not seem to trigger this...
            stream.onended = function () {
                /*
                var idx = self.localStreams.indexOf(stream);
                if (idx > -1) {
                    self.localScreens.splice(idx, 1);
                }
                self.emit('localStreamStopped', stream);
                */
            };

            self.emit('localStream', stream);
        }
        if (cb) {
            return cb(err, stream);
        }
    });
};

LocalMedia.prototype.stop = function (stream) {
    var self = this;
    // FIXME: duplicates cleanup code until fixed in FF
    if (stream) {
        stream.stop();
        self.emit('localStreamStopped', stream);
        var idx = self.localStreams.indexOf(stream);
        if (idx > -1) {
            self.localStreams = self.localStreams.splice(idx, 1);
        }
    } else {
        this.localStreams.forEach(function (stream) {
            stream.stop();
            self.emit('localStreamStopped', stream);
        });
        this.localStreams = [];
    }
};

LocalMedia.prototype.startScreenShare = function (cb) {
    var self = this;
    getScreenMedia(function (err, stream) {
        if (!err) {
            self.localScreens.push(stream);

            // TODO: might need to migrate to the video tracks onended
            // Firefox does not support .onended but it does not support
            // screensharing either
            stream.onended = function () {
                var idx = self.localScreens.indexOf(stream);
                if (idx > -1) {
                    self.localScreens.splice(idx, 1);
                }
                self.emit('localScreenStopped', stream);
            };
            self.emit('localScreen', stream);
        }

        // enable the callback
        if (cb) {
            return cb(err, stream);
        }
    });
};

LocalMedia.prototype.stopScreenShare = function (stream) {
    if (stream) {
        stream.stop();
    } else {
        this.localScreens.forEach(function (stream) {
            stream.stop();
        });
        this.localScreens = [];
    }
};

// Audio controls
LocalMedia.prototype.mute = function () {
    this._audioEnabled(false);
    this.hardMuted = true;
    this.emit('audioOff');
};

LocalMedia.prototype.unmute = function () {
    this._audioEnabled(true);
    this.hardMuted = false;
    this.emit('audioOn');
};

LocalMedia.prototype.setupAudioMonitor = function (stream, harkOptions) {
    this._log('Setup audio');
    var audio = hark(stream, harkOptions);
    var self = this;
    var timeout;

    audio.on('speaking', function () {
        self.emit('speaking');
        if (self.hardMuted) {
            return;
        }
        self.setMicIfEnabled(1);
    });

    audio.on('stopped_speaking', function () {
        if (timeout) {
            clearTimeout(timeout);
        }

        timeout = setTimeout(function () {
            self.emit('stoppedSpeaking');
            if (self.hardMuted) {
                return;
            }
            self.setMicIfEnabled(0.5);
        }, 1000);
    });
    audio.on('volume_change', function (volume, treshold) {
        self.emit('volumeChange', volume, treshold);
    });
};

// We do this as a seperate method in order to
// still leave the "setMicVolume" as a working
// method.
LocalMedia.prototype.setMicIfEnabled = function (volume) {
    if (!this.config.autoAdjustMic) {
        return;
    }
    this.gainController.setGain(volume);
};

// Video controls
LocalMedia.prototype.pauseVideo = function () {
    this._videoEnabled(false);
    this.emit('videoOff');
};
LocalMedia.prototype.resumeVideo = function () {
    this._videoEnabled(true);
    this.emit('videoOn');
};

// Combined controls
LocalMedia.prototype.pause = function () {
    this._audioEnabled(false);
    this.pauseVideo();
};
LocalMedia.prototype.resume = function () {
    this._audioEnabled(true);
    this.resumeVideo();
};

// Internal methods for enabling/disabling audio/video
LocalMedia.prototype._audioEnabled = function (bool) {
    // work around for chrome 27 bug where disabling tracks
    // doesn't seem to work (works in canary, remove when working)
    this.setMicIfEnabled(bool ? 1 : 0);
    this.localStreams.forEach(function (stream) {
        stream.getAudioTracks().forEach(function (track) {
            track.enabled = !!bool;
        });
    });
};
LocalMedia.prototype._videoEnabled = function (bool) {
    this.localStreams.forEach(function (stream) {
        stream.getVideoTracks().forEach(function (track) {
            track.enabled = !!bool;
        });
    });
};

// check if all audio streams are enabled
LocalMedia.prototype.isAudioEnabled = function () {
    var enabled = true;
    this.localStreams.forEach(function (stream) {
        stream.getAudioTracks().forEach(function (track) {
            enabled = enabled && track.enabled;
        });
    });
    return enabled;
};

// check if all video streams are enabled
LocalMedia.prototype.isVideoEnabled = function () {
    var enabled = true;
    this.localStreams.forEach(function (stream) {
        stream.getVideoTracks().forEach(function (track) {
            enabled = enabled && track.enabled;
        });
    });
    return enabled;
};

// Backwards Compat
LocalMedia.prototype.startLocalMedia = LocalMedia.prototype.start;
LocalMedia.prototype.stopLocalMedia = LocalMedia.prototype.stop;

// fallback for old .localStream behaviour
Object.defineProperty(LocalMedia.prototype, 'localStream', {
    get: function () {
        return this.localStreams.length > 0 ? this.localStreams[0] : null;
    }
});
// fallback for old .localScreen behaviour
Object.defineProperty(LocalMedia.prototype, 'localScreen', {
    get: function () {
        return this.localScreens.length > 0 ? this.localScreens[0] : null;
    }
});

module.exports = LocalMedia;
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';

var Funnel = require('broccoli-funnel');
var Concat = require('broccoli-concat');
var Merge = require('broccoli-merge-trees');
var ProcessStyles = require('./lib/pod-style.js');
var ExtractNames = require('./lib/pod-names.js');
var IncludeAll = require('./lib/include-all.js');

module.exports = {

  _getPodStyleFunnel: function() {
    return new Funnel('app', {
      srcDir: this._podDirectory(),
      exclude: ['styles/**/*'],
      include: ['**/*.{' + this.allowedStyleExtentions + '}'],
      allowEmpty: true,
      annotation: 'Funnel (ember-component-css grab files)'
    });
  },

  _podDirectory: function() {
    return this.appConfig.podModulePrefix ? this.appConfig.podModulePrefix.replace(this.appConfig.modulePrefix, '') : '';
  },

  included: function(app) {
    this._super.included.apply(this, arguments);
    this.appConfig = app.project.config();
    this.allowedStyleExtentions = app.registry.extensionsForType('css');
  },

  treeForAddon: function(tree) {
    var podStyles = this._getPodStyleFunnel();
    var podNames = new ExtractNames(podStyles, {
      annotation: 'Walk (ember-component-css extract class names from style paths)'
    });

    var treeAndNames = new Merge([tree, podNames], {
      overwrite: true,
      annotation: 'Merge (ember-component-css merge names with addon tree)'
    });

    return this._super.treeForAddon.call(this, treeAndNames);
  },

  treeForStyles: function(tree) {
    var podStyles = this._getPodStyleFunnel();

    var processedStyles = new ProcessStyles(podStyles, {
      extensions: this.allowedStyleExtentions,
      annotation: 'Filter (ember-component-css process :--component with class names)'
    });

    var podStyles = new IncludeAll(processedStyles, {
      annotation: 'IncludeAll (ember-component-css combining all style files that there are extentions for)'
    });

    return this._super.treeForStyles.call(this, podStyles);
  },

  name: 'ember-component-css'
};
<commit_msg>Filter undefined type extensions.<commit_after>/* jshint node: true */
'use strict';

var Funnel = require('broccoli-funnel');
var Concat = require('broccoli-concat');
var Merge = require('broccoli-merge-trees');
var ProcessStyles = require('./lib/pod-style.js');
var ExtractNames = require('./lib/pod-names.js');
var IncludeAll = require('./lib/include-all.js');

module.exports = {

  _getPodStyleFunnel: function() {
    return new Funnel('app', {
      srcDir: this._podDirectory(),
      exclude: ['styles/**/*'],
      include: ['**/*.{' + this.allowedStyleExtentions + '}'],
      allowEmpty: true,
      annotation: 'Funnel (ember-component-css grab files)'
    });
  },

  _podDirectory: function() {
    return this.appConfig.podModulePrefix ? this.appConfig.podModulePrefix.replace(this.appConfig.modulePrefix, '') : '';
  },

  included: function(app) {
    this._super.included.apply(this, arguments);
    this.appConfig = app.project.config();
    this.allowedStyleExtentions = app.registry.extensionsForType('css').filter(Boolean);
  },

  treeForAddon: function(tree) {
    var podStyles = this._getPodStyleFunnel();
    var podNames = new ExtractNames(podStyles, {
      annotation: 'Walk (ember-component-css extract class names from style paths)'
    });

    var treeAndNames = new Merge([tree, podNames], {
      overwrite: true,
      annotation: 'Merge (ember-component-css merge names with addon tree)'
    });

    return this._super.treeForAddon.call(this, treeAndNames);
  },

  treeForStyles: function(tree) {
    var podStyles = this._getPodStyleFunnel();

    var processedStyles = new ProcessStyles(podStyles, {
      extensions: this.allowedStyleExtentions,
      annotation: 'Filter (ember-component-css process :--component with class names)'
    });

    var podStyles = new IncludeAll(processedStyles, {
      annotation: 'IncludeAll (ember-component-css combining all style files that there are extentions for)'
    });

    return this._super.treeForStyles.call(this, podStyles);
  },

  name: 'ember-component-css'
};
<|endoftext|>


<commit_before>'use strict';

module.exports = Protobuf;

var Buffer = typeof window !== 'undefined' ? require('./buffer') : global.Buffer;

function Protobuf(buf) {
    this.buf = buf instanceof Uint8Array ? Buffer.wrap(buf) : buf;
    this.pos = 0;
}

Protobuf.prototype = {
    get length() { return this.buf.length; }
};

Protobuf.Varint  = 0; // varint: int32, int64, uint32, uint64, sint32, sint64, bool, enum
Protobuf.Fixed64 = 1; // double, fixed64, sfixed64
Protobuf.Bytes   = 2; // length-delimited: string, bytes, embedded messages, packed repeated fields
Protobuf.Fixed32 = 5; // float, fixed32, sfixed32

Protobuf.prototype.destroy = function() {
    this.buf = null;
};

var SHIFT_LEFT_32 = (1 << 16) * (1 << 16),
    SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32;

// === READING =================================================================

Protobuf.prototype.read = function(readField, end) {
    var buf = this.buf;
    end = end || buf.length;

    while (this.pos < end) {
        var val = this.readVarint(),
            tag = val >> 3,
            startPos = this.pos;
        readField(tag);
        if (this.pos === startPos) this.skip(val);
    }
};

Protobuf.prototype.readMessage = function(readField) {
    var bytes = this.readVarint();
    this.read(readField, this.pos + bytes);
};

Protobuf.prototype.readFixed32 = function() {
    var val = this.buf.readUInt32LE(this.pos);
    this.pos += 4;
    return val;
};

Protobuf.prototype.readFixed64 = function() {
    var val = this.buf.readUInt32LE(this.pos) + this.buf.readUInt32LE(this.pos + 4) * SHIFT_LEFT_32;
    this.pos += 8;
    return val;
};

Protobuf.prototype.readFloat = function() {
    var val = this.buf.readFloatLE(this.pos);
    this.pos += 4;
    return val;
};

Protobuf.prototype.readDouble = function() {
    var val = this.buf.readDoubleLE(this.pos);
    this.pos += 8;
    return val;
};

Protobuf.prototype.readVarint = function() {
    // TODO: bounds checking
    var buf = this.buf,
        val, b, b0, b1, b2, b3;

    b0 = buf[this.pos++]; if (b0 < 0x80) return b0; b0 = b0 & 0x7f;
    b1 = buf[this.pos++]; if (b1 < 0x80) return b0 | b1 << 7; b1 = (b1 & 0x7f) << 7;
    b2 = buf[this.pos++]; if (b2 < 0x80) return b0 | b1 | b2 << 14; b2 = (b2 & 0x7f) << 14;
    b3 = buf[this.pos++]; if (b3 < 0x80) return b0 | b1 | b2 | b3 << 21;

    val = b0 | b1 | b2 | (b3 & 0x7f) << 21;

    b = buf[this.pos++]; val += (b & 0x7f) * 0x10000000; if (b < 0x80) return val;
    b = buf[this.pos++]; val += (b & 0x7f) * 0x800000000; if (b < 0x80) return val;
    b = buf[this.pos++]; val += (b & 0x7f) * 0x40000000000; if (b < 0x80) return val;
    b = buf[this.pos++]; val += (b & 0x7f) * 0x2000000000000; if (b < 0x80) return val;
    b = buf[this.pos++]; val += (b & 0x7f) * 0x100000000000000; if (b < 0x80) return val;
    b = buf[this.pos++]; val += (b & 0x7f) * 0x8000000000000000; if (b < 0x80) return val;

    throw new Error('Expected varint not more than 10 bytes');
};

Protobuf.prototype.readSVarint = function() {
    var num = this.readVarint();
    if (num > 2147483647) throw new Error('TODO: Handle numbers >= 2^30');
    // zigzag encoding
    return ((num >> 1) ^ -(num & 1));
};

Protobuf.prototype.readBoolean = function() {
    return Boolean(this.readVarint());
};

Protobuf.prototype.readString = function() {
    var bytes = this.readVarint(),
        str = this.buf.toString('utf8', this.pos, this.pos + bytes);
    // TODO: bounds checking
    this.pos += bytes;
    return str;
};

Protobuf.prototype.readBuffer = function() {
    var bytes = this.readVarint();
    var buffer = this.buf.slice(this.pos, this.pos + bytes);
    this.pos += bytes;
    return buffer;
};

Protobuf.prototype.readPacked = function(type) {
    // TODO: bounds checking
    var bytes = this.readVarint();
    var end = this.pos + bytes;
    var array = [];
    var read = this['read' + type];
    while (this.pos < end) {
        array.push(read.call(this));
    }
    return array;
};

Protobuf.prototype.skip = function(val) {
    // TODO: bounds checking
    var type = val & 0x7;

    if (type === Protobuf.Varint) {
        var buf = this.buf;
        while (buf[this.pos++] > 0x7f);

    } else if (type === Protobuf.Bytes) {
        var bytes = this.readVarint();
        this.pos += bytes;

    } else if (type === Protobuf.Fixed32) this.pos += 4;
    else if (type === Protobuf.Fixed64) this.pos += 8;
    else throw new Error('Unimplemented type: ' + type);
};

// === WRITING =================================================================

Protobuf.prototype.writeTag = function(tag, type) {
    this.writeVarint((tag << 3) | type);
};

Protobuf.prototype.realloc = function(min) {
    var length = this.length || 1;

    while (length < this.pos + min) length *= 2;

    if (length != this.length) {
        var buf = new Buffer(length);
        this.buf.copy(buf);
        this.buf = buf;
    }
};

Protobuf.prototype.finish = function() {
    return this.buf.slice(0, this.pos);
};

Protobuf.prototype.writePacked = function(type, tag, items) {
    if (!items.length) return;

    var message = new Protobuf();
    var write = message['write' + type];
    for (var i = 0; i < items.length; i++) {
        write.call(this, items[i]);
    }
    var data = message.finish();

    this.writeTag(tag, Protobuf.Bytes);
    this.writeBytes(data);
};

Protobuf.prototype.writeFixed32 = function(val) {
    this.realloc(4);
    this.buf.writeUInt32LE(val, this.pos);
    this.pos += 4;
};

Protobuf.prototype.writeTaggedFixed32 = function(tag, val) {
    this.writeTag(tag, Protobuf.Fixed32);
    this.writeFixed32(val);
};

Protobuf.prototype.writeFixed64 = function(val) {
    this.realloc(8);
    this.buf.writeInt32LE(val & -1, this.pos);
    this.buf.writeUInt32LE(Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);
    this.pos += 8;
};

Protobuf.prototype.writeTaggedFixed64 = function(tag, val) {
    this.writeTag(tag, Protobuf.Fixed64);
    this.writeFixed64(val);
};

Protobuf.prototype.writeVarint = function(val) {
    val = +val;
    if (isNaN(val)) val = 0;

    if (val <= 0x7f) {
        this.realloc(1);
        this.buf[this.pos++] = val;
    } else if (val <= 0x3fff) {
        this.realloc(2);
        this.buf[this.pos++] = 0x80 | ((val >>> 0) & 0x7f);
        this.buf[this.pos++] = 0x00 | ((val >>> 7) & 0x7f);
    } else if (val <= 0x1fffff) {
        this.realloc(3);
        this.buf[this.pos++] = 0x80 | ((val >>> 0) & 0x7f);
        this.buf[this.pos++] = 0x80 | ((val >>> 7) & 0x7f);
        this.buf[this.pos++] = 0x00 | ((val >>> 14) & 0x7f);
    } else if (val <= 0xfffffff) {
        this.realloc(4);
        this.buf[this.pos++] = 0x80 | ((val >>> 0) & 0x7f);
        this.buf[this.pos++] = 0x80 | ((val >>> 7) & 0x7f);
        this.buf[this.pos++] = 0x80 | ((val >>> 14) & 0x7f);
        this.buf[this.pos++] = 0x00 | ((val >>> 21) & 0x7f);
    } else {
        while (val > 0) {
            var b = val & 0x7f;
            val = Math.floor(val / 128);
            if (val > 0) b |= 0x80;
            this.realloc(1);
            this.buf[this.pos++] = b;
        }
    }
};

Protobuf.prototype.writeTaggedVarint = function(tag, val) {
    this.writeTag(tag, Protobuf.Varint);
    this.writeVarint(val);
};

Protobuf.prototype.writeSVarint = function(val) {
    if (val >= 0) {
        this.writeVarint(val * 2);
    } else {
        this.writeVarint(val * -2 - 1);
    }
};

Protobuf.prototype.writeTaggedSVarint = function(tag, val) {
    this.writeTag(tag, Protobuf.Varint);
    this.writeSVarint(val);
};

Protobuf.prototype.writeBoolean = function(val) {
    this.writeVarint(Boolean(val));
};

Protobuf.prototype.writeTaggedBoolean = function(tag, val) {
    this.writeTaggedVarint(tag, Boolean(val));
};

Protobuf.prototype.writeString = function(str) {
    str = String(str);
    var bytes = Buffer.byteLength(str);
    this.writeVarint(bytes);
    this.realloc(bytes);
    this.buf.write(str, this.pos);
    this.pos += bytes;
};

Protobuf.prototype.writeTaggedString = function(tag, str) {
    this.writeTag(tag, Protobuf.Bytes);
    this.writeString(str);
};

Protobuf.prototype.writeFloat = function(val) {
    this.realloc(4);
    this.buf.writeFloatLE(val, this.pos);
    this.pos += 4;
};

Protobuf.prototype.writeTaggedFloat = function(tag, val) {
    this.writeTag(tag, Protobuf.Fixed32);
    this.writeFloat(val);
};

Protobuf.prototype.writeDouble = function(val) {
    this.realloc(8);
    this.buf.writeDoubleLE(val, this.pos);
    this.pos += 8;
};

Protobuf.prototype.writeTaggedDouble = function(tag, val) {
    this.writeTag(tag, Protobuf.Fixed64);
    this.writeDouble(val);
};

Protobuf.prototype.writeBytes = function(buffer) {
    var len = buffer.length;
    this.writeVarint(len);
    this.realloc(len);
    for (var i = 0; i < len; i++) {
        this.buf[this.pos + i] = buffer[i];
    }
    this.pos += len;
};

Protobuf.prototype.writeTaggedBytes = function(tag, buffer) {
    this.writeTag(tag, Protobuf.Bytes);
    this.writeBytes(buffer);
};

Protobuf.prototype.writeMessage = function(tag, protobuf) {
    var buffer = protobuf.finish();
    this.writeTag(tag, Protobuf.Bytes);
    this.writeBytes(buffer);
};
<commit_msg>remove bounds checking todos, ref #15<commit_after>'use strict';

module.exports = Protobuf;

var Buffer = typeof window !== 'undefined' ? require('./buffer') : global.Buffer;

function Protobuf(buf) {
    this.buf = buf instanceof Uint8Array ? Buffer.wrap(buf) : buf;
    this.pos = 0;
}

Protobuf.prototype = {
    get length() { return this.buf.length; }
};

Protobuf.Varint  = 0; // varint: int32, int64, uint32, uint64, sint32, sint64, bool, enum
Protobuf.Fixed64 = 1; // double, fixed64, sfixed64
Protobuf.Bytes   = 2; // length-delimited: string, bytes, embedded messages, packed repeated fields
Protobuf.Fixed32 = 5; // float, fixed32, sfixed32

Protobuf.prototype.destroy = function() {
    this.buf = null;
};

var SHIFT_LEFT_32 = (1 << 16) * (1 << 16),
    SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32;

// === READING =================================================================

Protobuf.prototype.read = function(readField, end) {
    var buf = this.buf;
    end = end || buf.length;

    while (this.pos < end) {
        var val = this.readVarint(),
            tag = val >> 3,
            startPos = this.pos;
        readField(tag);
        if (this.pos === startPos) this.skip(val);
    }
};

Protobuf.prototype.readMessage = function(readField) {
    var bytes = this.readVarint();
    this.read(readField, this.pos + bytes);
};

Protobuf.prototype.readFixed32 = function() {
    var val = this.buf.readUInt32LE(this.pos);
    this.pos += 4;
    return val;
};

Protobuf.prototype.readFixed64 = function() {
    var val = this.buf.readUInt32LE(this.pos) + this.buf.readUInt32LE(this.pos + 4) * SHIFT_LEFT_32;
    this.pos += 8;
    return val;
};

Protobuf.prototype.readFloat = function() {
    var val = this.buf.readFloatLE(this.pos);
    this.pos += 4;
    return val;
};

Protobuf.prototype.readDouble = function() {
    var val = this.buf.readDoubleLE(this.pos);
    this.pos += 8;
    return val;
};

Protobuf.prototype.readVarint = function() {
    var buf = this.buf,
        val, b, b0, b1, b2, b3;

    b0 = buf[this.pos++]; if (b0 < 0x80) return b0; b0 = b0 & 0x7f;
    b1 = buf[this.pos++]; if (b1 < 0x80) return b0 | b1 << 7; b1 = (b1 & 0x7f) << 7;
    b2 = buf[this.pos++]; if (b2 < 0x80) return b0 | b1 | b2 << 14; b2 = (b2 & 0x7f) << 14;
    b3 = buf[this.pos++]; if (b3 < 0x80) return b0 | b1 | b2 | b3 << 21;

    val = b0 | b1 | b2 | (b3 & 0x7f) << 21;

    b = buf[this.pos++]; val += (b & 0x7f) * 0x10000000; if (b < 0x80) return val;
    b = buf[this.pos++]; val += (b & 0x7f) * 0x800000000; if (b < 0x80) return val;
    b = buf[this.pos++]; val += (b & 0x7f) * 0x40000000000; if (b < 0x80) return val;
    b = buf[this.pos++]; val += (b & 0x7f) * 0x2000000000000; if (b < 0x80) return val;
    b = buf[this.pos++]; val += (b & 0x7f) * 0x100000000000000; if (b < 0x80) return val;
    b = buf[this.pos++]; val += (b & 0x7f) * 0x8000000000000000; if (b < 0x80) return val;

    throw new Error('Expected varint not more than 10 bytes');
};

Protobuf.prototype.readSVarint = function() {
    var num = this.readVarint();
    if (num > 2147483647) throw new Error('TODO: Handle numbers >= 2^30');
    // zigzag encoding
    return ((num >> 1) ^ -(num & 1));
};

Protobuf.prototype.readBoolean = function() {
    return Boolean(this.readVarint());
};

Protobuf.prototype.readString = function() {
    var bytes = this.readVarint(),
        str = this.buf.toString('utf8', this.pos, this.pos + bytes);
    this.pos += bytes;
    return str;
};

Protobuf.prototype.readBuffer = function() {
    var bytes = this.readVarint();
    var buffer = this.buf.slice(this.pos, this.pos + bytes);
    this.pos += bytes;
    return buffer;
};

Protobuf.prototype.readPacked = function(type) {
    var bytes = this.readVarint();
    var end = this.pos + bytes;
    var array = [];
    var read = this['read' + type];
    while (this.pos < end) {
        array.push(read.call(this));
    }
    return array;
};

Protobuf.prototype.skip = function(val) {
    var type = val & 0x7;

    if (type === Protobuf.Varint) {
        var buf = this.buf;
        while (buf[this.pos++] > 0x7f);

    } else if (type === Protobuf.Bytes) {
        var bytes = this.readVarint();
        this.pos += bytes;

    } else if (type === Protobuf.Fixed32) this.pos += 4;
    else if (type === Protobuf.Fixed64) this.pos += 8;
    else throw new Error('Unimplemented type: ' + type);
};

// === WRITING =================================================================

Protobuf.prototype.writeTag = function(tag, type) {
    this.writeVarint((tag << 3) | type);
};

Protobuf.prototype.realloc = function(min) {
    var length = this.length || 1;

    while (length < this.pos + min) length *= 2;

    if (length != this.length) {
        var buf = new Buffer(length);
        this.buf.copy(buf);
        this.buf = buf;
    }
};

Protobuf.prototype.finish = function() {
    return this.buf.slice(0, this.pos);
};

Protobuf.prototype.writePacked = function(type, tag, items) {
    if (!items.length) return;

    var message = new Protobuf();
    var write = message['write' + type];
    for (var i = 0; i < items.length; i++) {
        write.call(this, items[i]);
    }
    var data = message.finish();

    this.writeTag(tag, Protobuf.Bytes);
    this.writeBytes(data);
};

Protobuf.prototype.writeFixed32 = function(val) {
    this.realloc(4);
    this.buf.writeUInt32LE(val, this.pos);
    this.pos += 4;
};

Protobuf.prototype.writeTaggedFixed32 = function(tag, val) {
    this.writeTag(tag, Protobuf.Fixed32);
    this.writeFixed32(val);
};

Protobuf.prototype.writeFixed64 = function(val) {
    this.realloc(8);
    this.buf.writeInt32LE(val & -1, this.pos);
    this.buf.writeUInt32LE(Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);
    this.pos += 8;
};

Protobuf.prototype.writeTaggedFixed64 = function(tag, val) {
    this.writeTag(tag, Protobuf.Fixed64);
    this.writeFixed64(val);
};

Protobuf.prototype.writeVarint = function(val) {
    val = +val;
    if (isNaN(val)) val = 0;

    if (val <= 0x7f) {
        this.realloc(1);
        this.buf[this.pos++] = val;
    } else if (val <= 0x3fff) {
        this.realloc(2);
        this.buf[this.pos++] = 0x80 | ((val >>> 0) & 0x7f);
        this.buf[this.pos++] = 0x00 | ((val >>> 7) & 0x7f);
    } else if (val <= 0x1fffff) {
        this.realloc(3);
        this.buf[this.pos++] = 0x80 | ((val >>> 0) & 0x7f);
        this.buf[this.pos++] = 0x80 | ((val >>> 7) & 0x7f);
        this.buf[this.pos++] = 0x00 | ((val >>> 14) & 0x7f);
    } else if (val <= 0xfffffff) {
        this.realloc(4);
        this.buf[this.pos++] = 0x80 | ((val >>> 0) & 0x7f);
        this.buf[this.pos++] = 0x80 | ((val >>> 7) & 0x7f);
        this.buf[this.pos++] = 0x80 | ((val >>> 14) & 0x7f);
        this.buf[this.pos++] = 0x00 | ((val >>> 21) & 0x7f);
    } else {
        while (val > 0) {
            var b = val & 0x7f;
            val = Math.floor(val / 128);
            if (val > 0) b |= 0x80;
            this.realloc(1);
            this.buf[this.pos++] = b;
        }
    }
};

Protobuf.prototype.writeTaggedVarint = function(tag, val) {
    this.writeTag(tag, Protobuf.Varint);
    this.writeVarint(val);
};

Protobuf.prototype.writeSVarint = function(val) {
    if (val >= 0) {
        this.writeVarint(val * 2);
    } else {
        this.writeVarint(val * -2 - 1);
    }
};

Protobuf.prototype.writeTaggedSVarint = function(tag, val) {
    this.writeTag(tag, Protobuf.Varint);
    this.writeSVarint(val);
};

Protobuf.prototype.writeBoolean = function(val) {
    this.writeVarint(Boolean(val));
};

Protobuf.prototype.writeTaggedBoolean = function(tag, val) {
    this.writeTaggedVarint(tag, Boolean(val));
};

Protobuf.prototype.writeString = function(str) {
    str = String(str);
    var bytes = Buffer.byteLength(str);
    this.writeVarint(bytes);
    this.realloc(bytes);
    this.buf.write(str, this.pos);
    this.pos += bytes;
};

Protobuf.prototype.writeTaggedString = function(tag, str) {
    this.writeTag(tag, Protobuf.Bytes);
    this.writeString(str);
};

Protobuf.prototype.writeFloat = function(val) {
    this.realloc(4);
    this.buf.writeFloatLE(val, this.pos);
    this.pos += 4;
};

Protobuf.prototype.writeTaggedFloat = function(tag, val) {
    this.writeTag(tag, Protobuf.Fixed32);
    this.writeFloat(val);
};

Protobuf.prototype.writeDouble = function(val) {
    this.realloc(8);
    this.buf.writeDoubleLE(val, this.pos);
    this.pos += 8;
};

Protobuf.prototype.writeTaggedDouble = function(tag, val) {
    this.writeTag(tag, Protobuf.Fixed64);
    this.writeDouble(val);
};

Protobuf.prototype.writeBytes = function(buffer) {
    var len = buffer.length;
    this.writeVarint(len);
    this.realloc(len);
    for (var i = 0; i < len; i++) {
        this.buf[this.pos + i] = buffer[i];
    }
    this.pos += len;
};

Protobuf.prototype.writeTaggedBytes = function(tag, buffer) {
    this.writeTag(tag, Protobuf.Bytes);
    this.writeBytes(buffer);
};

Protobuf.prototype.writeMessage = function(tag, protobuf) {
    var buffer = protobuf.finish();
    this.writeTag(tag, Protobuf.Bytes);
    this.writeBytes(buffer);
};
<|endoftext|>