'_initCommand': function() {
     var self = this;
     var commands = [
         {
             'value': 'list-droplets',
             'description': 'List active droplets',
             'action': function() {
                 self.listDroplets();
             }
         },
         {
             'value': 'destroy-droplet <id>',
             'description': 'Destroy droplet with specified ID',
             'action': function(id) {
                 self.api.dropletDestroy(id, function(err, result) {
                     if (err) {
                         throw err;
                     }
                     self._log('info', 'Destroyed droplet', result);
                 });
             }
         }
     ];
     commander.version(this._package.version);
     commander.description(this._package.description);
     _.each(commands, function(command) {
         commander.command(command.value).description(command.description).action(command.action);
     });
     commander.parse(process.argv);
 },
Example #2
0
File: jam.js Project: blackjk3/jam
  cli: function() {
        var program = require('commander');

        program
          .description('Generates new projects, views, models, etc.  Makes build web apps not so damn hard!@')
    
          .option('new, --new <name>', 'Generates a new project.')
          .option('g, --generate <framework>:<type> <name>', 'Generates a new model or view.')
          .option('bundle, --bundle', 'Updates dependencies based on package.json file.')
          .option('add, --add', 'Adds a dependency into the current directory.')
          .option('-m, --minified', 'Flag to get minified version when adding.')
          .option('-v, --ver <version>', 'Flag to get a specific version when adding.')
          .parse(process.argv);
        
        if ( process.argv.length === 2 ) {
            sys.puts('Try running --help for all the options.');
        }
        else {
          
          if ( program.new ) {
            commands.newProject( program.new );
          }
          else if ( program.generate ) {
            if ( program.generate === 'view' ) {
              commands.newView( program.args[0] );
            } else if ( program.generate === 'model' ) {
              commands.newModel( program.args[0] );
            }
          }
          else if ( program.watch ) {
            watchProject();
          }
          else if ( program.bundle ) {
            bundler.bundle();
          }
          else if ( program.add ) {
            
            var optPath = '',
                min = program.minified ?  true : false,
                version = program.ver ? program.ver : false;
            
            bundler.onRails().then(function( rails ) {
              if ( rails ) {
                program.confirm('Detected rails. Do you want to put file in vendor/assets/javascripts? ', function( ok ) {
                  
                  if ( ok ) {
                    optPath = 'vendor/assets/javascripts/';
                  }

                  bundler.add( program.args[0], min, optPath, version );
                  process.stdin.destroy();
                });
              } else {
                bundler.add( program.args[0], min, '', version );
              }
            });
          }
        }
    }
Example #3
0
function main() {
    program
        .description('Start a partition heal coordinated by the coordinator node')
        .option('--tchannel-v1')
        .option('--tries <tries>', 'Number of times to try the heal', safeParseInt, 10)
        .usage('[options] <discoveryUri>');
    program.parse(process.argv);

    var discoveryUri = program.args[0];

    if (!discoveryUri) {
        console.error(getTime(), 'Error: discoveryUri is required');
        process.exit(1);
    }

    var clusterManager = new ClusterManager({
        useTChannelV1: program.tchannelV1,
        discoveryUri: discoveryUri
    });

    function executeHeal(tries) {
        if (tries <= 0) {
            console.error(getTime(), 'unable to heal partitions after multiple retries');
            process.exit(2);
        }

        clusterManager.heal(function onHeal(err, resp) {
            // assert that there is no error, quit if there is an error.
            assertNoError(err);

            if (!resp) {
                console.error(getTime(), 'did not receive a response during heal.');
                process.exit(3);
            }

            var targets = resp.targets || [];
            if (targets.length === 0) {
                console.log(getTime(), 'No known partitions left');
                // graceful exit
                return process.exit(0);
            }

            console.log(getTime(), 'Executed heal to', targets.length, 'targets');
            targets.forEach(function (target) {
                console.log(getTime(), ' - ' + target);
            });

            setTimeout(executeHeal, 1000, tries - 1);
            return;
        });
    }

    executeHeal(program.tries);

}
Example #4
0
me.setup = function() {
    program
        .description('reads the schema of a db and creates a json-schema')
        .option('-c, --config [value]', 'db-config file')
        .option('-o, --output [value]', 'output filename')
        .option('-s, --silent', 'no console output')
        .option('-f, --force', 'override file if existing')
        .option('-d, --dry-run', 'don\'t create files')
        .option('-D, --debug', 'print error object')
        .option('-T, --trace', 'print stacktrace')
        .version('0.0.1');
    winston.cli();
};
Example #5
0
module.exports = function parseArgs() {
    var program = require('commander');
    program.description('Run an example')
        .option('-n, --clusterName <name>', 'Name of cluster')
        .option('-s, --size <size>', 'Size of cluster')
        .option('-b, --bootstrap <bootstrap>', 'JSON compatible array of hosts')
        .option('-p, --port <port>', 'Base port for cluster')
        .option('-h, --host <host>', 'Address of host')
        .option('[options] example.js')
    program.parse(process.argv);
    return {
        name: program.clusterName,
        size: Number(program.size),
        bootstrapNodes: safeParse(program.bootstrap),
        basePort: Number(program.port),
        host: program.host
    };
};
Example #6
0
        function(config, callback) {
            program
                .description('Use this command to generate a license file.')
                .version(packageInfo.version)
                .option('-a, --author <author>', 'Your name.', config.author || '')
                .option('-y, --year <year>', 'Year used in your license.', new Date().getFullYear())
                .option('-p, --project <project>', 'Project\'s name', packageInfo.name)
                .parse(process.argv);

            var configCli = {}

            if(program.author) configCli.author = program.author
            if(program.year) configCli.year = program.year
            if(program.project) configCli.project = program.project

            config = _.extend(config, configCli)

            var remainArgs = program.args;

            callback(null, config, remainArgs);
        }
Example #7
0
function main() {
    program
        .description('Lookup a key in the ring')
        .option('-k --key <key>', 'Key to lookup')
        .option('--tchannel-v1')
        .usage('[options] <discoveryUri>');
    program.parse(process.argv);

    var discoveryUri = program.args[0];

    if (!discoveryUri) {
        console.error('Error: discoveryUri is required');
        process.exit(1);
    }

    if (!program.key) {
        console.error('Error: key is required');
        process.exit(1);
    }

    var clusterManager = new ClusterManager({
        useTChannelV1: program.tchannelV1,
        discoveryUri: discoveryUri
    });
    clusterManager.lookup(program.key, function onLookup(err, res) {
        if (err) {
            console.error('Error: ' + err.message);
            process.exit(1);
        }

        if (clusterManager.getPartitionCount() > 1) {
            console.error('Error: cluster is partitioned. An consistent lookup cannot be provided.');
            process.exit(1);
        }

        console.log(res.dest);
        clusterManager.printConnectionErrorMsg();
        process.exit();
    });
}
Example #8
0
#!/usr/bin/env node
var fs = require('fs');
var program = require('commander');

var html2csv = require('../lib/html2csv');

program
  .description('Read HTML and creates one CSV file for every table')
  .action(toCSV);

program.parse(process.argv);

// Actions ---------------------------------

function toCSV(filename) {
  var html = fs.readFileSync(filename).toString().trim();

  html2csv.htmlToCSVs(html, function(err, csvs) {
    if (err) return console.error(err);

    csvs.forEach(function (csv, i) {
      fs.writeFileSync(pad2(i + 1) + '.csv', csv);
    });
  });
}

function pad2(number) {
   return (number < 10 ? '0' : '') + number
}
#!/usr/bin/env node --harmony
var program = require('commander');
var chalk = require('chalk');

// Returns a hash of configuration values.
const configData = require('./lib/config').configData;
// Performs the create-list operation.
const Portfolio = require('./lib/portfolio');

program
  .description('Create a list of JIRA issues from a YAML command file.')
  .arguments('<file>')
  .usage('[options] p <file>')
  .option('-h, --host <host>', "The host name of the JIRA instance.")
  .option('--port <port>', "The port for the JIRA instance connection.")
  .option('-u, --username <username>', "The JIRA user's username.")
  .option('-p, --password <password>', "The JIRA user's password.")
  .option('-v, --verbose', "Log lots of extra details.")
  .option('-s, --silent', "Don't log anything unless there is an error.")
  .action(function (file) {
    try {
      var portfolio = new Portfolio(configData(program))
      portfolio.process(file);
    } catch (e) {
      console.log(chalk.bold.red(e));
    }
  })
  .parse(process.argv);
#!/usr/bin/env node

var app = require("commander");
var opn = require("opn");
var Configstore = require("configstore");
var conf = new Configstore("wunderline", { platform: "web" });

app.description("Opens Wunderlist").parse(process.argv);

if (conf.get("platform") === "mac") {
  opn("wunderlist://");
  process.exit();
} else {
  opn("https://www.wunderlist.com/#/lists/inbox");
  process.exit();
}
#!/usr/bin/env node

const program = require('commander');

const readImageLocalFileSync = require('itk/readImageLocalFileSync');
const writeImageLocalFileSync = require('itk/writeImageLocalFileSync');

program
  .description('Convert images files from one format to another.')
  .arguments('<inputFile> <outputFile>')
  .parse(process.argv);

if (program.args.length < 2) {
  console.error('Please pass in both the input and output image file paths.');
  process.exit(1);
}

const inputFile = program.args[0]
const outputFile = program.args[1]

try {
  const image = readImageLocalFileSync(inputFile);
  const useCompression = true;
  writeImageLocalFileSync(useCompression, image, outputFile);
} catch (error) {
  console.error('Error during conversion:\n');
  console.error(error);
}
Example #12
0
#!/usr/bin/env node

var util = require('util');
var fs = require('fs');
var path = require('path');
var commander = require('commander');
var chalk = require('chalk');
var Program = require("./Program");
var Settings = require("./Settings");
var pjson = require('./package.json');
var readlineSync = require('readline-sync');

commander
  .description(chalk.yellow("Create/modify user and project level configurations."))
  .usage("[options]")
  .option('-s, --show', 
          'Show what settings are currently being used.')
  .option('-l, --change-local', 
          'Change (or create) the ' + chalk.bold('local') + ' config file to customise behaviour ' + chalk.bold('in this project') + '.')
  .option('-g, --change-global', 
          'Change (or create) the ' + chalk.bold('global') + ' config file to customise behaviour ' + chalk.bold('for all projects') + '.');
  
process.argv[1] = 'smelt config';
commander.parse(process.argv);  

Settings.ReadConfigs();

var doSomething = false;

if(commander.show)
{
Example #13
0
#!/usr/bin/env node
var program = require('commander');
var fs = require("fs");
var each = require("lodash/collection/each");
var keys = require("lodash/object/keys");
var pkg = require("../package.json");

program.option("-o, --out-file [out]", "Compile into a single file");
program.description(pkg.description);
program.version(pkg.version);
program.usage("[options] <file>");
program.parse(process.argv);

var errors = [],
  filenames = program.args;

if(filenames.length === 0) {
  errors.push('File name is required.');
}
each(filenames, function (filename) {
  if (!fs.existsSync(filename)) {
    errors.push(filename + ' doesn\'t exist');
  }
});

if(! program.outFile) {
  program.outFile = 'output.js';
}

if (errors.length) {
  console.error(errors.join(". "));
Example #14
0
#!/usr/bin/env node

var util = require('util');
var commander = require('commander');
var chalk = require('chalk');
var Settings = require("./Settings");
var pjson = require('./package.json');
var BangCommandHelper = require("./BangCommandHelper");

commander
  .description(chalk.yellow("Manage plugins."))
  .usage("[options]")
  .option('--list', 
          'List all available plugins.');
  
process.argv[1] = 'smelt plugins';
commander.parse(process.argv);  

Settings.ReadConfigs();

var doSomething = false;

if(commander.list)
{
    doSomething = true;
    var plugins = BangCommandHelper.GetAllPlugins();

    if(plugins.length > 0)
    {
        console.log(chalk.yellow("\nThe following plugins were found:"));
        plugins.forEach(function(plugin)
Example #15
0
import program from 'commander';
import chalk from 'chalk';
import Generate from '../tasks/generate';
import getMernConfig from '../tasks/getMernConfig';

program
    .description('Generate components, routes, controllers, models using mern generator')
    .arguments('<generator> [args]')
    .parse(process.argv);

/**
 * Generate string output for a single blueprint
 * @param blueprint
 */
const printBlueprint = blueprint => {
    console.log(`    ${chalk.yellow(blueprint.name)} - ${blueprint.description}`);
    console.log(`    Usage: ${blueprint.usage}`);
    console.log('');
};

program.on('--help', () => {
    // Get available blueprints from the current mern project
    const blueprints = getMernConfig().blueprints;
    console.log(chalk.yellow('Available Generators'));
    console.log(chalk.yellow('____________________'));
    console.log('');

    blueprints.forEach(b => printBlueprint(b));
});

if (!program.args.length) {
Example #16
0
const commander = require('commander'),
    program = require('../package.json'),
    fs = require('fs'),
    detect = require('./detect.js');

commander
  .description('Verify proxy list')
  .usage('--input <file ...> --output <file ...>')
  .version(program.version)
  .option('-i, --input <path>', 'proxy list txt file')
  .option('-o, --output <path>', 'verified proxy list')
  .option('-c, --concurrency <concurrency>', 'concurrency, default 10')
  .option('-t, --timeout <n>', 'timeout(s), default 10s')
  .option('-s, --socks5', 'default socks5,if ignore protocol')
  .parse(process.argv);


if (commander.socks5) {
    detect.enable_socks5();
}

if(commander.timeout) {
    detect.timeout(commander.timeout);
}

if (commander.input && !fs.existsSync(commander.input)) {
    console.error(commander.input+' not exists');
    process.exit(1);
}

var stream;
#!/usr/bin/env node

import cmdline from 'commander'
import findUpSync from 'findup-sync'
import sysexits from 'sysexits'
import DNSMEDDNSUpdater from '../index.js'

const packageInfo = require(findUpSync('package.json', {cwd:__dirname}))

cmdline
  .description('Keeps DNS Made Easy dynamic DNS records up-to-date')
  .version(packageInfo.version)
  .option('--username [username]', 'DNS Made Easy username (required)')
  .option('--record-id [recordId]', 'Record identifier (required)')
  .option('--password [password]', 'Record password (required)')
  .option('--check-interval [checkInterval]', 'Seconds between public IP checks', parseInt)
  .parse(process.argv)

const {username, recordId, password, checkInterval} = cmdline

if (username === undefined || recordId === undefined || password === undefined) {
  cmdline.outputHelp()
  process.exit(sysexits.USAGE)
}

const updater = new DNSMEDDNSUpdater({username, recordId, password, checkInterval})
updater
  .on('change', ip => warn(`public IP change: ${ip}`))
  .on('error', err => warn((err && err.message) || err))

info(`starting`)
Example #18
0
#!/usr/bin/env node

var app = require('commander')
var async = require('async')
var fuzzysearch = require('fuzzysearch')
var inquirer = require('inquirer')

var getLists = require('./lib/get-lists')
var auth = require('./lib/auth')
var updateTask = require('./lib/update-task')

app
  .description('Mark a task as done')
  .usage('[task]')
  .parse(process.argv)

function complete (id, callback) {
  updateTask(id, {completed: true}, callback)
}

function match (terms, tasks) {
  return tasks.filter(function (task) {
    return terms.find(function (term) {
      return fuzzysearch(term.toLowerCase(), task.title.toLowerCase())
    })
  })
}

function main () {
  getLists(function (error, lists) {
    if (error) {
Example #19
0
#!/usr/bin/env node
var program  = require('commander');
var  _ = require('lodash');
var nc = require('ncurses');

var utils = require('./lib/utils');
var gui = require('./lib/gui.js');
var streamapi = require('./lib/streamapi.js');


program
  .description('Search for shows by title')
  .parse(process.argv);


var searchString = "";

var isRight = false;
var rowPos = 0;
var linkPos = 0;



gui.w.on('inputChar', function(letter,key_code, is_key) {

	if(key_code === 10){
		var movie = curResults[rowPos -1];
		if(movie){
			var link = SelectedLink(linkPos);
			utils.openLink(movie.links[link]);
		}
Example #20
0
#!/usr/bin/env node
var path = require('path')
var program = require('commander')
var hg = require('../lib/main')

if (!hg.getTaskFile()) {
  hg.setTaskFile(path.join(process.env.HOME, '.hourglass'))
}

program
  .description('A CLI time management tool that runs on NodeJS.')
  .option('-t --task-file <path>', 'set task file, default $HOURGLASS_TASKS or ~/.hourglass',
          hg.setTaskFile)

program
  .command('init')
  .description('create an initial task file')
  .action(hg.init)

program
  .command('set <task> <time>')
  .alias('edit')
  .description('manually set the amount of time needed for an task')
  .action(hg.setTask)

program
  .command('remove <task>')
  .alias('delete')
  .description('remove all data for the given task')
  .action(hg.removeTask)
Example #21
0
/**
 * Module dependencies.
 */

const program = require('commander');
const settings = require('./docsmith/utils/settings').config;
const spawn = require('child_process').spawn;
const path = require('path');
const fs = require('fs');

let component;

const id = x => x;

program
  .description('Builds or serves the current content')
  .option('-f, --force', 'Initialise whether the current directory is empty or not.', id, false)
  .option('-s, --serve', 'Serves')
  .option('-w, --watch', 'Serves and watches')
  .option('-r, --reload', 'Live reload')
  .option('-v, --validate', 'Validate links')
  .option('-c, --config <config>', 'Specify configuration file')
  .option('-d, --destination <directory>', 'Specify build destination')
  .arguments('[component] [options]')
  .action(function(comp) {
    component = comp;
  })
  .parse(process.argv);

if (!program.force) {
  console.log('EXPERIMENTAL -  This is probably not working. Use --force to bypass this warning.');
Example #22
0
var app = require('commander')
var inquirer = require('inquirer')
var request = require('request')
var Configstore = require('configstore')
var conf = new Configstore('wunderline')
var wrap = require('wordwrap')(80)

app
  .description('Authenticate Wunderline')
  .parse(process.argv)

var questions = [
  {
    name: 'client_id',
    message: 'CLIENT ID',
    validate: function (input) {
      return input.length > 0
    }
  },
  {
    name: 'access_token',
    message: 'ACCESS TOKEN',
    validate: function (input) {
      return input.length > 0
    }
  }
]

console.log(wrap('Please create a Wunderlist Application before you proceed, you can do so over here: https://developer.wunderlist.com/apps/new, once that is done please enter your access token and client id below.'))

inquirer.prompt(questions).then(function (answers) {
Example #23
0
    'Enhancement': {
        'cost': 'cost',
        'forceIcons': 'forceIcons',
        'resourceValue': 'resourceValue'
    },
    'Event': {
        'cost': 'cost',
        'forceIcons': 'forceIcons'
    },
    'Fate': {
        'forceIcons': 'forceIcons',
        'edgePriorityNumber': 'edgePriorityNumber'
    }
};

program
    .description('Parses Star Wars LCG Octgn set XMLs into JSON.')
    .option('-p, --path <path>', 'The path to the OCTGN sets directory. These can be downloaded from https://github.com/db0/Star-Wars-LCG-OCTGN/tree/master/o8g/Sets')
    .parse(process.argv);

let
    xmlParser = new xml2js.Parser(),
    files = glob.sync(path.resolve(process.cwd(), program.path, '**/set.xml')),
    cards = [];

when.all(_.map(files, (file) => {
    return when.promise((resolve, reject) => {
        let
            xml = fs.readFileSync(file);

        xmlParser.parseString(xml, (error, result) => {
            let
Example #24
0
#!/usr/bin/env node

var path = require( 'path' );
var shell = require( 'shelljs' );
var fs = require( 'fs' );
var program = require( 'commander' );

var lzUtil = require( 'lz-node-utils' );
var fromLib = lzUtil.getReqFn( 'lib' );
var snips = fromLib( 'snips' );

var defaultConfig = path.join( __dirname, '../config/default-settings.js' );
var snipConfig = path.join( snips.dir, 'settings.js' );

program
	.description( 'Initializes a settings.js file in your snippets directory for customization.' )
	.option( '-r, --rm', 'remove your settings.js, if it exists' )
	.option( '-e, --edit', 'edit the file before the process exits' )
	.parse( process.argv );

var exists = fs.existsSync( snipConfig );
if ( exists && program.rm ) {
	snips.logger.user( 'Removing settings file %s.'.green, snipConfig.blue );
	shell.rm( snipConfig );
	exists = false;
}

if ( !exists ) {
	snips.logger.user( 'Initializing settings file.'.green );
	shell.cp( defaultConfig, snipConfig );
}
Example #25
0
#!/usr/bin/env node

var app = require('commander')
var async = require('async')
var api = require('./lib/api')
var auth = require('./lib/auth')

app
  .description('Export your data')
  .option('--pretty', 'Pretty print output')
  .parse(process.argv)

function showProgress () {
  process.stderr.write('.')
}

function getUser (callback) {
  api('/user', function (err, res, body) {
    if (err) process.exit(1)

    showProgress()
    callback(null, {user: body})
  })
}

function getLists (callback) {
  api('/lists', function (err, res, body) {
    if (err) process.exit(1)

    showProgress()
    callback(null, {lists: body})
'use strict';

var fs = require('fs');
var util = require('util');

var command = require('commander');
var config = require('config');
var moment = require('moment');
var nodemailer = require('nodemailer');
var tar = require('tar-fs');

var helper = require('./helper');

command
  .description('Create tarballs from Github snapshots')
  .option('-d, --dir [directory]', 'snapshot directory to archive')
  .parse(process.argv);

var log = helper.logger('github-archive', config.get('log.dir'),
  config.get('log.level'), config.get('log.retention'));

/**
 * Alert that a failure occured by sending an email to a number of recipients
 */
var alert = function(recipients, sender, snapshot, archive, done) {
  log.debug('Sending alert email to', recipients);

  nodemailer.createTransport().sendMail({
    from: sender,
    to: recipients.join(','),
    subject: 'GHE Snapshot Archiving Failed!',
Example #27
0
    console.log('registering ' + email)
    operations.signUp({
      email: email,
      password: password
    }, function (error2, user) {
      cli.exitIfError(error2)
      console.log(user)
      /* eslint no-process-exit:0 */
      process.exit()
    })
  })
}

function keyMW (options) {
  operations.createKey(options, function (error, key) {
    cli.exitIfError(error)
    console.log(key)
    process.exit()
  })
}

program.description('operate on user records')
program.command('sign-up <email>')
  .description('register a new user account').action(signUp)

var keyStack = cli.command(
  program, 'create-key', 'create an authentication key for CLI/API access')
cli.signInMW(keyStack).use(keyMW)

program.parse(process.argv)
Example #28
0
#!/usr/bin/env node

var app = require('commander')
var auth = require('./lib/auth')
var async = require('async')
var api = require('./lib/api')
var printList = require('./lib/print-list')
var getInbox = require('./lib/get-inbox')

app
  .description('View your inbox')
  .parse(process.argv)

function main () {
  async.waterfall([
    function (callback) {
      getInbox(function (list) {
        callback(null, list)
      })
    },
    function (list, callback) {
      async.parallel([
        function (cb) {
          api({url: '/tasks', qs: {list_id: list.id}}, function (err, res, body) {
            if (err) process.exit(1)
            cb(null, body)
          })
        },
        function (cb) {
          api({url: '/subtasks', qs: {list_id: list.id}}, function (err, res, body) {
            if (err) process.exit(1)
 *
 * Authors:
 *   fengmk2 <*****@*****.**> (http://fengmk2.github.com)
 */

'use strict';

/**
 * Module dependencies.
 */

var commander = require('commander');
var PhantomDriver = require('../lib/driver');
var pkg = require('../package.json');

commander
  .description(pkg.description)
  .option('-v, --version', 'output the version number')
  .option('-s, --server [s]', 'specify server and port, default is server.totorojs.org:9999')
  .on('version', function () {
    console.log(pkg.version);
    process.exit(0);
  });

// listen before parse
commander.parse(process.argv);

var driver = new PhantomDriver({
  server: commander.server || 'server.totorojs.org:9999',
});

driver.init();
Example #30
0
var async = require('async');
var csv = require('csv');
var _ = require('lodash');

var kue = require('kue');
var jobs = kue.createQueue();

var program = require('commander');

program
  .description('Enqueues snuffle tasks to the queue from a csv file containing ranks and urls')
  .usage('[options] <file>')
  .option('-s, --start [offset]', 'Row of input csv from which to begin adding jobs [0]', parseInt)
  .option('-c, --count [number]', 'Number of rows to add [100]', parseInt)
  .option('-r, --retries [number]', 'Number of times to retry failed jobs [3]', parseInt)
  .parse(process.argv);

if (!program.args[0]) {
  console.log('  An input file must be specified');
  program.help();
}

_.defaults(program, {
  start: 0,
  count: 10,
  retries: 3
});

csv()
  .from.path( program.args[0] )
  .to.array( function(sites) {