<commit_before>var _ = require( "lodash" );
var when = require( "when" );
var open = require( "open" );
var path = require( "path" );
var mocha = require( "gulp-spawn-mocha" );
var processhost = require( "processhost" )();
var cmdPostfix = process.platform === "win32" ? ".cmd" : "";
var defaults = {
	allSpecPaths: [ "./spec" ],
	behaviorSpecPaths: [ "./spec/behavior" ],
	integrationSpecPaths: [ "./spec/integration" ],
	specs: [ "**/*.spec.js" ],
	watchPaths: [ "./src/**/*", "./spec/**/*", "./resource/**/*" ],
	sourcePaths: [ "./src", "./resource" ],
	sources: [ "**/*.js" ],
	coverageHtml: "./coverage/lcov-report/index.html",
	exclude: [ "!node_modules/**", "!coverage/**" ],
	jscsCfgPath: ".jscsrc"
};
var jshint = require( "gulp-jshint" );
var jscs = require( "gulp-jscs" );
var gutil = require( "gulp-util" );
var gulpChanged = require( "gulp-changed" );
var stylish = require( "jshint-stylish" );

function permuPath( dirs, globs ) {
	return _.reduce( globs, function( accum, glb ) {
		Array.prototype.push.apply(
			accum,
			_.map( dirs, function( dir ) {
				return path.join( dir, glb );
			} )
		);
		return accum;
	}, [] );
}

module.exports = function( gulpRef, cfg ) {
	var gulp = gulpRef;
	var options = _.defaults( cfg || {}, defaults );
	var processesDefined = false;

	function runSpecs( testCfg ) {
		var mochaOpts = {
			R: "spec",
			istanbul: testCfg.coverage ? { x: testCfg.coverageExclude } : false
		};
		if ( options.esnext ) {
			mochaOpts.r = "babel/register";
		}
		return gulp.src( testCfg.specs, { read: false } )
			.pipe( mocha( mochaOpts ) );
	}

	function test( specs ) {
		var s = _.isArray( specs ) ? specs : [ specs ];
		return runSpecs( {
			specs: s
		} );
	}

	function testOnce( specs ) {
		return test( specs )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function testAll( opt ) {
		var _opt = opt || options;
		var specs = permuPath( _opt.allSpecPaths, _opt.specs );
		var coverageExclude = permuPath( _opt.allSpecPaths, [ "**/*" ] );
		return runSpecs( {
			specs: specs,
			coverageExclude: coverageExclude,
			coverage: _opt.coverage
		} );
	}

	function testAllAndExit( opt ) {
		return testAll( opt )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function testBehavior( opt ) {
		var _opt = opt || options;
		var specs = permuPath( _opt.behaviorSpecPaths, _opt.specs );
		var coverageExclude = permuPath( _opt.allSpecPaths, [ "**/*" ] );
		return runSpecs( {
			specs: specs,
			coverageExclude: coverageExclude,
			coverage: _opt.coverage
		} );
	}

	function testBehaviorAndExit( opt ) {
		return testBehavior( opt )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function testIntegration( opt ) {
		var _opt = opt || options;
		var specs = permuPath( _opt.integrationSpecPaths, _opt.specs );
		var coverageExclude = permuPath( _opt.allSpecPaths, [ "**/*" ] );
		return runSpecs( {
			specs: specs,
			coverageExclude: coverageExclude,
			coverage: _opt.coverage
		} );
	}

	function testIntegrationAndExit( opt ) {
		return testIntegration( opt )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function cover( opt ) {
		var _opt = opt || _.clone( options );
		_opt.coverage = true;
		return testAll( _opt );
	}

	function showCoverage( opt ) {
		var _opt = opt || _.clone( options );
		_opt.coverage = true;
		return testAll( opt ).on( "end", function() {
			open( _opt.coverageHtml );
			process.exit();
		} );
	}

	function setupProcess( processName, opts ) {
		processesDefined = true;
		return processhost.startProcess( processName, {
			command: opts.command || opts.cmd || "node" + cmdPostfix,
			args: opts.arguments || opts.args || [],
			stdio: opts.stdio || "inherits",
			restart: opts.restart
		} );
	}

	function setupProcesses( opts ) {
		processesDefined = true;
		return processhost.setup( opts );
	}

	function groklate( ngrok, opts ) {
		if ( !opts && !options.ngrok ) {
			throw new Error( "To use ngrok you must supply an options argument containing port, subdomain and token" );
		}
		var _opt = opts || options.ngrok;
		return when.promise( function( resolve, reject ) {
			ngrok.connect( {
				port: _opt.port,
				subdomain: _opt.subdomain,
				authtoken: _opt.token
			}, function( err, url ) {
					if ( err ) {
						reject( err );
					} else {
						resolve( url );
					}
				} );
		} );
	}

	function watch( opt, tasks ) {
		var _tasks;
		var _opt;
		if ( arguments.length === 1 ) {
			_opt = options;
			_tasks = opt;
		} else {
			_opt = opt;
			_tasks = tasks;
		}
		if ( processesDefined ) {
			_tasks.concat( "restartProcesses" );
		}
		return gulp.watch( _opt.watchPaths, _tasks );
	}

	function format( opt ) {
		var _opt = opt || options;
		return gulp.src( _opt.sources.concat( _opt.exclude ) )
			.pipe( jscs( {
				configPath: _opt.jscsCfgPath,
				fix: true
			} ) )
			.on( "error", function( error ) {
				gutil.log( gutil.colors.red( error.message ) );
				this.end();
			} )
			.pipe( gulpChanged( ".", { hasChanged: gulpChanged.compareSha1Digest } ) )
			.pipe( gulp.dest( "." ) );
	}

	function lint( opt ) {
		var _opt = opt || options;
		return gulp.src( _opt.sources.concat( _opt.exclude ) )
			.on( "error", function( error ) {
				gutil.log( gutil.colors.red( error.message + " in " + error.fileName ) );
				this.end();
			} )
			.pipe( jshint() )
			.pipe( jshint.reporter( stylish ) )
			.pipe( jshint.reporter( "fail" ) );
	}

	gulp.task( "restartProcesses", function( cb ) {
		processhost.restart()
			.then( function() {
				cb();
			}, function( err ) {
				cb( err );
			} );
	} );

	return {
		cover: cover,
		ngrok: groklate,
		process: setupProcess,
		setupProcesses: setupProcesses,
		showCoverage: showCoverage,
		test: test,
		testOnce: testOnce,
		testAll: testAll,
		testAllOnce: testAllAndExit,
		testBehavior: testBehavior,
		testBehaviorOnce: testBehaviorAndExit,
		testIntegration: testIntegration,
		testIntegrationOnce: testIntegrationAndExit,
		watch: watch,
		withCoverage: cover,
		format: format,
		lint: lint
	};
};
<commit_msg>Fix call to renamed processhost method<commit_after>var _ = require( "lodash" );
var when = require( "when" );
var open = require( "open" );
var path = require( "path" );
var mocha = require( "gulp-spawn-mocha" );
var processhost = require( "processhost" )();
var cmdPostfix = process.platform === "win32" ? ".cmd" : "";
var defaults = {
	allSpecPaths: [ "./spec" ],
	behaviorSpecPaths: [ "./spec/behavior" ],
	integrationSpecPaths: [ "./spec/integration" ],
	specs: [ "**/*.spec.js" ],
	watchPaths: [ "./src/**/*", "./spec/**/*", "./resource/**/*" ],
	sourcePaths: [ "./src", "./resource" ],
	sources: [ "**/*.js" ],
	coverageHtml: "./coverage/lcov-report/index.html",
	exclude: [ "!node_modules/**", "!coverage/**" ],
	jscsCfgPath: ".jscsrc"
};
var jshint = require( "gulp-jshint" );
var jscs = require( "gulp-jscs" );
var gutil = require( "gulp-util" );
var gulpChanged = require( "gulp-changed" );
var stylish = require( "jshint-stylish" );

function permuPath( dirs, globs ) {
	return _.reduce( globs, function( accum, glb ) {
		Array.prototype.push.apply(
			accum,
			_.map( dirs, function( dir ) {
				return path.join( dir, glb );
			} )
		);
		return accum;
	}, [] );
}

module.exports = function( gulpRef, cfg ) {
	var gulp = gulpRef;
	var options = _.defaults( cfg || {}, defaults );
	var processesDefined = false;

	function runSpecs( testCfg ) {
		var mochaOpts = {
			R: "spec",
			istanbul: testCfg.coverage ? { x: testCfg.coverageExclude } : false
		};
		if ( options.esnext ) {
			mochaOpts.r = "babel/register";
		}
		return gulp.src( testCfg.specs, { read: false } )
			.pipe( mocha( mochaOpts ) );
	}

	function test( specs ) {
		var s = _.isArray( specs ) ? specs : [ specs ];
		return runSpecs( {
			specs: s
		} );
	}

	function testOnce( specs ) {
		return test( specs )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function testAll( opt ) {
		var _opt = opt || options;
		var specs = permuPath( _opt.allSpecPaths, _opt.specs );
		var coverageExclude = permuPath( _opt.allSpecPaths, [ "**/*" ] );
		return runSpecs( {
			specs: specs,
			coverageExclude: coverageExclude,
			coverage: _opt.coverage
		} );
	}

	function testAllAndExit( opt ) {
		return testAll( opt )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function testBehavior( opt ) {
		var _opt = opt || options;
		var specs = permuPath( _opt.behaviorSpecPaths, _opt.specs );
		var coverageExclude = permuPath( _opt.allSpecPaths, [ "**/*" ] );
		return runSpecs( {
			specs: specs,
			coverageExclude: coverageExclude,
			coverage: _opt.coverage
		} );
	}

	function testBehaviorAndExit( opt ) {
		return testBehavior( opt )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function testIntegration( opt ) {
		var _opt = opt || options;
		var specs = permuPath( _opt.integrationSpecPaths, _opt.specs );
		var coverageExclude = permuPath( _opt.allSpecPaths, [ "**/*" ] );
		return runSpecs( {
			specs: specs,
			coverageExclude: coverageExclude,
			coverage: _opt.coverage
		} );
	}

	function testIntegrationAndExit( opt ) {
		return testIntegration( opt )
			.on( "end", process.exit.bind( process, 0 ) )
			.on( "error", process.exit.bind( process, 100 ) );
	}

	function cover( opt ) {
		var _opt = opt || _.clone( options );
		_opt.coverage = true;
		return testAll( _opt );
	}

	function showCoverage( opt ) {
		var _opt = opt || _.clone( options );
		_opt.coverage = true;
		return testAll( opt ).on( "end", function() {
			open( _opt.coverageHtml );
			process.exit();
		} );
	}

	function setupProcess( processName, opts ) {
		processesDefined = true;
		return processhost.start( processName, {
			command: opts.command || opts.cmd || "node" + cmdPostfix,
			args: opts.arguments || opts.args || [],
			stdio: opts.stdio || "inherits",
			restart: opts.restart
		} );
	}

	function setupProcesses( opts ) {
		processesDefined = true;
		return processhost.setup( opts );
	}

	function groklate( ngrok, opts ) {
		if ( !opts && !options.ngrok ) {
			throw new Error( "To use ngrok you must supply an options argument containing port, subdomain and token" );
		}
		var _opt = opts || options.ngrok;
		return when.promise( function( resolve, reject ) {
			ngrok.connect( {
				port: _opt.port,
				subdomain: _opt.subdomain,
				authtoken: _opt.token
			}, function( err, url ) {
					if ( err ) {
						reject( err );
					} else {
						resolve( url );
					}
				} );
		} );
	}

	function watch( opt, tasks ) {
		var _tasks;
		var _opt;
		if ( arguments.length === 1 ) {
			_opt = options;
			_tasks = opt;
		} else {
			_opt = opt;
			_tasks = tasks;
		}
		if ( processesDefined ) {
			_tasks.concat( "restartProcesses" );
		}
		return gulp.watch( _opt.watchPaths, _tasks );
	}

	function format( opt ) {
		var _opt = opt || options;
		return gulp.src( _opt.sources.concat( _opt.exclude ) )
			.pipe( jscs( {
				configPath: _opt.jscsCfgPath,
				fix: true
			} ) )
			.on( "error", function( error ) {
				gutil.log( gutil.colors.red( error.message ) );
				this.end();
			} )
			.pipe( gulpChanged( ".", { hasChanged: gulpChanged.compareSha1Digest } ) )
			.pipe( gulp.dest( "." ) );
	}

	function lint( opt ) {
		var _opt = opt || options;
		return gulp.src( _opt.sources.concat( _opt.exclude ) )
			.on( "error", function( error ) {
				gutil.log( gutil.colors.red( error.message + " in " + error.fileName ) );
				this.end();
			} )
			.pipe( jshint() )
			.pipe( jshint.reporter( stylish ) )
			.pipe( jshint.reporter( "fail" ) );
	}

	gulp.task( "restartProcesses", function( cb ) {
		processhost.restart()
			.then( function() {
				cb();
			}, function( err ) {
				cb( err );
			} );
	} );

	return {
		cover: cover,
		ngrok: groklate,
		process: setupProcess,
		setupProcesses: setupProcesses,
		showCoverage: showCoverage,
		test: test,
		testOnce: testOnce,
		testAll: testAll,
		testAllOnce: testAllAndExit,
		testBehavior: testBehavior,
		testBehaviorOnce: testBehaviorAndExit,
		testIntegration: testIntegration,
		testIntegrationOnce: testIntegrationAndExit,
		watch: watch,
		withCoverage: cover,
		format: format,
		lint: lint
	};
};
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const getPackageJson = require('./get-package-json');
const getProjectType = require('./get-project-type');
const getPackageVersion = require('./get-package-version');
const getVersions = require('./get-versions');
const getProjectVersion = require('./get-project-version');
const getTagVersion = require('./get-tag-version');
const getRemoteUrl = require('./get-remote-url');
const compareVersions = require('./compare-versions');
const formatStats = require('./format-stats');
const getApplicableCodemods = require('./get-applicable-codemods');
const runCodemods = require('./run-codemods');
const mergePackageJson = require('merge-package.json');
const gitDiffApply = require('git-diff-apply');
const run = require('./run');
const utils = require('./utils');
const getStartAndEndCommands = require('./get-start-and-end-commands');

module.exports = function emberCliUpdate({
  from,
  to,
  resolveConflicts,
  runCodemods: _runCodemods,
  reset,
  compareOnly,
  statsOnly,
  listCodemods,
  createCustomDiff
}) {
  return Promise.resolve().then(() => {
    if (listCodemods) {
      return utils.getCodemods().then(codemods => {
        return JSON.stringify(codemods, null, 2);
      });
    }

    let packageJson = getPackageJson('.');
    let projectType = getProjectType(packageJson);
    let packageVersion = getPackageVersion(packageJson, projectType);
    let versions = getVersions(projectType);

    let startVersion;
    if (from) {
      startVersion = getTagVersion(from, versions, projectType);
    } else {
      startVersion = getProjectVersion(packageVersion, versions, projectType);
    }

    let endVersion = getTagVersion(to, versions, projectType);

    let remoteUrl = getRemoteUrl(projectType);

    let startTag = `v${startVersion}`;
    let endTag = `v${endVersion}`;

    if (compareOnly) {
      return compareVersions({
        remoteUrl,
        startTag,
        endTag
      });
    }

    if (statsOnly) {
      return getApplicableCodemods({
        projectType,
        startVersion
      }).then(codemods => {
        return formatStats({
          projectType,
          startVersion,
          endVersion,
          remoteUrl,
          codemods
        });
      });
    }

    if (_runCodemods) {
      return getApplicableCodemods({
        projectType,
        startVersion
      }).then(codemods => {
        const inquirer = require('inquirer');

        return inquirer.prompt([{
          type: 'checkbox',
          message: 'These codemods apply to your project. Select which one\'s to run.',
          name: 'codemods',
          choices: Object.keys(codemods)
        }]).then(answers => {
          return runCodemods(answers.codemods.map(codemod => codemods[codemod]));
        });
      });
    }

    let startCommand;
    let endCommand;

    return Promise.resolve().then(() => {
      if (createCustomDiff) {
        return getStartAndEndCommands({
          projectName: packageJson.name,
          projectType,
          startVersion,
          endVersion
        }).then(commands => {
          startCommand = commands.startCommand;
          endCommand = commands.endCommand;
        });
      }
    }).then(() => {
      let ignoredFiles;
      if (!reset) {
        ignoredFiles = ['package.json'];
      } else {
        ignoredFiles = [];
      }

      return gitDiffApply({
        remoteUrl,
        startTag,
        endTag,
        resolveConflicts,
        ignoredFiles,
        reset,
        createCustomDiff,
        startCommand,
        endCommand
      }).then(results => {
        if (reset) {
          return;
        }

        let myPackageJson = fs.readFileSync('package.json', 'utf8');
        let fromPackageJson = results.from['package.json'];
        let toPackageJson = results.to['package.json'];

        let newPackageJson = mergePackageJson(myPackageJson, fromPackageJson, toPackageJson);

        fs.writeFileSync('package.json', newPackageJson);

        run('git add package.json');
      });
    });
  });
};
<commit_msg>Fix typo in message<commit_after>'use strict';

const fs = require('fs');
const getPackageJson = require('./get-package-json');
const getProjectType = require('./get-project-type');
const getPackageVersion = require('./get-package-version');
const getVersions = require('./get-versions');
const getProjectVersion = require('./get-project-version');
const getTagVersion = require('./get-tag-version');
const getRemoteUrl = require('./get-remote-url');
const compareVersions = require('./compare-versions');
const formatStats = require('./format-stats');
const getApplicableCodemods = require('./get-applicable-codemods');
const runCodemods = require('./run-codemods');
const mergePackageJson = require('merge-package.json');
const gitDiffApply = require('git-diff-apply');
const run = require('./run');
const utils = require('./utils');
const getStartAndEndCommands = require('./get-start-and-end-commands');

module.exports = function emberCliUpdate({
  from,
  to,
  resolveConflicts,
  runCodemods: _runCodemods,
  reset,
  compareOnly,
  statsOnly,
  listCodemods,
  createCustomDiff
}) {
  return Promise.resolve().then(() => {
    if (listCodemods) {
      return utils.getCodemods().then(codemods => {
        return JSON.stringify(codemods, null, 2);
      });
    }

    let packageJson = getPackageJson('.');
    let projectType = getProjectType(packageJson);
    let packageVersion = getPackageVersion(packageJson, projectType);
    let versions = getVersions(projectType);

    let startVersion;
    if (from) {
      startVersion = getTagVersion(from, versions, projectType);
    } else {
      startVersion = getProjectVersion(packageVersion, versions, projectType);
    }

    let endVersion = getTagVersion(to, versions, projectType);

    let remoteUrl = getRemoteUrl(projectType);

    let startTag = `v${startVersion}`;
    let endTag = `v${endVersion}`;

    if (compareOnly) {
      return compareVersions({
        remoteUrl,
        startTag,
        endTag
      });
    }

    if (statsOnly) {
      return getApplicableCodemods({
        projectType,
        startVersion
      }).then(codemods => {
        return formatStats({
          projectType,
          startVersion,
          endVersion,
          remoteUrl,
          codemods
        });
      });
    }

    if (_runCodemods) {
      return getApplicableCodemods({
        projectType,
        startVersion
      }).then(codemods => {
        const inquirer = require('inquirer');

        return inquirer.prompt([{
          type: 'checkbox',
          message: 'These codemods apply to your project. Select which ones to run.',
          name: 'codemods',
          choices: Object.keys(codemods)
        }]).then(answers => {
          return runCodemods(answers.codemods.map(codemod => codemods[codemod]));
        });
      });
    }

    let startCommand;
    let endCommand;

    return Promise.resolve().then(() => {
      if (createCustomDiff) {
        return getStartAndEndCommands({
          projectName: packageJson.name,
          projectType,
          startVersion,
          endVersion
        }).then(commands => {
          startCommand = commands.startCommand;
          endCommand = commands.endCommand;
        });
      }
    }).then(() => {
      let ignoredFiles;
      if (!reset) {
        ignoredFiles = ['package.json'];
      } else {
        ignoredFiles = [];
      }

      return gitDiffApply({
        remoteUrl,
        startTag,
        endTag,
        resolveConflicts,
        ignoredFiles,
        reset,
        createCustomDiff,
        startCommand,
        endCommand
      }).then(results => {
        if (reset) {
          return;
        }

        let myPackageJson = fs.readFileSync('package.json', 'utf8');
        let fromPackageJson = results.from['package.json'];
        let toPackageJson = results.to['package.json'];

        let newPackageJson = mergePackageJson(myPackageJson, fromPackageJson, toPackageJson);

        fs.writeFileSync('package.json', newPackageJson);

        run('git add package.json');
      });
    });
  });
};
<|endoftext|>


<commit_before>import { Fragment, createElement } from 'react';

const linkRegexp = /(?:\S+)(\w+:\/\/)\S*|[^\s.]+(\.[a-z-]{2,63})+\S*/gim;

const headerRegexp = /^(#+)[^\S\r\n]*[^#\s].*$/gm;

const defaultProtocol = 'http://';

const terminators = '.,;:?!';

const wrappers = {
  '(': ')',
  '[': ']',
  '"': '"',
  "'": "'",
  '<': '>'
};

const unwrap = (text, index) => {
  const [first, last] = [text[0], text[text.length - 1]];
  if (terminators.indexOf(last) > -1) return unwrap(text.slice(0, -1), index);
  if (wrappers[first] === last) return unwrap(text.slice(1, -1), index + 1);
  return [text, index];
};

const comparator = (a, b) =>
  a.from < b.from ? -1 : a.from > b.from ? 1 : a.to >= b.to ? -1 : 1;

const getBlocks = text => {
  const blocks = [];

  let match;

  while ((match = headerRegexp.exec(text))) {
    blocks.push({
      type: 'header',
      from: match.index,
      to: match.index + match[0].length,
      props: { level: match[1].length }
    });
  }

  while ((match = linkRegexp.exec(text))) {
    let [all, protocol, tld] = match;

    // To qualify as a link, either the protocol or TLD must be specified.
    if (!protocol && !tld) continue;

    let { index } = match;
    [all, index] = unwrap(all, index);
    blocks.push({
      type: 'link',
      from: index,
      to: index + all.length,
      props: {
        href: protocol
          ? all
          : all.includes('@')
          ? `mailto:${all}`
          : defaultProtocol + all
      }
    });
  }

  return blocks.sort(comparator);
};

const renderBlocks = ({ blocks, render, text }) => {
  if (!blocks.length) return [text];

  const components = [text.slice(0, blocks[0].from)];
  for (let i = 0; i < blocks.length; ++i) {
    const { from, to, type, props } = blocks[i];
    const subtext = text.slice(from, to);
    const subBlocks = [];
    for (let j = i + 1; j < blocks.length; ++j) {
      const subBlock = blocks[j];
      if (subBlock.to > to) break;

      subBlocks.push({
        ...subBlock,
        from: subBlock.from - from,
        to: subBlock.to - from
      });
      ++i;
    }
    const children = renderBlocks({ blocks: subBlocks, render, text: subtext });
    components.push(
      createElement(Fragment, { key: i }, render({ children, type, ...props }))
    );

    components.push(text.slice(to, blocks[i + 1]?.from));
  }

  return components;
};

const defaultRender = ({ type, children, ...props }) => {
  if (type === 'link') return createElement('a', props, children);

  if (type === 'header') {
    children = [children[0].replace(/^#*\S/, ''), ...children.slice(1)];
    return createElement(`h${Math.min(props.level, 6)}`, { children });
  }

  return null;
};

export default ({ children: text, render = defaultRender }) =>
  typeof text === 'string'
    ? renderBlocks({ blocks: getBlocks(text), render, text })
    : null;
<commit_msg>Update space replacer<commit_after>import { Fragment, createElement } from 'react';

const linkRegexp = /(?:\S+)(\w+:\/\/)\S*|[^\s.]+(\.[a-z-]{2,63})+\S*/gim;

const headerRegexp = /^(#+)[^\S\r\n]*[^#\s].*$/gm;

const defaultProtocol = 'http://';

const terminators = '.,;:?!';

const wrappers = {
  '(': ')',
  '[': ']',
  '"': '"',
  "'": "'",
  '<': '>'
};

const unwrap = (text, index) => {
  const [first, last] = [text[0], text[text.length - 1]];
  if (terminators.indexOf(last) > -1) return unwrap(text.slice(0, -1), index);
  if (wrappers[first] === last) return unwrap(text.slice(1, -1), index + 1);
  return [text, index];
};

const comparator = (a, b) =>
  a.from < b.from ? -1 : a.from > b.from ? 1 : a.to >= b.to ? -1 : 1;

const getBlocks = text => {
  const blocks = [];

  let match;

  while ((match = headerRegexp.exec(text))) {
    blocks.push({
      type: 'header',
      from: match.index,
      to: match.index + match[0].length,
      props: { level: match[1].length }
    });
  }

  while ((match = linkRegexp.exec(text))) {
    let [all, protocol, tld] = match;

    // To qualify as a link, either the protocol or TLD must be specified.
    if (!protocol && !tld) continue;

    let { index } = match;
    [all, index] = unwrap(all, index);
    blocks.push({
      type: 'link',
      from: index,
      to: index + all.length,
      props: {
        href: protocol
          ? all
          : all.includes('@')
          ? `mailto:${all}`
          : defaultProtocol + all
      }
    });
  }

  return blocks.sort(comparator);
};

const renderBlocks = ({ blocks, render, text }) => {
  if (!blocks.length) return [text];

  const components = [text.slice(0, blocks[0].from)];
  for (let i = 0; i < blocks.length; ++i) {
    const { from, to, type, props } = blocks[i];
    const subtext = text.slice(from, to);
    const subBlocks = [];
    for (let j = i + 1; j < blocks.length; ++j) {
      const subBlock = blocks[j];
      if (subBlock.to > to) break;

      subBlocks.push({
        ...subBlock,
        from: subBlock.from - from,
        to: subBlock.to - from
      });
      ++i;
    }
    const children = renderBlocks({ blocks: subBlocks, render, text: subtext });
    components.push(
      createElement(Fragment, { key: i }, render({ children, type, ...props }))
    );

    components.push(text.slice(to, blocks[i + 1]?.from));
  }

  return components;
};

const defaultRender = ({ type, children, ...props }) => {
  if (type === 'link') return createElement('a', props, children);

  if (type === 'header') {
    children = [children[0].replace(/^#*\s*/, ''), ...children.slice(1)];
    return createElement(`h${Math.min(props.level, 6)}`, { children });
  }

  return null;
};

export default ({ children: text, render = defaultRender }) =>
  typeof text === 'string'
    ? renderBlocks({ blocks: getBlocks(text), render, text })
    : null;
<|endoftext|>


<commit_before>// @flow

import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/css/bootstrap-theme.css';
import 'font-awesome/css/font-awesome.css'
import './index.css';
import Root from './containers/Root';
import registerServiceWorker from './registerServiceWorker';
import configureStore from './store/configureStore';

const store = configureStore();

ReactDOM.render(
  <Root store={store} />,
  document.getElementById('root'),
);
registerServiceWorker();
<commit_msg>Remove reference to bootstrap-theme<commit_after>// @flow

import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.css';
import 'font-awesome/css/font-awesome.css';
import './index.css';
import Root from './containers/Root';
import registerServiceWorker from './registerServiceWorker';
import configureStore from './store/configureStore';

const store = configureStore();

ReactDOM.render(
  <Root store={store} />,
  document.getElementById('root'),
);
registerServiceWorker();
<|endoftext|>


<commit_before>import Kinvey from 'kinvey-javascript-sdk-core';
import { KinveyError } from 'kinvey-javascript-sdk-core/es5/errors';
import { NetworkRack } from 'kinvey-javascript-sdk-core/es5/rack/rack';
import { HttpMiddleware } from 'kinvey-javascript-sdk-core/es5/rack/middleware/http';
import { PhoneGapHttpMiddleware } from './http';
import { PhoneGapPush } from './push';
import { PhoneGapPopup } from './popup';
import { PhoneGapDevice } from './device';

// Add Http middleware
const networkRack = NetworkRack.sharedInstance();
networkRack.swap(HttpMiddleware, new PhoneGapHttpMiddleware());

// Extend the Kinvey class
class PhoneGapKinvey extends Kinvey {
  static init(options) {
    if (PhoneGapDevice.isPhoneGap()) {
      const onDeviceReady = () => {
        document.removeEventListener('deviceready', onDeviceReady);

        if (typeof global.device === 'undefined') {
          throw new KinveyError('Cordova Device Plugin is not installed.',
            'Please refer to http://devcenter.kinvey.com/phonegap-v3.0/guides/push#ProjectSetUp for help with'
            + ' setting up your project.');
        }
      };

      document.addEventListener('deviceready', onDeviceReady, false);
    }

    // Initialize Kinvey
    const client = super.init(options);

    // Add Push module to Kinvey
    this.Push = new PhoneGapPush();

    // Return the client
    return client;
  }
}

// Expose some globals
global.KinveyDevice = PhoneGapDevice;
global.KinveyPopup = PhoneGapPopup;

// Export
module.exports = PhoneGapKinvey;
<commit_msg>Check if the cordova device plugin is installed outside of init<commit_after>import Kinvey from 'kinvey-javascript-sdk-core';
import { KinveyError } from 'kinvey-javascript-sdk-core/es5/errors';
import { NetworkRack } from 'kinvey-javascript-sdk-core/es5/rack/rack';
import { HttpMiddleware } from 'kinvey-javascript-sdk-core/es5/rack/middleware/http';
import { PhoneGapHttpMiddleware } from './http';
import { PhoneGapPush } from './push';
import { PhoneGapPopup } from './popup';
import { PhoneGapDevice } from './device';

// Add Http middleware
const networkRack = NetworkRack.sharedInstance();
networkRack.swap(HttpMiddleware, new PhoneGapHttpMiddleware());

// Check that the cordova device plugin is installed
if (PhoneGapDevice.isPhoneGap()) {
  const onDeviceReady = () => {
    document.removeEventListener('deviceready', onDeviceReady);

    if (typeof global.device === 'undefined') {
      throw new KinveyError('Cordova Device Plugin is not installed.',
        'Please refer to http://devcenter.kinvey.com/phonegap-v3.0/guides/push#ProjectSetUp for help with'
        + ' setting up your project.');
    }
  };

  document.addEventListener('deviceready', onDeviceReady, false);
}

// Extend the Kinvey class
class PhoneGapKinvey extends Kinvey {
  static init(options) {
    // Initialize Kinvey
    const client = super.init(options);

    // Add Push module to Kinvey
    this.Push = new PhoneGapPush();

    // Return the client
    return client;
  }
}

// Expose some globals
global.KinveyDevice = PhoneGapDevice;
global.KinveyPopup = PhoneGapPopup;

// Export
module.exports = PhoneGapKinvey;
<|endoftext|>


<commit_before>const { app, clipboard, remote } = require('electron');
const fs = require('fs');
const electronApp = remote ? remote.app : app;

const snippetsDir = `${electronApp.getPath('userData')}/plugins/node_modules/cerebro-snippets/snippets/`;
const icon = require('./icons/icon.png');
const deleteIcon = require('./icons/deleteIcon.png');

const selectSnippet = require('./lib/selectSnippet');
const createSnippet = require('./lib/createSnippet');
const deleteSnippet = require('./lib/deleteSnippet');

const plugin = ({ term, display, actions, settings }) => {
    let results = [];

    // split term into command and param
    let command = term.split(' ')[0];
    let param = term.split(' ')[1] || '';

    // list of available commands
    let commands = [
        {
            title: 'Create snippet',
            subtitle: 'from clipboard content',
            term: 'snipc',
            icon: icon,
            onSelect: (ev) => {
                ev.preventDefault();
                actions.replaceTerm('snipc ');
            }
        },
        {
            title: 'Search snippets',
            term: 'snip',
            icon: icon,
            onSelect: (ev) => {
                ev.preventDefault();
                actions.replaceTerm('snip ');
            }
        },
        {
            title: 'Delete snippets',
            term: 'snipd',
            icon: deleteIcon,
            onSelect: (ev) => {
                ev.preventDefault();
                actions.replaceTerm('snipd ');
            }
        }
    ];

    // handle different commands
    switch (command) {
        case 'snip':
            results = selectSnippet(snippetsDir, param, actions);
            break;
        case 'snipc':
            results = createSnippet(snippetsDir, param);
            break;
        case 'snipd':
            results = deleteSnippet(snippetsDir, param);
            break;
    }

    // add autocomplete for possible commands
    results = [
        ...results,
        ...commands.filter(item => (command != item.term && item.term.indexOf(command) !== -1))
    ];

    // display results
    if (results.length > 0) {
        // add icon to results
        results.map(obj => {
            if (!obj.icon) {
                obj.icon = icon
            }
        });

        display(results);
    }
}

module.exports = {
    fn: plugin,
    icon: icon
};<commit_msg>Add setting to disable the search keyword "snip"<commit_after>const { app, clipboard, remote } = require('electron');
const fs = require('fs');
const electronApp = remote ? remote.app : app;

const snippetsDir = `${electronApp.getPath('userData')}/plugins/node_modules/cerebro-snippets/snippets/`;
const icon = require('./icons/icon.png');
const deleteIcon = require('./icons/deleteIcon.png');

const selectSnippet = require('./lib/selectSnippet');
const createSnippet = require('./lib/createSnippet');
const deleteSnippet = require('./lib/deleteSnippet');

const plugin = ({ term, display, actions, settings }) => {
    let results = [];

    // split term into command and param
    let command = term.split(' ')[0];
    let param = term.split(' ')[1] || '';

    // list of available commands
    let commands = [
        {
            title: 'Create snippet',
            subtitle: 'from clipboard content',
            term: 'snipc',
            icon: icon,
            onSelect: (ev) => {
                ev.preventDefault();
                actions.replaceTerm('snipc ');
            }
        },
        {
            title: 'Search snippets',
            term: 'snip',
            icon: icon,
            onSelect: (ev) => {
                ev.preventDefault();
                actions.replaceTerm('snip ');
            }
        },
        {
            title: 'Delete snippets',
            term: 'snipd',
            icon: deleteIcon,
            onSelect: (ev) => {
                ev.preventDefault();
                actions.replaceTerm('snipd ');
            }
        }
    ];

    // handle different commands
    switch (command) {
        case 'snip':
            results = selectSnippet(snippetsDir, param, actions);
            break;
        case 'snipc':
            results = createSnippet(snippetsDir, param);
            break;
        case 'snipd':
            results = deleteSnippet(snippetsDir, param);
            break;
    }

    // search without keyword "snip"
    if (settings.disableSearchKeyword && param === '') {
        results = selectSnippet(snippetsDir, command, actions);
    }

    // add autocomplete for possible commands
    results = [
        ...results,
        ...commands.filter(item => (command != item.term && item.term.indexOf(command) !== -1))
    ];

    // display results
    if (results.length > 0) {
        // add icon to results
        results.map(obj => {
            if (!obj.icon) {
                obj.icon = icon
            }
        });

        display(results);
    }
}

module.exports = {
    fn: plugin,
    icon: icon,
    settings: {
        disableSearchKeyword: {
            type: "bool",
            label: 'Search without keyword "snip"',
            defaultValue: false,
        }
    }
};<|endoftext|>


<commit_before>import 'source-map-support/register';
import "babel-polyfill";

import buildApp from './build/buildMain';

export default buildApp;
<commit_msg>Fix lint error<commit_after>import 'source-map-support/register';
import 'babel-polyfill';

import buildApp from './build/buildMain';

export default buildApp;
<|endoftext|>


<commit_before>/**
 Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.

 Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at

 http://aws.amazon.com/apache2.0/

 or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
 */

/**
 * This simple sample has no external dependencies or session management, and shows the most basic
 * example of how to create a Lambda function for handling Alexa Skill requests.
 *
 * Examples:
 * One-shot model:
 *  User: "Alexa, tell Greeter to say hello"
 *  Alexa: "Hello World!"
 */

/**
 * App ID for the skill
 */
var APP_ID = undefined; //replace with "amzn1.echo-sdk-ams.app.[your-unique-value-here]";

/**
 * The AlexaSkill prototype and helper functions
 */
var AlexaSkill = require('./AlexaSkill');
var Speech = require('./lib/speech');

/**
 * DrSpeech is a child of AlexaSkill.
 * To read more about inheritance in JavaScript, see the link below.
 *
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript#Inheritance
 */
var DrSpeech = function () {
    AlexaSkill.call(this, APP_ID);
};

// Extend AlexaSkill
DrSpeech.prototype = Object.create(AlexaSkill.prototype);
DrSpeech.prototype.constructor = DrSpeech;

DrSpeech.prototype.eventHandlers.onSessionStarted = function (sessionStartedRequest, session) {
    console.log("DrSpeech onSessionStarted requestId: " + sessionStartedRequest.requestId
        + ", sessionId: " + session.sessionId);
    // any initialization logic goes here
};

DrSpeech.prototype.eventHandlers.onLaunch = function (launchRequest, session, response) {
    var speech = new Speech();
    speech.say("Welcome to Doctor Speech. Let's Begin Your Lesson.");
    speech.say("When you give an answer, start with saying its.");
    speech.pause("1s");
    speech.say("How do you say fork?");

    response.ask(speech.toObject(), "How do you say fork?");
};

DrSpeech.prototype.eventHandlers.onSessionEnded = function (sessionEndedRequest, session) {
    console.log("DrSpeech onSessionEnded requestId: " + sessionEndedRequest.requestId
        + ", sessionId: " + session.sessionId);
    // any cleanup logic goes here
};

DrSpeech.prototype.intentHandlers = {
    // register custom intent handlers
    "SayWordIntent": function (intent, session, response) {
        var speech = new Speech();
        var word = intent.slots.Word.value;
        if (word == "fork") {
            speech.say("You said it correctly.");
            speech.audio("https://ssl.gstatic.com/dictionary/static/sounds/de/0/" + word.toLowerCase() + ".mp3");
            speech.pause("1s");
            speech.say("It spells as ");
            speech.spell(word);
        } else {
            speech.say("That was not correct. I heard ");
            speech.say(word)
            speech.say(" which is spelled");
            speech.spell(word);
            speech.pause("1s");
            speech.say("The correct way to pronounce it is");
            speech.pause("800ms");
            speech.audio("https://ssl.gstatic.com/dictionary/static/sounds/de/0/fork.mp3");
        }

        response.tell(speech.toObject());
    },
    "AMAZON.HelpIntent": function (intent, session, response) {
        response.ask("Try again and listen carefully", "You can do this!");
    }
};

// Create the handler that responds to the Alexa Request.
exports.handler = function (event, context) {
    // Create an instance of the DrSpeech skill.
    var helloWorld = new DrSpeech();
    helloWorld.execute(event, context);
};
<commit_msg>failed<commit_after>/**
 Copyright 2014-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.

 Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at

 http://aws.amazon.com/apache2.0/

 or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
 */

/**
 * This simple sample has no external dependencies or session management, and shows the most basic
 * example of how to create a Lambda function for handling Alexa Skill requests.
 *
 * Examples:
 * One-shot model:
 *  User: "Alexa, tell Greeter to say hello"
 *  Alexa: "Hello World!"
 */

/**
 * App ID for the skill
 */
var APP_ID = undefined; //replace with "amzn1.echo-sdk-ams.app.[your-unique-value-here]";

/**
 * The AlexaSkill prototype and helper functions
 */
var AlexaSkill = require('./AlexaSkill');
var Speech = require('./lib/speech');

/**
 * DrSpeech is a child of AlexaSkill.
 * To read more about inheritance in JavaScript, see the link below.
 *
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript#Inheritance
 */
var DrSpeech = function () {
    AlexaSkill.call(this, APP_ID);
};

// Extend AlexaSkill
DrSpeech.prototype = Object.create(AlexaSkill.prototype);
DrSpeech.prototype.constructor = DrSpeech;

DrSpeech.prototype.eventHandlers.onSessionStarted = function (sessionStartedRequest, session) {
    console.log("DrSpeech onSessionStarted requestId: " + sessionStartedRequest.requestId
        + ", sessionId: " + session.sessionId);
    // any initialization logic goes here
};

DrSpeech.prototype.eventHandlers.onLaunch = function (launchRequest, session, response) {
    var speech = new Speech();
    speech.say("Welcome to Doctor Speech. Let's Begin Your Lesson.");
    speech.say("When you give an answer, start with saying its.");
    speech.pause("1s");
    speech.say("How do you say fork?");

    response.ask(speech.toObject(), "How do you say fork?");
};

DrSpeech.prototype.eventHandlers.onSessionEnded = function (sessionEndedRequest, session) {
    console.log("DrSpeech onSessionEnded requestId: " + sessionEndedRequest.requestId
        + ", sessionId: " + session.sessionId);
    // any cleanup logic goes here
};

DrSpeech.prototype.intentHandlers = {
    // register custom intent handlers
    "SayWordIntent": function (intent, session, response) {
        var speech = new Speech();
        var word = intent.slots.Word.value;
        if (word == "fork") {
            speech.say("You said it correctly.");
            speech.say(word);
            speech.pause("1s");
            speech.say("It spells as ");
            speech.spell(word);
        } else {
            speech.say("That was not correct. I heard ");
            speech.say(word);
            speech.say(" which is spelled");
            speech.spell(word);
        }

        response.tell(speech.toObject());
    },
    "AMAZON.HelpIntent": function (intent, session, response) {
        response.ask("Try again and listen carefully", "You can do this!");
    }
};

// Create the handler that responds to the Alexa Request.
exports.handler = function (event, context) {
    // Create an instance of the DrSpeech skill.
    var helloWorld = new DrSpeech();
    helloWorld.execute(event, context);
};
<|endoftext|>


<commit_before>const GitHubApi = require('github');
const Menu = require('terminal-menu');
const {
  execSync
} = require('child_process');
const parse = require('parse-github-repo-url');

class Pullit {
  constructor() {
    this.init();
    this.hostname = 'api.github.com';
    this.github = new GitHubApi({
      hostname: this.hostname
    });
  }

  init() {
    const url = execSync(`git config --get remote.origin.url`, {
      encoding: 'utf8'
    }).trim();

    if (url.includes('github.com')) {
      return this.parsedGithubUrl(url);
    } else {
      return this.parsedGithubEnterpriseUrl(url);
    }
  }

  parsedGithubUrl(url) {
    const parsedUrl = parse(url);

    (this.owner = parsedUrl[0]), (this.repo = parsedUrl[1]);
  }

  parsedGithubEnterpriseUrl(url) {
    const splitUrl = url.split(':');
    const splitRepo = splitUrl[1].split('/');
    (this.owner = splitRepo[0]), (this.repo = splitRepo[1]), (this.hostname = splitUrl[0]);
  }

  fetch(id) {
    return this.github.pullRequests
      .get({
        owner: this.owner,
        repo: this.repo,
        number: id
      })
      .then(res => {
        const branch = res.data.head.ref;
        execSync(
          `git fetch origin pull/${id}/head:${branch} && git checkout ${branch}`
        );
      });
  }

  fetchRequests() {
    return this.github.pullRequests.getAll({
      owner: this.owner,
      repo: this.repo
    });
  }

  display() {
    this.fetchRequests().then(results => {
      const menu = Menu({
        width: 100,
        x: 4,
        y: 2
      });
      menu.reset();
      menu.write('Currently open pull requests:\n');
      menu.write('-------------------------\n');

      results.data.forEach(element => {
        menu.add(`${element.number} - ${element.title}`);
      });

      menu.add(`Exit`);

      menu.on('select', label => {
        menu.close();
        this.fetch(label.split(' ')[0]);
      });
      process.stdin.pipe(menu.createStream()).pipe(process.stdout);

      process.stdin.setRawMode(true);
      menu.on('close', () => {
        process.stdin.setRawMode(false);
        process.stdin.end();
      });
    });
  }
}

module.exports = Pullit;<commit_msg>back to basics<commit_after>const GitHubApi = require('github');
const Menu = require('terminal-menu');
const {
  execSync
} = require('child_process');
const parse = require('parse-github-repo-url');

class Pullit {
  constructor() {
    this.init();
    this.github = new GitHubApi({});
  }

  init() {
    const url = execSync(`git config --get remote.origin.url`, {
      encoding: 'utf8'
    }).trim();

    return this.parsedGithubUrl(url);
  }

  parsedGithubUrl(url) {
    const parsedUrl = parse(url);

    (this.owner = parsedUrl[0]), (this.repo = parsedUrl[1]);
  }

  fetch(id) {
    return this.github.pullRequests
      .get({
        owner: this.owner,
        repo: this.repo,
        number: id
      })
      .then(res => {
        const branch = res.data.head.ref;
        execSync(
          `git fetch origin pull/${id}/head:${branch} && git checkout ${branch}`
        );
      });
  }

  fetchRequests() {
    return this.github.pullRequests.getAll({
      owner: this.owner,
      repo: this.repo
    });
  }

  display() {
    this.fetchRequests().then(results => {
      const menu = Menu({
        width: 100,
        x: 4,
        y: 2
      });
      menu.reset();
      menu.write('Currently open pull requests:\n');
      menu.write('-------------------------\n');

      results.data.forEach(element => {
        menu.add(`${element.number} - ${element.title}`);
      });

      menu.add(`Exit`);

      menu.on('select', label => {
        menu.close();
        this.fetch(label.split(' ')[0]);
      });
      process.stdin.pipe(menu.createStream()).pipe(process.stdout);

      process.stdin.setRawMode(true);
      menu.on('close', () => {
        process.stdin.setRawMode(false);
        process.stdin.end();
      });
    });
  }
}

module.exports = Pullit;<|endoftext|>


<commit_before>import fs from 'fs';
import path from 'path';
import homeOrTmp from 'home-or-tmp';
import tar from 'tar';
import EventEmitter from 'events';
import chalk from 'chalk';
import { rimrafSync } from 'sander';
import { DegitError, exec, fetch, mkdirp, tryRequire, stashFiles, unstashFiles, degitConfigName } from './utils';

const base = path.join(homeOrTmp, '.degit');

export default function degit(src, opts) {
	return new Degit(src, opts);
}

class Degit extends EventEmitter {
	constructor(src, opts = {}) {
		super();

		this.src = src;
		this.cache = opts.cache;
		this.force = opts.force;
		this.verbose = opts.verbose;

		this.repo = parse(src);

		this.directiveActions = {
			clone: async (dest, action) => {
        const opts = Object.assign({force: true}, {cache: action.cache, verbose: action.verbose});
				const d = degit(action.src, opts);

				d.on('info', event => {
					console.error(chalk.cyan(`> ${event.message.replace('options.', '--')}`));
				});

				d.on('warn', event => {
					console.error(chalk.magenta(`! ${event.message.replace('options.', '--')}`));
				});

				await d.clone(dest)
					.catch(err => {
						console.error(chalk.red(`! ${err.message}`));
						process.exit(1);
					});
			},
			remove: this.remove.bind(this)
		};
	}

	async clone(dest) {
		this._checkDirIsEmpty(dest);

		const repo = this.repo;

		const dir = path.join(base, repo.site, repo.user, repo.name);
		const cached = tryRequire(path.join(dir, 'map.json')) || {};

		const hash = this.cache ?
			this._getHashFromCache(repo, cached) :
			await this._getHash(repo, cached);

		if (!hash) {
			// TODO 'did you mean...?'
			throw new DegitError(`could not find commit hash for ${repo.ref}`, {
				code: 'MISSING_REF',
				ref: repo.ref
			});
		}

		const file = `${dir}/${hash}.tar.gz`;
		const url = (
			repo.site === 'gitlab' ? `${repo.url}/repository/archive.tar.gz?ref=${hash}` :
			repo.site === 'bitbucket' ? `${repo.url}/get/${hash}.tar.gz` :
			`${repo.url}/archive/${hash}.tar.gz`
		);

		try {
			if (!this.cache) {
				try {
					fs.statSync(file);
					this._verbose({
						code: 'FILE_EXISTS',
						message: `${file} already exists locally`
					});
				} catch (err) {
					mkdirp(path.dirname(file));
					this._verbose({
						code: 'DOWNLOADING',
						message: `downloading ${url} to ${file}`
					});

					await fetch(url, file);
				}
			}
		} catch (err) {
			throw new DegitError(`could not download ${url}`, {
				code: 'COULD_NOT_DOWNLOAD',
				url,
				original: err
			});
		}

		updateCache(dir, repo, hash, cached);

		this._verbose({
			code: 'EXTRACTING',
			message: `extracting ${file} to ${dest}`
		});

		mkdirp(dest);
		await untar(file, dest);

		this._info({
			code: 'SUCCESS',
			message: `cloned ${chalk.bold(repo.user + '/' + repo.name)}#${chalk.bold(repo.ref)}${dest !== '.' ? ` to ${dest}` : ''}`,
			repo,
			dest
		});

		const directives = tryRequire(path.resolve(dest, degitConfigName), {clearCache: true}) || false;
		if (directives) {
			stashFiles(dir, dest);
			for (const d of directives) {
        // TODO, can this be a loop with an index to pass for better error messages?
				await this.directiveActions[d.action](dest, d);
			}
			unstashFiles(dir, dest);
		}
	}

	remove(dest, action) {
    let files = action.files;
    if (!Array.isArray(files)) {
      files = [files];
    }
		const removedFiles = files.map(file => {
			const filePath = path.resolve(dest, file);
			if (fs.existsSync(filePath)) {
        const isDir = fs.lstatSync(filePath).isDirectory();
        if (isDir) {
          rimrafSync(filePath);
          return file + '/';
        } else {
          fs.unlinkSync(filePath);
          return file;
        }
			} else {
				this._warn({
					code: 'FILE_DOES_NOT_EXIST',
					message: `action wants to remove ${chalk.bold(file)} but it does not exist`
				});
        return null;
			}
	  }).filter(d => d);
	  this._info({
			code: 'REMOVED',
			message: `removed: ${chalk.bold(removedFiles.map(d => chalk.bold(d)).join(', '))}`
	  });

	}

	_checkDirIsEmpty(dir) {
		try {
			const files = fs.readdirSync(dir);
			if (files.length > 0) {
				if (this.force) {
					this._info({
						code: 'DEST_NOT_EMPTY',
						message: `destination directory is not empty. Using options.force, continuing`
					});
				} else {
					throw new DegitError(`destination directory is not empty, aborting. Use options.force to override`, {
						code: 'DEST_NOT_EMPTY'
					});
				}
			} else {
				this._verbose({
					code: 'DEST_IS_EMPTY',
					message: `destination directory is empty`
				});
			}
		} catch (err) {
			if (err.code !== 'ENOENT') throw err;
		}
	}

	_info(info) {
		this.emit('info', info);
	}

	_warn(info) {
		this.emit('warn', info);
	}

	_verbose(info) {
		if (this.verbose) this._info(info);
	}

	async _getHash(repo, cached) {
		try {
			const refs = await fetchRefs(repo);
			return this._selectRef(refs, repo.ref);
		} catch (err) {
			return this._getHashFromCache(repo, cached);
		}
	}

	_getHashFromCache(repo, cached) {
		if (repo.ref in cached) {
			const hash = cached[repo.ref];
			this._info({
				code: 'USING_CACHE',
				message: `using cached commit hash ${hash}`
			});
			return hash;
		}
	}

	_selectRef(refs, selector) {
		for (const ref of refs) {
			if (ref.name === selector) {
				this._verbose({
					code: 'FOUND_MATCH',
					message: `found matching commit hash: ${ref.hash}`
				});
				return ref.hash;
			}
		}

		if (selector.length < 8) return null;

		for (const ref of refs) {
			if (ref.hash.startsWith(selector)) return ref.hash;
		}
	}
}

const supported = new Set(['github', 'gitlab', 'bitbucket']);

function parse(src) {
	const match = /^(?:https:\/\/([^/]+)\/|git@([^/]+):|([^/]+):)?([^/\s]+)\/([^/\s#]+)(?:#(.+))?/.exec(src);
	if (!match) {
		throw new DegitError(`could not parse ${src}`, {
			code: 'BAD_SRC'
		});
	}

	const site = (match[1] || match[2] || match[3] || 'github').replace(/\.(com|org)$/, '');
	if (!supported.has(site)) {
		throw new DegitError(`degit supports GitHub, GitLab and BitBucket`, {
			code: 'UNSUPPORTED_HOST'
		});
	}

	const user = match[4];
	const name = match[5].replace(/\.git$/, '');
	const ref = match[6] || 'master';

	const url = `https://${site}.${site === 'bitbucket' ? 'org' : 'com'}/${user}/${name}`;

	return { site, user, name, ref, url };
}

async function untar(file, dest) {
	return tar.extract({
		file,
		strip: 1,
		C: dest
	});
}

async function fetchRefs(repo) {
	const { stdout } = await exec(`git ls-remote ${repo.url}`);

	return stdout.split('\n').filter(Boolean).map(row => {
		const [hash, ref] = row.split('\t');

		if (ref === 'HEAD') {
			return {
				type: 'HEAD',
				hash
			};
		}

		const match = /refs\/(\w+)\/(.+)/.exec(ref);
		if (!match) throw new DegitError(`could not parse ${ref}`, { code: 'BAD_REF' });

		return {
			type: (
				match[1] === 'heads' ? 'branch' :
				match[1] === 'refs' ? 'ref' :
				match[1]
			),
			name: match[2],
			hash
		};
	});
}

function updateCache(dir, repo, hash, cached) {
	if (cached[repo.ref] === hash) return;

	const oldHash = cached[repo.ref];
	if (oldHash) {
		let used = false;
		for (const key in cached) {
			if (cached[key] === hash) {
				used = true;
				break;
			}
		}

		if (!used) {
			// we no longer need this tar file
			try {
				fs.unlinkSync(path.join(dir, `${oldHash}.tar.gz`));
			} catch (err) {
				// ignore
			}
		}
	}

	cached[repo.ref] = hash;
	fs.writeFileSync(path.join(dir, 'map.json'), JSON.stringify(cached, null, '  '));
}
<commit_msg>formatting<commit_after>import fs from 'fs';
import path from 'path';
import homeOrTmp from 'home-or-tmp';
import tar from 'tar';
import EventEmitter from 'events';
import chalk from 'chalk';
import { rimrafSync } from 'sander';
import { DegitError, exec, fetch, mkdirp, tryRequire, stashFiles, unstashFiles, degitConfigName } from './utils';

const base = path.join(homeOrTmp, '.degit');

export default function degit(src, opts) {
	return new Degit(src, opts);
}

class Degit extends EventEmitter {
	constructor(src, opts = {}) {
		super();

		this.src = src;
		this.cache = opts.cache;
		this.force = opts.force;
		this.verbose = opts.verbose;

		this.repo = parse(src);

		this.directiveActions = {
			clone: async (dest, action) => {
        const opts = Object.assign({force: true}, {cache: action.cache, verbose: action.verbose});
				const d = degit(action.src, opts);

				d.on('info', event => {
					console.error(chalk.cyan(`> ${event.message.replace('options.', '--')}`));
				});

				d.on('warn', event => {
					console.error(chalk.magenta(`! ${event.message.replace('options.', '--')}`));
				});

				await d.clone(dest)
					.catch(err => {
						console.error(chalk.red(`! ${err.message}`));
						process.exit(1);
					});
			},
			remove: this.remove.bind(this)
		};
	}

	async clone(dest) {
		this._checkDirIsEmpty(dest);

		const repo = this.repo;

		const dir = path.join(base, repo.site, repo.user, repo.name);
		const cached = tryRequire(path.join(dir, 'map.json')) || {};

		const hash = this.cache ?
			this._getHashFromCache(repo, cached) :
			await this._getHash(repo, cached);

		if (!hash) {
			// TODO 'did you mean...?'
			throw new DegitError(`could not find commit hash for ${repo.ref}`, {
				code: 'MISSING_REF',
				ref: repo.ref
			});
		}

		const file = `${dir}/${hash}.tar.gz`;
		const url = (
			repo.site === 'gitlab' ? `${repo.url}/repository/archive.tar.gz?ref=${hash}` :
			repo.site === 'bitbucket' ? `${repo.url}/get/${hash}.tar.gz` :
			`${repo.url}/archive/${hash}.tar.gz`
		);

		try {
			if (!this.cache) {
				try {
					fs.statSync(file);
					this._verbose({
						code: 'FILE_EXISTS',
						message: `${file} already exists locally`
					});
				} catch (err) {
					mkdirp(path.dirname(file));
					this._verbose({
						code: 'DOWNLOADING',
						message: `downloading ${url} to ${file}`
					});

					await fetch(url, file);
				}
			}
		} catch (err) {
			throw new DegitError(`could not download ${url}`, {
				code: 'COULD_NOT_DOWNLOAD',
				url,
				original: err
			});
		}

		updateCache(dir, repo, hash, cached);

		this._verbose({
			code: 'EXTRACTING',
			message: `extracting ${file} to ${dest}`
		});

		mkdirp(dest);
		await untar(file, dest);

		this._info({
			code: 'SUCCESS',
			message: `cloned ${chalk.bold(repo.user + '/' + repo.name)}#${chalk.bold(repo.ref)}${dest !== '.' ? ` to ${dest}` : ''}`,
			repo,
			dest
		});

		const directives = tryRequire(path.resolve(dest, degitConfigName), {clearCache: true}) || false;
		if (directives) {
			stashFiles(dir, dest);
			for (const d of directives) {
				// TODO, can this be a loop with an index to pass for better error messages?
				await this.directiveActions[d.action](dest, d);
			}
			unstashFiles(dir, dest);
		}
	}

	remove(dest, action) {
    let files = action.files;
    if (!Array.isArray(files)) {
      files = [files];
    }
		const removedFiles = files.map(file => {
			const filePath = path.resolve(dest, file);
			if (fs.existsSync(filePath)) {
				const isDir = fs.lstatSync(filePath).isDirectory();
				if (isDir) {
					rimrafSync(filePath);
					return file + '/';
				} else {
					fs.unlinkSync(filePath);
					return file;
				}
			} else {
				this._warn({
					code: 'FILE_DOES_NOT_EXIST',
					message: `action wants to remove ${chalk.bold(file)} but it does not exist`
				});
				return null;
			}
		}).filter(d => d);

		this._info({
			code: 'REMOVED',
			message: `removed: ${chalk.bold(removedFiles.map(d => chalk.bold(d)).join(', '))}`
		});
	}

	_checkDirIsEmpty(dir) {
		try {
			const files = fs.readdirSync(dir);
			if (files.length > 0) {
				if (this.force) {
					this._info({
						code: 'DEST_NOT_EMPTY',
						message: `destination directory is not empty. Using options.force, continuing`
					});
				} else {
					throw new DegitError(`destination directory is not empty, aborting. Use options.force to override`, {
						code: 'DEST_NOT_EMPTY'
					});
				}
			} else {
				this._verbose({
					code: 'DEST_IS_EMPTY',
					message: `destination directory is empty`
				});
			}
		} catch (err) {
			if (err.code !== 'ENOENT') throw err;
		}
	}

	_info(info) {
		this.emit('info', info);
	}

	_warn(info) {
		this.emit('warn', info);
	}

	_verbose(info) {
		if (this.verbose) this._info(info);
	}

	async _getHash(repo, cached) {
		try {
			const refs = await fetchRefs(repo);
			return this._selectRef(refs, repo.ref);
		} catch (err) {
			return this._getHashFromCache(repo, cached);
		}
	}

	_getHashFromCache(repo, cached) {
		if (repo.ref in cached) {
			const hash = cached[repo.ref];
			this._info({
				code: 'USING_CACHE',
				message: `using cached commit hash ${hash}`
			});
			return hash;
		}
	}

	_selectRef(refs, selector) {
		for (const ref of refs) {
			if (ref.name === selector) {
				this._verbose({
					code: 'FOUND_MATCH',
					message: `found matching commit hash: ${ref.hash}`
				});
				return ref.hash;
			}
		}

		if (selector.length < 8) return null;

		for (const ref of refs) {
			if (ref.hash.startsWith(selector)) return ref.hash;
		}
	}
}

const supported = new Set(['github', 'gitlab', 'bitbucket']);

function parse(src) {
	const match = /^(?:https:\/\/([^/]+)\/|git@([^/]+):|([^/]+):)?([^/\s]+)\/([^/\s#]+)(?:#(.+))?/.exec(src);
	if (!match) {
		throw new DegitError(`could not parse ${src}`, {
			code: 'BAD_SRC'
		});
	}

	const site = (match[1] || match[2] || match[3] || 'github').replace(/\.(com|org)$/, '');
	if (!supported.has(site)) {
		throw new DegitError(`degit supports GitHub, GitLab and BitBucket`, {
			code: 'UNSUPPORTED_HOST'
		});
	}

	const user = match[4];
	const name = match[5].replace(/\.git$/, '');
	const ref = match[6] || 'master';

	const url = `https://${site}.${site === 'bitbucket' ? 'org' : 'com'}/${user}/${name}`;

	return { site, user, name, ref, url };
}

async function untar(file, dest) {
	return tar.extract({
		file,
		strip: 1,
		C: dest
	});
}

async function fetchRefs(repo) {
	const { stdout } = await exec(`git ls-remote ${repo.url}`);

	return stdout.split('\n').filter(Boolean).map(row => {
		const [hash, ref] = row.split('\t');

		if (ref === 'HEAD') {
			return {
				type: 'HEAD',
				hash
			};
		}

		const match = /refs\/(\w+)\/(.+)/.exec(ref);
		if (!match) throw new DegitError(`could not parse ${ref}`, { code: 'BAD_REF' });

		return {
			type: (
				match[1] === 'heads' ? 'branch' :
				match[1] === 'refs' ? 'ref' :
				match[1]
			),
			name: match[2],
			hash
		};
	});
}

function updateCache(dir, repo, hash, cached) {
	if (cached[repo.ref] === hash) return;

	const oldHash = cached[repo.ref];
	if (oldHash) {
		let used = false;
		for (const key in cached) {
			if (cached[key] === hash) {
				used = true;
				break;
			}
		}

		if (!used) {
			// we no longer need this tar file
			try {
				fs.unlinkSync(path.join(dir, `${oldHash}.tar.gz`));
			} catch (err) {
				// ignore
			}
		}
	}

	cached[repo.ref] = hash;
	fs.writeFileSync(path.join(dir, 'map.json'), JSON.stringify(cached, null, '  '));
}
<|endoftext|>


<commit_before>import fs from 'fs';
import path from 'path';
import relative from 'require-relative';
import { compile } from 'svelte';
import { createFilter } from 'rollup-pluginutils';
import { encode, decode } from 'sourcemap-codec';

function sanitize(input) {
	return path
		.basename(input)
		.replace(path.extname(input), '')
		.replace(/[^a-zA-Z_$0-9]+/g, '_')
		.replace(/^_/, '')
		.replace(/_$/, '')
		.replace(/^(\d)/, '_$1');
}

function capitalize(str) {
	return str[0].toUpperCase() + str.slice(1);
}

const pluginOptions = {
	include: true,
	exclude: true,
	extensions: true
};

function tryRequire(id) {
	try {
		return require(id);
	} catch (err) {
		return null;
	}
}

function tryResolve(pkg, importer) {
	try {
		return relative.resolve(pkg, importer);
	} catch (err) {
		if (err.code === 'MODULE_NOT_FOUND') return null;
		throw err;
	}
}

function exists(file) {
	try {
		fs.statSync(file);
		return true;
	} catch (err) {
		if (err.code === 'ENOENT') return false;
		throw err;
	}
}

function mkdirp(dir) {
	const parent = path.dirname(dir);
	if (parent === dir) return;

	mkdirp(parent);

	try {
		fs.mkdirSync(dir);
	} catch (err) {
		if (err.code !== 'EEXIST') throw err;
	}
}

class CssWriter {
	constructor (code, map) {
		this.code = code;
		this.map = {
			version: 3,
			file: null,
			sources: map.sources,
			sourcesContent: map.sourcesContent,
			names: [],
			mappings: map.mappings
		};
	}

	write(dest, map) {
		dest = path.resolve(dest);
		mkdirp(path.dirname(dest));

		const basename = path.basename(dest);

		if (map !== false) {
			fs.writeFileSync(dest, `${this.code}\n/*# sourceMappingURL=${basename}.map */`);
			fs.writeFileSync(`${dest}.map`, JSON.stringify({
				version: 3,
				file: basename,
				sources: this.map.sources.map(source => path.relative(path.dirname(dest), source)),
				sourcesContent: this.map.sourcesContent,
				names: [],
				mappings: this.map.mappings
			}, null, '  '));
		} else {
			fs.writeFileSync(dest, this.code);
		}
	}

	toString() {
		console.log('[DEPRECATION] As of rollup-plugin-svelte@3, the argument to the `css` function is an object, not a string — use `css.write(file)`. Consult the documentation for more information: https://github.com/rollup/rollup-plugin-svelte'); // eslint-disable-line no-console
		return this.code;
	}
}

export default function svelte(options = {}) {
	const filter = createFilter(options.include, options.exclude);

	const extensions = options.extensions || ['.html', '.svelte'];

	const fixedOptions = {};

	Object.keys(options).forEach(key => {
		// add all options except include, exclude, extensions
		if (pluginOptions[key]) return;
		fixedOptions[key] = options[key];
	});

	fixedOptions.format = 'es';
	fixedOptions.shared = require.resolve('svelte/shared.js');
	fixedOptions.onerror = err => {
		let message =
			(err.loc ? `(${err.loc.line}:${err.loc.column}) ` : '') + err.message;
		if (err.frame) message += `\n${err.frame}`;

		const err2 = new Error(message);
		err2.stack = err.stack;

		throw err2;
	};

	// handle CSS extraction
	if ('css' in options) {
		if (typeof options.css !== 'function' && typeof options.css !== 'boolean') {
			throw new Error('options.css must be a boolean or a function');
		}
	}

	let css = options.css && typeof options.css === 'function'
		? options.css
		: null;
	const cssLookup = new Map();

	if (css) {
		fixedOptions.css = false;
	}

	return {
		name: 'svelte',

		resolveId(importee, importer) {
			if (!importer || importee[0] === '.' || importee[0] === '\0' || path.isAbsolute(importee))
				return null;

			// if this is a bare import, see if there's a valid pkg.svelte
			const parts = importee.split('/');
			let name = parts.shift();
			if (name[0] === '@') name += `/${parts.shift()}`;

			const resolved = tryResolve(
				`${name}/package.json`,
				path.dirname(importer)
			);
			if (!resolved) return null;
			const pkg = tryRequire(resolved);
			if (!pkg) return null;

			const dir = path.dirname(resolved);

			if (parts.length === 0) {
				// use pkg.svelte
				if (pkg.svelte) {
					return path.resolve(dir, pkg.svelte);
				}
			} else {
				if (pkg['svelte.root']) {
					const sub = path.resolve(dir, pkg['svelte.root'], parts.join('/'));
					if (exists(sub)) return sub;
				}
			}
		},

		transform(code, id) {
			if (!filter(id)) return null;
			if (!~extensions.indexOf(path.extname(id))) return null;

			const compiled = compile(
				code,
				Object.assign({}, fixedOptions, {
					name: capitalize(sanitize(id)),
					filename: id
				})
			);

			if (css) {
				cssLookup.set(id, {
					code: compiled.css,
					map: compiled.cssMap
				});
			}

			return {
				code: compiled.code,
				map: compiled.map
			};
		},

		ongenerate() {
			if (css) {
				// write out CSS file. TODO would be nice if there was a
				// a more idiomatic way to do this in Rollup
				let result = '';

				const mappings = [];
				const sources = [];
				const sourcesContent = [];

				for (let chunk of cssLookup.values()) {
					if (!chunk.code) continue;

					result += chunk.code + '\n';

					if (chunk.map) {
						const i = sources.length;
						sources.push(chunk.map.sources[0]);
						sourcesContent.push(chunk.map.sourcesContent[0]);

						const decoded = decode(chunk.map.mappings);

						if (i > 0) {
							decoded.forEach(line => {
								line.forEach(segment => {
									segment[1] = i;
								});
							});
						}

						mappings.push(...decoded);
					}
				}

				const writer = new CssWriter(result, {
					sources,
					sourcesContent,
					mappings: encode(mappings)
				});

				css(writer);
			}
		}
	};
}<commit_msg>Added support for passing a custom `shared` file.<commit_after>import fs from 'fs';
import path from 'path';
import relative from 'require-relative';
import { compile } from 'svelte';
import { createFilter } from 'rollup-pluginutils';
import { encode, decode } from 'sourcemap-codec';

function sanitize(input) {
	return path
		.basename(input)
		.replace(path.extname(input), '')
		.replace(/[^a-zA-Z_$0-9]+/g, '_')
		.replace(/^_/, '')
		.replace(/_$/, '')
		.replace(/^(\d)/, '_$1');
}

function capitalize(str) {
	return str[0].toUpperCase() + str.slice(1);
}

const pluginOptions = {
	include: true,
	exclude: true,
	extensions: true,
	shared: true
};

function tryRequire(id) {
	try {
		return require(id);
	} catch (err) {
		return null;
	}
}

function tryResolve(pkg, importer) {
	try {
		return relative.resolve(pkg, importer);
	} catch (err) {
		if (err.code === 'MODULE_NOT_FOUND') return null;
		throw err;
	}
}

function exists(file) {
	try {
		fs.statSync(file);
		return true;
	} catch (err) {
		if (err.code === 'ENOENT') return false;
		throw err;
	}
}

function mkdirp(dir) {
	const parent = path.dirname(dir);
	if (parent === dir) return;

	mkdirp(parent);

	try {
		fs.mkdirSync(dir);
	} catch (err) {
		if (err.code !== 'EEXIST') throw err;
	}
}

class CssWriter {
	constructor (code, map) {
		this.code = code;
		this.map = {
			version: 3,
			file: null,
			sources: map.sources,
			sourcesContent: map.sourcesContent,
			names: [],
			mappings: map.mappings
		};
	}

	write(dest, map) {
		dest = path.resolve(dest);
		mkdirp(path.dirname(dest));

		const basename = path.basename(dest);

		if (map !== false) {
			fs.writeFileSync(dest, `${this.code}\n/*# sourceMappingURL=${basename}.map */`);
			fs.writeFileSync(`${dest}.map`, JSON.stringify({
				version: 3,
				file: basename,
				sources: this.map.sources.map(source => path.relative(path.dirname(dest), source)),
				sourcesContent: this.map.sourcesContent,
				names: [],
				mappings: this.map.mappings
			}, null, '  '));
		} else {
			fs.writeFileSync(dest, this.code);
		}
	}

	toString() {
		console.log('[DEPRECATION] As of rollup-plugin-svelte@3, the argument to the `css` function is an object, not a string — use `css.write(file)`. Consult the documentation for more information: https://github.com/rollup/rollup-plugin-svelte'); // eslint-disable-line no-console
		return this.code;
	}
}

export default function svelte(options = {}) {
	const filter = createFilter(options.include, options.exclude);

	const extensions = options.extensions || ['.html', '.svelte'];

	const fixedOptions = {};

	Object.keys(options).forEach(key => {
		// add all options except include, exclude, extensions, and shared
		if (pluginOptions[key]) return;
		fixedOptions[key] = options[key];
	});

	fixedOptions.format = 'es';
	fixedOptions.shared = require.resolve(options.shared || 'svelte/shared.js');
	fixedOptions.onerror = err => {
		let message =
			(err.loc ? `(${err.loc.line}:${err.loc.column}) ` : '') + err.message;
		if (err.frame) message += `\n${err.frame}`;

		const err2 = new Error(message);
		err2.stack = err.stack;

		throw err2;
	};

	// handle CSS extraction
	if ('css' in options) {
		if (typeof options.css !== 'function' && typeof options.css !== 'boolean') {
			throw new Error('options.css must be a boolean or a function');
		}
	}

	let css = options.css && typeof options.css === 'function'
		? options.css
		: null;
	const cssLookup = new Map();

	if (css) {
		fixedOptions.css = false;
	}

	return {
		name: 'svelte',

		resolveId(importee, importer) {
			if (!importer || importee[0] === '.' || importee[0] === '\0' || path.isAbsolute(importee))
				return null;

			// if this is a bare import, see if there's a valid pkg.svelte
			const parts = importee.split('/');
			let name = parts.shift();
			if (name[0] === '@') name += `/${parts.shift()}`;

			const resolved = tryResolve(
				`${name}/package.json`,
				path.dirname(importer)
			);
			if (!resolved) return null;
			const pkg = tryRequire(resolved);
			if (!pkg) return null;

			const dir = path.dirname(resolved);

			if (parts.length === 0) {
				// use pkg.svelte
				if (pkg.svelte) {
					return path.resolve(dir, pkg.svelte);
				}
			} else {
				if (pkg['svelte.root']) {
					const sub = path.resolve(dir, pkg['svelte.root'], parts.join('/'));
					if (exists(sub)) return sub;
				}
			}
		},

		transform(code, id) {
			if (!filter(id)) return null;
			if (!~extensions.indexOf(path.extname(id))) return null;

			const compiled = compile(
				code,
				Object.assign({}, fixedOptions, {
					name: capitalize(sanitize(id)),
					filename: id
				})
			);

			if (css) {
				cssLookup.set(id, {
					code: compiled.css,
					map: compiled.cssMap
				});
			}

			return {
				code: compiled.code,
				map: compiled.map
			};
		},

		ongenerate() {
			if (css) {
				// write out CSS file. TODO would be nice if there was a
				// a more idiomatic way to do this in Rollup
				let result = '';

				const mappings = [];
				const sources = [];
				const sourcesContent = [];

				for (let chunk of cssLookup.values()) {
					if (!chunk.code) continue;

					result += chunk.code + '\n';

					if (chunk.map) {
						const i = sources.length;
						sources.push(chunk.map.sources[0]);
						sourcesContent.push(chunk.map.sourcesContent[0]);

						const decoded = decode(chunk.map.mappings);

						if (i > 0) {
							decoded.forEach(line => {
								line.forEach(segment => {
									segment[1] = i;
								});
							});
						}

						mappings.push(...decoded);
					}
				}

				const writer = new CssWriter(result, {
					sources,
					sourcesContent,
					mappings: encode(mappings)
				});

				css(writer);
			}
		}
	};
}
<|endoftext|>


<commit_before>'use strict'

const WS = require('libp2p-websockets')
const WebRTCStar = require('libp2p-webrtc-star')
const spdy = require('libp2p-spdy')
const multiplex = require('libp2p-multiplex')
const secio = require('libp2p-secio')
const Railing = require('libp2p-railing')
const libp2p = require('libp2p')

function mapMuxers (list) {
  return list.map((pref) => {
    if (typeof pref !== 'string') {
      return pref
    }
    switch (pref.trim().toLowerCase()) {
      case 'spdy':
        return spdy
      case 'multiplex':
        return multiplex
      default:
        throw new Error(pref + ' muxer not available')
    }
  })
}

function getMuxers (options) {
  if (options) {
    return mapMuxers(options)
  } else {
    return [multiplex, spdy]
  }
}

class Node extends libp2p {
  constructor (peerInfo, peerBook, options) {
    options = options || {}
    const webRTCStar = new WebRTCStar()

    const modules = {
      transport: [
        new WS(),
        webRTCStar
      ],
      connection: {
        muxer: getMuxers(options.muxer),
        crypto: [
          secio
        ]
      },
      discovery: []
    }

    if (options.webRTCStar) {
      modules.discovery.push(webRTCStar.discovery)
    }

    if (options.bootstrap && process.env.IPFS_BOOTSTRAP) {
      const r = new Railing(options.bootstrap)
      modules.discovery.push(r)
    }

    super(modules, peerInfo, peerBook, options)
  }
}

module.exports = Node
<commit_msg>feat: remove IPFS_BOOTSTRAP flag<commit_after>'use strict'

const WS = require('libp2p-websockets')
const WebRTCStar = require('libp2p-webrtc-star')
const spdy = require('libp2p-spdy')
const multiplex = require('libp2p-multiplex')
const secio = require('libp2p-secio')
const Railing = require('libp2p-railing')
const libp2p = require('libp2p')

function mapMuxers (list) {
  return list.map((pref) => {
    if (typeof pref !== 'string') {
      return pref
    }
    switch (pref.trim().toLowerCase()) {
      case 'spdy':
        return spdy
      case 'multiplex':
        return multiplex
      default:
        throw new Error(pref + ' muxer not available')
    }
  })
}

function getMuxers (options) {
  if (options) {
    return mapMuxers(options)
  } else {
    return [multiplex, spdy]
  }
}

class Node extends libp2p {
  constructor (peerInfo, peerBook, options) {
    options = options || {}
    const webRTCStar = new WebRTCStar()

    const modules = {
      transport: [
        new WS(),
        webRTCStar
      ],
      connection: {
        muxer: getMuxers(options.muxer),
        crypto: [
          secio
        ]
      },
      discovery: []
    }

    if (options.webRTCStar) {
      modules.discovery.push(webRTCStar.discovery)
    }

    if (options.bootstrap) {
      const r = new Railing(options.bootstrap)
      modules.discovery.push(r)
    }

    super(modules, peerInfo, peerBook, options)
  }
}

module.exports = Node
<|endoftext|>


<commit_before>import {Observable as O, Subject} from "rx"
import selmatch from "matches-selector"
import dom from "./dom"
import {isVNode, VNode} from "./vnode"
import {EventListener, EventSource} from "./events"

const htmlAttrs =
  "accept accept-charset accesskey action align alt async autocomplete autofocus " +
  "autoplay autosave bgcolor buffered challenge charset checked cite code " +
  "codebase color cols colspan content contenteditable contextmenu controls coords " +
  "data data- datetime default defer dir dirname disabled download draggable dropzone " +
  "enctype for form formaction headers height hidden high href hreflang http-equiv " +
  "icon id ismap itemprop keytype kind label lang language list loop low manifest " +
  "max maxlength media method min multiple muted name novalidate open optimum pattern " +
  "ping placeholder poster preload radiogroup readonly rel required reversed rows " +
  "rowspan sandbox scope scoped seamless selected shape size sizes span spellcheck " +
  "src srcdoc srclang srcset start step summary tabindex target title type " +
  "usemap value width wrap"

const boolAttrs =
  "allowfullscreen async autofocus autoplay checked compact controls declare default " +
  "defaultchecked defaultmuted defaultselected defer disabled draggable enabled " +
  "formnovalidate hidden indeterminate inert ismap itemscope loop multiple muted " +
  "nohref noresize noshade novalidate nowrap open pauseonexit readonly required reversed " +
  "scoped seamless selected sortable spellcheck translate truespeed typemustmatch visible"

const attrByName =
  zipObj(htmlAttrs.split(" ").map(a => [a.trim(), true]))

const boolAttrByName =
  zipObj(boolAttrs.split(" ").map(a => [a.trim(), true]))

const isAttr = attr => {
  return attrByName[attr] || (attr.indexOf("data-") === 0 && attr.length > 5)
}

const toClassObj = (klass) => {
  let i, list, c, res = {}
  for (i = 0, list = (klass || "").split(" "); i < list.length; i++) {
    if (c = list[i].trim()) res[c] = true   // eslint-disable-line
  }
  return res
}

function h(tag, props, children) {
  if (arguments.length === 1) {
    props = {}
    children = []
  } else if (arguments.length === 2) {
    if (isPlainObj(props)) {
      children = []
    } else {
      children = props
      props = {}
    }
  }

  if (!isStr(tag)) {
    throw new Error("Tag selector must be a string")
  }

  // parse children
  if (!isArray(children)) {
    children = [children]
  }
  let temp = []
  for (var i = 0; i < children.length; i++) {
    const child = children[i]
    if (isVNode(child)) {
      temp.push(child)
    } else if (isPrimitive(child)) {
      temp.push(VNode(undefined, undefined, undefined, `${child}`))
    } else {
      throw new Error(`Invalid virtual node: ${child}`)
    }
  }
  children = temp

  // parse props
  const key = props.key
  const attrs = {}
  const style = props.style || {}
  const klass = toClassObj(props.class || props.className)
  keys(props).forEach(k => isAttr(k) && (attrs[k] = props[k]))

  const data = {
    key, attrs, style, klass
  }

  return VNode(tag, data, children)
}

const updateAttrs = (old, cur) => {
  const {elm} = cur
  let key, oldAttrs = old.data.attrs || {}, attrs = cur.data.attrs || {}
  for (key in attrs) {
    var c = attrs[key], o = oldAttrs[key]
    if (o !== c) {
      !c && boolAttrByName[key] ? elm.removeAttribute(key) : elm.setAttribute(key, c)
    }
  }
  for (key in oldAttrs) {
    if (!(key in attrs)) elm.removeAttribute(key)
  }
}

const updateKlass = (old, cur) => {
  const {elm} = cur
  let kl, oldKlass = old.data.klass || {}, klass = cur.data.klass || {}
  for (kl in oldKlass) {
    if (!(kl in klass)) elm.classList.remove(kl)
  }
  for (kl in klass) {
    if (!(kl in oldKlass)) elm.classList.add(kl)
  }
}

const updateStyle = (old, cur) => {
  const {elm} = cur
  let s, oldStyle = old.data.style || {}, style = cur.data.style || {}
  for (s in style) {
    var c = style[s], o = style[s]
    if (c !== o) elm.style[s] = c
  }
  for (s in oldStyle) {
    if (!(s in style)) elm.style[s] = ""
  }
}

const attachEvents = vnode => {
  vnode.data.eventSource && vnode.data.eventSource.attach(vnode.elm)
}

const reattachEvents = (old, cur) => {
  if (cur.data.eventSource !== old.data.eventSource) {
    old.data.eventSource && old.data.eventSource.detach()
    cur.data.eventSource && cur.data.eventSource.attach(cur.elm)
  }
}
const detachEvents = vnode => {
  vnode.data.eventSource && vnode.data.eventSource.detach()
}

export default function makeSnabbdom(rootElem) {
  return function snabbdom() {
    const patch = dom.init([
      {
        create(old, cur) {
          updateAttrs(old, cur)
          updateKlass(old, cur)
          updateStyle(old, cur)
          attachEvents(cur)
        },
        update(old, cur) {
          updateAttrs(old, cur)
          updateKlass(old, cur)
          updateStyle(old, cur)
          reattachEvents(old, cur)
        },
        destroy(vnode) {
          detachEvents(vnode)
        }
      }
    ])

    function cloneTree(vnode) {
      const cloned = extend({}, vnode)
      cloned.children = vnode.children && vnode.children.map(cloneTree)
      return cloned
    }

    function prepare(vdom$) {
      const newSource = () => new EventSource()
      const withSource = src => vdom$
        .merge(O.never())
        .map(vnode => (vnode.data.eventSource = vnode.data.eventSource || src) && vnode)
      return O.using(newSource, withSource).shareReplay(1)
    }

    function events(vdom$, selector, eventName) {
      const newListener = () => new EventListener(selector, eventName, false)
      const listen = listener => vdom$
        .distinctUntilChanged(vnode => vnode.data.eventSource)
        .map(vnode => {
          if (!vnode.data.eventSource) {
            console.warn(                                 // eslint-disable-line
              "DOM.events :: VDOM is not prepared for event listening.",
              "Perhaps you forgot to call DOM.prepare(vdom$)?"
            )
            return O.never()
          }
          return vnode.data.eventSource.listen(listener)
        })
      return O.using(newListener, listen).switch().share()
    }

    const Transforms = {
      h,
      events,
      prepare
    }

    function executor(vdom$) {
      const elm = isStr(rootElem) ? document.querySelector(rootElem) : rootElem
      let prev = elm
      const dispose = vdom$.subscribe(vnode => {
        vnode = cloneTree(vnode)
        patch(prev, vnode)
        prev = vnode
      })
      return {
        dispose: () => {
          dispose();
          prev = null
        }
      }
    }

    return [Transforms, executor]
  }
}
<commit_msg>Fix event listener attaching/detaching <commit_after>import {Observable as O} from "rx"
import dom from "./dom"
import {isVNode, VNode} from "./vnode"
import {zipObj, isPlainObj, isStr, isArray, isPrimitive, keys, extend} from "./util"
import {EventListener, EventSource} from "./events"

const htmlAttrs =
  "accept accept-charset accesskey action align alt async autocomplete autofocus " +
  "autoplay autosave bgcolor buffered challenge charset checked cite code " +
  "codebase color cols colspan content contenteditable contextmenu controls coords " +
  "data data- datetime default defer dir dirname disabled download draggable dropzone " +
  "enctype for form formaction headers height hidden high href hreflang http-equiv " +
  "icon id ismap itemprop keytype kind label lang language list loop low manifest " +
  "max maxlength media method min multiple muted name novalidate open optimum pattern " +
  "ping placeholder poster preload radiogroup readonly rel required reversed rows " +
  "rowspan sandbox scope scoped seamless selected shape size sizes span spellcheck " +
  "src srcdoc srclang srcset start step summary tabindex target title type " +
  "usemap value width wrap"

const boolAttrs =
  "allowfullscreen async autofocus autoplay checked compact controls declare default " +
  "defaultchecked defaultmuted defaultselected defer disabled draggable enabled " +
  "formnovalidate hidden indeterminate inert ismap itemscope loop multiple muted " +
  "nohref noresize noshade novalidate nowrap open pauseonexit readonly required reversed " +
  "scoped seamless selected sortable spellcheck translate truespeed typemustmatch visible"

const attrByName =
  zipObj(htmlAttrs.split(" ").map(a => [a.trim(), true]))

const boolAttrByName =
  zipObj(boolAttrs.split(" ").map(a => [a.trim(), true]))

const isAttr = attr => {
  return attrByName[attr] || (attr.indexOf("data-") === 0 && attr.length > 5)
}

const toClassObj = (klass) => {
  let i, list, c, res = {}
  for (i = 0, list = (klass || "").split(" "); i < list.length; i++) {
    if (c = list[i].trim()) res[c] = true   // eslint-disable-line
  }
  return res
}

function h(tag, props, children) {
  if (arguments.length === 1) {
    props = {}
    children = []
  } else if (arguments.length === 2) {
    if (isPlainObj(props)) {
      children = []
    } else {
      children = props
      props = {}
    }
  }

  if (!isStr(tag)) {
    throw new Error("Tag selector must be a string")
  }

  // parse children
  if (!isArray(children)) {
    children = [children]
  }
  let temp = []
  for (var i = 0; i < children.length; i++) {
    const child = children[i]
    if (isVNode(child)) {
      temp.push(child)
    } else if (isPrimitive(child)) {
      temp.push(VNode(undefined, undefined, undefined, `${child}`))
    } else {
      throw new Error(`Invalid virtual node: ${child}`)
    }
  }
  children = temp

  // parse props
  const key = props.key
  const attrs = {}
  const style = props.style || {}
  const klass = toClassObj(props.class || props.className)
  keys(props).forEach(k => isAttr(k) && (attrs[k] = props[k]))

  const data = {
    key, attrs, style, klass
  }

  return VNode(tag, data, children)
}

const updateAttrs = (old, cur) => {
  const {elm} = cur
  let key, oldAttrs = old.data.attrs || {}, attrs = cur.data.attrs || {}
  for (key in attrs) {
    var c = attrs[key], o = oldAttrs[key]
    if (o !== c) {
      !c && boolAttrByName[key] ? elm.removeAttribute(key) : elm.setAttribute(key, c)
    }
  }
  for (key in oldAttrs) {
    if (!(key in attrs)) elm.removeAttribute(key)
  }
}

const updateKlass = (old, cur) => {
  const {elm} = cur
  let kl, oldKlass = old.data.klass || {}, klass = cur.data.klass || {}
  for (kl in oldKlass) {
    if (!(kl in klass)) elm.classList.remove(kl)
  }
  for (kl in klass) {
    if (!(kl in oldKlass)) elm.classList.add(kl)
  }
}

const updateStyle = (old, cur) => {
  const {elm} = cur
  let s, oldStyle = old.data.style || {}, style = cur.data.style || {}
  for (s in style) {
    var c = style[s], o = style[s]
    if (c !== o) elm.style[s] = c
  }
  for (s in oldStyle) {
    if (!(s in style)) elm.style[s] = ""
  }
}

const attachEvents = vnode => {
  if (vnode.data && vnode.data.eventSource) {
    vnode.data.eventSource.attach(vnode.elm)
  }
}

const reattachEvents = (old, cur) => {
  const curSrc = (cur.data || {}).eventSource
  const oldSrc = (old.data || {}).eventSource
  if (curSrc !== oldSrc) {
    oldSrc && oldSrc.detach(cur.elm)
    curSrc && curSrc.reattach(cur.elm)
  }
}
const detachEvents = vnode => {
  if (vnode.data && vnode.data.eventSource) {
    vnode.data.eventSource.detach(vnode.elm)
  }
}

export default function makeSnabbdom(rootElem) {
  return function snabbdom() {
    const patch = dom.init([
      {
        create(old, cur) {
          updateAttrs(old, cur)
          updateKlass(old, cur)
          updateStyle(old, cur)
          attachEvents(cur)
        },
        update(old, cur) {
          updateAttrs(old, cur)
          updateKlass(old, cur)
          updateStyle(old, cur)
        },
        postpatch(old, cur) {
          reattachEvents(old, cur)
        },
        destroy(vnode) {
          detachEvents(vnode)
        }
      }
    ])

    function cloneTree(vnode) {
      const cloned = extend({}, vnode)
      cloned.children = vnode.children && vnode.children.map(cloneTree)
      return cloned
    }

    function prepare(vdom$) {
      const newSource = () => new EventSource()
      const withSource = src => vdom$
        .merge(O.never())
        .map(vnode => (vnode.data.eventSource = vnode.data.eventSource || src) && vnode)
      return O.using(newSource, withSource).shareReplay(1)
    }

    function events(vdom$, selector, eventName) {
      const newListener = () => new EventListener(selector, eventName, false)
      const listen = listener => vdom$
        .distinctUntilChanged(vnode => vnode.data.eventSource)
        .map(vnode => {
          if (!vnode.data.eventSource) {
            console.warn(                                 // eslint-disable-line
              "DOM.events :: VDOM is not prepared for event listening.",
              "Perhaps you forgot to call DOM.prepare(vdom$)?"
            )
            return O.never()
          }
          return vnode.data.eventSource.listen(listener)
        })
      return O.using(newListener, listen).switch().share()
    }

    const Transforms = {
      h,
      events,
      prepare
    }

    function executor(vdom$) {
      const elm = isStr(rootElem) ? document.querySelector(rootElem) : rootElem
      let prev = elm
      const dispose = vdom$.subscribe(vnode => {
        vnode = cloneTree(vnode)
        patch(prev, vnode)
        prev = vnode
      })
      return {
        dispose: () => {
          dispose();
          prev = null
        }
      }
    }

    return [Transforms, executor]
  }
}
<|endoftext|>