<commit_before>#!/usr/bin/env node
'use strict';
const childProcess = require('child_process');
const chalk = require('chalk');
const meow = require('meow');
const inquirer = require('inquirer');
const isBin = require('isbin');
const dateFormat = require('dateformat');
const trim = require('trim');
const termTitle = require('term-title');
const cliTruncate = require('cli-truncate');
const copy = require('copy-paste').copy;
const logUpdate = require('log-update');
const cliCursor = require('cli-cursor');
const notifier = require('node-notifier');
const editor = require('editor');
const figures = require('./figures');
const utils = require('./utils');
const somafm = require('.');

const cli = meow(`
  Usage
    $ somafm [<command> <args>]

  Example
    $ somafm
    $ somafm list
    $ somafm list ambient
    $ somafm info groovesalad
    $ somafm play fluid

  Commands
    list [<keywords>]   list channels, optionally filter by keywords
    info <channel>      show channel information
    play <channel>      play channel
    record <channel>    start recording channel
    list-favourites     list your favourite songs
    edit-favourites     edit your favourite songs
`, {
  alias: {
    h: 'help',
    v: 'version'
  }
});

const players = [
  {
    cmd: 'mplayer',
    args: ['-quiet'],
    titleRegex: /StreamTitle='(.*)';StreamUrl=/,
    keyPress: true
  },
  {
    cmd: 'mpv',
    args: ['--msg-level=all=info'],
    titleRegex: /.*icy-title: (.*)$/
  }
];
const streamripperBin = 'streamripper';

function showChannelList(channels) {
  console.log();

  for (const channel of channels) {
    const str = `${chalk.bold(channel.title)} [${chalk.green(channel.id)}] (${chalk.blue(channel.genre)}) - ${(channel.description)}`;

    if (process.stdout.columns) {
      console.log(cliTruncate(str, process.stdout.columns - 1));
    } else {
      console.log(str);
    }
  }
}

function showChannel(channel) {
  console.log(
  `
  ${chalk.bold(channel.fullTitle)} [${chalk.green(channel.id)}]

  ${chalk.blue(channel.description)}

    ${chalk.yellow('Now playing')}   ${channel.lastPlaying}

             ${chalk.yellow('DJ')}   ${channel.dj}
          ${chalk.yellow('Genre')}   ${channel.genre}
      ${chalk.yellow('Listeners')}   ${channel.listeners}

     ${chalk.yellow('Stream URL')}   ${channel.stream.urls[0]}`
  );
}

function list(search) {
  somafm.getChannels({search, sortChannels: true})
    .then(showChannelList)
    .catch(err => {
      console.error(err.toString());
      process.exit(20);
    });
}

function info(channelId) {
  somafm.getChannel(channelId)
    .then(channel => {
      showChannel(channel);
    })
    .catch(err => {
      console.error(err.toString());
      process.exit(10);
    });
}

function play(channelId) {
  somafm.getChannel(channelId)
    .then(playChannel)
    .catch(err => {
      console.error(err.toString());
      process.exit(10);
    });
}

function getPlayer() {
  return new Promise((resolve, reject) => {
    for (const player of players) {
      if (isBin(player.cmd)) {
        resolve(player);
      }
    }

    reject(new Error('No player executable found. Please ensure mpv or MPlayer is installed on your system and runnable within your shell.'));
  });
}

function playChannel(channel) {
  return getPlayer()
    .then(player => {
      let currentTitle = '';
      let currentTitleOut;
      let currentTime;
      let currentFavourite;

      cliCursor.hide();
      console.log(`\n  Playing   ${chalk.bold(channel.fullTitle)}\n`);

      const args = player.args.concat(channel.stream.urls[0]);
      const playerProc = childProcess.spawn(player.cmd, args);

      const stdin = process.stdin;
      stdin.setRawMode(true);
      stdin.resume();
      stdin.setEncoding('utf-8');

      stdin.on('data', key => {
        if (player.keyPress && ['m', '9', '0', '/', '*'].indexOf(key) > -1) {
          playerProc.stdin.write(key);
        }

        if (key === 'c') {
          copy(currentTitle);
        }

        if (['f', '+'].indexOf(key) > -1) {
          utils.addToFavourites(currentTitle);
          currentFavourite = true;

          logTitle(currentTime, currentTitleOut, true, true);
          windowTitle(currentTitleOut, true);
        }

        if (['u', '-'].indexOf(key) > -1) {
          utils.removeFromFavourites(currentTitle);
          currentFavourite = false;

          logTitle(currentTime, currentTitleOut, false, true);
          windowTitle(currentTitleOut);
        }

        // `ctrl`+`c`, `esc`, `q`
        if (['\u0003', '\u001b', 'q'].indexOf(key) > -1) {
          if (currentTitleOut) {
            logTitle(currentTime, currentTitleOut, currentFavourite);
          }
          logUpdate.done();

          playerProc.kill();
        }
      });

      playerProc.stdout.on('data', data => {
        const line = trim(data.toString());

        const res = line.match(player.titleRegex);
        let title;

        if (res && (title = res[1])) {
          const time = dateFormat(new Date(), 'HH:MM:ss');
          const titleOut = title.match(new RegExp(`SomaFM|Big Url|${channel.title}`, 'i')) ? chalk.gray(title) : title;

          // Overwrite last line
          if (currentTime) {
            logTitle(currentTime, currentTitleOut, currentFavourite);
          }

          currentTitle = title;
          currentTime = chalk.yellow(time);
          currentTitleOut = titleOut;

          currentFavourite = utils.isFavourite(currentTitle);

          logUpdate.done();
          logTitle(currentTime, currentTitleOut, currentFavourite, true);
          windowTitle(currentTitle, currentFavourite);
          notify({
            title: currentTitle,
            message: channel.fullTitle,
            icon: channel.imageFile
          });
        }
      });

      playerProc.on('error', Promise.reject);

      playerProc.on('exit', () => {
        termTitle();
        process.exit(0);
      });

      return Promise.resolve();
    });
}

function interactive() {
  somafm.getChannels({sortChannels: true})
    .then(showPrompt)
    .then(answers => {
      play(answers.channel);
    })
    .catch(err => {
      console.error(err.toString());
      process.exit(20);
    });
}

function showPrompt(channels) {
  inquirer.registerPrompt('autocomplete', require('inquirer-autocomplete-prompt'));

  const lines = channels.map(channel => ({
    name: `${channel.title} (${chalk.blue(channel.genre)})`,
    value: channel.id,
    short: channel.title
  }));

  return inquirer.prompt([
    {
      type: 'autocomplete',
      name: 'channel',
      message: 'Channel  ',
      source: (answers, input) => Promise.resolve().then(() => filerLines(input, lines))
    }
  ]);
}

function filerLines(input, lines) {
  if (input !== null) {
    return lines.filter(channel => channel.name.toLowerCase().includes(input.toLowerCase()));
  }

  return lines;
}

function logTitle(time, title, favourite, playing) {
  let state = 0;
  let prefix = '';

  if (favourite) {
    state++;
  }
  if (playing) {
    state += 2;
  }

  switch (state) {
    case 1:
      prefix = `${chalk.red(figures.heart)} `;
      break;
    case 2:
      prefix = `${chalk.green(figures.play)} `;
      break;
    case 3:
      prefix = `${chalk.green(figures.heart)} `;
      break;
    default:
  }

  logUpdate(`  ${time}  ${prefix}${title}`);
}

function windowTitle(title, favourite) {
  termTitle(`${favourite ? figures.heart : figures.play} ${title}`);
}

function notify(data) {
  notifier.notify(data);
}

function record(channel) {
  return new Promise((resolve, reject) => {
    if (!isBin(streamripperBin)) {
      reject(new Error('Streamripper executable not found. Please ensure Streamripper is installed on your system and runnable with the "streamripper" command.'));
    }

    const date = dateFormat(new Date(), 'yyyymmdd_HHMMss');
    const args = [
      channel.stream.url,
      '-D', `${channel.fullTitle}/${date}/%1q %A - %T`
    ];
    const streamripperProc = childProcess.spawn(streamripperBin, args, {stdio: [process.stdin, 'pipe', 'pipe']});
    let currentStatus;
    let currentTitle;

    cliCursor.hide();
    console.log(`
    Recording ${chalk.bold(channel.fullTitle)}
    to directory ${chalk.yellow(`${channel.fullTitle}/${date}`)}\n`
    );

    streamripperProc.stdout.on('data', data => {
      const line = data.toString();

      const regex = /^\[(r|sk)ipping.*] (.*) \[(.{7})]$/m;
      const res = line.match(regex);

      if (res && res[1] && res[2]) {
        if ((currentStatus !== res[1] || currentTitle !== res[2]) && res[2].length > 1) {
          if (res[3] && trim(res[3]) === '0b') {
            return;
          }

          currentStatus = res[1];
          currentTitle = res[2];

          const time = dateFormat(new Date(), 'HH:MM:ss');
          const status = res[1] === 'r' ? 'Recording' : 'Skipping ';
          console.log(`  ${chalk.yellow(time)}  ${chalk.bold(status)}  ${currentTitle}`);
        }
      }
    });

    streamripperProc.on('error', reject);

    streamripperProc.on('exit', resolve);
  });
}

function init() {
  if (cli.flags.n) {
    // Disable desktop notifications
    notify = () => {};
  }

  if (cli.input.length === 0) {
    interactive();
    return;
  }

  if (['list', 'ls', 'l'].indexOf(cli.input[0]) > -1) {
    list(cli.input.slice(1));
    return;
  }

  if (['info', 'i'].indexOf(cli.input[0]) > -1 && cli.input[1]) {
    info(cli.input[1]);
    return;
  }

  if (['play', 'p'].indexOf(cli.input[0]) > -1 && cli.input[1]) {
    play(cli.input[1]);
    return;
  }

  if (['record', 'r'].indexOf(cli.input[0]) > -1 && cli.input[1]) {
    somafm.getChannel(cli.input[1])
      .then(channel => {
        record(channel);
      })
      .catch(err => {
        console.error(err.toString());
        process.exit(10);
      });
    return;
  }

  if (['list-favourites', 'list-favorites', 'lf'].indexOf(cli.input[0]) > -1) {
    utils.getFavourites().then(favourites => {
      console.log();
      for (const title of favourites) {
        console.log(`  ${chalk.red(figures.heart)} ${title}`);
      }
    });
    return;
  }

  if (['edit-favourites', 'edit-favorites', 'ef'].indexOf(cli.input[0]) > -1) {
    editor(utils.getFavouritesFile());
    return;
  }

  cli.showHelp();
  process.exit(1);
}

init();
<commit_msg>Show favourite indicator in desktop notification<commit_after>#!/usr/bin/env node
'use strict';
const childProcess = require('child_process');
const chalk = require('chalk');
const meow = require('meow');
const inquirer = require('inquirer');
const isBin = require('isbin');
const dateFormat = require('dateformat');
const trim = require('trim');
const termTitle = require('term-title');
const cliTruncate = require('cli-truncate');
const copy = require('copy-paste').copy;
const logUpdate = require('log-update');
const cliCursor = require('cli-cursor');
const notifier = require('node-notifier');
const editor = require('editor');
const figures = require('./figures');
const utils = require('./utils');
const somafm = require('.');

const cli = meow(`
  Usage
    $ somafm [<command> <args>]

  Example
    $ somafm
    $ somafm list
    $ somafm list ambient
    $ somafm info groovesalad
    $ somafm play fluid

  Commands
    list [<keywords>]   list channels, optionally filter by keywords
    info <channel>      show channel information
    play <channel>      play channel
    record <channel>    start recording channel
    list-favourites     list your favourite songs
    edit-favourites     edit your favourite songs
`, {
  alias: {
    h: 'help',
    v: 'version'
  }
});

const players = [
  {
    cmd: 'mplayer',
    args: ['-quiet'],
    titleRegex: /StreamTitle='(.*)';StreamUrl=/,
    keyPress: true
  },
  {
    cmd: 'mpv',
    args: ['--msg-level=all=info'],
    titleRegex: /.*icy-title: (.*)$/
  }
];
const streamripperBin = 'streamripper';

function showChannelList(channels) {
  console.log();

  for (const channel of channels) {
    const str = `${chalk.bold(channel.title)} [${chalk.green(channel.id)}] (${chalk.blue(channel.genre)}) - ${(channel.description)}`;

    if (process.stdout.columns) {
      console.log(cliTruncate(str, process.stdout.columns - 1));
    } else {
      console.log(str);
    }
  }
}

function showChannel(channel) {
  console.log(
  `
  ${chalk.bold(channel.fullTitle)} [${chalk.green(channel.id)}]

  ${chalk.blue(channel.description)}

    ${chalk.yellow('Now playing')}   ${channel.lastPlaying}

             ${chalk.yellow('DJ')}   ${channel.dj}
          ${chalk.yellow('Genre')}   ${channel.genre}
      ${chalk.yellow('Listeners')}   ${channel.listeners}

     ${chalk.yellow('Stream URL')}   ${channel.stream.urls[0]}`
  );
}

function list(search) {
  somafm.getChannels({search, sortChannels: true})
    .then(showChannelList)
    .catch(err => {
      console.error(err.toString());
      process.exit(20);
    });
}

function info(channelId) {
  somafm.getChannel(channelId)
    .then(channel => {
      showChannel(channel);
    })
    .catch(err => {
      console.error(err.toString());
      process.exit(10);
    });
}

function play(channelId) {
  somafm.getChannel(channelId)
    .then(playChannel)
    .catch(err => {
      console.error(err.toString());
      process.exit(10);
    });
}

function getPlayer() {
  return new Promise((resolve, reject) => {
    for (const player of players) {
      if (isBin(player.cmd)) {
        resolve(player);
      }
    }

    reject(new Error('No player executable found. Please ensure mpv or MPlayer is installed on your system and runnable within your shell.'));
  });
}

function playChannel(channel) {
  return getPlayer()
    .then(player => {
      let currentTitle = '';
      let currentTitleOut;
      let currentTime;
      let currentFavourite;

      cliCursor.hide();
      console.log(`\n  Playing   ${chalk.bold(channel.fullTitle)}\n`);

      const args = player.args.concat(channel.stream.urls[0]);
      const playerProc = childProcess.spawn(player.cmd, args);

      const stdin = process.stdin;
      stdin.setRawMode(true);
      stdin.resume();
      stdin.setEncoding('utf-8');

      stdin.on('data', key => {
        if (player.keyPress && ['m', '9', '0', '/', '*'].indexOf(key) > -1) {
          playerProc.stdin.write(key);
        }

        if (key === 'c') {
          copy(currentTitle);
        }

        if (['f', '+'].indexOf(key) > -1) {
          utils.addToFavourites(currentTitle);
          currentFavourite = true;

          logTitle(currentTime, currentTitleOut, true, true);
          windowTitle(currentTitleOut, true);
        }

        if (['u', '-'].indexOf(key) > -1) {
          utils.removeFromFavourites(currentTitle);
          currentFavourite = false;

          logTitle(currentTime, currentTitleOut, false, true);
          windowTitle(currentTitleOut);
        }

        // `ctrl`+`c`, `esc`, `q`
        if (['\u0003', '\u001b', 'q'].indexOf(key) > -1) {
          if (currentTitleOut) {
            logTitle(currentTime, currentTitleOut, currentFavourite);
          }
          logUpdate.done();

          playerProc.kill();
        }
      });

      playerProc.stdout.on('data', data => {
        const line = trim(data.toString());

        const res = line.match(player.titleRegex);
        let title;

        if (res && (title = res[1])) {
          const time = dateFormat(new Date(), 'HH:MM:ss');
          const titleOut = title.match(new RegExp(`SomaFM|Big Url|${channel.title}`, 'i')) ? chalk.gray(title) : title;

          // Overwrite last line
          if (currentTime) {
            logTitle(currentTime, currentTitleOut, currentFavourite);
          }

          currentTitle = title;
          currentTime = chalk.yellow(time);
          currentTitleOut = titleOut;

          currentFavourite = utils.isFavourite(currentTitle);

          logUpdate.done();
          logTitle(currentTime, currentTitleOut, currentFavourite, true);
          windowTitle(currentTitle, currentFavourite);
          notify({
            title: currentTitle,
            message: channel.fullTitle,
            icon: channel.imageFile
          }, currentFavourite);
        }
      });

      playerProc.on('error', Promise.reject);

      playerProc.on('exit', () => {
        termTitle();
        process.exit(0);
      });

      return Promise.resolve();
    });
}

function interactive() {
  somafm.getChannels({sortChannels: true})
    .then(showPrompt)
    .then(answers => {
      play(answers.channel);
    })
    .catch(err => {
      console.error(err.toString());
      process.exit(20);
    });
}

function showPrompt(channels) {
  inquirer.registerPrompt('autocomplete', require('inquirer-autocomplete-prompt'));

  const lines = channels.map(channel => ({
    name: `${channel.title} (${chalk.blue(channel.genre)})`,
    value: channel.id,
    short: channel.title
  }));

  return inquirer.prompt([
    {
      type: 'autocomplete',
      name: 'channel',
      message: 'Channel  ',
      source: (answers, input) => Promise.resolve().then(() => filerLines(input, lines))
    }
  ]);
}

function filerLines(input, lines) {
  if (input !== null) {
    return lines.filter(channel => channel.name.toLowerCase().includes(input.toLowerCase()));
  }

  return lines;
}

function logTitle(time, title, favourite, playing) {
  let state = 0;
  let prefix = '';

  if (favourite) {
    state++;
  }
  if (playing) {
    state += 2;
  }

  switch (state) {
    case 1:
      prefix = `${chalk.red(figures.heart)} `;
      break;
    case 2:
      prefix = `${chalk.green(figures.play)} `;
      break;
    case 3:
      prefix = `${chalk.green(figures.heart)} `;
      break;
    default:
  }

  logUpdate(`  ${time}  ${prefix}${title}`);
}

function windowTitle(title, favourite) {
  termTitle(`${favourite ? figures.heart : figures.play} ${title}`);
}

function notify(data, favourite) {
  if (favourite) {
    data.title = `${figures.heart} ${data.title}`;
  }

  notifier.notify(data);
}

function record(channel) {
  return new Promise((resolve, reject) => {
    if (!isBin(streamripperBin)) {
      reject(new Error('Streamripper executable not found. Please ensure Streamripper is installed on your system and runnable with the "streamripper" command.'));
    }

    const date = dateFormat(new Date(), 'yyyymmdd_HHMMss');
    const args = [
      channel.stream.url,
      '-D', `${channel.fullTitle}/${date}/%1q %A - %T`
    ];
    const streamripperProc = childProcess.spawn(streamripperBin, args, {stdio: [process.stdin, 'pipe', 'pipe']});
    let currentStatus;
    let currentTitle;

    cliCursor.hide();
    console.log(`
    Recording ${chalk.bold(channel.fullTitle)}
    to directory ${chalk.yellow(`${channel.fullTitle}/${date}`)}\n`
    );

    streamripperProc.stdout.on('data', data => {
      const line = data.toString();

      const regex = /^\[(r|sk)ipping.*] (.*) \[(.{7})]$/m;
      const res = line.match(regex);

      if (res && res[1] && res[2]) {
        if ((currentStatus !== res[1] || currentTitle !== res[2]) && res[2].length > 1) {
          if (res[3] && trim(res[3]) === '0b') {
            return;
          }

          currentStatus = res[1];
          currentTitle = res[2];

          const time = dateFormat(new Date(), 'HH:MM:ss');
          const status = res[1] === 'r' ? 'Recording' : 'Skipping ';
          console.log(`  ${chalk.yellow(time)}  ${chalk.bold(status)}  ${currentTitle}`);
        }
      }
    });

    streamripperProc.on('error', reject);

    streamripperProc.on('exit', resolve);
  });
}

function init() {
  if (cli.flags.n) {
    // Disable desktop notifications
    notify = () => {};
  }

  if (cli.input.length === 0) {
    interactive();
    return;
  }

  if (['list', 'ls', 'l'].indexOf(cli.input[0]) > -1) {
    list(cli.input.slice(1));
    return;
  }

  if (['info', 'i'].indexOf(cli.input[0]) > -1 && cli.input[1]) {
    info(cli.input[1]);
    return;
  }

  if (['play', 'p'].indexOf(cli.input[0]) > -1 && cli.input[1]) {
    play(cli.input[1]);
    return;
  }

  if (['record', 'r'].indexOf(cli.input[0]) > -1 && cli.input[1]) {
    somafm.getChannel(cli.input[1])
      .then(channel => {
        record(channel);
      })
      .catch(err => {
        console.error(err.toString());
        process.exit(10);
      });
    return;
  }

  if (['list-favourites', 'list-favorites', 'lf'].indexOf(cli.input[0]) > -1) {
    utils.getFavourites().then(favourites => {
      console.log();
      for (const title of favourites) {
        console.log(`  ${chalk.red(figures.heart)} ${title}`);
      }
    });
    return;
  }

  if (['edit-favourites', 'edit-favorites', 'ef'].indexOf(cli.input[0]) > -1) {
    editor(utils.getFavouritesFile());
    return;
  }

  cli.showHelp();
  process.exit(1);
}

init();
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

const fs = require('fs');
const http = require('http');
const dns = require('dns');
const got = require('got');
const colors = require('colors/safe');
const mkdirp = require('mkdirp');
const ora = require('ora');
const updateNotifier = require('update-notifier');
const pkg = require('./package.json');

updateNotifier({pkg}).notify();

console.log();
const spinner = ora();

dns.lookup('xkcd.com', err => {
	if (err && err.code === 'ENOTFOUND') {
		console.log(colors.red.bold(' ❱ Internet Connection   :   ✖\n'));
		process.exit(1);
	}
	spinner.start();
	spinner.text = colors.cyan.bold('XKCD Loves You!');
});

const xkcdComics = './XKCD/';

mkdirp(xkcdComics, err => {
	if (err) {
		console.log(colors.red.bold('\n ❱ Directory Created      :    ✖\n'));
		process.exit(1);
	} else {
		/* no need */
	}
});

function comicsName(img) {
	return img.split('/').pop();
}

got('http://xkcd.com/info.0.json').then(res => {
	spinner.start();
	spinner.text = colors.green.bold('Have patience. All things are difficult before they become easy.');
	const getCount = JSON.parse(res.body);
	const startCount = getCount.num;
	let randCount = Math.floor((Math.random() * startCount) + 1);
	if (randCount === 404) {
		randCount = Math.floor((Math.random() * startCount) + 1);
	}
	const staticURL = `http://xkcd.com/${randCount}/info.0.json`;
	got(staticURL).then(res => {
		spinner.stop();
		const semLink = JSON.parse(res.body);
		const imageLink = semLink.img;
		const alt = semLink.alt;
		const comicName = comicsName(imageLink);
		console.log(colors.cyan.bold(' ', alt));
		console.log();
		spinner.stop();
		// for backup
		mkdirp(xkcdComics, err => {
			if (err) {
				process.exit(1);
			} else {
				// no message
			}
		});
		const comicOn = fs.createWriteStream(xkcdComics + comicName);
		http.get(imageLink, (res, cb) => {
			const dirMessage = colors.cyan.bold(xkcdComics.replace('./', '').replace('/', ''));
			const comicColor = colors.cyan.bold(comicName);
			spinner.start();
			spinner.text = colors.green.bold(`Saving comics in ${dirMessage} ❱ ${comicColor}`);
			res.pipe(comicOn);
			comicOn.on('finish', () => {
				spinner.stop();
				comicOn.close(cb);
			});
		});
	});
}).catch(error => {
	process.exit(1);
	console.log(error);
});
<commit_msg>fix `catch-error-name`<commit_after>#!/usr/bin/env node

'use strict';

const fs = require('fs');
const http = require('http');
const dns = require('dns');
const got = require('got');
const colors = require('colors/safe');
const mkdirp = require('mkdirp');
const ora = require('ora');
const updateNotifier = require('update-notifier');
const pkg = require('./package.json');

updateNotifier({pkg}).notify();

console.log();
const spinner = ora();

dns.lookup('xkcd.com', err => {
	if (err && err.code === 'ENOTFOUND') {
		console.log(colors.red.bold(' ❱ Internet Connection   :   ✖\n'));
		process.exit(1);
	}
	spinner.start();
	spinner.text = colors.cyan.bold('XKCD Loves You!');
});

const xkcdComics = './XKCD/';

mkdirp(xkcdComics, err => {
	if (err) {
		console.log(colors.red.bold('\n ❱ Directory Created      :    ✖\n'));
		process.exit(1);
	} else {
		/* no need */
	}
});

function comicsName(img) {
	return img.split('/').pop();
}

got('http://xkcd.com/info.0.json').then(res => {
	spinner.start();
	spinner.text = colors.green.bold('Have patience. All things are difficult before they become easy.');
	const getCount = JSON.parse(res.body);
	const startCount = getCount.num;
	let randCount = Math.floor((Math.random() * startCount) + 1);
	if (randCount === 404) {
		randCount = Math.floor((Math.random() * startCount) + 1);
	}
	const staticURL = `http://xkcd.com/${randCount}/info.0.json`;
	got(staticURL).then(res => {
		spinner.stop();
		const semLink = JSON.parse(res.body);
		const imageLink = semLink.img;
		const alt = semLink.alt;
		const comicName = comicsName(imageLink);
		console.log(colors.cyan.bold(' ', alt));
		console.log();
		spinner.stop();
		// for backup
		mkdirp(xkcdComics, err => {
			if (err) {
				process.exit(1);
			} else {
				// no message
			}
		});
		const comicOn = fs.createWriteStream(xkcdComics + comicName);
		http.get(imageLink, (res, cb) => {
			const dirMessage = colors.cyan.bold(xkcdComics.replace('./', '').replace('/', ''));
			const comicColor = colors.cyan.bold(comicName);
			spinner.start();
			spinner.text = colors.green.bold(`Saving comics in ${dirMessage} ❱ ${comicColor}`);
			res.pipe(comicOn);
			comicOn.on('finish', () => {
				spinner.stop();
				comicOn.close(cb);
			});
		});
	});
}).catch(err => {
	process.exit(1);
	console.log(err);
});
<|endoftext|>


<commit_before>/*
* jQuery Mobile Framework : "textinput" plugin for text inputs, textareas
* Copyright (c) jQuery Project
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/

(function( $, undefined ) {

$.widget( "mobile.textinput", $.mobile.widget, {
	options: {
		theme: null,
		initSelector: "input[type='text'], input[type='search'], :jqmData(type='search'), input[type='number'], :jqmData(type='number'), input[type='password'], input[type='email'], input[type='url'], input[type='tel'], textarea, input[type='time'], input[type='date'], input[type='month'], input[type='week'], input[type='datetime'], input[type='datetime-local'], input[type='color'], input:not([type])"
	},

	_create: function() {

		var input = this.element,
			o = this.options,
			theme = o.theme,
			themeclass, focusedEl, clearbtn;

		if ( !theme ) {
			theme = $.mobile.getInheritedTheme( this.element, "c" );
		}

		themeclass = " ui-body-" + theme;

		$( "label[for='" + input.attr( "id" ) + "']" ).addClass( "ui-input-text" );

		input.addClass("ui-input-text ui-body-"+ theme );

		focusedEl = input;

		// XXX: Temporary workaround for issue 785 (Apple bug 8910589).
		//      Turn off autocorrect and autocomplete on non-iOS 5 devices
		//      since the popup they use can't be dismissed by the user. Note
		//      that we test for the presence of the feature by looking for
		//      the autocorrect property on the input element. We currently
		//      have no test for iOS 5 or newer so we're temporarily using
		//      the touchOverflow support flag for jQM 1.0. Yes, I feel dirty. - jblas
		if ( typeof input[0].autocorrect !== "undefined" && !$.support.touchOverflow ) {
			// Set the attribute instead of the property just in case there
			// is code that attempts to make modifications via HTML.
			input[0].setAttribute( "autocorrect", "off" );
			input[0].setAttribute( "autocomplete", "off" );
		}

		//"search" input widget
		if ( input.is( "[type='search'],:jqmData(type='search')" ) ) {

			focusedEl = input.wrap( "

" ).parent();
			clearbtn = $( "clear text" )
				.tap(function( event ) {
					input.val( "" ).focus();
					input.trigger( "change" );
					clearbtn.addClass( "ui-input-clear-hidden" );
					event.preventDefault();
				})
				.appendTo( focusedEl )
				.buttonMarkup({
					icon: "delete",
					iconpos: "notext",
					corners: true,
					shadow: true
				});

			function toggleClear() {
				if ( !input.val() ) {
					clearbtn.addClass( "ui-input-clear-hidden" );
				} else {
					clearbtn.removeClass( "ui-input-clear-hidden" );
				}
			}

			toggleClear();

			input.keyup( toggleClear )
				.focus( toggleClear );

		} else {
			input.addClass( "ui-corner-all ui-shadow-inset" + themeclass );
		}

		input.focus(function() {
				focusedEl.addClass( "ui-focus" );
			})
			.blur(function(){
				focusedEl.removeClass( "ui-focus" );
			});

		// Autogrow
		if ( input.is( "textarea" ) ) {
			var extraLineHeight = 15,
				keyupTimeoutBuffer = 100,
				keyup = function() {
					var scrollHeight = input[ 0 ].scrollHeight,
						clientHeight = input[ 0 ].clientHeight;

					if ( clientHeight < scrollHeight ) {
						input.css({
							height: (scrollHeight + extraLineHeight)
						});
					}
				},
				keyupTimeout;

			input.keyup(function() {
				clearTimeout( keyupTimeout );
				keyupTimeout = setTimeout( keyup, keyupTimeoutBuffer );
			});

			// Issue 509: the browser is not giving scrollHeight properly until after the document
			// is ready.
			if ($.trim(input.text())) {
				$(keyup);
			}
		}
	},

	disable: function(){
		( this.element.attr( "disabled", true ).is( "[type='search'],:jqmData(type='search')" ) ?
			this.element.parent() : this.element ).addClass( "ui-disabled" );
	},

	enable: function(){
		( this.element.attr( "disabled", false).is( "[type='search'],:jqmData(type='search')" ) ?
			this.element.parent() : this.element ).removeClass( "ui-disabled" );
	}
});

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ){
	$.mobile.textinput.prototype.enhanceWithin( e.target );
});

})( jQuery );
<commit_msg>Some code cleanup<commit_after>/*
* jQuery Mobile Framework : "textinput" plugin for text inputs, textareas
* Copyright (c) jQuery Project
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/

(function( $, undefined ) {

$.widget( "mobile.textinput", $.mobile.widget, {
	options: {
		theme: null,
		initSelector: "input[type='text'], input[type='search'], :jqmData(type='search'), input[type='number'], :jqmData(type='number'), input[type='password'], input[type='email'], input[type='url'], input[type='tel'], textarea, input[type='time'], input[type='date'], input[type='month'], input[type='week'], input[type='datetime'], input[type='datetime-local'], input[type='color'], input:not([type])"
	},

	_create: function() {

		var input = this.element,
			o = this.options,
			theme = o.theme || $.mobile.getInheritedTheme( this.element, "c" ),
			themeclass  = " ui-body-" + theme,
			focusedEl, clearbtn;

		$( "label[for='" + input.attr( "id" ) + "']" ).addClass( "ui-input-text" );

		focusedEl = input.addClass("ui-input-text ui-body-"+ theme );

		// XXX: Temporary workaround for issue 785 (Apple bug 8910589).
		//      Turn off autocorrect and autocomplete on non-iOS 5 devices
		//      since the popup they use can't be dismissed by the user. Note
		//      that we test for the presence of the feature by looking for
		//      the autocorrect property on the input element. We currently
		//      have no test for iOS 5 or newer so we're temporarily using
		//      the touchOverflow support flag for jQM 1.0. Yes, I feel dirty. - jblas
		if ( typeof input[0].autocorrect !== "undefined" && !$.support.touchOverflow ) {
			// Set the attribute instead of the property just in case there
			// is code that attempts to make modifications via HTML.
			input[0].setAttribute( "autocorrect", "off" );
			input[0].setAttribute( "autocomplete", "off" );
		}

		//"search" input widget
		if ( input.is( "[type='search'],:jqmData(type='search')" ) ) {

			focusedEl = input.wrap( "

" ).parent();
			clearbtn = $( "clear text" )
				.tap(function( event ) {
					input.val( "" ).focus();
					input.trigger( "change" );
					clearbtn.addClass( "ui-input-clear-hidden" );
					event.preventDefault();
				})
				.appendTo( focusedEl )
				.buttonMarkup({
					icon: "delete",
					iconpos: "notext",
					corners: true,
					shadow: true
				});

			function toggleClear() {
				if ( !input.val() ) {
					clearbtn.addClass( "ui-input-clear-hidden" );
				} else {
					clearbtn.removeClass( "ui-input-clear-hidden" );
				}
			}

			toggleClear();

			input.keyup( toggleClear )
				.focus( toggleClear );

		} else {
			input.addClass( "ui-corner-all ui-shadow-inset" + themeclass );
		}

		input.focus(function() {
				focusedEl.addClass( "ui-focus" );
			})
			.blur(function(){
				focusedEl.removeClass( "ui-focus" );
			});

		// Autogrow
		if ( input.is( "textarea" ) ) {
			var extraLineHeight = 15,
				keyupTimeoutBuffer = 100,
				keyup = function() {
					var scrollHeight = input[ 0 ].scrollHeight,
						clientHeight = input[ 0 ].clientHeight;

					if ( clientHeight < scrollHeight ) {
						input.css({
							height: (scrollHeight + extraLineHeight)
						});
					}
				},
				keyupTimeout;

			input.keyup(function() {
				clearTimeout( keyupTimeout );
				keyupTimeout = setTimeout( keyup, keyupTimeoutBuffer );
			});

			// Issue 509: the browser is not giving scrollHeight properly until after the document
			// is ready.
			if ($.trim(input.text())) {
				$(keyup);
			}
		}
	},

	disable: function(){
		( this.element.attr( "disabled", true ).is( "[type='search'],:jqmData(type='search')" ) ?
			this.element.parent() : this.element ).addClass( "ui-disabled" );
	},

	enable: function(){
		( this.element.attr( "disabled", false).is( "[type='search'],:jqmData(type='search')" ) ?
			this.element.parent() : this.element ).removeClass( "ui-disabled" );
	}
});

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ){
	$.mobile.textinput.prototype.enhanceWithin( e.target );
});

})( jQuery );
<|endoftext|>


<commit_before>var klp = klp || {};

(function(){
	var active_volunteer_step = "date";
	var volunteer_steps;
	var modal_tpl;
	var $modal_wrapper;
	var $modal_overlay;

	var init = function(){
		volunteer_steps = ['date', 'organization', 'opportunities'];
		modal_tpl = swig.compile($("#tpl-volunteer-modal").html());
		$modal_wrapper = $("#modal_wrapper");
		$modal_overlay = $("#modal_overlay");

		// setTimeout(open_modal,1500);
		// open_modal();
	};

	var open_modal = function(e){
		if( $(window).width()<768 ){
			return true;
		}
		e.preventDefault();

		var html = modal_tpl();
		$modal_wrapper.append(html);
		var $modal = $modal_wrapper.find(".modal-volunteer");
		init_modal($modal);

		setTimeout(function(){
			$modal.addClass("show");
			$modal_overlay.addClass("show");
		},0);
	};

	var init_modal = function($modal){
		var $input_data_location = $modal.find( "input[name=data_location]" );
		var $input_data_date = $modal.find( "input[name=data_date]" );
		var $input_data_type = $modal.find( "input[name=data_type]" );

		var $btn_close = $modal.find(".btn-modal-close");
		var $btn_back = $modal.find(".btn-modal-back");
		var $btn_next_step_cal = $modal.find('.btn-next-step-cal');
		var $btn_next_step_org = $modal.find('.btn-next-step-org');
		var $datepicker_input = $modal.find('#datepicker-input');
		var $select_location = $modal.find('#select-location').selectize({onChange: onLocationChange});

		function onLocationChange(value){
			$input_data_location.val(value);
		}

		$datepicker_input.Zebra_DatePicker({
		    always_visible: $modal.find('#datepicker-wrapper'),
		    first_day_of_week: 0,
		    show_clear_date: false,
		    show_select_today: false,
		    disabled_dates: ['1,3,4,5,12,13,14,22,24'],
		    onSelect: onDateSelect,
		    onClear: onDateClear
		});
		var datepicker = $datepicker_input.data('Zebra_DatePicker');

		function onDateSelect(date){
			$input_data_date.val(date);
			$btn_next_step_cal.show();
		}
		function onDateClear(){
			$input_data_date.val("");
			$btn_next_step_cal.hide();
		}

		$btn_next_step_cal.on("click", function(e){
			e.preventDefault();
			active_volunteer_step = "organization";
			show_next_step($modal, active_volunteer_step);
			$btn_back.show();
		});

		$btn_next_step_org.on("click", function(e){
			e.preventDefault();
			active_volunteer_step = "opportunities";
			show_next_step($modal, active_volunteer_step);
			$btn_back.show();
		});

		$btn_close.on("click", function(e){
			e.preventDefault();

			$modal.removeClass("show");
			$modal_overlay.removeClass("show");

			setTimeout(function(){
				$modal.remove();
			},300);
		});

		$btn_back.on("click", function(e){
			e.preventDefault();

			var current_step_index = jQuery.inArray(active_volunteer_step, volunteer_steps);
			if(current_step_index<=0){
				return;
			}
			current_step_index--;
			var prev_step = volunteer_steps[current_step_index];
			active_volunteer_step = prev_step;
			show_prev_step($modal, prev_step);

			if(current_step_index<=0){
				$btn_back.hide();
			}
		});

		$modal.on('click', ".js-open-map", open_map);

		function open_map(e){
			e.preventDefault();
			var location = $input_data_location.val();
			var date = $input_data_date.val();
			var type = $(this).data("type");
			var url = "map.php?location="+location+"&date="+date+"&type="+type;
			window.location.href = url;
		}
	};

	var show_prev_step = function($modal, step_name){
		var $step_current = $modal.find(".step-item.visible");
		var $step_prev = $modal.find(".step-item[data-step-name='" + step_name +"']");

		$step_current.removeClass("fadein").addClass("move-right fadeout");
        $step_prev.removeClass("fadeut").addClass("move-left visible");

        // Hide current step
        setTimeout(function(){
            $step_current.removeClass("visible");
        },300);

        setTimeout(function(){
            $step_prev.addClass("fadein").removeClass("move-left");
        },10);
    };

	var show_next_step = function($modal, step_name){
		var $step_current = $modal.find(".step-item.visible");
		var $step_next = $modal.find(".step-item[data-step-name='" + step_name +"']");

		// Hide current step
    	$step_current.removeClass("move-right fadein").addClass("fadeout move-left");
        setTimeout(function(){
            $step_current.removeClass("visible");
        },300);

        // Show next step
        $step_next.addClass("move-right visible");
        setTimeout(function(){
            $step_next.addClass("fadein").removeClass("move-right");
        },10);
	};

	$(document).ready(function(){
		init();
		$(document).on('click', ".js-trigger-volunteer", open_modal);
	});

})();<commit_msg>Open volunteer map instead of the normal map after initial vol process is complete<commit_after>var klp = klp || {};

(function(){
	var active_volunteer_step = "date";
	var volunteer_steps;
	var modal_tpl;
	var $modal_wrapper;
	var $modal_overlay;

	var init = function(){
		volunteer_steps = ['date', 'organization', 'opportunities'];
		modal_tpl = swig.compile($("#tpl-volunteer-modal").html());
		$modal_wrapper = $("#modal_wrapper");
		$modal_overlay = $("#modal_overlay");

		// setTimeout(open_modal,1500);
		// open_modal();
	};

	var open_modal = function(e){
		if( $(window).width()<768 ){
			return true;
		}
		e.preventDefault();

		var html = modal_tpl();
		$modal_wrapper.append(html);
		var $modal = $modal_wrapper.find(".modal-volunteer");
		init_modal($modal);

		setTimeout(function(){
			$modal.addClass("show");
			$modal_overlay.addClass("show");
		},0);
	};

	var init_modal = function($modal){
		var $input_data_location = $modal.find( "input[name=data_location]" );
		var $input_data_date = $modal.find( "input[name=data_date]" );
		var $input_data_type = $modal.find( "input[name=data_type]" );

		var $btn_close = $modal.find(".btn-modal-close");
		var $btn_back = $modal.find(".btn-modal-back");
		var $btn_next_step_cal = $modal.find('.btn-next-step-cal');
		var $btn_next_step_org = $modal.find('.btn-next-step-org');
		var $datepicker_input = $modal.find('#datepicker-input');
		var $select_location = $modal.find('#select-location').selectize({onChange: onLocationChange});

		function onLocationChange(value){
			$input_data_location.val(value);
		}

		$datepicker_input.Zebra_DatePicker({
		    always_visible: $modal.find('#datepicker-wrapper'),
		    first_day_of_week: 0,
		    show_clear_date: false,
		    show_select_today: false,
		    disabled_dates: ['1,3,4,5,12,13,14,22,24'],
		    onSelect: onDateSelect,
		    onClear: onDateClear
		});
		var datepicker = $datepicker_input.data('Zebra_DatePicker');

		function onDateSelect(date){
			$input_data_date.val(date);
			$btn_next_step_cal.show();
		}
		function onDateClear(){
			$input_data_date.val("");
			$btn_next_step_cal.hide();
		}

		$btn_next_step_cal.on("click", function(e){
			e.preventDefault();
			active_volunteer_step = "organization";
			show_next_step($modal, active_volunteer_step);
			$btn_back.show();
		});

		$btn_next_step_org.on("click", function(e){
			e.preventDefault();
			active_volunteer_step = "opportunities";
			show_next_step($modal, active_volunteer_step);
			$btn_back.show();
		});

		$btn_close.on("click", function(e){
			e.preventDefault();

			$modal.removeClass("show");
			$modal_overlay.removeClass("show");

			setTimeout(function(){
				$modal.remove();
			},300);
		});

		$btn_back.on("click", function(e){
			e.preventDefault();

			var current_step_index = jQuery.inArray(active_volunteer_step, volunteer_steps);
			if(current_step_index<=0){
				return;
			}
			current_step_index--;
			var prev_step = volunteer_steps[current_step_index];
			active_volunteer_step = prev_step;
			show_prev_step($modal, prev_step);

			if(current_step_index<=0){
				$btn_back.hide();
			}
		});

		$modal.on('click', ".js-open-map", open_map);

		function open_map(e){
			e.preventDefault();
			var location = $input_data_location.val();
			var date = $input_data_date.val();
			var type = $(this).data("type");
			var url = "volunteer-map.php?location="+location+"&date="+date+"&type="+type;
			window.location.href = url;
		}
	};

	var show_prev_step = function($modal, step_name){
		var $step_current = $modal.find(".step-item.visible");
		var $step_prev = $modal.find(".step-item[data-step-name='" + step_name +"']");

		$step_current.removeClass("fadein").addClass("move-right fadeout");
        $step_prev.removeClass("fadeut").addClass("move-left visible");

        // Hide current step
        setTimeout(function(){
            $step_current.removeClass("visible");
        },300);

        setTimeout(function(){
            $step_prev.addClass("fadein").removeClass("move-left");
        },10);
    };

	var show_next_step = function($modal, step_name){
		var $step_current = $modal.find(".step-item.visible");
		var $step_next = $modal.find(".step-item[data-step-name='" + step_name +"']");

		// Hide current step
    	$step_current.removeClass("move-right fadein").addClass("fadeout move-left");
        setTimeout(function(){
            $step_current.removeClass("visible");
        },300);

        // Show next step
        $step_next.addClass("move-right visible");
        setTimeout(function(){
            $step_next.addClass("fadein").removeClass("move-right");
        },10);
	};

	$(document).ready(function(){
		init();
		$(document).on('click', ".js-trigger-volunteer", open_modal);
	});

})();<|endoftext|>


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

/*
 * Dependencies.
 */

var mdast,
    fs,
    path,
    pack;

mdast = require('./');
fs = require('fs');
path = require('path');
pack = require('./package.json');

/*
 * Cached methods.
 */

var resolve,
    exists;

resolve = path.resolve;
exists = fs.existsSync;

/*
 * Current working directory.
 */

var cwd;

cwd = process.cwd();

/*
 * Detect if a value is expected to be piped in.
 */

var expextPipeIn;

expextPipeIn = !process.stdin.isTTY;

/*
 * Arguments.
 */

var argv;

argv = process.argv.slice(2);

/*
 * Command.
 */

var command;

command = Object.keys(pack.bin)[0];

/**
 * Help.
 *
 * @return {string}
 */
function help() {
    return [
        '',
        'Usage: ' + command + ' [options] file',
        '',
        pack.description,
        '',
        'Options:',
        '',
        '  -h, --help            output usage information',
        '  -v, --version         output version number',
        '  -a, --ast             output AST information',
        '      --options         output available settings',
        '  -o, --output <path>   specify output location',
        '  -O, --option <option> specify settings',
        '  -u, --use    <plugin> specify plugins',
        '',
        'Usage:',
        '',
        '# Note that bash does not allow reading and writing to the',
        '# same file through pipes',
        '',
        '# Pass `Readme.md` through mdast',
        '$ ' + command + ' Readme.md -o Readme.md',
        '',
        '# Pass stdin through mdast, with options, to stdout',
        '$ cat Readme.md | ' + command + ' --option ' +
            '"setext, bullet: *" > Readme-new.md',
        '',
        '# Use an npm module',
        '$ npm install some-plugin',
        '$ ' + command + ' --use some-plugin History.md > History-new.md'
    ].join('\n  ') + '\n';
}

/**
 * Fail w/ `exception`.
 *
 * @param {null|string|Error} exception
 */
function fail(exception) {
    if (!exception) {
        exception = help();
    }

    process.stderr.write((exception.stack || exception) + '\n');

    process.exit(1);
}

/**
 * Log available options.
 *
 * @return {string}
 */
function getOptions() {
    return [
        '',
        '# Options',
        '',
        'Both camel- and dash-cased options are allowed.',
        '',
        '## [Parse](https://github.com/wooorm/mdast#mdastparsevalue-options)',
        '',
        '-  `gfm` (boolean, default: true)',
        '-  `tables` (boolean, default: true)',
        '-  `pedantic` (boolean, default: false)',
        '-  `breaks` (boolean, default: false)',
        '-  `footnotes` (boolean, default: false)',
        '',
        '## [Stringify](https://github.com/wooorm/mdast#' +
            'mdaststringifyast-options)',
        '',
        '-  `setext` (boolean, default: false)',
        '-  `closeAtx` (boolean, default: false)',
        '-  `looseTable` (boolean, default: false)',
        '-  `spaced-table` (boolean, default: true)',
        '-  `reference-links` (boolean, default: false)',
        '-  `reference-footnotes` (boolean, default: true)',
        '-  `fences` (boolean, default: false)',
        '-  `bullet` ("-", "*", or "+", default: "-")',
        '-  `rule` ("-", "*", or "_", default: "*")',
        '-  `rule-repetition` (number, default: 3)',
        '-  `rule-spaces` (boolean, default: false)',
        '-  `strong` ("_", or "*", default: "*")',
        '-  `emphasis` ("_", or "*", default: "_")',
        '',
        'Settings are specified as follows:',
        '',
        '```',
        '$ ' + command + ' --option "some-option:some-value"',
        '# Multiple options:',
        '$ ' + command + ' --option "emphasis:*,strong:_"',
        '```'
    ].join('\n  ') + '\n';
}

/**
 * Transform a dash-cased string to camel-cased.
 *
 * @param {string} value
 * @return {string}
 */
function camelCase(value) {
    return value.toLowerCase().replace(/-([a-z])/gi, function ($0, $1) {
        return $1.toUpperCase();
    });
}

/*
 * Program.
 */

var index,
    expectOption,
    expectPlugin,
    expectOutput,
    expectAST,
    plugins,
    options,
    output,
    files;

plugins = [];

/**
 * Run the program.
 *
 * @param {string} value
 */
function program(value) {
    var doc,
        parser,
        local,
    fn;

    if (!value.length) {
        fail();
    } else {
        parser = mdast;

        plugins.forEach(function (plugin) {
            local = resolve(cwd, plugin);

            if (exists(local) || exists(local + '.js')) {
                fn = require(local);
            } else {
                try {
                    fn = require(resolve(cwd, 'node_modules', plugin));
                } catch (exception) {
                    fail(exception);
                }
            }

            parser = parser.use(fn);
        });

        doc = parser.parse(value, options);

        if (expectAST) {
            doc = JSON.stringify(doc, null, 2);
        } else {
            doc = mdast.stringify(doc, options);
        }

        if (output) {
            fs.writeFile(output, doc, function (exception) {
                if (exception) {
                    fail(exception);
                }
            });
        } else {
            process.stdout.write(doc);
        }
    }
}

if (
    argv.indexOf('--help') !== -1 ||
    argv.indexOf('-h') !== -1
) {
    console.log(help());
} else if (
    argv.indexOf('--version') !== -1 ||
    argv.indexOf('-v') !== -1
) {
    console.log(pack.version);
} else if (
    argv.indexOf('--options') !== -1
) {
    console.log(getOptions());
} else {
    index = argv.indexOf('--ast');

    if (index === -1) {
        index = argv.indexOf('-a');
    }

    if (index !== -1) {
        expectAST = true;
        argv.splice(index, 1);
    }

    files = [];
    options = {};

    argv.forEach(function (argument) {
        if (argument === '--option' || argument === '-O') {
            expectOption = true;
        } else if (argument === '--use' || argument === '-u') {
            expectPlugin = true;
        } else if (argument === '--output' || argument === '-o') {
            expectOutput = true;
        } else if (expectPlugin) {
            argument.split(',').forEach(function (plugin) {
                plugins.push(plugin);
            });

            expectPlugin = false;
        } else if (expectOutput) {
            output = argument;

            expectOutput = false;
        } else if (expectOption) {
            argument
                .split(',')
                .map(function (value) {
                    var values;

                    values = value.split(':');

                    return [
                        camelCase(values.shift().trim()),
                        values.join(':').trim()
                    ];
                })
                .map(function (values) {
                    var value;

                    value = values[1];

                    if (value === 'true') {
                        value = true;
                    } else if (value === 'false') {
                        value = false;
                    } else if (value === '') {
                        value = true;
                    } else if (Number(value) === Number(value)) {
                        value = Number(value);
                    }

                    values[1] = value;

                    return values;
                })
                .forEach(function (values) {
                    options[values[0]] = values[1];
                });

            expectOption = false;
        } else {
            files.push(argument);
        }
    });

    if (expectOption || expectPlugin || expectOutput) {
        fail();
    } else if (!expextPipeIn && !files.length) {
        if (output) {
            files.push(output);
        } else {
            fail();
        }
    } else if (
        (expextPipeIn && files.length) ||
        (!expextPipeIn && files.length !== 1)
    ) {
        fail('mdast currently expects one file.');
    }

    if (files[0]) {
        fs.readFile(files[0], function (exception, content) {
            if (exception) {
                fail(exception);
            }

            program(content.toString());
        });
    } else {
        process.stdin.resume();

        process.stdin.setEncoding('utf8');

        process.stdin.on('data', program);
    }
}
<commit_msg>Fix option casing in `cli.js`<commit_after>#!/usr/bin/env node
'use strict';

/*
 * Dependencies.
 */

var mdast,
    fs,
    path,
    pack;

mdast = require('./');
fs = require('fs');
path = require('path');
pack = require('./package.json');

/*
 * Cached methods.
 */

var resolve,
    exists;

resolve = path.resolve;
exists = fs.existsSync;

/*
 * Current working directory.
 */

var cwd;

cwd = process.cwd();

/*
 * Detect if a value is expected to be piped in.
 */

var expextPipeIn;

expextPipeIn = !process.stdin.isTTY;

/*
 * Arguments.
 */

var argv;

argv = process.argv.slice(2);

/*
 * Command.
 */

var command;

command = Object.keys(pack.bin)[0];

/**
 * Help.
 *
 * @return {string}
 */
function help() {
    return [
        '',
        'Usage: ' + command + ' [options] file',
        '',
        pack.description,
        '',
        'Options:',
        '',
        '  -h, --help            output usage information',
        '  -v, --version         output version number',
        '  -a, --ast             output AST information',
        '      --options         output available settings',
        '  -o, --output <path>   specify output location',
        '  -O, --option <option> specify settings',
        '  -u, --use    <plugin> specify plugins',
        '',
        'Usage:',
        '',
        '# Note that bash does not allow reading and writing to the',
        '# same file through pipes',
        '',
        '# Pass `Readme.md` through mdast',
        '$ ' + command + ' Readme.md -o Readme.md',
        '',
        '# Pass stdin through mdast, with options, to stdout',
        '$ cat Readme.md | ' + command + ' --option ' +
            '"setext, bullet: *" > Readme-new.md',
        '',
        '# Use an npm module',
        '$ npm install some-plugin',
        '$ ' + command + ' --use some-plugin History.md > History-new.md'
    ].join('\n  ') + '\n';
}

/**
 * Fail w/ `exception`.
 *
 * @param {null|string|Error} exception
 */
function fail(exception) {
    if (!exception) {
        exception = help();
    }

    process.stderr.write((exception.stack || exception) + '\n');

    process.exit(1);
}

/**
 * Log available options.
 *
 * @return {string}
 */
function getOptions() {
    return [
        '',
        '# Options',
        '',
        'Both camel- and dash-cased options are allowed.',
        '',
        '## [Parse](https://github.com/wooorm/mdast#mdastparsevalue-options)',
        '',
        '-  `gfm` (boolean, default: true)',
        '-  `tables` (boolean, default: true)',
        '-  `pedantic` (boolean, default: false)',
        '-  `breaks` (boolean, default: false)',
        '-  `footnotes` (boolean, default: false)',
        '',
        '## [Stringify](https://github.com/wooorm/mdast#' +
            'mdaststringifyast-options)',
        '',
        '-  `setext` (boolean, default: false)',
        '-  `close-atx` (boolean, default: false)',
        '-  `loose-table` (boolean, default: false)',
        '-  `spaced-table` (boolean, default: true)',
        '-  `reference-links` (boolean, default: false)',
        '-  `reference-footnotes` (boolean, default: true)',
        '-  `fences` (boolean, default: false)',
        '-  `bullet` ("-", "*", or "+", default: "-")',
        '-  `rule` ("-", "*", or "_", default: "*")',
        '-  `rule-repetition` (number, default: 3)',
        '-  `rule-spaces` (boolean, default: false)',
        '-  `strong` ("_", or "*", default: "*")',
        '-  `emphasis` ("_", or "*", default: "_")',
        '',
        'Settings are specified as follows:',
        '',
        '```',
        '$ ' + command + ' --option "some-option:some-value"',
        '# Multiple options:',
        '$ ' + command + ' --option "emphasis:*,strong:_"',
        '```'
    ].join('\n  ') + '\n';
}

/**
 * Transform a dash-cased string to camel-cased.
 *
 * @param {string} value
 * @return {string}
 */
function camelCase(value) {
    return value.toLowerCase().replace(/-([a-z])/gi, function ($0, $1) {
        return $1.toUpperCase();
    });
}

/*
 * Program.
 */

var index,
    expectOption,
    expectPlugin,
    expectOutput,
    expectAST,
    plugins,
    options,
    output,
    files;

plugins = [];

/**
 * Run the program.
 *
 * @param {string} value
 */
function program(value) {
    var doc,
        parser,
        local,
    fn;

    if (!value.length) {
        fail();
    } else {
        parser = mdast;

        plugins.forEach(function (plugin) {
            local = resolve(cwd, plugin);

            if (exists(local) || exists(local + '.js')) {
                fn = require(local);
            } else {
                try {
                    fn = require(resolve(cwd, 'node_modules', plugin));
                } catch (exception) {
                    fail(exception);
                }
            }

            parser = parser.use(fn);
        });

        doc = parser.parse(value, options);

        if (expectAST) {
            doc = JSON.stringify(doc, null, 2);
        } else {
            doc = mdast.stringify(doc, options);
        }

        if (output) {
            fs.writeFile(output, doc, function (exception) {
                if (exception) {
                    fail(exception);
                }
            });
        } else {
            process.stdout.write(doc);
        }
    }
}

if (
    argv.indexOf('--help') !== -1 ||
    argv.indexOf('-h') !== -1
) {
    console.log(help());
} else if (
    argv.indexOf('--version') !== -1 ||
    argv.indexOf('-v') !== -1
) {
    console.log(pack.version);
} else if (
    argv.indexOf('--options') !== -1
) {
    console.log(getOptions());
} else {
    index = argv.indexOf('--ast');

    if (index === -1) {
        index = argv.indexOf('-a');
    }

    if (index !== -1) {
        expectAST = true;
        argv.splice(index, 1);
    }

    files = [];
    options = {};

    argv.forEach(function (argument) {
        if (argument === '--option' || argument === '-O') {
            expectOption = true;
        } else if (argument === '--use' || argument === '-u') {
            expectPlugin = true;
        } else if (argument === '--output' || argument === '-o') {
            expectOutput = true;
        } else if (expectPlugin) {
            argument.split(',').forEach(function (plugin) {
                plugins.push(plugin);
            });

            expectPlugin = false;
        } else if (expectOutput) {
            output = argument;

            expectOutput = false;
        } else if (expectOption) {
            argument
                .split(',')
                .map(function (value) {
                    var values;

                    values = value.split(':');

                    return [
                        camelCase(values.shift().trim()),
                        values.join(':').trim()
                    ];
                })
                .map(function (values) {
                    var value;

                    value = values[1];

                    if (value === 'true') {
                        value = true;
                    } else if (value === 'false') {
                        value = false;
                    } else if (value === '') {
                        value = true;
                    } else if (Number(value) === Number(value)) {
                        value = Number(value);
                    }

                    values[1] = value;

                    return values;
                })
                .forEach(function (values) {
                    options[values[0]] = values[1];
                });

            expectOption = false;
        } else {
            files.push(argument);
        }
    });

    if (expectOption || expectPlugin || expectOutput) {
        fail();
    } else if (!expextPipeIn && !files.length) {
        if (output) {
            files.push(output);
        } else {
            fail();
        }
    } else if (
        (expextPipeIn && files.length) ||
        (!expextPipeIn && files.length !== 1)
    ) {
        fail('mdast currently expects one file.');
    }

    if (files[0]) {
        fs.readFile(files[0], function (exception, content) {
            if (exception) {
                fail(exception);
            }

            program(content.toString());
        });
    } else {
        process.stdin.resume();

        process.stdin.setEncoding('utf8');

        process.stdin.on('data', program);
    }
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';
const meow = require('meow');
const download = require('download');

const cli = meow(`
	Usage
	  $ download <url>
	  $ download <url> > <file>
	  $ download --out <directory> <url>

	Example
	  $ download http://foo.com/file.zip
	  $ download http://foo.com/cat.png > dog.png
	  $ download --extract --strip 1 --out dest http://foo.com/file.zip

	Options
	  -e, --extract         Try decompressing the file
	  -o, --out             Where to place the downloaded files
	  -s, --strip <number>  Strip leading paths from file names on extraction
	  --filename <string>   Name of the saved file
	  --proxy <string>      Proxy endpoint
`, {
	boolean: [
		'extract'
	],
	string: [
		'filename',
		'out',
		'proxy',
		'strip'
	],
	alias: {
		e: 'extract',
		o: 'out',
		s: 'strip'
	}
});

if (cli.input.length === 0) {
	console.error('Specify a URL');
	process.exit(1);
}

download(cli.input[0], cli.flags.out, cli.flags).pipe(process.stdout);
<commit_msg>Don't convert `strip` option to string (#1)<commit_after>#!/usr/bin/env node
'use strict';
const meow = require('meow');
const download = require('download');

const cli = meow(`
	Usage
	  $ download <url>
	  $ download <url> > <file>
	  $ download --out <directory> <url>

	Example
	  $ download http://foo.com/file.zip
	  $ download http://foo.com/cat.png > dog.png
	  $ download --extract --strip 1 --out dest http://foo.com/file.zip

	Options
	  -e, --extract         Try decompressing the file
	  -o, --out             Where to place the downloaded files
	  -s, --strip <number>  Strip leading paths from file names on extraction
	  --filename <string>   Name of the saved file
	  --proxy <string>      Proxy endpoint
`, {
	boolean: [
		'extract'
	],
	string: [
		'filename',
		'out',
		'proxy'
	],
	alias: {
		e: 'extract',
		o: 'out',
		s: 'strip'
	}
});

if (cli.input.length === 0) {
	console.error('Specify a URL');
	process.exit(1);
}

download(cli.input[0], cli.flags.out, cli.flags).pipe(process.stdout);
<|endoftext|>


<commit_before>function initLoadedPage_meslek_tetkik_islemleri() {
    loadCheckBoxList('lstTetkikler', 'idTetkik', 'tetkik', 'tetkikler');
        firebase.database().ref('Meslektetkikler').once('value').then(function (snapshot) {
            var rows = [];
            snapshot.forEach(function (element) {
                var cleanelement = JSON.parse(JSON.stringify(element));
                cleanelement['id'] = rows.length + 1;
                rows.push(cleanelement);
            });
        });
        $("#drpMeslek").change(function () {
            var meslekId=$("#drpMeslek").val();
            firebase.database().ref('Meslektetkikler').orderByChild('meslek').equalTo(meslekId).once('value').then(function (snapshot) {
                if(snapshot==null){
                    return;
                }

                $("input[type='checkbox']").prop("checked",false);

                snapshot.forEach(function (element) {
                    var cleanelement = JSON.parse(JSON.stringify(element));

                    $("#chkitem"+cleanelement.tetkik).prop("checked", true);
                });

                // $("#drpUygulamaTuru select").val(snapshot.val().uygulamaTuru);
                // $("#drpUygulamaTuru select[value='"+snapshot.val().uygulamaTuru +"']").attr("selected",true);
                //  $("#drpMeslek").val(snapsh  ot.val().uygulamaTuru ).find("option[value=" + snapshot.val().uygulamaTuru +"]").attr('selected', true);
                $('#myModal').modal('show');
            });
        });
        LoadDrop('drpMeslek','idMeslek','meslek','meslekler','');
        setHeader("Mesleğe Göre Tetkik Belirleme İşlemleri");
    }

function setEditTetkikMeslek(id) {

}

function kaydetMeslekTetkikBilgisi() {
    var d = new Date();
    var n = d.getTime()

    var meslek = $("#drpMeslek").val();
    var idMeslekTetkik = meslek.replace(/[^\x00-\x7F]/g, "") + n;

    $('#mt_TetkikListe input:checked').each(function() {
    var veri = {
        "idMeslekTetkik": idMeslekTetkik,
        "tetkik": this.value,
        "meslek":meslek,
        "kayitEden": firebase.auth().currentUser.providerData[0]["email"]
    }

    kaydetVeritabani("Meslektetkikler", idMeslekTetkik, veri);
});
    // clearAllFieldsTetkik()

}

function clearAllFieldsTetkik() {
    $("#hdnId").val('');
    $("#txtTetkik").val("");
    $("#txtFiyat").val('');
    $("#drpUygulamaTuru select").val("Seçiniz");
    $("#drpUygulamaTuru").val("Seçiniz").find("option[value=0]").attr('selected', true);
}<commit_msg>chekcboxx<commit_after>function initLoadedPage_meslek_tetkik_islemleri() {
    loadCheckBoxList('lstTetkikler', 'idTetkik', 'tetkik', 'tetkikler');
    firebase.database().ref('Meslektetkikler').once('value').then(function (snapshot) {
        var rows = [];
        snapshot.forEach(function (element) {
            var cleanelement = JSON.parse(JSON.stringify(element));
            cleanelement['id'] = rows.length + 1;
            rows.push(cleanelement);
        });
    });
    $("#drpMeslek").change(function () {
        var meslekId = $("#drpMeslek").val();
        firebase.database().ref('Meslektetkikler').orderByChild('meslek').equalTo(meslekId).once('value').then(function (snapshot) {
            if (snapshot == null) {
                return;
            }

            $("input[type='checkbox']").prop("checked", false);

            snapshot.forEach(function (element) {
                var cleanelement = JSON.parse(JSON.stringify(element));

                $("#chkitem" + cleanelement.tetkik).prop("checked", true);
            });

            // $("#drpUygulamaTuru select").val(snapshot.val().uygulamaTuru);
            // $("#drpUygulamaTuru select[value='"+snapshot.val().uygulamaTuru +"']").attr("selected",true);
            //  $("#drpMeslek").val(snapsh  ot.val().uygulamaTuru ).find("option[value=" + snapshot.val().uygulamaTuru +"]").attr('selected', true);
            $('#myModal').modal('show');
        });
    });
    LoadDrop('drpMeslek', 'idMeslek', 'meslek', 'meslekler', '');
    setHeader("Mesleğe Göre Tetkik Belirleme İşlemleri");
}

function setEditTetkikMeslek(id) {

}

function kaydetMeslekTetkikBilgisi() {
    var d = new Date();
    var n = d.getTime()

    var meslek = $("#drpMeslek").val();
    var idMeslekTetkik = meslek.replace(/[^\x00-\x7F]/g, "") + n;

    $('#mt_TetkikListe input[type="checkbox"]:checked').each(function () {
        var veri = {
            "idMeslekTetkik": idMeslekTetkik,
            "tetkik": this.value,
            "meslek": meslek,
            "kayitEden": firebase.auth().currentUser.providerData[0]["email"]
        }

        kaydetVeritabani("Meslektetkikler", idMeslekTetkik, veri);
    });
    // clearAllFieldsTetkik()

}

function clearAllFieldsTetkik() {
    $("#hdnId").val('');
    $("#txtTetkik").val("");
    $("#txtFiyat").val('');
    $("#drpUygulamaTuru select").val("Seçiniz");
    $("#drpUygulamaTuru").val("Seçiniz").find("option[value=0]").attr('selected', true);
}<|endoftext|>


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

var pkg = require('./package.json');
var ipaMetadata = require('./');
var meow = require('meow');

var Table = require('cli-table');
var _ = require('lodash');
var chalk = require('chalk');

var cli = meow({
  help: [
    'Example',
    '  ipa-metadata Facebook.ipa',
    '',
    '  ipa-metadata Facebook.ipa --verbose',
    '',
    '  ipa-metadata Facebook.ipa --verify',
    '  (verifies entitlements between `.app` bundle and `embedded.mobileprovision`)',
    '',
    '  => data displayed in a table'
  ].join('\n')
});

function format(value, compare) {
  if(!_.isPlainObject(value)) {
    return value;
  }

  var string = [];
  _.each(value, function(value, key) {
    var shouldCompareEquality = cli.flags.verify && compare;

    if(shouldCompareEquality && (key === 'keychain-access-groups')){
      return string.push(compareKeychainEntitlement(value, key, compare[key]), '\n');
    }

    if(shouldCompareEquality){
      var match = value === compare[key];
      var stringResult = chalk[match ? 'green' : 'red'](key + ': ' + format(value));
      return string.push(stringResult, '\n');
    }

    string.push(key, ': ', format(value), '\n');
  });
  string.pop();

  return string.join('');
}

function compareKeychainEntitlement(value, key, compare) {
  function splitKeychain(value) {
    return value[0].split('.')[0];
  }

  var match = splitKeychain(value) === splitKeychain(compare);
  return chalk[match ? 'green' : 'red'](key + ': ' + format(value));
}

function verboseFormatting(data){
  var types = Object.keys(data);

  _.each(types, function(type){
    var table = new Table();
    _.each(data[type], function(value, key){
      table.push([key, format(value)]) ;
    });

    console.log(table.toString());
  });
}

if(!cli.input[0]){
  return cli.showHelp();
}

ipaMetadata(cli.input[0], function(error, data){
  if(error){
    return console.log(error.message);
  }

  if(cli.flags.verbose){
    return verboseFormatting(data);
  }

  var types = {
    metadata: ['CFBundleDisplayName', 'CFBundleIdentifier', 'CFBundleShortVersionString', 'CFBundleVersion'],
    provisioning: ['Name', 'TeamIdentifier', 'TeamName', 'Entitlements']
  };

  var table = new Table();
  _.each(types, function(keys, type) {
    if(data[type]){
      _.each(keys, function(key) {
        var value = data[type][key];
        table.push([key, format(value, data.entitlements)]);
      });
    }
  });

  console.log(table.toString());
});
<commit_msg>Simplify CLI code for outputting comparison data<commit_after>#!/usr/bin/env node
'use strict';

var pkg = require('./package.json');
var ipaMetadata = require('./');
var meow = require('meow');

var Table = require('cli-table');
var _ = require('lodash');
var chalk = require('chalk');

var cli = meow({
  help: [
    'Example',
    '  ipa-metadata Facebook.ipa',
    '',
    '  ipa-metadata Facebook.ipa --verbose',
    '',
    '  ipa-metadata Facebook.ipa --verify',
    '  (verifies entitlements between `.app` bundle and `embedded.mobileprovision`)',
    '',
    '  => data displayed in a table'
  ].join('\n')
});

function format(value, compare) {
  if(!_.isPlainObject(value)) {
    return value;
  }

  var string = [];
  _.each(value, function(value, key) {
    var shouldCompareEquality = cli.flags.verify && compare;

    if(!shouldCompareEquality){
      return string.push(key, ': ', format(value), '\n');
    }

    if(key === 'keychain-access-groups'){
      return string.push(compareKeychainEntitlement(value, key, compare[key]), '\n');
    }

    return string.push(compareOutputString(value, compare[key], key), '\n');
  });
  string.pop();

  return string.join('');
}

function compareKeychainEntitlement(value, key, compare) {
  function splitKeychain(value) {
    return value[0].split('.')[0];
  }

  return compareOutputString(splitKeychain(value), splitKeychain(compare), key);
}

function compareOutputString(value, target, key) {
  var match = value === target;

  return chalk[match ? 'green' : 'red'](key + ': ' + format(value));
}

function verboseFormatting(data){
  var types = Object.keys(data);

  _.each(types, function(type){
    var table = new Table();
    _.each(data[type], function(value, key){
      table.push([key, format(value)]) ;
    });

    console.log(table.toString());
  });
}

if(!cli.input[0]){
  return cli.showHelp();
}

ipaMetadata(cli.input[0], function(error, data){
  if(error){
    return console.log(error.message);
  }

  if(cli.flags.verbose){
    return verboseFormatting(data);
  }

  var types = {
    metadata: ['CFBundleDisplayName', 'CFBundleIdentifier', 'CFBundleShortVersionString', 'CFBundleVersion'],
    provisioning: ['Name', 'TeamIdentifier', 'TeamName', 'Entitlements']
  };

  var table = new Table();
  _.each(types, function(keys, type) {
    if(data[type]){
      _.each(keys, function(key) {
        var value = data[type][key];
        table.push([key, format(value, data.entitlements)]);
      });
    }
  });

  console.log(table.toString());
});
<|endoftext|>


<commit_before>var RandomIdentifiers;

function getRandomId(randomStream)
{
   var index = randomStream.nextIntRange(RandomIdentifiers.length);
   var id = RandomIdentifiers[index];
   RandomIdentifiers.splice(index,1);
   return id;
}

function randomIntStatement(randomStream, variable)
{
  var ret = {};
  var constant = randomStream.nextIntRange(10);
  switch(randomStream.nextIntRange(5))
  {
    //add x + 1
    case 0:
      ret.value = variable.value + constant;
      ret.text = variable.text + " + " + constant.toString();
      break;
    //add 1 + x
    case 1:
      ret.value = variable.value + constant;
      ret.text = constant.toString() + " + " + variable.text;
      break;
    //mult c*x
    case 2:
      ret.value = variable.value * constant;
      ret.text = constant.toString() + " * " + variable.text;
      break;
    case 3:
      ret.value = variable.value * constant;
      ret.text = variable.text + " * " + constant.toString();
      break;
    case 4:
      ret.value = variable.value - constant;
      ret.text = variable.text + " - " + constant.toString();
      break;
    //add 1 + x
    case 5:
      ret.value =  constant - variable.value;
      ret.text =  constant.toString() + " - " + variable.text;
    break;
  }
  return ret;
}

function randomReturnFunc(randomStream, argument)
{
   RandomIdentifiers = ["foo","bar","baz","fiddle","faddle","bim","bam","quux","snork","snap"];
   var func = {};
   var id = getRandomId(randomStream);

   var variable = {};
   variable.text = getRandomId(randomStream);
   variable.value = argument.value;

   var ret = randomIntStatement(randomStream, variable);
   func.value = ret.value
   func.def = "def " + id + "(" + variable.text + "):\n"
                 + "\treturn " + ret.text + "\n\n";
   func.text = id + "(" + argument.text + ")";
   return func;
}

function getRandomVariable (randomStream)
{
  var variable = {};
  variable.text = getRandomId(randomStream);
  variable.value = randomStream.nextIntRange(10);
  return variable;
}

//function PythonProgramGenerator2FuncAndPrint(randomStream)
function pythonProgramOutputA(randomStream)
{
	var programString = '';
        var variable = {};
        variable.value = randomStream.nextIntRange(10);
        variable.text = variable.value.toString();
	var randomFunc1 = randomReturnFunc(randomStream,variable);
	var randomFunc2 = randomReturnFunc(randomStream, randomFunc1);

	programString = randomFunc1.def + randomFunc2.def +
	  "print " + randomFunc2.text + "";

  this.answerChoices = [ {value: randomFunc2.value, flag: true},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false} ]

      this.correctIndex = 0;

    randomStream.shuffle(this.answerChoices);

    for(var i=0; i<this.answerChoices.length; i++)

    {
         if(this.answerChoices[i].flag == true)
         this.correctIndex = i;
    }

    this.formatQuestion = function(format) {

        switch (format) {
            case "HTML": return this.formatQuestionHTML();
            }
            return "unknown format";
    };

    this.formatQuestionHTML = function () {
            var questionText = "
Output

" + programString + "
";

        questionText += "
a) "
                + this.answerChoices[0].value + "
b) "
                + this.answerChoices[1].value + "
c) "
                + this.answerChoices[2].value + "
d) "
                + this.answerChoices[3].value + "
";

        return questionText;
    };

    this.formatAnswer = function(format) {
        switch (format) {
            case "HTML": return this.formatAnswerHTML();
        }
        return "unknown format"; // TODO: consider exception
    };

    this.formatAnswerHTML = function () {
        var text = "";// String.fromCharCode(3); //0 = 'a', 1 = 'b', 2 = 'c', etc...
        return text;
    };

};

function pythonProgramOutputB(randomStream)
{
	var programString = '';
        var variable = {};
        variable.value = randomStream.nextIntRange(10);
        variable.text = variable.value.toString();
	var randomFunc1 = randomReturnFunc(randomStream,variable);
        variable.value = randomStream.nextIntRange(10);
        variable.text = variable.value.toString();
	var randomFunc2 = randomReturnFunc(randomStream, variable);

	programString = randomFunc1.def + randomFunc2.def +
	   randomFunc1.text + "\n" + randomFunc2.text + "\n";

  this.answerChoices = [ {value: "
"+randomFunc1.value.toString() +
            "\n" + randomFunc2.value.toString()+ "
", flag: true},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false} ]

      this.correctIndex = 0;

    randomStream.shuffle(this.answerChoices);

    for(var i=0; i<this.answerChoices.length; i++)

    {
         if(this.answerChoices[i].flag == true)
         this.correctIndex = i;
    }

    this.formatQuestion = function(format) {

        switch (format) {
            case "HTML": return this.formatQuestionHTML();
            }
            return "unknown format";
    };

    this.formatQuestionHTML = function () {
            var questionText = "
Output

" + programString + "
";

        questionText += "
a) "
                + this.answerChoices[0].value + "
b) "
                + this.answerChoices[1].value + "
c) "
                + this.answerChoices[2].value + "
d) "
                + this.answerChoices[3].value + "
";

        return questionText;
    };

    this.formatAnswer = function(format) {
        switch (format) {
            case "HTML": return this.formatAnswerHTML();
        }
        return "unknown format"; // TODO: consider exception
    };

    this.formatAnswerHTML = function () {
        var text = "";// String.fromCharCode(3); //0 = 'a', 1 = 'b', 2 = 'c', etc...
        return text;
    };

};

/*
function pythonProgramOutputC(randomStream)
{
	var programString = '';
        var variable1 = {};
	var variable2 = {};
        variable1.value = randomStream.nextIntRange(10);
        variable1.text = variable1.value.toString();
	variable2.value = randomStream.nextIntRange(10);
        variable2.text = variable2.value.toString();
	var randomFunc1 = randomIfFunc(randomStream,variable1, variable2);
	var variable;
        variable.value = randomStream.nextIntRange(10);
        variable.text = variable.value.toString();
	var randomFunc2 = randomReturnFunc(randomStream, variable);

	var assignment = assignment(randomStream,

	programString = randomFunc1.def + randomFunc2.def +
	   randomFunc1.text + "\n" + randomFunc2.text + "\n";

  this.answerChoices = [ {value: "
"+randomFunc1.value.toString() +
            "\n" + randomFunc2.value.toString()+ "
", flag: true},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false} ]

      this.correctIndex = 0;

    randomStream.shuffle(this.answerChoices);

    for(var i=0; i<this.answerChoices.length; i++)

    {
         if(this.answerChoices[i].flag == true)
         this.correctIndex = i;
    }

    this.formatQuestion = function(format) {

        switch (format) {
            case "HTML": return this.formatQuestionHTML();
            }
            return "unknown format";
    };

    this.formatQuestionHTML = function () {
            var questionText = "
Output

" + programString + "
";

        questionText += "
a) "
                + this.answerChoices[0].value + "
b) "
                + this.answerChoices[1].value + "
c) "
                + this.answerChoices[2].value + "
d) "
                + this.answerChoices[3].value + "
";

        return questionText;
    };

    this.formatAnswer = function(format) {
        switch (format) {
            case "HTML": return this.formatAnswerHTML();
        }
        return "unknown format"; // TODO: consider exception
    };

    this.formatAnswerHTML = function () {
        var text = "";// String.fromCharCode(3); //0 = 'a', 1 = 'b', 2 = 'c', etc...
        return text;
    };

};
*/

function pythonProgramOutput(randomStream)
{
  switch(randomStream.nextIntRange(2))
  {
    case 0:
      return new pythonProgramOutputA(randomStream)
    case 1:
      return new pythonProgramOutputB(randomStream)
  }
}
<commit_msg>fixed duplicate identifier names<commit_after>RandomIdentifiers =
   {
    one: ["foo","bar","baz","fiddle","faddle","bim","bam","quux","snork","snap"],
    two: ["squish","squash","smoot","spiffle","splin","squal","spork","smop","smick","smock"],
    three: ["a","b","c","d","e","moop","minx","mox","mole"]
  };

function getRandomId(randomStream, num)
{
   var id;
switch(num){
  case 0:
    var index = randomStream.nextIntRange(RandomIdentifiers.one.length);
    id = RandomIdentifiers.one[index];
    //RandomIdentifiers.one.splice(index,1);
    break;
  case 1:
    var index = randomStream.nextIntRange(RandomIdentifiers.two.length);
    id = RandomIdentifiers.two[index];
    //RandomIdentifiers.two.splice(index,1);
    break;
  case 2:
   var index = randomStream.nextIntRange(RandomIdentifiers.three.length);
    id = RandomIdentifiers.three[index];
    //RandomIdentifiers.two.splice(index,1);
    break;
  default:
    alert("hit default");
    break;
}
  alert(id);
   return id;
}

function randomIntStatement(randomStream, variable)
{
  var ret = {};
  var constant = randomStream.nextIntRange(10);
  switch(randomStream.nextIntRange(5))
  {
    //add x + 1
    case 0:
      ret.value = variable.value + constant;
      ret.text = variable.text + " + " + constant.toString();
      break;
    //add 1 + x
    case 1:
      ret.value = variable.value + constant;
      ret.text = constant.toString() + " + " + variable.text;
      break;
    //mult c*x
    case 2:
      ret.value = variable.value * constant;
      ret.text = constant.toString() + " * " + variable.text;
      break;
    case 3:
      ret.value = variable.value * constant;
      ret.text = variable.text + " * " + constant.toString();
      break;
    case 4:
      ret.value = variable.value - constant;
      ret.text = variable.text + " - " + constant.toString();
      break;
    //add 1 + x
    case 5:
      ret.value =  constant - variable.value;
      ret.text =  constant.toString() + " - " + variable.text;
    break;
  }
  return ret;
}

function randomReturnFunc(randomStream, argument, num)
{
   var func = {};
   var id = getRandomId(randomStream,num);

   var variable = {};
   variable.text = getRandomId(randomStream,2);
   variable.value = argument.value;

   var ret = randomIntStatement(randomStream, variable);
   func.value = ret.value
   func.def = "def " + id + "(" + variable.text + "):\n"
                 + "\treturn " + ret.text + "\n\n";
   func.text = id + "(" + argument.text + ")";
   return func;
}

function getRandomVariable (randomStream)
{
  var variable = {};
  variable.text = getRandomId(randomStream,2);
  variable.value = randomStream.nextIntRange(10);
  return variable;
}

//function PythonProgramGenerator2FuncAndPrint(randomStream)
function pythonProgramOutputA(randomStream)
{
	var programString = '';
        var variable = {};
        variable.value = randomStream.nextIntRange(10);
        variable.text = variable.value.toString();
	var randomFunc1 = randomReturnFunc(randomStream,variable,0);
	var randomFunc2 = randomReturnFunc(randomStream,randomFunc1,1);

	programString = randomFunc1.def + randomFunc2.def +
	  "print " + randomFunc2.text + "";

  this.answerChoices = [ {value: randomFunc2.value, flag: true},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false} ]

      this.correctIndex = 0;

    randomStream.shuffle(this.answerChoices);

    for(var i=0; i<this.answerChoices.length; i++)

    {
         if(this.answerChoices[i].flag == true)
         this.correctIndex = i;
    }

    this.formatQuestion = function(format) {

        switch (format) {
            case "HTML": return this.formatQuestionHTML();
            }
            return "unknown format";
    };

    this.formatQuestionHTML = function () {
            var questionText = "
Output

" + programString + "
";

        questionText += "
a) "
                + this.answerChoices[0].value + "
b) "
                + this.answerChoices[1].value + "
c) "
                + this.answerChoices[2].value + "
d) "
                + this.answerChoices[3].value + "
";

        return questionText;
    };

    this.formatAnswer = function(format) {
        switch (format) {
            case "HTML": return this.formatAnswerHTML();
        }
        return "unknown format"; // TODO: consider exception
    };

    this.formatAnswerHTML = function () {
        var text = "";// String.fromCharCode(3); //0 = 'a', 1 = 'b', 2 = 'c', etc...
        return text;
    };

};

function pythonProgramOutputB(randomStream)
{
	var programString = '';
        var variable = {};
        variable.value = randomStream.nextIntRange(10);
        variable.text = variable.value.toString();
	var randomFunc1 = randomReturnFunc(randomStream,variable,0);
        variable.value = randomStream.nextIntRange(10);
        variable.text = variable.value.toString();
	var randomFunc2 = randomReturnFunc(randomStream, variable,1);

	programString = randomFunc1.def + randomFunc2.def +
	   randomFunc1.text + "\n" + randomFunc2.text + "\n";

  this.answerChoices = [ {value: "
"+randomFunc1.value.toString() +
            "\n" + randomFunc2.value.toString()+ "
", flag: true},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false} ]

      this.correctIndex = 0;

    randomStream.shuffle(this.answerChoices);

    for(var i=0; i<this.answerChoices.length; i++)

    {
         if(this.answerChoices[i].flag == true)
         this.correctIndex = i;
    }

    this.formatQuestion = function(format) {

        switch (format) {
            case "HTML": return this.formatQuestionHTML();
            }
            return "unknown format";
    };

    this.formatQuestionHTML = function () {
            var questionText = "
Output

" + programString + "
";

        questionText += "
a) "
                + this.answerChoices[0].value + "
b) "
                + this.answerChoices[1].value + "
c) "
                + this.answerChoices[2].value + "
d) "
                + this.answerChoices[3].value + "
";

        return questionText;
    };

    this.formatAnswer = function(format) {
        switch (format) {
            case "HTML": return this.formatAnswerHTML();
        }
        return "unknown format"; // TODO: consider exception
    };

    this.formatAnswerHTML = function () {
        var text = "";// String.fromCharCode(3); //0 = 'a', 1 = 'b', 2 = 'c', etc...
        return text;
    };

};

/*
function pythonProgramOutputC(randomStream)
{
	var programString = '';
        var variable1 = {};
	var variable2 = {};
        variable1.value = randomStream.nextIntRange(10);
        variable1.text = variable1.value.toString();
	variable2.value = randomStream.nextIntRange(10);
        variable2.text = variable2.value.toString();
	var randomFunc1 = randomIfFunc(randomStream,variable1, variable2);
	var variable;
        variable.value = randomStream.nextIntRange(10);
        variable.text = variable.value.toString();
	var randomFunc2 = randomReturnFunc(randomStream, variable);

	var assignment = assignment(randomStream,

	programString = randomFunc1.def + randomFunc2.def +
	   randomFunc1.text + "\n" + randomFunc2.text + "\n";

  this.answerChoices = [ {value: "
"+randomFunc1.value.toString() +
            "\n" + randomFunc2.value.toString()+ "
", flag: true},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false},
      {value: (randomStream.nextIntRange(50)).toString(),
	flag: false} ]

      this.correctIndex = 0;

    randomStream.shuffle(this.answerChoices);

    for(var i=0; i<this.answerChoices.length; i++)

    {
         if(this.answerChoices[i].flag == true)
         this.correctIndex = i;
    }

    this.formatQuestion = function(format) {

        switch (format) {
            case "HTML": return this.formatQuestionHTML();
            }
            return "unknown format";
    };

    this.formatQuestionHTML = function () {
            var questionText = "
Output

" + programString + "
";

        questionText += "
a) "
                + this.answerChoices[0].value + "
b) "
                + this.answerChoices[1].value + "
c) "
                + this.answerChoices[2].value + "
d) "
                + this.answerChoices[3].value + "
";

        return questionText;
    };

    this.formatAnswer = function(format) {
        switch (format) {
            case "HTML": return this.formatAnswerHTML();
        }
        return "unknown format"; // TODO: consider exception
    };

    this.formatAnswerHTML = function () {
        var text = "";// String.fromCharCode(3); //0 = 'a', 1 = 'b', 2 = 'c', etc...
        return text;
    };

};
*/

function pythonProgramOutput(randomStream)
{
  switch(randomStream.nextIntRange(2))
  {
    case 0:
      return new pythonProgramOutputA(randomStream)
    case 1:
      return new pythonProgramOutputB(randomStream)
  }
}
<|endoftext|>


<commit_before>import { existsSync, readFileSync } from 'node:fs'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { log } from '@serverless/utils/log.js'
import OfflineEndpoint from './OfflineEndpoint.js'

const { keys } = Object

const __dirname = dirname(fileURLToPath(import.meta.url))

function readFile(filePath) {
  return readFileSync(filePath, 'utf8')
}

// velocity template defaults
const defaultRequestTemplate = readFile(
  resolve(__dirname, './templates/offline-default.req.vm'),
)
const defaultResponseTemplate = readFile(
  resolve(__dirname, './templates/offline-default.res.vm'),
)

function getResponseContentType(fep) {
  if (fep.response && fep.response.headers['Content-Type']) {
    return fep.response.headers['Content-Type'].replace(/'/gm, '')
  }

  return 'application/json'
}

export default class Endpoint {
  #handlerPath = null

  #http = null

  constructor(handlerPath, http) {
    this.#handlerPath = handlerPath
    this.#http = http

    // TODO FIXME
    // eslint-disable-next-line no-constructor-return
    return this.#generate()
  }

  // determine whether we have function level overrides for velocity templates
  // if not we will use defaults
  #setVmTemplates(fullEndpoint) {
    // determine requestTemplate
    // first check if requestTemplate is set through serverless
    const fep = fullEndpoint

    try {
      // determine request template override
      const reqFilename = `${this.#handlerPath}.req.vm`

      // check if serverless framework populates the object itself
      if (
        typeof this.#http.request === 'object' &&
        typeof this.#http.request.template === 'object'
      ) {
        const templatesConfig = this.#http.request.template

        keys(templatesConfig).forEach((key) => {
          fep.requestTemplates[key] = templatesConfig[key]
        })
      }
      // load request template if exists if not use default from serverless offline
      else if (existsSync(reqFilename)) {
        fep.requestTemplates['application/json'] = readFile(reqFilename)
      } else {
        fep.requestTemplates['application/json'] = defaultRequestTemplate
      }

      // determine response template
      const resFilename = `${this.#handlerPath}.res.vm`

      fep.responseContentType = getResponseContentType(fep)
      log.debug('Response Content-Type ', fep.responseContentType)

      // load response template from http response template, or load file if exists other use default
      if (fep.response && fep.response.template) {
        fep.responses.default.responseTemplates[fep.responseContentType] =
          fep.response.template
      } else if (existsSync(resFilename)) {
        fep.responses.default.responseTemplates[fep.responseContentType] =
          readFile(resFilename)
      } else {
        fep.responses.default.responseTemplates[fep.responseContentType] =
          defaultResponseTemplate
      }
    } catch (err) {
      log.debug(`Error: ${err}`)
    }

    return fep
  }

  // loosely based on:
  // https://github.com/serverless/serverless/blob/v1.59.2/lib/plugins/aws/package/compile/events/apiGateway/lib/validate.js#L380
  #getIntegration(http) {
    const { integration, async: isAsync } = http
    if (integration) {
      const normalizedIntegration = integration.toUpperCase().replace('-', '_')
      if (normalizedIntegration === 'LAMBDA') {
        return 'AWS'
      }
      if (normalizedIntegration === 'LAMBDA_PROXY') {
        return 'AWS_PROXY'
      }
      return normalizedIntegration
    }

    if (isAsync) {
      return 'AWS'
    }

    return 'AWS_PROXY'
  }

  // return fully generated Endpoint
  #generate() {
    const offlineEndpoint = new OfflineEndpoint()

    const fullEndpoint = {
      ...offlineEndpoint,
      ...this.#http,
    }

    fullEndpoint.integration = this.#getIntegration(this.#http)

    if (fullEndpoint.integration === 'AWS') {
      // determine request and response templates or use defaults
      return this.#setVmTemplates(fullEndpoint)
    }

    return fullEndpoint
  }
}
<commit_msg>refactor: remove readfile function<commit_after>import { existsSync, readFileSync } from 'node:fs'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { log } from '@serverless/utils/log.js'
import OfflineEndpoint from './OfflineEndpoint.js'

const { keys } = Object

const __dirname = dirname(fileURLToPath(import.meta.url))

// velocity template defaults
const defaultRequestTemplate = readFileSync(
  resolve(__dirname, './templates/offline-default.req.vm'),
  'utf8',
)
const defaultResponseTemplate = readFileSync(
  resolve(__dirname, './templates/offline-default.res.vm'),
  'utf8',
)

function getResponseContentType(fep) {
  if (fep.response && fep.response.headers['Content-Type']) {
    return fep.response.headers['Content-Type'].replace(/'/gm, '')
  }

  return 'application/json'
}

export default class Endpoint {
  #handlerPath = null

  #http = null

  constructor(handlerPath, http) {
    this.#handlerPath = handlerPath
    this.#http = http

    // TODO FIXME
    // eslint-disable-next-line no-constructor-return
    return this.#generate()
  }

  // determine whether we have function level overrides for velocity templates
  // if not we will use defaults
  #setVmTemplates(fullEndpoint) {
    // determine requestTemplate
    // first check if requestTemplate is set through serverless
    const fep = fullEndpoint

    try {
      // determine request template override
      const reqFilename = `${this.#handlerPath}.req.vm`

      // check if serverless framework populates the object itself
      if (
        typeof this.#http.request === 'object' &&
        typeof this.#http.request.template === 'object'
      ) {
        const templatesConfig = this.#http.request.template

        keys(templatesConfig).forEach((key) => {
          fep.requestTemplates[key] = templatesConfig[key]
        })
      }
      // load request template if exists if not use default from serverless offline
      else if (existsSync(reqFilename)) {
        fep.requestTemplates['application/json'] = readFileSync(
          reqFilename,
          'utf8',
        )
      } else {
        fep.requestTemplates['application/json'] = defaultRequestTemplate
      }

      // determine response template
      const resFilename = `${this.#handlerPath}.res.vm`

      fep.responseContentType = getResponseContentType(fep)
      log.debug('Response Content-Type ', fep.responseContentType)

      // load response template from http response template, or load file if exists other use default
      if (fep.response && fep.response.template) {
        fep.responses.default.responseTemplates[fep.responseContentType] =
          fep.response.template
      } else if (existsSync(resFilename)) {
        fep.responses.default.responseTemplates[fep.responseContentType] =
          readFileSync(resFilename, 'utf8')
      } else {
        fep.responses.default.responseTemplates[fep.responseContentType] =
          defaultResponseTemplate
      }
    } catch (err) {
      log.debug(`Error: ${err}`)
    }

    return fep
  }

  // loosely based on:
  // https://github.com/serverless/serverless/blob/v1.59.2/lib/plugins/aws/package/compile/events/apiGateway/lib/validate.js#L380
  #getIntegration(http) {
    const { integration, async: isAsync } = http
    if (integration) {
      const normalizedIntegration = integration.toUpperCase().replace('-', '_')
      if (normalizedIntegration === 'LAMBDA') {
        return 'AWS'
      }
      if (normalizedIntegration === 'LAMBDA_PROXY') {
        return 'AWS_PROXY'
      }
      return normalizedIntegration
    }

    if (isAsync) {
      return 'AWS'
    }

    return 'AWS_PROXY'
  }

  // return fully generated Endpoint
  #generate() {
    const offlineEndpoint = new OfflineEndpoint()

    const fullEndpoint = {
      ...offlineEndpoint,
      ...this.#http,
    }

    fullEndpoint.integration = this.#getIntegration(this.#http)

    if (fullEndpoint.integration === 'AWS') {
      // determine request and response templates or use defaults
      return this.#setVmTemplates(fullEndpoint)
    }

    return fullEndpoint
  }
}
<|endoftext|>