<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var message = commit_messages[randomIntFromInterval(0, commit_messages.length - 1)]
    var args = ['commit', outFile, '-m', message]
    for (var counter = 0; counter < length; counter++)
    {
      var message = commit_messages[randomIntFromInterval(0, commit_messages.le<commit_msg>How many more of these can I make?<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var message = commit_messages[randomIntFromInterval(0, commit_messages.length - 1)]
    var args = ['commit', outFile, '-m', message]
    for (var counter = 0; counter < length; counter++)
    {
      var message = commit_messages[randomIntFromInterval(0, commit_messages.len<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?"<commit_msg>Fixing an important issue with the universe.<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var args = ['commit', outFile, '-m', 'Update character']
    for (var counter = 0; counter < length; counter++)
    {
      fs.writeSync(outFD, data.slice(counter, counter+1), 0, 1)
      sleep(Math.random() * max_sleep)
      child_process.execFileSync('/usr/bin/git', args)
    }
  })
}

function sleep(seconds) {
  var endTime = new Date().getTime() + (seconds * 1000);
  while (new Date().getTime() <= endTime) {;}
}

process.on('exit', function () <commit_msg>Update character<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var args = ['commit', outFile, '-m', 'Update character']
    for (var counter = 0; counter < length; counter++)
    {
      fs.writeSync(outFD, data.slice(counter, counter+1), 0, 1)
      sleep(Math.random() * max_sleep)
      child_process.execFileSync('/usr/bin/git', args)
    }
  })
}

function sleep(seconds) {
  var endTime = new Date().getTime() + (seconds * 1000);
  while (new Date().getTime() <= endTime) {;}
}

process.on('exit', function () {<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the univer<commit_msg>Re-commiting last<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the univers<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git',<commit_msg>Incompatible dimensions found, Cthuhlu Error 666<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', <|endoftext|>


<commit_before>var fs = require('fs');
var child_process<commit_msg>Update character<commit_after>var fs = require('fs');
var child_process <|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);
  })
} else {
  console.info("Usage:")
  console.info("node commit.js infile outfile [max_time_in_seconds] [step]")
}

function sleep(second<commit_msg>You feeling lucky punk?<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);
  })
} else {
  console.info("Usage:")
  console.info("node commit.js infile outfile [max_time_in_seconds] [step]")
}

function sleep(seconds<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var args = ['commit', outFile, '-m', 'Update character']
    for (var counter = 0; counter < length; counter++)
    {
      fs.writeSync(outFD, data.slice(counte<commit_msg>Update character<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var args = ['commit', outFile, '-m', 'Update character']
    for (var counter = 0; counter < length; counter++)
    {
      fs.writeSync(outFD, data.slice(counter<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing fr<commit_msg>Fixed memory parsing error #1337<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing fro<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(pr<commit_msg>Back out the last commit<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(pro<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
/<commit_msg>Sprint complete<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed<commit_msg>Fixing an important issue with the universe.<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed <|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = pro<commit_msg>Fixing an error introduced in the last commit<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = proc<|endoftext|>


<commit_before>define(
  'ephox.phoenix.extract.Extract',

  [
    'ephox.compass.Arr',
    'ephox.phoenix.data.DocElement',
    'ephox.phoenix.data.Spot',
    'ephox.phoenix.util.doc.List',
    'ephox.phoenix.util.node.Classification',
    'ephox.sugar.api.Node',
    'ephox.sugar.api.PredicateFind',
    'ephox.sugar.api.Traverse'
  ],

  function (Arr, DocElement, Spot, List, Classification, Node, PredicateFind, Traverse) {

    var from = function (element) {
      if (Node.isText(element)) {
        return [ DocElement.text(element) ];
      } else if (Classification.isEmpty(element)) {
        return [ DocElement.empty(element) ];
      } else if (Node.isElement(element)) {
        var children = Traverse.children(element);
        var current = Classification.isBoundary(element) ? [DocElement.boundary()] : [];
        var rest = Arr.bind(children, from);
        return current.concat(rest).concat(current);
      } else {
        return [];
      }
    };

    var extractToElem = function (child, offset, element) {
      var extractions = from(element);
      var prior = List.dropUntil(extractions, child);
      var count = List.count(prior);
      return Spot.point(element, count + offset);
    };

    var extract = function (child, offset) {
      var parent = Traverse.parent(child).getOrDie('No parent for element.');
      return extractToElem(child, offset, parent);
    };

    var extractTo = function (child, offset, pred) {
      var parent = PredicateFind.ancestor(child, pred).getOrDie('No parent matching predicate.');
      return extractToElem(child, offset, parent);
    };

    return {
      extract: extract,
      extractTo: extractTo,
      from: from
    };
  }
);
<commit_msg>safer extractions<commit_after>define(
  'ephox.phoenix.extract.Extract',

  [
    'ephox.compass.Arr',
    'ephox.phoenix.data.DocElement',
    'ephox.phoenix.data.Spot',
    'ephox.phoenix.util.doc.List',
    'ephox.phoenix.util.node.Classification',
    'ephox.sugar.api.Node',
    'ephox.sugar.api.PredicateFind',
    'ephox.sugar.api.Traverse'
  ],

  function (Arr, DocElement, Spot, List, Classification, Node, PredicateFind, Traverse) {

    var from = function (element) {
      if (Node.isText(element)) {
        return [ DocElement.text(element) ];
      } else if (Classification.isEmpty(element)) {
        return [ DocElement.empty(element) ];
      } else if (Node.isElement(element)) {
        var children = Traverse.children(element);
        var current = Classification.isBoundary(element) ? [DocElement.boundary()] : [];
        var rest = Arr.bind(children, from);
        return current.concat(rest).concat(current);
      } else {
        return [];
      }
    };

    var extractToElem = function (child, offset, element) {
      var extractions = from(element);
      var prior = List.dropUntil(extractions, child);
      var count = List.count(prior);
      return Spot.point(element, count + offset);
    };

    var extract = function (child, offset) {
      return Traverse.parent(child).fold(function () {
        return Spot.point(child, offset);
      }, function (v) {
        return extractToElem(child, offset, v);
      });
    };

    var extractTo = function (child, offset, pred) {
      return PredicateFind.ancestor(child, pred).fold(function () {
        return Spot.point(child, offset);
      }, function (v) {
        return extractToElem(child, offset, v);
      });
    };

    return {
      extract: extract,
      extractTo: extractTo,
      from: from
    };
  }
);
<|endoftext|>


<commit_before>/**
 * Copyright IBM Corp. 2016, 2018
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import React from 'react';
import { iconAdd, iconAddSolid, iconAddOutline } from 'carbon-icons';
import { storiesOf } from '@storybook/react';
import { withKnobs, select, text } from '@storybook/addon-knobs';
import Icon from '../Icon';
import IconSkeleton from '../Icon/Icon.Skeleton';

const icons = {
  'Add (iconAdd from `carbon-icons`)': 'iconAdd',
  'Add with filled circle (iconAddSolid from `carbon-icons`)': 'iconAddSolid',
  'Add with circle (iconAddOutline from `carbon-icons`)': 'iconAddOutline',
};

const iconMap = {
  iconAdd,
  iconAddSolid,
  iconAddOutline,
};

const props = () => {
  const selectedIcon = select(
    'The icon (icon (regular)/name (legacy))',
    icons,
    'iconAdd'
  );
  return {
    style: {
      margin: '50px',
    },
    icon: iconMap[selectedIcon],
    name: iconMap[selectedIcon] ? undefined : selectedIcon,
    role: text('ARIA role (role)', ''),
    fill: text('The SVG `fill` attribute (fill)', 'grey'),
    fillRule: text('The SVG `fillRule` attribute (fillRule)', ''),
    width: text('The SVG `width` attribute (width)', ''),
    height: text('The SVG `height` attribute (height)', ''),
    description: text(
      'The a11y text (description)',
      'This is a description of the icon and what it does in context'
    ),
    iconTitle: text('The content in <title> in SVG (iconTitle)', ''),
    className: 'extra-class',
  };
};

const propsSkeleton = {
  style: {
    margin: '50px',
  },
};

const propsSkeleton2 = {
  style: {
    margin: '50px',
    width: '24px',
    height: '24px',
  },
};

storiesOf('Icon', module)
  .addDecorator(withKnobs)
  .add(
    'Default',
    () => (

        <Icon {...props()} />

    ),
    {
      info: {
        text: `
            Icons are used in the product to present common actions and commands. Modify the fill property to change the color of the icon. The name property defines which icon to display. For accessibility, provide a context-rich description with the description prop. For a full list of icon names, see https://www.carbondesignsystem.com/guidelines/iconography/library
          `,
      },
    }
  )
  .add(
    'Skeleton',
    () => (

        <IconSkeleton {...propsSkeleton} />
        <IconSkeleton {...propsSkeleton2} />

    ),
    {
      info: {
        text: `
            Icons are used in the product to present common actions and commands. Modify the fill property to change the color of the icon. The name property defines which icon to display. For accessibility, provide a context-rich description with the description prop. For a full list of icon names, see https://www.carbondesignsystem.com/guidelines/iconography/library
          `,
      },
    }
  );
<commit_msg>chore(icon): set role prop in story (#3363)<commit_after>/**
 * Copyright IBM Corp. 2016, 2018
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import React from 'react';
import { iconAdd, iconAddSolid, iconAddOutline } from 'carbon-icons';
import { storiesOf } from '@storybook/react';
import { withKnobs, select, text } from '@storybook/addon-knobs';
import Icon from '../Icon';
import IconSkeleton from '../Icon/Icon.Skeleton';

const icons = {
  'Add (iconAdd from `carbon-icons`)': 'iconAdd',
  'Add with filled circle (iconAddSolid from `carbon-icons`)': 'iconAddSolid',
  'Add with circle (iconAddOutline from `carbon-icons`)': 'iconAddOutline',
};

const iconMap = {
  iconAdd,
  iconAddSolid,
  iconAddOutline,
};

const props = () => {
  const selectedIcon = select(
    'The icon (icon (regular)/name (legacy))',
    icons,
    'iconAdd'
  );
  return {
    style: {
      margin: '50px',
    },
    icon: iconMap[selectedIcon],
    name: iconMap[selectedIcon] ? undefined : selectedIcon,
    role: text('ARIA role (role)', 'img'),
    fill: text('The SVG `fill` attribute (fill)', 'grey'),
    fillRule: text('The SVG `fillRule` attribute (fillRule)', ''),
    width: text('The SVG `width` attribute (width)', ''),
    height: text('The SVG `height` attribute (height)', ''),
    description: text(
      'The a11y text (description)',
      'This is a description of the icon and what it does in context'
    ),
    iconTitle: text('The content in <title> in SVG (iconTitle)', ''),
    className: 'extra-class',
  };
};

const propsSkeleton = {
  style: {
    margin: '50px',
  },
};

const propsSkeleton2 = {
  style: {
    margin: '50px',
    width: '24px',
    height: '24px',
  },
};

storiesOf('Icon', module)
  .addDecorator(withKnobs)
  .add(
    'Default',
    () => (

        <Icon {...props()} />

    ),
    {
      info: {
        text: `
            Icons are used in the product to present common actions and commands. Modify the fill property to change the color of the icon. The name property defines which icon to display. For accessibility, provide a context-rich description with the description prop. For a full list of icon names, see https://www.carbondesignsystem.com/guidelines/iconography/library
          `,
      },
    }
  )
  .add(
    'Skeleton',
    () => (

        <IconSkeleton {...propsSkeleton} />
        <IconSkeleton {...propsSkeleton2} />

    ),
    {
      info: {
        text: `
            Icons are used in the product to present common actions and commands. Modify the fill property to change the color of the icon. The name property defines which icon to display. For accessibility, provide a context-rich description with the description prop. For a full list of icon names, see https://www.carbondesignsystem.com/guidelines/iconography/library
          `,
      },
    }
  );
<|endoftext|>


<commit_before>import babel from 'rollup-plugin-babel'

export default {
  entry: 'src/index.js',
  format: 'cjs',
  plugins: [
    babel({
      babelrc: false,
      presets: ['es2015-rollup', 'stage-1'],
      plugins: ['transform-decorators-legacy']
    })
  ],
  dest: 'dist/index.js',
  exports: 'named',
  external: [
    'ramda',
    'mobx',
    'ramdasauce',
    'socket.io'
  ]
}
<commit_msg>Removes socket.io from rollup config.<commit_after>import babel from 'rollup-plugin-babel'

export default {
  entry: 'src/index.js',
  format: 'cjs',
  plugins: [
    babel({
      babelrc: false,
      presets: ['es2015-rollup', 'stage-1'],
      plugins: ['transform-decorators-legacy']
    })
  ],
  dest: 'dist/index.js',
  exports: 'named',
  external: [
    'ramda',
    'mobx',
    'ramdasauce'
  ]
}
<|endoftext|>


<commit_before>/**
 * Arrays of compound selectors and combinators that form a complex selector
 * when interleaved.
 *
 * @typedef {{
 *   compoundSelectors: !Array<string>,
 *   combinators: !Array<string>,
 * }}
 */
export let ComplexSelectorParts;

/**
 * @type {!Map<string, {end: string, matchNestedParens: boolean}>}
 */
const PARENS = new Map([
  ['(', {end: ')', matchNestedParens: true}],
  ['[', {end: ']', matchNestedParens: true}],
  ['"', {end: '"', matchNestedParens: false}],
  ["'", {end: "'", matchNestedParens: false}],
]);

/**
 * @param {string} str
 * @param {!Array<string>} queryChars
 * @param {boolean} matchNestedParens
 * @return {number}
 */
const findNext = (str, queryChars, matchNestedParens = true) => {
  for (let i = 0; i < str.length; i++) {
    if (str[i] === '\\' && i < str.length - 1 && str[i + 1] !== '\n') {
      // Skip escaped character.
      i++;
    } else if (queryChars.includes(str[i])) {
      return i;
    } else if (matchNestedParens && PARENS.has(str[i])) {
      const parenInfo = PARENS.get(str[i]);
      i += findNext(
        str.substring(i + 1),
        [parenInfo.end],
        parenInfo.matchNestedParens
      );
      continue;
    }

    // Do nothing, let `i++` happen.
  }

  // Reached the end of the string without finding a final char.
  return str.length;
};

/**
 * @type {!Array<string>}
 */
const COMBINATORS = [' ', '>', '~', '+'];

/**
 * @param {string} str
 * @return {!ComplexSelectorParts}
 */
const parseComplexSelector = (str) => {
  str = str.trim();

  /**
   * @type {!Array<string>}
   */
  let chunks = [];

  while (str.length) {
    const index = findNext(str, COMBINATORS);
    if (index === 0) {
      chunks.push(str[0]);
      str = str.substring(1);
    } else {
      chunks.push(str.substring(0, index));
      str = str.substring(index);
    }
  }

  // Remove whitespace next to combinators.
  chunks = chunks.filter((x, i) => {
    return !(
      x === ' ' &&
      (COMBINATORS.includes(chunks[i - 1]) ||
        COMBINATORS.includes(chunks[i + 1]))
    );
  });

  return {
    compoundSelectors: chunks.filter((x, i) => i % 2 === 0),
    combinators: chunks.filter((x, i) => i % 2 === 1),
  };
};

/**
 * @param {string} str
 * @return {!Array<!ComplexSelectorParts>}
 */
export const parseSelectorList = (str) => {
  const results = [];

  while (str.length) {
    const index = findNext(str, [',']);
    results.push(parseComplexSelector(str.substring(0, index)));
    str = str.substring(index + 1);
  }

  return results;
};
<commit_msg>`findIndex` now takes a start index.<commit_after>/**
 * Arrays of compound selectors and combinators that form a complex selector
 * when interleaved.
 *
 * @typedef {{
 *   compoundSelectors: !Array<string>,
 *   combinators: !Array<string>,
 * }}
 */
export let ComplexSelectorParts;

/**
 * @type {!Map<string, {end: string, matchNestedParens: boolean}>}
 */
const PARENS = new Map([
  ['(', {end: ')', matchNestedParens: true}],
  ['[', {end: ']', matchNestedParens: true}],
  ['"', {end: '"', matchNestedParens: false}],
  ["'", {end: "'", matchNestedParens: false}],
]);

/**
 * @param {string} str
 * @param {number} start
 * @param {!Array<string>} queryChars
 * @param {boolean} matchNestedParens
 * @return {number}
 */
const findNext = (str, start, queryChars, matchNestedParens = true) => {
  for (let i = start; i < str.length; i++) {
    if (str[i] === '\\' && i < str.length - 1 && str[i + 1] !== '\n') {
      // Skip escaped character.
      i++;
    } else if (queryChars.includes(str[i])) {
      return i;
    } else if (matchNestedParens && PARENS.has(str[i])) {
      const parenInfo = PARENS.get(str[i]);
      i += findNext(str, i + 1, [parenInfo.end], parenInfo.matchNestedParens);
      continue;
    }

    // Do nothing, let `i++` happen.
  }

  // Reached the end of the string without finding a final char.
  return str.length;
};

/**
 * @type {!Array<string>}
 */
const COMBINATORS = [' ', '>', '~', '+'];

/**
 * @param {string} str
 * @return {!ComplexSelectorParts}
 */
const parseComplexSelector = (str) => {
  str = str.trim();

  /**
   * @type {!Array<string>}
   */
  let chunks = [];

  for (let i = 0; i < str.length;) {
    const next = findNext(str, i, COMBINATORS);
    if (next === i) {
      chunks.push(str[i]);
      i++;
    } else {
      chunks.push(str.substring(i, next));
      i = next;
    }
  }

  // Remove whitespace next to combinators.
  chunks = chunks.filter((x, i) => {
    return !(
      x === ' ' &&
      (COMBINATORS.includes(chunks[i - 1]) ||
        COMBINATORS.includes(chunks[i + 1]))
    );
  });

  return {
    compoundSelectors: chunks.filter((x, i) => i % 2 === 0),
    combinators: chunks.filter((x, i) => i % 2 === 1),
  };
};

/**
 * @param {string} str
 * @return {!Array<!ComplexSelectorParts>}
 */
export const parseSelectorList = (str) => {
  const results = [];

  for (let i = 0; i < str.length;) {
    const next = findNext(str, i, [',']);
    results.push(parseComplexSelector(str.substring(i, next)));
    i = next + 1;
  }

  return results;
};
<|endoftext|>


<commit_before>module.exports = {
  "parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module",
    "ecmaFeatures": {
      "experimentalObjectRestSpread": true,
    },
  },

  "rules": {
    "arrow-parens": "warn",
    "comma-dangle": ["error", "always-multiline"],
    "max-len": ["error", {
      "code": 100,
      "ignoreUrls": true,
      "ignoreRegExpLiterals": true,
      "tabWidth": 2,
    }],
    "no-prototype-builtins": "off",
    "no-underscore-dangle": "off",
    "quotes": ["error", "double", {
      "avoidEscape": true,
    }],
    "semi": ["error", "never"],
    "import/no-unresolved": "off",
  },
}
<commit_msg>Allow plusplus in for loops<commit_after>module.exports = {
  "parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module",
    "ecmaFeatures": {
      "experimentalObjectRestSpread": true,
    },
  },

  "rules": {
    "arrow-parens": "warn",
    "comma-dangle": ["error", "always-multiline"],
    "max-len": ["error", {
      "code": 100,
      "ignoreUrls": true,
      "ignoreRegExpLiterals": true,
      "tabWidth": 2,
    }],
    "no-plusplus": ["error", {
      "allowForLoopAfterthoughts": true,
    }],
    "no-prototype-builtins": "off",
    "no-underscore-dangle": "off",
    "quotes": ["error", "double", {
      "avoidEscape": true,
    }],
    "semi": ["error", "never"],
    "import/no-unresolved": "off",
  },
}
<|endoftext|>


<commit_before>var CONFIG = require("./config");
var http   = require("https");
var sys    = require('sys');
var exec   = require('child_process').exec;

module.exports.getOrgsRepos = function (repos, organization_name) {
  var orgsRepos = []
  for (var index in repos) {
    var current_repo_owner = repos[index].owner.login;
    var current_repo_name = repos[index].owner.name;

    if (organization_name === current_repo_owner) {
      var repo_name = repos[index].name

      orgsRepos.push (repo_name)
    }
  }

  return orgsRepos;
}

module.exports.getMyRepos = function (repos, current_user) {
  var myRepos = []

  for (var index in repos) {
    var current_repo_owner = repos[index].owner.login;
    var current_repo_name = repos[index].owner.name;

    if (current_user === current_repo_owner) {
      var ssh_repo_address = repos[index].ssh_url

      myRepos.push (ssh_repo_address)
    }
  }

  return myRepos;
}

module.exports.forkRepos = function (owner, repos, index, callback) {
  var repo_name = repos[index]

  var options = {
    host: "api.github.com",
    port: 443,
    path: "/repos/" + owner + "/" + repo_name + "/forks",
    method: 'POST',
    headers: {
      "Authorization": "token " + CONFIG.GITHUB_TOKEN,
      "User-Agent": "git-tools-cloner"
    }
  };

  var req = http.request(options, function(res) {
    var username = "";

    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      username += chunk;
    });

    res.on('end', function () {
      console.log (options.path)

      if (repos.length - 1 === index) {
        callback ()
      } else {
        module.exports.forkRepos (owner, repos, ++index, callback)
      }
    });
  });

  req.on('error', function(e) {
    console.log('problem with request: ' + e.message);
  });

  // write data to request body
  req.write('');
  req.end();
}

module.exports.checkoutRepos = function (repos, index, callback) {
  var address = repos[index]

  exec ("cd " + CONFIG.REPOSITORIES + " && git clone " + address, function (error, stdout, stderr) {
    console.log (address);

    if (error) {
      console.log (error)
    }

    if (repos.length - 1 === index) {
      callback ()
    } else {
      module.exports.checkoutRepos (repos, ++index, callback)
    }

    console.log ("\n")
  })
}

module.exports.getCurrentUser = function (callback) {
  var options = {
    host: "api.github.com",
    port: 443,
    path: "/user",
    method: 'GET',
    headers: {
      "Authorization": "token " + CONFIG.GITHUB_TOKEN,
      "User-Agent": "git-tools-cloner"
    }
  };

  var req = http.request(options, function(res) {
    var username = "";

    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      username += chunk;
    });

    res.on('end', function () {
      callback(JSON.parse (username).login);
    });
  });

  req.on('error', function(e) {
    console.log('problem with request: ' + e.message);
  });

  // write data to request body
  req.write('data\n');
  req.write('data\n');
  req.end();
}

module.exports.getAllRepos = function (page, repos, callback) {
  var options = {
    host: "api.github.com",
    port: 443,
    path: "/user/repos?page=" + page + "&per_page=" + CONFIG.PER_PAGE,
    method: 'GET',
    headers: {
      "Authorization": "token " + CONFIG.GITHUB_TOKEN,
      "User-Agent": "git-tools-cloner"
    }
  };

  var req = http.request(options, function(res) {
    var buffered_output = "";

    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      buffered_output += chunk;
    });

    res.on('end', function () {
      var current_json_object = JSON.parse (buffered_output);
      var current_page_length = current_json_object.length;

      if (current_page_length > 0) {
        repos = module.exports.add_repos (repos, current_json_object);
      }

      if (current_page_length === CONFIG.PER_PAGE) {
        module.exports.getAllRepos (++page, repos, callback);
      } else {
        if (current_page_length > 0) {
          if (typeof callback === "function") {
            callback(repos);
          }
        }
      }
    });
  });

  req.on('error', function(e) {
    console.log('problem with request: ' + e.message);
  });

  // write data to request body
  req.write('data\n');
  req.write('data\n');
  req.end();
}

module.exports.add_repos = function (repos, append_repos) {
  for (var index in append_repos) {
    repos.push (append_repos[index]);
  }

  return repos;
}
<commit_msg>return error<commit_after>var CONFIG = require("./config");
var http   = require("https");
var sys    = require('sys');
var exec   = require('child_process').exec;

module.exports.getOrgsRepos = function (repos, organization_name) {
  var orgsRepos = []
  for (var index in repos) {
    var current_repo_owner = repos[index].owner.login;
    var current_repo_name = repos[index].owner.name;

    if (organization_name === current_repo_owner) {
      var repo_name = repos[index].name

      orgsRepos.push (repo_name)
    }
  }

  return orgsRepos;
}

module.exports.getMyRepos = function (repos, current_user) {
  var myRepos = []

  for (var index in repos) {
    var current_repo_owner = repos[index].owner.login;
    var current_repo_name = repos[index].owner.name;

    if (current_user === current_repo_owner) {
      var ssh_repo_address = repos[index].ssh_url

      myRepos.push (ssh_repo_address)
    }
  }

  return myRepos;
}

module.exports.forkRepos = function (owner, repos, index, callback) {
  var repo_name = repos[index]

  var options = {
    host: "api.github.com",
    port: 443,
    path: "/repos/" + owner + "/" + repo_name + "/forks",
    method: 'POST',
    headers: {
      "Authorization": "token " + CONFIG.GITHUB_TOKEN,
      "User-Agent": "git-tools-cloner"
    }
  };

  var req = http.request(options, function(res) {
    var username = "";

    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      username += chunk;
    });

    res.on('end', function () {
      console.log (options.path)

      if (repos.length - 1 === index) {
        callback ()
      } else {
        module.exports.forkRepos (owner, repos, ++index, callback)
      }
    });
  });

  req.on('error', function(e) {
    console.log('problem with request: ' + e.message);
  });

  // write data to request body
  req.write('');
  req.end();
}

module.exports.checkoutRepos = function (repos, index, callback) {
  var address = repos[index]

  exec ("cd " + CONFIG.REPOSITORIES + " && git clone " + address, function (error, stdout, stderr) {
    console.log (address);

    if (error) {
      return console.log (error)
    }

    if (repos.length - 1 === index) {
      callback ()
    } else {
      module.exports.checkoutRepos (repos, ++index, callback)
    }

    console.log ("\n")
  })
}

module.exports.getCurrentUser = function (callback) {
  var options = {
    host: "api.github.com",
    port: 443,
    path: "/user",
    method: 'GET',
    headers: {
      "Authorization": "token " + CONFIG.GITHUB_TOKEN,
      "User-Agent": "git-tools-cloner"
    }
  };

  var req = http.request(options, function(res) {
    var username = "";

    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      username += chunk;
    });

    res.on('end', function () {
      callback(JSON.parse (username).login);
    });
  });

  req.on('error', function(e) {
    console.log('problem with request: ' + e.message);
  });

  // write data to request body
  req.write('data\n');
  req.write('data\n');
  req.end();
}

module.exports.getAllRepos = function (page, repos, callback) {
  var options = {
    host: "api.github.com",
    port: 443,
    path: "/user/repos?page=" + page + "&per_page=" + CONFIG.PER_PAGE,
    method: 'GET',
    headers: {
      "Authorization": "token " + CONFIG.GITHUB_TOKEN,
      "User-Agent": "git-tools-cloner"
    }
  };

  var req = http.request(options, function(res) {
    var buffered_output = "";

    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      buffered_output += chunk;
    });

    res.on('end', function () {
      var current_json_object = JSON.parse (buffered_output);
      var current_page_length = current_json_object.length;

      if (current_page_length > 0) {
        repos = module.exports.add_repos (repos, current_json_object);
      }

      if (current_page_length === CONFIG.PER_PAGE) {
        module.exports.getAllRepos (++page, repos, callback);
      } else {
        if (current_page_length > 0) {
          if (typeof callback === "function") {
            callback(repos);
          }
        }
      }
    });
  });

  req.on('error', function(e) {
    console.log('problem with request: ' + e.message);
  });

  // write data to request body
  req.write('data\n');
  req.write('data\n');
  req.end();
}

module.exports.add_repos = function (repos, append_repos) {
  for (var index in append_repos) {
    repos.push (append_repos[index]);
  }

  return repos;
}
<|endoftext|>


<commit_before>var _choosed_packages = null;

var update_choosed_packages = function(choosed_packages){
    chrome.storage.local.set({choosed_packages: choosed_packages});
};

var get_choosed_packages = function(cb){
    chrome.storage.local.get({choosed_packages: {}}, function(items){
        get_package_info(function(package_info){
            var choosed_packages = {};
            var current_package = null;
            for (var i = 0; i < package_info.packages.length; i ++) {
                current_package = package_info.packages[i];
                if ('undefined' === typeof(items.choosed_packages[current_package.id])) {
                    if (current_package) {
                        choosed_packages[current_package.id] = true;
                    }
                } else if (false === items.choosed_packages[current_package.id]) {
                } else {
                    choosed_packages[current_package.id] = true;
                }
            }
            cb(choosed_packages);
        });
    });
};

var get_package_info = function(cb){
    chrome.storage.local.get({packages: {}}, function(items){
        if ('undefined' === typeof(items.packages.fetch_at) || ((new Date()).getTime() - items.packages.fetch_at) > 86400 * 1000) {
            update_packages(cb);
            return;
        }

        cb(items.packages);
    });
};

var update_packages = function(cb){
    $.get('http://jobhelper.g0v.ronny.tw/api/getpackages', function(ret){
        ret.fetch_at = (new Date()).getTime();
        chrome.storage.local.set({packages: ret}, function(){
            cb(ret);
        });
    }, 'json');
};

var _package_csv = null;

var get_package_csv_from_storage = function(cb){
    if (null !== _package_csv) {
        cb(_package_csv);
    }
    chrome.storage.local.get({package_csv: {}}, function(items){
        _package_csv = items.package_csv;
        cb(_package_csv);
    });
};
var get_package_info_by_id = function(package_info, id){
    for (var i = 0; i < package_info.packages.length; i ++) {
       if (package_info.packages[i].id == id) {
           return package_info.packages[i];
       }
    }
    return null;
};

var get_package_csv_by_id = function(id, cb){
    get_package_info(function(package_info){
        get_package_csv_from_storage(function(package_csv){
            if ('undefined' !== typeof(package_csv[id]) && package_csv[id].package_time == get_package_info_by_id(package_info, id).package_time) {
                cb(package_csv[id].content);
                return;
            }
            $.get('http://jobhelper.g0v.ronny.tw/api/getpackage?id=' + parseInt(id), function(package_csv){
                _package_csv[id] = package_csv;
                cb(_package_csv[id].content);
            });
        });
    });
};

var check_name = function(web_name, db_name){
    if ('string' !== typeof(db_name)) {
        return false;
    }
    // 先比對一次
    if (web_name.indexOf(db_name) >= 0) {
        return true;
    }

    // 如果不是 "公司" 結尾的(Ex: 宏達國際電子股份有限公司桃園廠), 只判斷到公司
    if (db_name.match('公司') && !db_name.match('公司$')) {
        if (web_name.indexOf(db_name.match('(^.*公司)')[1]) >= 0) {
            return true;
        }
    }

    // 處理 "吳美玉(即玉皇手作茶飲店)" 格式
    if (db_name.match('.*\\(即.*\\)')) {
        if (web_name.indexOf(db_name.match('.*\\(即(.*)\\)')[1]) >= 0) {
            return true;
        }
    }
    return false;
};
<commit_msg>加上私立xxx的命名情況<commit_after>var _choosed_packages = null;

var update_choosed_packages = function(choosed_packages){
    chrome.storage.local.set({choosed_packages: choosed_packages});
};

var get_choosed_packages = function(cb){
    chrome.storage.local.get({choosed_packages: {}}, function(items){
        get_package_info(function(package_info){
            var choosed_packages = {};
            var current_package = null;
            for (var i = 0; i < package_info.packages.length; i ++) {
                current_package = package_info.packages[i];
                if ('undefined' === typeof(items.choosed_packages[current_package.id])) {
                    if (current_package) {
                        choosed_packages[current_package.id] = true;
                    }
                } else if (false === items.choosed_packages[current_package.id]) {
                } else {
                    choosed_packages[current_package.id] = true;
                }
            }
            cb(choosed_packages);
        });
    });
};

var get_package_info = function(cb){
    chrome.storage.local.get({packages: {}}, function(items){
        if ('undefined' === typeof(items.packages.fetch_at) || ((new Date()).getTime() - items.packages.fetch_at) > 86400 * 1000) {
            update_packages(cb);
            return;
        }

        cb(items.packages);
    });
};

var update_packages = function(cb){
    $.get('http://jobhelper.g0v.ronny.tw/api/getpackages', function(ret){
        ret.fetch_at = (new Date()).getTime();
        chrome.storage.local.set({packages: ret}, function(){
            cb(ret);
        });
    }, 'json');
};

var _package_csv = null;

var get_package_csv_from_storage = function(cb){
    if (null !== _package_csv) {
        cb(_package_csv);
    }
    chrome.storage.local.get({package_csv: {}}, function(items){
        _package_csv = items.package_csv;
        cb(_package_csv);
    });
};
var get_package_info_by_id = function(package_info, id){
    for (var i = 0; i < package_info.packages.length; i ++) {
       if (package_info.packages[i].id == id) {
           return package_info.packages[i];
       }
    }
    return null;
};

var get_package_csv_by_id = function(id, cb){
    get_package_info(function(package_info){
        get_package_csv_from_storage(function(package_csv){
            if ('undefined' !== typeof(package_csv[id]) && package_csv[id].package_time == get_package_info_by_id(package_info, id).package_time) {
                cb(package_csv[id].content);
                return;
            }
            $.get('http://jobhelper.g0v.ronny.tw/api/getpackage?id=' + parseInt(id), function(package_csv){
                _package_csv[id] = package_csv;
                cb(_package_csv[id].content);
            });
        });
    });
};

var check_name = function(web_name, db_name){
    if ('string' !== typeof(db_name)) {
        return false;
    }
    // 先比對一次
    if (web_name.indexOf(db_name) >= 0) {
        return true;
    }

    // 如果不是 "公司" 結尾的(Ex: 宏達國際電子股份有限公司桃園廠), 只判斷到公司
    if (db_name.match('公司') && !db_name.match('公司$')) {
        if (web_name.indexOf(db_name.match('(^.*公司)')[1]) >= 0) {
            return true;
        }
    }

    // 處理 "吳美玉(即玉皇手作茶飲店)" 格式
    if (db_name.match('.*\\(即.*\\)')) {
        if (web_name.indexOf(db_name.match('.*\\(即(.*)\\)')[1]) >= 0) {
            return true;
        }
    }

    // 處理 高雄市私立新東海老人養護中心
    if (db_name.match('.*私立(.*)')) {
        if (web_name.indexOf(db_name.match('.*私立(.*)')[1]) >= 0) {
            return true;
        }
    }
    return false;
};
<|endoftext|>


<commit_before>(function(){

  var polyProto = google.maps.Polygon.prototype;

  // Default lineSize to 100
  polyProto.lineSize = 100;

  // Default to normal non-editable state
  polyProto.editable = false;

  // Default highlight color for edit lines
  polyProto.highlightColor = '#cccccc';

  polyProto.editLines = [];

  /**
   * Override setOptions so that we can intercept
   * the editable and lineSize options.
   */
  var _setOptions = polyProto.setOptions;
  polyProto.setOptions = function(options){
    if(_isObject(options)){

      // Intercept the editable option
      var editable = this.getEditable();
      if(!_isUndefined(options.editable)){
        editable = options.editable;
        delete options.editable;
      }

      // Intercept the lineSize option
      var lineSize = this.lineSize;
      if(!_isUndefined(options.lineSize)){
        lineSize = options.lineSize;
        delete options.lineSize;
      }

      // Intercept the highlightColor option
      var highlightColor = this.highlightColor;
      if(!_isUndefined(options.highlightColor)){
        highlightColor = options.highlightColor;
        delete options.highlightColor;
      }

      // Pass other options on to the Polygon
      _setOptions.call(this, options);

      // Set the new properties after setting
      // normal Polygon properties so that we
      // can be sure to get the last say on
      // any settings or behavior
      this.lineSize = lineSize;
      this.setEditable(editable);
      this.highlightColor = highlightColor;
    }
  }

  /**
   * Override the setEditable function so that
   * we know when to generate the polylines
   */
  polyProto.setEditable = function(editable){
    if(_isBoolean(editable)){
      this.editable = editable;
      if(editable){
        this.generateEditLines();
      }
    }
  };

  /**
   * Override getEditable since we don't
   * actually make the underlying polygon
   * editable
   */
  polyProto.getEditable = function(){
    return this.editable;
  };

  /**
   * Create the edit lines
   */
  polyProto.generateEditLines = function(){

    var self = this,
        map = self.getMap(),
        lineStyle = {
          strokeColor: self.get('strokeColor'),
          strokeOpacity: self.get('strokeOpacity'),
          strokeWeight: self.get('strokeWeight')
        };

    // Process each path independently
    this.getPaths().forEach(function(path, pathIndex){

      var lineLengths = _lineLengths(path.getLength(), self.lineSize),
          lines = [];

      // Iterate over each edit line
      var position = 0;
      for(var i = 0; i < lineLengths.length; i++){
        var newLinePath = [],
            end = Math.min(position + lineLengths[i], path.getLength());

        // Add the relevent points to the line's path
        for(; position < end; position++){
          newLinePath.push(path.getAt(position));
        }

        // Decrement position by 1 so that the next
        // line duplicates the last point of this line
        position--;

        // Create the google maps line object
        // and style it to match the polygon's borders
        var line = new google.maps.Polyline();
        line.setPath(newLinePath);
        line.setOptions(lineStyle);
        line.setMap(map);

        // Add events
        line.addListener('click', function(){
          this.setEditable(true);
        });
        line.addListener('mouseover', function(){
          this.set('strokeColor', self.highlightColor);
        });
        line.addListener('mouseout', function(){
          this.setOptions(lineStyle);
        });

        // Save the line
        lines.push(line);
      }

      // Add the first point of the path to the end of the last line
      lines[lines.length-1].getPath().push(path.getAt(0));

      // Keep track of whether a point event was fired
      // by the user or by us updating a neighbor point
      var updatingNeighbor = false;

      // Setup event listeners on the line's paths so that
      // we can update the underlying shape when the lines change
      $.each(lines, function(i, line){

        // New point
        line.getPath().addListener('insert_at', function(){
          self.updateFromLines(pathIndex, lines);
        });

        // Point removed
        line.getPath().addListener('remove_at', function(){
          self.updateFromLines(pathIndex, lines);
        });

        // Point moved
        line.getPath().addListener('set_at', function(vertex){

          // When either the first or last point was moved we need
          // to move the matching point of the neighboring line.
          // Because lines may be deleted (unlikely, but possible)
          // we have to figure out the line's position and neighbors
          // at runtime.
          if((vertex === 0 || vertex === this.getLength() - 1) && !updatingNeighbor){
            var neighbor = findNeighbor(lines, line, vertex);
            updatingNeighbor = true;
            neighbor.path.setAt(neighbor.index, this.getAt(vertex));
          }

          // Update underlying shape with changes only if we're moving
          // a point in the middle of the line or we're updating a neighbor
          // point after the user moved a first/last point
          else {
            updatingNeighbor = false;
            self.updateFromLines(pathIndex, lines);
          }
        });

        // Deleting a point when rightclicked.
        // updateFromLines is not called here to update the polygon
        // because we modify the lines which fire the event listeners
        // bound above which then call updateFromLines
        // Inspired by http://stackoverflow.com/a/14441786
        line.addListener('rightclick', function(event){
          var vertex = event.vertex;

          if(vertex != null){

            // Remove the point
            this.getPath().removeAt(event.vertex);

            // If the point being removed is the first or last
            // point in the line then we need to find and move
            // the neigbor's point to match our new end point.
            if(vertex === 0 || vertex === this.getPath().getLength()){
              var neighbor = findNeighbor(lines, this, vertex),
                  newEndIndex = vertex === 0 ? 0 : this.getPath().getLength() - 1;
              neighbor.path.setAt(neighbor.index, this.getPath().getAt(newEndIndex));
            }

            // If there is only one point left then delete the line.
            // It's neghbors should both be overlapping now.
            if(this.getPath().getLength() === 1){
              this.setMap(null);
              var linePos = lines.indexOf(this);
              lines.splice(linePos, 1);
            }

            // Delete the entire path if there is less than
            // three points left; with only one or two points
            // you don't have a polygon
            if(self.getPaths().getAt(pathIndex).getLength() < 3){
              self.getPaths().removeAt(pathIndex);
              // If this path isn't the last one then it will change
              // the ordering and make pathIndex irrelevent and break
              // a lot of code
            }

            // TODO: fire changed event
          }
        });
      });

      self.editLines = self.editLines.concat(lines);

    });
  };

  /**
   * Called whenever lines change; updates the specified
   * path of the shape based on the lines that were
   * derived from it
   */
  polyProto.updateFromLines = function(pathIndex, lines){
    var newPoints = [];
    for(var i = 0; i < lines.length; i++){
      var linePath = lines[i].getPath(),
          lineLength = linePath.getLength();
      linePath.forEach(function(point, j){
        // Don't add the last point of each line
        // because those are duplicated
        if(j !== lineLength - 1){
          newPoints.push(point);
        }
      });
    }
    this.getPaths().setAt(pathIndex, new google.maps.MVCArray(newPoints));
    // TODO: Fire changed event
  };

  /**
   * Finds the neighboring path and point index for
   * updating a neighbor's matching end point.
   */
  function findNeighbor(lines, line, pointIndex){
    var numLines = lines.length,
        lineIndex = lines.indexOf(line),
        neighborLineIndex, neighborPath, neighborPointIndex;

    // First point in line
    if(pointIndex === 0){
      neighborLineIndex = lineIndex === 0 ? numLines - 1 : lineIndex - 1;
      neighborPath = lines[neighborLineIndex].getPath();
      neighborPointIndex = neighborPath.getLength() - 1;
    }

    // Last point in line
    else {
      neighborLineIndex = lineIndex === numLines - 1 ? 0 : lineIndex + 1;
      neighborPath = lines[neighborLineIndex].getPath();
      neighborPointIndex = 0;
    }

    return {
      path: neighborPath,
      index: neighborPointIndex
    };
  };

  /**
   * Calculate length of each edit line.
   * Returns an array of numbers which represent
   * the length. Tries to even out the length of
   * the lines as best it can.
   */
  function _lineLengths(pathLength, lineSizeLimit){

    // Short circuit if there will only be one edit line
    if(lineSizeLimit >= pathLength){
      return [pathLength];
    }

    var rawNum = _numLines(pathLength, lineSizeLimit),
        numLines = Math.floor(rawNum),
        remainder = rawNum - numLines,
        lineLengths = [];

    // If lineSizeLimit divides into pathLenght evenly
    // then just return an array of length numLines
    // filled with lineSizeLimit.
    lineLengths = _numberArray(lineSizeLimit, numLines);

    // If lineSize doesn't divide into the pathLength evently
    // then try to even out the lengths of the lines.
    if(remainder) {
      var lastLength = Math.ceil(lineSizeLimit * remainder);

      // The last line cannot have 1 point
      if(lastLength < 2){
        lastLength = 2;
      }

      lineLengths.push(lastLength);

      // Starting at the second to last number (skip the
      // number we just pushed on), iterate backwards
      // over the array and decrement the numbers by one
      // until we make up the difference between the
      // lastLength and the LineSizeLimit

      var difference = lineSizeLimit - lastLength - 1,
          i = lineLengths.length - 2,
          last = lineLengths.length - 1;

      while(difference > 0){
        // Allow i to wrap back to the end
        if(i < 0){
          i = lineLengths.length - 1;
        }
        lineLengths[i] = lineLengths[i] - 1;
        difference--;
        i--;
        lineLengths[last]++;
      }
    }

    return lineLengths;
  };

  /**
   * Generate an array filled with a given number
   */
  function _numberArray(number, length){
    var array = [];
    for(var i = 0; i < length; i++){
      array[i] = number;
    }
    return array;
  };

  /**
   * Calculate number of edit lines
   */
  function _numLines(pathLength, lineSizeLimit){
    // Subtract one frome lineSizeLimit to account for
    // overlapping points at the edges.
    return pathLength / (lineSizeLimit - 1);
  };

  /**
   * Utility functions lifted from underscore
   */

  _isBoolean = function(obj) {
    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
  };

  _isUndefined = function(obj) {
    return obj === void 0;
  };

  _isString = function(obj){
    return toString.call(obj) == '[object String]';
  };

  _isObject = function(obj) {
    return obj === Object(obj);
  };

  _isArray = Array.isArray || function(obj) {
    return toString.call(obj) == '[object Array]';
  };

  /**
   * Expose some internal functions when testing
   */
  if(window.GMAPS_LARGE_POLYGON_TESTING){
    window.gmlp = {
      _lineLengths: _lineLengths,
      _numLines: _numLines
    };
  }

}());<commit_msg>Experiment with custom change event; #1<commit_after>(function(){

  var polyProto = google.maps.Polygon.prototype;

  // Default lineSize to 100
  polyProto.lineSize = 100;

  // Default to normal non-editable state
  polyProto.editable = false;

  // Default highlight color for edit lines
  polyProto.highlightColor = '#cccccc';

  polyProto.editLines = [];

  /**
   * Override setOptions so that we can intercept
   * the editable and lineSize options.
   */
  var _setOptions = polyProto.setOptions;
  polyProto.setOptions = function(options){
    if(_isObject(options)){

      // Intercept the editable option
      var editable = this.getEditable();
      if(!_isUndefined(options.editable)){
        editable = options.editable;
        delete options.editable;
      }

      // Intercept the lineSize option
      var lineSize = this.lineSize;
      if(!_isUndefined(options.lineSize)){
        lineSize = options.lineSize;
        delete options.lineSize;
      }

      // Intercept the highlightColor option
      var highlightColor = this.highlightColor;
      if(!_isUndefined(options.highlightColor)){
        highlightColor = options.highlightColor;
        delete options.highlightColor;
      }

      // Pass other options on to the Polygon
      _setOptions.call(this, options);

      // Set the new properties after setting
      // normal Polygon properties so that we
      // can be sure to get the last say on
      // any settings or behavior
      this.lineSize = lineSize;
      this.setEditable(editable);
      this.highlightColor = highlightColor;
    }
  }

  /**
   * Override the setEditable function so that
   * we know when to generate the polylines
   */
  polyProto.setEditable = function(editable){
    if(_isBoolean(editable)){
      this.editable = editable;
      if(editable){
        this.generateEditLines();
      }
    }
  };

  /**
   * Override getEditable since we don't
   * actually make the underlying polygon
   * editable
   */
  polyProto.getEditable = function(){
    return this.editable;
  };

  /**
   * Create the edit lines
   */
  polyProto.generateEditLines = function(){

    var self = this,
        map = self.getMap(),
        lineStyle = {
          strokeColor: self.get('strokeColor'),
          strokeOpacity: self.get('strokeOpacity'),
          strokeWeight: self.get('strokeWeight')
        };

    // Process each path independently
    this.getPaths().forEach(function(path, pathIndex){

      var lineLengths = _lineLengths(path.getLength(), self.lineSize),
          lines = [];

      // Iterate over each edit line
      var position = 0;
      for(var i = 0; i < lineLengths.length; i++){
        var newLinePath = [],
            end = Math.min(position + lineLengths[i], path.getLength());

        // Add the relevent points to the line's path
        for(; position < end; position++){
          newLinePath.push(path.getAt(position));
        }

        // Decrement position by 1 so that the next
        // line duplicates the last point of this line
        position--;

        // Create the google maps line object
        // and style it to match the polygon's borders
        var line = new google.maps.Polyline();
        line.setPath(newLinePath);
        line.setOptions(lineStyle);
        line.setMap(map);

        // Add events
        line.addListener('click', function(){
          this.setEditable(true);
        });
        line.addListener('mouseover', function(){
          this.set('strokeColor', self.highlightColor);
        });
        line.addListener('mouseout', function(){
          this.setOptions(lineStyle);
        });

        // Save the line
        lines.push(line);
      }

      // Add the first point of the path to the end of the last line
      lines[lines.length-1].getPath().push(path.getAt(0));

      // Keep track of whether a point event was fired
      // by the user or by us updating a neighbor point
      var updatingNeighbor = false;

      // Setup event listeners on the line's paths so that
      // we can update the underlying shape when the lines change
      $.each(lines, function(i, line){

        // New point
        line.getPath().addListener('insert_at', function(){
          self.updateFromLines(pathIndex, lines);
        });

        // Point removed
        line.getPath().addListener('remove_at', function(){
          self.updateFromLines(pathIndex, lines);
        });

        // Point moved
        line.getPath().addListener('set_at', function(vertex){

          // When either the first or last point was moved we need
          // to move the matching point of the neighboring line.
          // Because lines may be deleted (unlikely, but possible)
          // we have to figure out the line's position and neighbors
          // at runtime.
          if((vertex === 0 || vertex === this.getLength() - 1) && !updatingNeighbor){
            var neighbor = findNeighbor(lines, line, vertex);
            updatingNeighbor = true;
            neighbor.path.setAt(neighbor.index, this.getAt(vertex));
          }

          // Update underlying shape with changes only if we're moving
          // a point in the middle of the line or we're updating a neighbor
          // point after the user moved a first/last point
          else {
            updatingNeighbor = false;
            self.updateFromLines(pathIndex, lines);
          }
        });

        // Deleting a point when rightclicked.
        // updateFromLines is not called here to update the polygon
        // because we modify the lines which fire the event listeners
        // bound above which then call updateFromLines
        // Inspired by http://stackoverflow.com/a/14441786
        line.addListener('rightclick', function(event){
          var vertex = event.vertex;

          if(vertex != null){

            // Remove the point
            this.getPath().removeAt(event.vertex);

            // If the point being removed is the first or last
            // point in the line then we need to find and move
            // the neigbor's point to match our new end point.
            if(vertex === 0 || vertex === this.getPath().getLength()){
              var neighbor = findNeighbor(lines, this, vertex),
                  newEndIndex = vertex === 0 ? 0 : this.getPath().getLength() - 1;
              neighbor.path.setAt(neighbor.index, this.getPath().getAt(newEndIndex));
            }

            // If there is only one point left then delete the line.
            // It's neghbors should both be overlapping now.
            if(this.getPath().getLength() === 1){
              this.setMap(null);
              var linePos = lines.indexOf(this);
              lines.splice(linePos, 1);
            }

            // Delete the entire path if there is less than
            // three points left; with only one or two points
            // you don't have a polygon
            if(self.getPaths().getAt(pathIndex).getLength() < 3){
              self.getPaths().removeAt(pathIndex);
              // If this path isn't the last one then it will change
              // the ordering and make pathIndex irrelevent and break
              // a lot of code
            }
          }
        });
      });

      self.editLines = self.editLines.concat(lines);

    });
  };

  /**
   * Called whenever lines change; updates the specified
   * path of the shape based on the lines that were
   * derived from it
   */
  polyProto.updateFromLines = function(pathIndex, lines){
    var newPoints = [];
    for(var i = 0; i < lines.length; i++){
      var linePath = lines[i].getPath(),
          lineLength = linePath.getLength();
      linePath.forEach(function(point, j){
        // Don't add the last point of each line
        // because those are duplicated
        if(j !== lineLength - 1){
          newPoints.push(point);
        }
      });
    }
    this.getPaths().setAt(pathIndex, new google.maps.MVCArray(newPoints));
    // This gets fired twice when deleting the ends of edit lines
    // google.maps.event.trigger(this, 'changed');
  };

  /**
   * Finds the neighboring path and point index for
   * updating a neighbor's matching end point.
   */
  function findNeighbor(lines, line, pointIndex){
    var numLines = lines.length,
        lineIndex = lines.indexOf(line),
        neighborLineIndex, neighborPath, neighborPointIndex;

    // First point in line
    if(pointIndex === 0){
      neighborLineIndex = lineIndex === 0 ? numLines - 1 : lineIndex - 1;
      neighborPath = lines[neighborLineIndex].getPath();
      neighborPointIndex = neighborPath.getLength() - 1;
    }

    // Last point in line
    else {
      neighborLineIndex = lineIndex === numLines - 1 ? 0 : lineIndex + 1;
      neighborPath = lines[neighborLineIndex].getPath();
      neighborPointIndex = 0;
    }

    return {
      path: neighborPath,
      index: neighborPointIndex
    };
  };

  /**
   * Calculate length of each edit line.
   * Returns an array of numbers which represent
   * the length. Tries to even out the length of
   * the lines as best it can.
   */
  function _lineLengths(pathLength, lineSizeLimit){

    // Short circuit if there will only be one edit line
    if(lineSizeLimit >= pathLength){
      return [pathLength];
    }

    var rawNum = _numLines(pathLength, lineSizeLimit),
        numLines = Math.floor(rawNum),
        remainder = rawNum - numLines,
        lineLengths = [];

    // If lineSizeLimit divides into pathLenght evenly
    // then just return an array of length numLines
    // filled with lineSizeLimit.
    lineLengths = _numberArray(lineSizeLimit, numLines);

    // If lineSize doesn't divide into the pathLength evently
    // then try to even out the lengths of the lines.
    if(remainder) {
      var lastLength = Math.ceil(lineSizeLimit * remainder);

      // The last line cannot have 1 point
      if(lastLength < 2){
        lastLength = 2;
      }

      lineLengths.push(lastLength);

      // Starting at the second to last number (skip the
      // number we just pushed on), iterate backwards
      // over the array and decrement the numbers by one
      // until we make up the difference between the
      // lastLength and the LineSizeLimit

      var difference = lineSizeLimit - lastLength - 1,
          i = lineLengths.length - 2,
          last = lineLengths.length - 1;

      while(difference > 0){
        // Allow i to wrap back to the end
        if(i < 0){
          i = lineLengths.length - 1;
        }
        lineLengths[i] = lineLengths[i] - 1;
        difference--;
        i--;
        lineLengths[last]++;
      }
    }

    return lineLengths;
  };

  /**
   * Generate an array filled with a given number
   */
  function _numberArray(number, length){
    var array = [];
    for(var i = 0; i < length; i++){
      array[i] = number;
    }
    return array;
  };

  /**
   * Calculate number of edit lines
   */
  function _numLines(pathLength, lineSizeLimit){
    // Subtract one frome lineSizeLimit to account for
    // overlapping points at the edges.
    return pathLength / (lineSizeLimit - 1);
  };

  /**
   * Utility functions lifted from underscore
   */

  _isBoolean = function(obj) {
    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
  };

  _isUndefined = function(obj) {
    return obj === void 0;
  };

  _isString = function(obj){
    return toString.call(obj) == '[object String]';
  };

  _isObject = function(obj) {
    return obj === Object(obj);
  };

  _isArray = Array.isArray || function(obj) {
    return toString.call(obj) == '[object Array]';
  };

  /**
   * Expose some internal functions when testing
   */
  if(window.GMAPS_LARGE_POLYGON_TESTING){
    window.gmlp = {
      _lineLengths: _lineLengths,
      _numLines: _numLines
    };
  }

}());<|endoftext|>