[
  {
    "path": ".npmignore",
    "content": "*.sock\nlogs/*\npids/*\n"
  },
  {
    "path": ".project",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<projectDescription>\n\t<name>express-mvc-bootstrap</name>\n\t<comment></comment>\n\t<projects>\n\t</projects>\n\t<buildSpec>\n\t</buildSpec>\n\t<natures>\n\t</natures>\n</projectDescription>\n"
  },
  {
    "path": "README.md",
    "content": "\n# THIS PROJECT IS NO LONGER MAINTAINED, TRY THIS ONE:  https://github.com/niftylettuce/eskimo\n\n# Express MVC Bootstrap\n\nA MVC boilerplate for Express.js\n\n## Description\n\nI built this application to create a template MVC `style` app that I could then use as the start point for further development. I used the excellent examples in the main [Express github repository](https://github.com/visionmedia/express), specifically the MVC example, as the starting point. I have however changed it quite substantially to make it clearer and remove some of the `magic` that confused me at first when learning. If you are familiar with other MVC frameworks hopefully my file structure makes some sense.\n\n## Requires\n\n### You need to manually install: \n\n  - [Node.js](http://nodejs.org/): Amazing javascript asynchronous IO library, install manually.\n  - [MongoDB](http://www.mongodb.org): NoSQL Database, install manually.\n  - [NPM](http://npmjs.org/): Node package manager, used to install the remaining.\n\n### And then install via NPM: \n\n  - [Express](http://expressjs.com/): Application Framework for Node.js\n  - [Mongoose](http://mongoosejs.com/): Node.JS ORM for Mongo\n  - [ejs](http://embeddedjs.com/): EmbeddedJS Templating\n  - [cluster](http://learnboost.github.com/cluster): extensible multi-core server manager\n  - log: Tiny logger with streaming reader\n  - [connect](https://github.com/senchalabs/connect): High performance middleware framework\n  - mime: A comprehensive library for mime-type mapping\n  - qs: querystring parser\n  - [expresso](https://github.com/visionmedia/expresso): TDD framework, light-weight, fast, CI-friendly\n  - should: test framework agnostic BDD-style assertions\n  - [socket.io](https://github.com/learnboost/Socket.IO-node): The cross-browser WebSocket\n\n### But I've included in this project:\n\n  - [jQuery](http://jquery.com/): Javascript Library\n  - [jQuery UI](http://jqueryui.com/): UI Library\n  - [jQuery Aristo Template](http://taitems.tumblr.com/post/482577430/introducing-aristo-a-jquery-ui-theme): Fantastic looking jQuery UI Template.\n\n## Installation\n\n  - Install node.js \n\n<!---->\n\n      // on osx with brew\n      brew update\n      brew install node\n    \n      // build from source\n      git clone git://github.com/joyent/node.git\n      ./configure\n      make\n      make install\n  \n  - Ininstall mongodb\n  \n<!---->\n\n      // on osx with brew\n      brew update\n      brew install mongodb\n    \n      // create db folder\n      mkdir -p /usr/local/db/\n\n> For more installation detail please see [this](http://www.mongodb.org/display/DOCS/Quickstart)\n    \n  - Install npm\n\n<!---->\n\n    curl http://npmjs.org/install.sh | clean=no sh\n    \n  - Install required packages\n\n<!---->\n    \n      // install executable package globally\n      npm install express-mvc-bootstrap -g\n    \n      // make project folder and go to that folder\n      mkdir /path/to/project\n      cd /path/to/project\n    \n      // install packages locally to be `require();`\n      npm install socket.io should mongoose log cluster expresso qs mime ejs connect express express-mvc-bootstrap\n\n## Setup\n  - In you project folder run\n  \n<!---->\n\n      // create app \n      eb create-app\n    \n      // running mongodb\n      mongod --dbpath /usr/local/db/\n    \n      // running server\n      eb\n    \n  - Browse to http://localhost:3000\n\n\n## Commands:\n    \n      // Shows help\n      eb script\n    \n      // Wrapper for 3 commands below\n      eb script generate-all HelloWorld\n    \n      // Creates a model\n      eb script create-model HelloWorld \n    \n      // Creates a controller\n      eb script create-controller HelloWorld\n    \n      // Creates views\n      eb script create-view HelloWorld\n    \n      // Creates tests\n      eb script create-test HelloWorld\n    \n      // Runs server on different port\n      eb server server.port=3000\n    \n      // Creates a new app\n      eb create-app\n\n## TODO: \nBuild some amazing apps!\n"
  },
  {
    "path": "app-cluster.js",
    "content": "/**\n * Module dependencies.\n */\nvar cluster = require('cluster');\nvar app;\n\n/**\n * Initial bootstrapping\n */\nexports.boot = function(port,path){\n  \n  //Create our express instance\t\n  app = require('./app').boot();\n  \n  // TODO : ENABLE Reload\n  /**\n   * var watchFolders = [path + '/models', \n                      path + '/controllers',\n                      path + '/views',\n                      path + '/utils']\n  \n     .use(cluster.reload(watchFolders,{ signal: 'SIGQUIT', interval: 60000 }))\n   \n   */    \n  \n  cluster(app)\n  \t  .set('working directory', path)\n  \t  .set('socket path',path)\n\t  .in('development')\n\t    .set('workers', 1)\t    \n\t    .use(cluster.logger(path + '/logs', 'debug'))\n\t    .use(cluster.debug())\t   \n\t    .use(cluster.pidfiles(path + '/pids'))\n\t  .in('test')\n\t    .set('workers', 1)\n\t    .use(cluster.logger(path + '/logs', 'warning'))\t    \n\t    .use(cluster.pidfiles(path + '/pids'))\n\t  .in('production')\n\t    .set('workers', 2)\n\t\t.use(cluster.logger(path + '/logs'))\t    \n\t\t.use(cluster.pidfiles(path + '/pids'))\n\t  .in('all')\n\t    .listen(parseInt(port));\n\t  \n};\n\n"
  },
  {
    "path": "app.js",
    "content": "/**\n * Module dependencies.\n */\nvar fs = require('fs'),express = require('express'),\n\t mongoose = require('mongoose'), nodepath = require('path');\n\nvar path = __dirname;\nvar app;\n\n/**\n * Initial bootstrapping\n */\nexports.boot = function(params){\n\t\n  //Create our express instance\n  app = express.createServer();\t\n\t\n   // Import configuration\n  require(path + '/conf/configuration.js')(app,express);\n  \n  // Bootstrap application\n  bootApplication(app);\n  bootModels(app);\n  bootControllers(app);\n  \n  return app;\n  \n};\n\n/**\n *  App settings and middleware\n *  Any of these can be added into the by environment configuration files to \n *  enable modification by env.\n */\n\nfunction bootApplication(app) {\t \n   \n   // launch\n  // app.use(express.logger({ format: ':method :url :status' }));\n  app.use(express.bodyParser());\n  app.use(express.methodOverride());\n  app.use(express.cookieParser());\n  app.use(express.session({ secret: 'helloworld' }));\n  app.use(express.static(path + '/public'));  // Before router to enable dynamic routing\n  app.use(app.router);\n\n  // Example 500 page\n  app['error'](function(err, req, res){\n    console.log('Internal Server Error: ' + err.message);\n    res.render('500');\n  });\n  \n  // Example 404 page via simple Connect middleware\n  app.use(function(req, res){\n    res.render('404');\n  });\n\n  // Setup ejs views as default, with .html as the extension\n  app.set('views', path + '/views');\n  app.register('.html', require('ejs'));\n  app.set('view engine', 'html');\n\n  // Some dynamic view helpers\n  app.dynamicHelpers({\n  \n\trequest: function(req){\n\t   return req;\n\t},\n\t    \n\thasMessages: function(req){\n      return Object.keys(req.session.flash || {}).length;\n    },\n\n    messages: function(req){\n      return function(){\n        var msgs = req.flash();\n        console.log(msgs);\n        return Object.keys(msgs).reduce(function(arr, type){\n          return arr.concat(msgs[type]);\n        }, []);        \n      }\n    }\n  });\n}\n\n//Bootstrap models \nfunction bootModels(app) {\n\t\n  fs.readdir(path + '/models', function(err, files){\n    if (err) throw err;\n    files.forEach(function(file){\n    \tbootModel(app, file);\n    });\n  });\n  \n  // Connect to mongoose\n  mongoose.connect(app.set('db-uri'));\n  \n}\n\n// Bootstrap controllers\nfunction bootControllers(app) {\n  fs.readdir(path + '/controllers', function(err, files){\n    if (err) throw err;\n    files.forEach(function(file){    \t\n    \t// bootController(app, file);    \t\t\n    });\n\t\n\n  });\n  \n  require(path + '/controllers/AppController')(app);\t\t\t// Include\n  \n}\n\n// simplistic model support\nfunction bootModel(app, file) {\n\n    var name = file.replace('.js', ''),\n    \tschema = require(path + '/models/'+ name);\t\t\t\t// Include the mongoose file        \n    \n}\n\n// Load the controller, link to its view file from here\nfunction bootController(app, file) {\n\t\n\tvar name = file.replace('.js', ''),\n    \tcontroller = path + '/controllers/' + name,   // full controller to include\n    \ttemplate = name.replace('Controller','').toLowerCase();\t\t\t\t\t\t\t\t\t// template folder for html - remove the ...Controller part.\n\t\n\t// Include the controller\n\t// require(controller)(app,template);\t\t\t// Include\n\t\n}\n\n// allow normal node loading if appropriate\nif (!module.parent) {\n  exports.boot().listen(3000);\n  console.log(\"Express server %s listening on port %d\", express.version, app.address().port)\n}\n\n"
  },
  {
    "path": "conf/configuration.js",
    "content": "\n/**\n * Default configuration manager\n * Inject app and express reference\n */\nmodule.exports = function(app,express) {\n\t\t\n\t// DEVELOPMENT\n\tapp.configure('development', function() {\n\t  require(\"./development.js\")(app,express);\n\t});\n\n\t// TEST\n\tapp.configure('test', function() {\n\t\trequire(\"./test.js\")(app,express);\n\t});\n\t\n\t// PRODUCTION\n\tapp.configure('production', function() {\n\t\trequire(\"./production.js\")(app,express);\n\t});\t\t\n\n}\n"
  },
  {
    "path": "conf/development.js",
    "content": "\n/**\n * DEVELOPMENT Environment settings\n */\nmodule.exports = function(app,express) {\n\t\t\n\tapp.set('db-uri', 'mongodb://localhost/mvc-development');\t       \n    app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));\n\t\n}\n"
  },
  {
    "path": "conf/production.js",
    "content": "\n/**\n * TEST Environment settings\n */\nmodule.exports = function(app,express) {\n\t\t\n\tapp.set('db-uri', 'mongodb://localhost/mvc-production');\n    app.use(express.errorHandler({ dumpExceptions: true, showStack: false }));\n\t\n}\n"
  },
  {
    "path": "conf/test.js",
    "content": "\n/**\n * PRODUCTION Environment settings\n */\nmodule.exports = function(app,express) {\n\t\t\n\tapp.set('db-uri', 'mongodb://localhost/mvc-production');\n    app.use(express.errorHandler({ dumpExceptions: false, showStack: false }));\n\t\n}\n"
  },
  {
    "path": "controllers/AppController.js",
    "content": "var fs = require('fs')\n\t, inflection = require('../lib/inflection');\n\nmodule.exports = function(app) {\n\t\n\t// app.get(\"/favicon.ico\", function() {}); // Required if you delete the favicon.ico from public\n\t\n\t// Plural\n\tapp.get(\"/:controller?\", router);\t\t\t\t        // Index\n\tapp.get(\"/:controller.:format?\", router);\t\t\t\t// Index\n\tapp.get(\"/:controller/:from-:to.:format?\", router);\t\t// Index\n\t\n\t// Plural Create & Delete\n\tapp.post(\"/:controller\", router);\t\t\t// Create\n\tapp.del(\"/:controller\", router);   \t\t\t// Delete all\n\t\n\t// Singular - different variable to clarify routing\n\tapp.get(\"/:controller/:id.:format?\", router);  \t// To support controller/index\t\n\tapp.get(\"/:controller/:id/:action\", router);\t\t// Show edit\n\tapp.put(\"/:controller/:id\", router);\t\t\t\t// Update\n\tapp.del(\"/:controller/:id\", router);\t\t\t\t// Delete\t\n\t\n}\n\n///\nfunction router(req, res, next) {\n\t\t\n\tvar controller = req.params.controller ? req.params.controller : '';\n\tvar action = req.params.action ? req.params.action : '';\n\tvar id = req.params.id ? req.params.id : '';\n\tvar method = req.method.toLowerCase();\n\tvar fn = 'index';\n\t\n\t// Default route\n\tif(controller.length == 0) {\n\t\tindex(req,res,next);\n\t\treturn;\n\t}\t\t\n\t\n\t// Determine the function to call based on controller / model and method\n\tif(id.length == 0) {\n\t\t\n\t\t// We are plural\n\t\tswitch(method) {\n\t\t\tcase 'get':\n\t\t\t\tfn = 'index';\n\t\t\t\tbreak;\n\t\t\tcase 'post':\n\t\t\t\tfn = 'create';\n\t\t\t\tbreak;\n\t\t\tcase 'delete':\n\t\t\t\tfn = 'destroyAll';\n\t\t\t\tbreak;\t\t\n\t\t}\t\t\n\t\t\n\t} else {\n\t\t\n\t\t// Controller name is now singular, need to switch it back \n\t\tcontroller = controller.pluralize();\n\t\t\n\t\tswitch(method) {\n\t\t\tcase 'get':\n\t\t\t\tif(action.length > 0) {\n\t\t\t\t\tfn = action;\n\t\t\t\t} else {\n\t\t\t\t\tfn = 'show';\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'put':\n\t\t\t\tfn = 'update';\n\t\t\t\tbreak;\n\t\t\tcase 'delete':\n\t\t\t\tfn = 'destroy';\n\t\t\t\tbreak;\t\t\n\t\t}\t\t\n\t\t\n\t}\n\ttry {\t\t\t\n\t\tvar controllerLibrary = require('./' + controller.capitalize() + 'Controller');\t\t\t\n\t\tif(typeof controllerLibrary[fn] === 'function') {\n\t\t\tcontrollerLibrary[fn](req,res,next);\t\t\n\t\t} else {\n\t\t\tres.render('404');\n\t\t}\t\n\t} catch (e) {\n\t\tres.render('404');\n\t}\n\t  \t\n};\n\n\n/**\n * Default Application index - shows a list of the controllers.\n * Redirect here if you prefer another controller to be your index.\n * @param req\n * @param res\n */\nfunction index(req, res, next) {\n\t\t \n\t/**\n\t * If you want to redirect to another controller, uncomment\n\t */\n\t// res.redirect('/controllerName');\n\t\n\tvar controllers = [];\n\t\n\t  fs.readdir(__dirname + '/', function(err, files){\n\t    \n\t\tif (err) throw err;\n\t    \n\t\tfiles.forEach(function(file){\n\t\t\tif(file != \"AppController.js\") {\n\t\t\t\tcontrollers.push(file.replace('Controller.js','').toLowerCase());\n\t\t\t}\n\t    });\n\t    \n\t\tres.render('app',{controllers:controllers});\n\t  \n\t  });\t\n\t\n\t  \t\n};\n"
  },
  {
    "path": "eb",
    "content": "#!/usr/bin/env node\n\n/**\n * ExpressJs MVC Bootstrap\n * @Params - cmd - serve\n r | script | params\n */\n \n \n/**\n * Framework version.\n */\n\nvar version = '0.1.2';\n \n\n/**\n * Require everything in the library folder\n */\nrequire.paths.unshift(__dirname + '/lib');\n\n/**\n * Explicit module dependencies\n */\nvar fs = require('fs'), nodepath = require('path'), exec = require('child_process').exec;\n\n/**\n * Paths\n **/\nvar path = fs.realpathSync('.');\nvar bootstrapPath = __dirname;\n\n/**\n * Main Command router\n */\nvar appLauncher = {\n\t\t\t\t\tcommand:'cluster',\n\t\t\t\t    server: { port:3000 },\n\t\t\t\t    script: { name:'help',\n\t\t\t\t    \t\t  params: []\n\t\t\t\t    \t\t}\n\t\t\t\t   };\n\nfor(var i in process.argv) {\n\t// Skip the first two - Node and app.js path\n\tif(i>1) {\t\t\n\t\tprocessParam(process.argv[i],i);\n\t}\t\n}\n\nrunLauncher(appLauncher);\n\n/**\n * Run the launcher\n * @param appLauncher\n */\nfunction runLauncher(appLauncher) {\n\t\n\t// Always use current directory?\n\tconsole.log('\\r\\n\\x1b[36mLaunching bootstrap from: \\x1b[0m ' + path);\n\tconsole.log('\\x1b[36mScript directory: \\x1b[0m ' + bootstrapPath + '/scripts');\t\n\t\n\t// Check if this is a bootstrap application?\n\tif(isLibrary()) {\n\t\tconsole.log('\\x1b[1mDo not run this from the bootstrap library folder, please run from an empty directory or a bootstrapped app, or please run \"npm install\"\\x1b[0m\\r\\n');\t\t\n\t\treturn;\n\t}\n\t\n\t// Check if this is a bootstrap application?\n\tif(!isBootstrap() && appLauncher.command != 'create-app') {\n\t\tconsole.log('\\x1b[1mApplication not bootstrapped - you must run:\\x1b[0m eb create-app\\r\\n');\n\t\treturn;\n\t}\n\t\n\tswitch(appLauncher.command) {\n\t\tcase 'test':\n\t\t\trunTests(appLauncher.script);\n\t\t\tbreak;\t\t\n\t\tcase 'cluster':\n\t\t\trunCluster(appLauncher.server.port);\n\t\t\tbreak;\n\t\tcase 'server':\n\t\t\trunServer(appLauncher.server.port);\n\t\t\tbreak;\n\t\tcase 'script':\n\t\t\trunScript(appLauncher.script);\n\t\t\tbreak;\t\t\t\n\t\tcase 'create-app':\n\t\t\tcreateApplication(path);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tappLauncher.command = 'script';\t\t\t\n\t\t\trunScript(appLauncher.script);\t\t\t\n\t}\n\t\n}\n\n/**\n * Check if express app.js exists\n **/\nfunction isLibrary() {\t\n\treturn nodepath.existsSync(path + '/eb');\n}\n\n/**\n * Check if .bootstrap exists\n **/\nfunction isBootstrap() {\t\n\treturn nodepath.existsSync(path + '/.eb-status');\t\t\n}\n\n/**\n * Run a script\n * @param appLauncher\n * Runs by default from path where bootstrap runs via __dirname.\n */\nfunction runScript(scriptLauncher) {\t\n\tvar script = require(bootstrapPath + '/scripts/'+ scriptLauncher.name);\n\tscript.execute(scriptLauncher.params,path);\n}\n\n/**\n * Process params into array to enable launch\n * @param param\n * @param params\n */\nfunction processParam(param,depth) {\n\t\n\tvar paramArray = param.split(\"=\");\n\t\n\t// Run command - must always come after the app\n\tif(i == 2) {\n\t\tappLauncher.command = param;\n\t}\n\t\n\t// Server.port\n\tif(paramArray[0] == \"server.port\" && paramArray[1] != undefined) {\n\t\tappLauncher.server.port = paramArray[1];\n\t}\n\t\n\t// \n\tif((appLauncher.command == \"script\" || appLauncher.command == \"test\") && i == 3) {\n\t\tappLauncher.script.name = param;\n\t}\n\t\n\t// Script params\n\tif(appLauncher.command == 'script' && i > 3) {\n\t\tappLauncher.script.params.push(param);\n\t}\n\t\n}\n\n/**\n * Run expresso tests\n */\nfunction runTests(appLauncher) {\n\n\tvar test = appLauncher.name ? appLauncher.name : 'all';\n\t\t\t\n\tif(test == 'help') {  // This is the default - ugly I know!\n\t\ttest = ['unit','integration','functional'];\n\t} else {\n\t\ttest = [test];\n\t}\n\t\n\ttest.forEach(function (item, index) {\n\t\texec('expresso -I . -s tests/' + item + '/* ', { timeout: 60000, cwd:path }, function (error, stdout, stderr) {\n\t\t\tconsole.log(\"Finished test: \" + item);\n\t    \tconsole.log(stdout);\n\t    \tconsole.log(stderr);\n    \t});\n    });\n}\n\n\n/**\n * Launch a server\n */\nfunction runServer(port) {\n\n\t// Ensure we run in the local folder of the application\n\tprocess.chdir(path);\t\n\tvar app = require(path + '/app').boot();\n\tapp.listen(port);\t\t\n\tconsole.log('\\r\\n\\x1b[36mApplication started on port:\\x1b[0m ' + port);\n}\n\n/**\n * Launch a cluster\n */\nfunction runCluster(port) {\n\n\t// Ensure we run in the local folder of the application\t\n\tprocess.chdir(path);\t\n\trequire(path + '/app-cluster').boot(port,path);\n\tconsole.log('\\r\\n\\x1b[36mLaunching cluster mode on port: \\x1b[0m' + port);\n\t\t\n}\n\n/**\n * Application Creation - Borrowed from Express scripts\n **/\n\n/**\n * Create application at the given directory `path`.\n *\n * @param {String} path\n */\nfunction createApplicationAt(path) {\n    \n    \n    mkdir(path + '/models',function() {\n    \t// Disabled as no default models            \n\t    // copy(bootstrapPath + '/models/*',path + '/models');\n\t});\n    \n    mkdir(path + '/controllers',function() {    \n    \tcopy(bootstrapPath + '/controllers/*',path + '/controllers');\n    });\n    \n    mkdir(path + '/conf',function() {\n    \tcopy(bootstrapPath + '/conf/*',path + '/conf');\n    });\n    mkdir(path + '/utils',function() {\n    \tcopy(bootstrapPath + '/utils/*',path + '/utils');\n    });\n    \n\tmkdir(path + '/views',function() {\t\n\t\tcopy(bootstrapPath + '/views/*',path + '/views');\n\t});\n\tmkdir(path + '/public',function() {\n\t\tcopy(bootstrapPath + '/public/*',path + '/public');\n\t});\n\t\n\tmkdir(path + '/lib',function() {\n    \tcopy(bootstrapPath + '/lib/*',path + '/lib');\n    });\n    \n    mkdir(path + '/tests',function() {\n    \n    \tmkdir(path + '/tests/unit',function() {\n    \t\tcopy(bootstrapPath + '/tests/unit/*',path + '/tests/unit');\n    \t});\n    \tmkdir(path + '/tests/integration',function() {\n    \t\tcopy(bootstrapPath + '/tests/integration/*',path + '/tests/integration');\n    \t});\n    \tmkdir(path + '/tests/functional',function() {\n    \t\tcopy(bootstrapPath + '/tests/functional/*',path + '/tests/functional');\n    \t});\n    \t\n    \t\n    });\n    \n\tmkdir(path + '/logs');\n\tmkdir(path + '/pids');\n\t\n\tcopy(bootstrapPath + '/app-cluster.js',path + '/');\n\tcopy(bootstrapPath + '/app.js',path + '/');\n\t\n\twrite(path + '/.eb-status','Created @ ' + new Date());\t\n\n}\n\nfunction createApplication(path) {\n  emptyDirectory(path, function(empty){\n    if (empty) {\n      createApplicationAt(path);\n    } else {\n      confirm('This will over-write the existing application, continue? ', function(ok){\n        if (ok) {\n          process.stdin.destroy();\n          createApplicationAt(path);\n        } else {\n          abort('aborting');\n        }\n      });\n    }\n  });\n};\n\n/**\n * Check if the given directory `path` is empty.\n *\n * @param {String} path\n * @param {Function} fn\n */\n\nfunction emptyDirectory(path, fn) {\n  fs.readdir(path, function(err, files){\n    if (err && 'ENOENT' != err.code) throw err;\n    fn(!files || !files.length);\n  });\n}\n\n/**\n * echo str > path.\n *\n * @param {String} path\n * @param {String} str\n */\n\nfunction write(path, str) {\n  fs.writeFile(path, str);\n  console.log('   \\x1b[36mcreate\\x1b[0m : ' + path);\n}\n\n/**\n * Prompt confirmation with the given `msg`.\n *\n * @param {String} msg\n * @param {Function} fn\n */\n\nfunction confirm(msg, fn) {\n  prompt(msg, function(val){\n    fn(/^ *y(es)?/i.test(val));\n  });\n}\n\n/**\n * Prompt input with the given `msg` and callback `fn`.\n *\n * @param {String} msg\n * @param {Function} fn\n */\n\nfunction prompt(msg, fn) {\n  // prompt\n  if (' ' == msg[msg.length - 1]) {\n    process.stdout.write(msg);\n  } else {\n    console.log(msg);\n  }\n\n  // stdin\n  process.stdin.setEncoding('ascii');\n  process.stdin.once('data', function(data){\n    fn(data);\n  }).resume();\n}\n\n/**\n * Mkdir -p.\n *\n * @param {String} path\n * @param {Function} fn\n */\n\nfunction mkdir(path, fn) {\n  exec('mkdir -p ' + path, function(err){\n    if (err) throw err;\n    console.log('   \\x1b[36mcreate\\x1b[0m : ' + path);\n    fn && fn();\n  });\n}\n\n\n/**\n * cp -r\n *\n * @param {String} path\n * @param {Function} fn\n */\n\nfunction copy(from, to, fn) {\n  exec('cp -R ' + from + ' ' + to, function(err){\n    if (err) throw err;\n    console.log('   \\x1b[36mCopied\\x1b[0m : ' + from + ' to ' + to);\n    fn && fn();\n  });\n}\n\n/**\n * Exit with the given `str`.\n *\n * @param {String} str\n */\n\nfunction abort(str) {\n  console.error(str);\n  process.exit(1);\n}\n"
  },
  {
    "path": "lib/AppController.js",
    "content": "var fs = require('fs')\n\t, inflection = require('../lib/inflection');\n\nmodule.exports = function(app) {\n\t\n\t// app.get(\"/favicon.ico\", function() {}); // Required if you delete the favicon.ico from public\n\t\n\t// Plural\n\tapp.get(\"/:controller?\", router);\t\t\t\t        // Index\n\tapp.get(\"/:controller.:format?\", router);\t\t\t\t// Index\n\tapp.get(\"/:controller/:from-:to.:format?\", router);\t\t// Index\n\t\n\t// Plural Create & Delete\n\tapp.post(\"/:controller\", router);\t\t\t// Create\n\tapp.del(\"/:controller\", router);   \t\t\t// Delete all\n\t\n\t// Singular - different variable to clarify routing\n\tapp.get(\"/:controller/:id.:format?\", router);  \t// To support controller/index\t\n\tapp.get(\"/:controller/:id/:action\", router);\t\t// Show edit\n\tapp.put(\"/:controller/:id\", router);\t\t\t\t// Update\n\tapp.del(\"/:controller/:id\", router);\t\t\t\t// Delete\t\n\t\n}\n\n///\nfunction router(req, res, next) {\n\t\t\n\tvar controller = req.params.controller ? req.params.controller : '';\n\tvar action = req.params.action ? req.params.action : '';\n\tvar id = req.params.id ? req.params.id : '';\n\tvar method = req.method.toLowerCase();\n\tvar fn = 'index';\n\t\n\t// Default route\n\tif(controller.length == 0) {\n\t\tindex(req,res,next);\n\t\treturn;\n\t}\t\t\n\t\n\t// Determine the function to call based on controller / model and method\n\tif(id.length == 0) {\n\t\t\n\t\t// We are plural\n\t\tswitch(method) {\n\t\t\tcase 'get':\n\t\t\t\tfn = 'index';\n\t\t\t\tbreak;\n\t\t\tcase 'post':\n\t\t\t\tfn = 'create';\n\t\t\t\tbreak;\n\t\t\tcase 'delete':\n\t\t\t\tfn = 'destroyAll';\n\t\t\t\tbreak;\t\t\n\t\t}\t\t\n\t\t\n\t} else {\n\t\t\n\t\t// Controller name is now singular, need to switch it back \n\t\tcontroller = controller.pluralize();\n\t\t\n\t\tswitch(method) {\n\t\t\tcase 'get':\n\t\t\t\tif(action.length > 0) {\n\t\t\t\t\tfn = action;\n\t\t\t\t} else {\n\t\t\t\t\tfn = 'show';\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'put':\n\t\t\t\tfn = 'update';\n\t\t\t\tbreak;\n\t\t\tcase 'delete':\n\t\t\t\tfn = 'destroy';\n\t\t\t\tbreak;\t\t\n\t\t}\t\t\n\t\t\n\t}\n\t\t\t\n\tvar controllerLibrary = require('./' + controller.capitalize() + 'Controller');\t\t\t\n\tif(typeof controllerLibrary[fn] === 'function') {\n\t\tcontrollerLibrary[fn](req,res,next);\t\t\n\t} else {\n\t\tres.render('404');\n\t}\n\t  \t\n};\n\n\n/**\n * Default Application index - shows a list of the controllers.\n * Redirect here if you prefer another controller to be your index.\n * @param req\n * @param res\n */\nfunction index(req, res, next) {\n\t\t \n\t/**\n\t * If you want to redirect to another controller, uncomment\n\t */\n\t// res.redirect('/controllerName');\n\t\n\tvar controllers = [];\n\t\n\t  fs.readdir(__dirname + '/', function(err, files){\n\t    \n\t\tif (err) throw err;\n\t    \n\t\tfiles.forEach(function(file){\n\t\t\tif(file != \"AppController.js\") {\n\t\t\t\tcontrollers.push(file.replace('Controller.js','').toLowerCase());\n\t\t\t}\n\t    });\n\t    \n\t\tres.render('app',{controllers:controllers});\n\t  \n\t  });\t\n\t\n\t  \t\n};"
  },
  {
    "path": "lib/ExamplesController.js",
    "content": "\n/**\n *  Examples Controller\n *  Created by create-controller script @ Fri Mar 11 2011 21:16:50 GMT+0000 (GMT)\n **/\n var mongoose = require('mongoose'),\t\n\tExample = mongoose.model('Example'),\n\tpager = require('../utils/pager.js'),\n\tViewTemplatePath = 'examples';\n\nmodule.exports = {\n\n\tinit: function(params) {\n\t\tViewTemplatePath = params.viewPath   // Enable over-ride of view path for testing\n\t},\n\t\n\t/**\n\t * Index action, returns a list either via the views/examples/index.html view or via json\n\t * Default mapping to GET '/examples'\n\t * For JSON use '/examples.json'\n\t **/\n\tindex: function(req, res, next) {\n\t\t  \t \n\t\t  var from = req.params.from ? parseInt(req.params.from) - 1 : 0;\n\t\t  var to = req.params.to ? parseInt(req.params.to) : 10;\n\t      var total = 0;\n\t      \n\t      Example.count({}, function (err, count) {\n\t    \ttotal = count;  \n\t    \tvar pagerHtml = pager.render(from,to,total,'/examples');    \t\n\t                  \n\t\t\t  Example.find({})\n\t\t\t  \t.sort('name', 1)\n\t\t\t  \t.skip(from).limit(to)\n\t\t\t  \t.find(function (err, examples) {\n\t\t\t\t\n\t\t\t\t  if(err) return next(err);\n\t\t\t\t  \n\t\t\t      switch (req.params.format) {\n\t\t\t        case 'json':\t          \n\t\t\t          res.send(examples.map(function(u) {\n\t\t\t              return u.toObject();\n\t\t\t          }));\n\t\t\t          break;\n\t\t\n\t\t\t        default:\t\t\t        \t\n\t\t\t        \tres.render(ViewTemplatePath,{examples:examples,pagerHtml:pagerHtml});\n\t\t\t      }\n\t\t\t      \n\t\t\t  });\n\t      \n\t      });\n\t      \t  \t\n\t},\n\t\n\t/**\n\t * Show action, returns shows a single item via views/examples/show.html view or via json\n\t * Default mapping to GET '/example/:id'\n\t * For JSON use '/example/:id.json'\n\t **/\t\n\tshow: function(req, res, next) {\t  \t\t  \n\t\t\t\n\t\t  Example.findById(req.params.id, function(err, example) {\n\t\t\t  \n\t\t\t  if(err) return next(err);\n\t\t\t  \n\t\t      switch (req.params.format) {\n\t\t        case 'json':\n\t\t          res.send(example.toObject());\n\t\t          break;\n\t\n\t\t        default:\n\t\t        \tres.render(ViewTemplatePath + \"/show\",{example:example});\n\t\t      }\n\t\t      \n\t\t  });\n\t\t      \n\t},\n\t\n\t/**\n\t * Edit action, returns a form via views/examples/edit.html view no JSON view.\n\t * Default mapping to GET '/example/:id/edit'\n\t **/  \t  \n\tedit: function(req, res, next){\n\t\t  Example.findById(req.params.id, function(err, example) {\n\t\t\t  if(err) return next(err);\n\t\t\t  res.render(ViewTemplatePath + \"/edit\",{example:example});\n\t\t});\n\t},\n\t  \n\t/**\n\t * Update action, updates a single item and redirects to Show or returns the object as json\n\t * Default mapping to PUT '/example/:id', no GET mapping\t \n\t **/  \n\tupdate: function(req, res, next){\n\t    \n\t\t\n\t\t\n\t    Example.findById(req.params.id, function(err, example) {\n\t        \n\t    \tif (!example) return next(err);\n\t        \n\t    \texample.name = req.body.example.name;\n\t    \t\n\t        example.save(function(err) {\n\t        \n\t    \t  if (err) {\n\t    \t\t  console.log(err);\n\t        \t  req.flash('error','Could not update example: ' + err);\n\t          \t  res.redirect('/examples');\n\t          \t  return;\n\t    \t  }\n\t    \t\t\n\t          switch (req.params.format) {\n\t            case 'json':\n\t              res.send(example.toObject());\n\t              break;\n\t            default:\n\t              req.flash('info', 'Example updated');\n\t              res.redirect('/example/' + req.params.id);\n\t          }\n\t        });\n\t      });\n\t},\n\t  \n\t/**\n\t * Create action, creates a single item and redirects to Show or returns the object as json\n\t * Default mapping to POST '/examples', no GET mapping\t \n\t **/  \n\tcreate: function(req, res, next){\n\t\t\n\t\t  var example = new Example(req.body.example);\n\t\t  \n\t\t  example.save(function(err) {\n\t\t   \n\t\t\tif (err) {\n\t    \t  req.flash('error','Could not create example: ' + err);\n\t      \t  res.redirect('/examples');\n\t      \t  return;\n\t\t\t}\n\t\n\t\t    switch (req.params.format) {\n\t\t      case 'json':\n\t\t        res.send(example.toObject());\n\t\t        break;\n\t\n\t\t      default:\n\t\t    \t  req.flash('info','Example created');\n\t\t      \t  res.redirect('/example/' + example.id);\n\t\t\t }\n\t\t  });\t  \n\t\t  \n\t},\n\t  \n\t/**\n\t * Delete action, deletes a single item and redirects to index\n\t * Default mapping to DEL '/example/:id', no GET mapping\t \n\t **/ \n\tdestroy: function(req, res, next){\n\t\t  \n\t\t  Example.findById(req.params.id, function(err, example) {\n\t\t        \n\t\t    \tif (!example) { \n\t  \t    \t  \treq.flash('error','Unable to locate the example to delete!');\n\t\t    \t\tres.render('404'); \n\t\t    \t\treturn false; \n\t\t    \t};\n\t\t    \t\t    \n\t\t    \texample.remove(function(err) {\n\t    \t\t  if(err) {\n\t    \t    \t  req.flash('error','There was an error deleting the example!');\n\t    \t\t\t  res.send('false');\n\t    \t\t  } else {\n\t    \t    \t  req.flash('info','Example deleted');\n\t    \t\t\t  res.send('true');\n\t    \t\t  }    \t          \n\t   \t      \t}); \n\t\t  });\n\t\t  \n\t}\n\t\n};"
  },
  {
    "path": "lib/README",
    "content": "Place any dependent libraries in here\n\n\n* inflection.js : http://code.google.com/p/inflection-js/\n\n    Modified to remove the link to window.\n\n\n"
  },
  {
    "path": "lib/inflection.js",
    "content": "/*\nCopyright (c) 2010 Ryan Schuft (ryan.schuft@gmail.com)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n*/\n\n/*\n  This code is based in part on the work done in Ruby to support\n  infection as part of Ruby on Rails in the ActiveSupport's Inflector\n  and Inflections classes.  It was initally ported to Javascript by\n  Ryan Schuft (ryan.schuft@gmail.com) in 2007.\n\n  The code is available at http://code.google.com/p/inflection-js/\n\n  The basic usage is:\n    1. Include this script on your web page.\n    2. Call functions on any String object in Javascript\n\n  Currently implemented functions:\n\n    String.pluralize(plural) == String\n      renders a singular English language noun into its plural form\n      normal results can be overridden by passing in an alternative\n\n    String.singularize(singular) == String\n      renders a plural English language noun into its singular form\n      normal results can be overridden by passing in an alterative\n\n    String.camelize(lowFirstLetter) == String\n      renders a lower case underscored word into camel case\n      the first letter of the result will be upper case unless you pass true\n      also translates \"/\" into \"::\" (underscore does the opposite)\n\n    String.underscore() == String\n      renders a camel cased word into words seperated by underscores\n      also translates \"::\" back into \"/\" (camelize does the opposite)\n\n    String.humanize(lowFirstLetter) == String\n      renders a lower case and underscored word into human readable form\n      defaults to making the first letter capitalized unless you pass true\n\n    String.capitalize() == String\n      renders all characters to lower case and then makes the first upper\n\n    String.dasherize() == String\n      renders all underbars and spaces as dashes\n\n    String.titleize() == String\n      renders words into title casing (as for book titles)\n\n    String.demodulize() == String\n      renders class names that are prepended by modules into just the class\n\n    String.tableize() == String\n      renders camel cased singular words into their underscored plural form\n\n    String.classify() == String\n      renders an underscored plural word into its camel cased singular form\n\n    String.foreign_key(dropIdUbar) == String\n      renders a class name (camel cased singular noun) into a foreign key\n      defaults to seperating the class from the id with an underbar unless\n      you pass true\n\n    String.ordinalize() == String\n      renders all numbers found in the string into their sequence like \"22nd\"\n*/\n\n/*\n  This sets up a container for some constants in its own namespace\n  We use the window (if available) to enable dynamic loading of this script\n  Window won't necessarily exist for non-browsers.\nif (window && !window.InflectionJS)\n{\n    window.InflectionJS = null;\n}\n*/\n\n/*\n  This sets up some constants for later use\n  This should use the window namespace variable if available\n*/\nInflectionJS =\n{\n    /*\n      This is a list of nouns that use the same form for both singular and plural.\n      This list should remain entirely in lower case to correctly match Strings.\n    */\n    uncountable_words: [\n        'equipment', 'information', 'rice', 'money', 'species', 'series',\n        'fish', 'sheep', 'moose', 'deer', 'news'\n    ],\n\n    /*\n      These rules translate from the singular form of a noun to its plural form.\n    */\n    plural_rules: [\n        [new RegExp('(m)an$', 'gi'),                 '$1en'],\n        [new RegExp('(pe)rson$', 'gi'),              '$1ople'],\n        [new RegExp('(child)$', 'gi'),               '$1ren'],\n        [new RegExp('^(ox)$', 'gi'),                 '$1en'],\n        [new RegExp('(ax|test)is$', 'gi'),           '$1es'],\n        [new RegExp('(octop|vir)us$', 'gi'),         '$1i'],\n        [new RegExp('(alias|status)$', 'gi'),        '$1es'],\n        [new RegExp('(bu)s$', 'gi'),                 '$1ses'],\n        [new RegExp('(buffal|tomat|potat)o$', 'gi'), '$1oes'],\n        [new RegExp('([ti])um$', 'gi'),              '$1a'],\n        [new RegExp('sis$', 'gi'),                   'ses'],\n        [new RegExp('(?:([^f])fe|([lr])f)$', 'gi'),  '$1$2ves'],\n        [new RegExp('(hive)$', 'gi'),                '$1s'],\n        [new RegExp('([^aeiouy]|qu)y$', 'gi'),       '$1ies'],\n        [new RegExp('(x|ch|ss|sh)$', 'gi'),          '$1es'],\n        [new RegExp('(matr|vert|ind)ix|ex$', 'gi'),  '$1ices'],\n        [new RegExp('([m|l])ouse$', 'gi'),           '$1ice'],\n        [new RegExp('(quiz)$', 'gi'),                '$1zes'],\n        [new RegExp('s$', 'gi'),                     's'],\n        [new RegExp('$', 'gi'),                      's']\n    ],\n\n    /*\n      These rules translate from the plural form of a noun to its singular form.\n    */\n    singular_rules: [\n        [new RegExp('(m)en$', 'gi'),                                                       '$1an'],\n        [new RegExp('(pe)ople$', 'gi'),                                                    '$1rson'],\n        [new RegExp('(child)ren$', 'gi'),                                                  '$1'],\n        [new RegExp('([ti])a$', 'gi'),                                                     '$1um'],\n        [new RegExp('((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$','gi'), '$1$2sis'],\n        [new RegExp('(hive)s$', 'gi'),                                                     '$1'],\n        [new RegExp('(tive)s$', 'gi'),                                                     '$1'],\n        [new RegExp('(curve)s$', 'gi'),                                                    '$1'],\n        [new RegExp('([lr])ves$', 'gi'),                                                   '$1f'],\n        [new RegExp('([^fo])ves$', 'gi'),                                                  '$1fe'],\n        [new RegExp('([^aeiouy]|qu)ies$', 'gi'),                                           '$1y'],\n        [new RegExp('(s)eries$', 'gi'),                                                    '$1eries'],\n        [new RegExp('(m)ovies$', 'gi'),                                                    '$1ovie'],\n        [new RegExp('(x|ch|ss|sh)es$', 'gi'),                                              '$1'],\n        [new RegExp('([m|l])ice$', 'gi'),                                                  '$1ouse'],\n        [new RegExp('(bus)es$', 'gi'),                                                     '$1'],\n        [new RegExp('(o)es$', 'gi'),                                                       '$1'],\n        [new RegExp('(shoe)s$', 'gi'),                                                     '$1'],\n        [new RegExp('(cris|ax|test)es$', 'gi'),                                            '$1is'],\n        [new RegExp('(octop|vir)i$', 'gi'),                                                '$1us'],\n        [new RegExp('(alias|status)es$', 'gi'),                                            '$1'],\n        [new RegExp('^(ox)en', 'gi'),                                                      '$1'],\n        [new RegExp('(vert|ind)ices$', 'gi'),                                              '$1ex'],\n        [new RegExp('(matr)ices$', 'gi'),                                                  '$1ix'],\n        [new RegExp('(quiz)zes$', 'gi'),                                                   '$1'],\n        [new RegExp('s$', 'gi'),                                                           '']\n    ],\n\n    /*\n      This is a list of words that should not be capitalized for title case\n    */\n    non_titlecased_words: [\n        'and', 'or', 'nor', 'a', 'an', 'the', 'so', 'but', 'to', 'of', 'at',\n        'by', 'from', 'into', 'on', 'onto', 'off', 'out', 'in', 'over',\n        'with', 'for'\n    ],\n\n    /*\n      These are regular expressions used for converting between String formats\n    */\n    id_suffix: new RegExp('(_ids|_id)$', 'g'),\n    underbar: new RegExp('_', 'g'),\n    space_or_underbar: new RegExp('[\\ _]', 'g'),\n    uppercase: new RegExp('([A-Z])', 'g'),\n    underbar_prefix: new RegExp('^_'),\n    \n    /*\n      This is a helper method that applies rules based replacement to a String\n      Signature:\n        InflectionJS.apply_rules(str, rules, skip, override) == String\n      Arguments:\n        str - String - String to modify and return based on the passed rules\n        rules - Array: [RegExp, String] - Regexp to match paired with String to use for replacement\n        skip - Array: [String] - Strings to skip if they match\n        override - String (optional) - String to return as though this method succeeded (used to conform to APIs)\n      Returns:\n        String - passed String modified by passed rules\n      Examples:\n        InflectionJS.apply_rules(\"cows\", InflectionJs.singular_rules) === 'cow'\n    */\n    apply_rules: function(str, rules, skip, override)\n    {\n        if (override)\n        {\n            str = override;\n        }\n        else\n        {\n            var ignore = (skip.indexOf(str.toLowerCase()) > -1);\n            if (!ignore)\n            {\n                for (var x = 0; x < rules.length; x++)\n                {\n                    if (str.match(rules[x][0]))\n                    {\n                        str = str.replace(rules[x][0], rules[x][1]);\n                        break;\n                    }\n                }\n            }\n        }\n        return str;\n    }\n};\n\n/*\n  This lets us detect if an Array contains a given element\n  Signature:\n    Array.indexOf(item, fromIndex, compareFunc) == Integer\n  Arguments:\n    item - Object - object to locate in the Array\n    fromIndex - Integer (optional) - starts checking from this position in the Array\n    compareFunc - Function (optional) - function used to compare Array item vs passed item\n  Returns:\n    Integer - index position in the Array of the passed item\n  Examples:\n    ['hi','there'].indexOf(\"guys\") === -1\n    ['hi','there'].indexOf(\"hi\") === 0\n*/\nif (!Array.prototype.indexOf)\n{\n    Array.prototype.indexOf = function(item, fromIndex, compareFunc)\n    {\n        if (!fromIndex)\n        {\n            fromIndex = -1;\n        }\n        var index = -1;\n        for (var i = fromIndex; i < this.length; i++)\n        {\n            if (this[i] === item || compareFunc && compareFunc(this[i], item))\n            {\n                index = i;\n                break;\n            }\n        }\n        return index;\n    };\n}\n\n/*\n  You can override this list for all Strings or just one depending on if you\n  set the new values on prototype or on a given String instance.\n*/\nif (!String.prototype._uncountable_words)\n{\n    String.prototype._uncountable_words = InflectionJS.uncountable_words;\n}\n\n/*\n  You can override this list for all Strings or just one depending on if you\n  set the new values on prototype or on a given String instance.\n*/\nif (!String.prototype._plural_rules)\n{\n    String.prototype._plural_rules = InflectionJS.plural_rules;\n}\n\n/*\n  You can override this list for all Strings or just one depending on if you\n  set the new values on prototype or on a given String instance.\n*/\nif (!String.prototype._singular_rules)\n{\n    String.prototype._singular_rules = InflectionJS.singular_rules;\n}\n\n/*\n  You can override this list for all Strings or just one depending on if you\n  set the new values on prototype or on a given String instance.\n*/\nif (!String.prototype._non_titlecased_words)\n{\n    String.prototype._non_titlecased_words = InflectionJS.non_titlecased_words;\n}\n\n/*\n  This function adds plurilization support to every String object\n    Signature:\n      String.pluralize(plural) == String\n    Arguments:\n      plural - String (optional) - overrides normal output with said String\n    Returns:\n      String - singular English language nouns are returned in plural form\n    Examples:\n      \"person\".pluralize() == \"people\"\n      \"octopus\".pluralize() == \"octopi\"\n      \"Hat\".pluralize() == \"Hats\"\n      \"person\".pluralize(\"guys\") == \"guys\"\n*/\nif (!String.prototype.pluralize)\n{\n    String.prototype.pluralize = function(plural)\n    {\n        return InflectionJS.apply_rules(\n            this,\n            this._plural_rules,\n            this._uncountable_words,\n            plural\n        );\n    };\n}\n\n/*\n  This function adds singularization support to every String object\n    Signature:\n      String.singularize(singular) == String\n    Arguments:\n      singular - String (optional) - overrides normal output with said String\n    Returns:\n      String - plural English language nouns are returned in singular form\n    Examples:\n      \"people\".singularize() == \"person\"\n      \"octopi\".singularize() == \"octopus\"\n      \"Hats\".singularize() == \"Hat\"\n      \"guys\".singularize(\"person\") == \"person\"\n*/\nif (!String.prototype.singularize)\n{\n    String.prototype.singularize = function(singular)\n    {\n        return InflectionJS.apply_rules(\n            this,\n            this._singular_rules,\n            this._uncountable_words,\n            singular\n        );\n    };\n}\n\n/*\n  This function adds camelization support to every String object\n    Signature:\n      String.camelize(lowFirstLetter) == String\n    Arguments:\n      lowFirstLetter - boolean (optional) - default is to capitalize the first\n        letter of the results... passing true will lowercase it\n    Returns:\n      String - lower case underscored words will be returned in camel case\n        additionally '/' is translated to '::'\n    Examples:\n      \"message_properties\".camelize() == \"MessageProperties\"\n      \"message_properties\".camelize(true) == \"messageProperties\"\n*/\nif (!String.prototype.camelize)\n{\n     String.prototype.camelize = function(lowFirstLetter)\n     {\n        var str = this.toLowerCase();\n        var str_path = str.split('/');\n        for (var i = 0; i < str_path.length; i++)\n        {\n            var str_arr = str_path[i].split('_');\n            var initX = ((lowFirstLetter && i + 1 === str_path.length) ? (1) : (0));\n            for (var x = initX; x < str_arr.length; x++)\n            {\n                str_arr[x] = str_arr[x].charAt(0).toUpperCase() + str_arr[x].substring(1);\n            }\n            str_path[i] = str_arr.join('');\n        }\n        str = str_path.join('::');\n        return str;\n    };\n}\n\n/*\n  This function adds underscore support to every String object\n    Signature:\n      String.underscore() == String\n    Arguments:\n      N/A\n    Returns:\n      String - camel cased words are returned as lower cased and underscored\n        additionally '::' is translated to '/'\n    Examples:\n      \"MessageProperties\".camelize() == \"message_properties\"\n      \"messageProperties\".underscore() == \"message_properties\"\n*/\nif (!String.prototype.underscore)\n{\n     String.prototype.underscore = function()\n     {\n        var str = this;\n        var str_path = str.split('::');\n        for (var i = 0; i < str_path.length; i++)\n        {\n            str_path[i] = str_path[i].replace(InflectionJS.uppercase, '_$1');\n            str_path[i] = str_path[i].replace(InflectionJS.underbar_prefix, '');\n        }\n        str = str_path.join('/').toLowerCase();\n        return str;\n    };\n}\n\n/*\n  This function adds humanize support to every String object\n    Signature:\n      String.humanize(lowFirstLetter) == String\n    Arguments:\n      lowFirstLetter - boolean (optional) - default is to capitalize the first\n        letter of the results... passing true will lowercase it\n    Returns:\n      String - lower case underscored words will be returned in humanized form\n    Examples:\n      \"message_properties\".humanize() == \"Message properties\"\n      \"message_properties\".humanize(true) == \"message properties\"\n*/\nif (!String.prototype.humanize)\n{\n    String.prototype.humanize = function(lowFirstLetter)\n    {\n        var str = this.toLowerCase();\n        str = str.replace(InflectionJS.id_suffix, '');\n        str = str.replace(InflectionJS.underbar, ' ');\n        if (!lowFirstLetter)\n        {\n            str = str.capitalize();\n        }\n        return str;\n    };\n}\n\n/*\n  This function adds capitalization support to every String object\n    Signature:\n      String.capitalize() == String\n    Arguments:\n      N/A\n    Returns:\n      String - all characters will be lower case and the first will be upper\n    Examples:\n      \"message_properties\".capitalize() == \"Message_properties\"\n      \"message properties\".capitalize() == \"Message properties\"\n*/\nif (!String.prototype.capitalize)\n{\n    String.prototype.capitalize = function()\n    {\n        var str = this.toLowerCase();\n        str = str.substring(0, 1).toUpperCase() + str.substring(1);\n        return str;\n    };\n}\n\n/*\n  This function adds dasherization support to every String object\n    Signature:\n      String.dasherize() == String\n    Arguments:\n      N/A\n    Returns:\n      String - replaces all spaces or underbars with dashes\n    Examples:\n      \"message_properties\".capitalize() == \"message-properties\"\n      \"Message Properties\".capitalize() == \"Message-Properties\"\n*/\nif (!String.prototype.dasherize)\n{\n    String.prototype.dasherize = function()\n    {\n        var str = this;\n        str = str.replace(InflectionJS.space_or_underbar, '-');\n        return str;\n    };\n}\n\n/*\n  This function adds titleize support to every String object\n    Signature:\n      String.titleize() == String\n    Arguments:\n      N/A\n    Returns:\n      String - capitalizes words as you would for a book title\n    Examples:\n      \"message_properties\".titleize() == \"Message Properties\"\n      \"message properties to keep\".titleize() == \"Message Properties to Keep\"\n*/\nif (!String.prototype.titleize)\n{\n    String.prototype.titleize = function()\n    {\n        var str = this.toLowerCase();\n        str = str.replace(InflectionJS.underbar, ' ');\n        var str_arr = str.split(' ');\n        for (var x = 0; x < str_arr.length; x++)\n        {\n            var d = str_arr[x].split('-');\n            for (var i = 0; i < d.length; i++)\n            {\n                if (this._non_titlecased_words.indexOf(d[i].toLowerCase()) < 0)\n                {\n                    d[i] = d[i].capitalize();\n                }\n            }\n            str_arr[x] = d.join('-');\n        }\n        str = str_arr.join(' ');\n        str = str.substring(0, 1).toUpperCase() + str.substring(1);\n        return str;\n    };\n}\n\n/*\n  This function adds demodulize support to every String object\n    Signature:\n      String.demodulize() == String\n    Arguments:\n      N/A\n    Returns:\n      String - removes module names leaving only class names (Ruby style)\n    Examples:\n      \"Message::Bus::Properties\".demodulize() == \"Properties\"\n*/\nif (!String.prototype.demodulize)\n{\n    String.prototype.demodulize = function()\n    {\n        var str = this;\n        var str_arr = str.split('::');\n        str = str_arr[str_arr.length - 1];\n        return str;\n    };\n}\n\n/*\n  This function adds tableize support to every String object\n    Signature:\n      String.tableize() == String\n    Arguments:\n      N/A\n    Returns:\n      String - renders camel cased words into their underscored plural form\n    Examples:\n      \"MessageBusProperty\".tableize() == \"message_bus_properties\"\n*/\nif (!String.prototype.tableize)\n{\n    String.prototype.tableize = function()\n    {\n        var str = this;\n        str = str.underscore().pluralize();\n        return str;\n    };\n}\n\n/*\n  This function adds classification support to every String object\n    Signature:\n      String.classify() == String\n    Arguments:\n      N/A\n    Returns:\n      String - underscored plural nouns become the camel cased singular form\n    Examples:\n      \"message_bus_properties\".classify() == \"MessageBusProperty\"\n*/\nif (!String.prototype.classify)\n{\n    String.prototype.classify = function()\n    {\n        var str = this;\n        str = str.camelize().singularize();\n        return str;\n    };\n}\n\n/*\n  This function adds foreign key support to every String object\n    Signature:\n      String.foreign_key(dropIdUbar) == String\n    Arguments:\n      dropIdUbar - boolean (optional) - default is to seperate id with an\n        underbar at the end of the class name, you can pass true to skip it\n    Returns:\n      String - camel cased singular class names become underscored with id\n    Examples:\n      \"MessageBusProperty\".foreign_key() == \"message_bus_property_id\"\n      \"MessageBusProperty\".foreign_key(true) == \"message_bus_propertyid\"\n*/\nif (!String.prototype.foreign_key)\n{\n    String.prototype.foreign_key = function(dropIdUbar)\n    {\n        var str = this;\n        str = str.demodulize().underscore() + ((dropIdUbar) ? ('') : ('_')) + 'id';\n        return str;\n    };\n}\n\n/*\n  This function adds ordinalize support to every String object\n    Signature:\n      String.ordinalize() == String\n    Arguments:\n      N/A\n    Returns:\n      String - renders all found numbers their sequence like \"22nd\"\n    Examples:\n      \"the 1 pitch\".ordinalize() == \"the 1st pitch\"\n*/\nif (!String.prototype.ordinalize)\n{\n    String.prototype.ordinalize = function()\n    {\n        var str = this;\n        var str_arr = str.split(' ');\n        for (var x = 0; x < str_arr.length; x++)\n        {\n            var i = parseInt(str_arr[x]);\n            if (i === NaN)\n            {\n                var ltd = str_arr[x].substring(str_arr[x].length - 2);\n                var ld = str_arr[x].substring(str_arr[x].length - 1);\n                var suf = \"th\";\n                if (ltd != \"11\" && ltd != \"12\" && ltd != \"13\")\n                {\n                    if (ld === \"1\")\n                    {\n                        suf = \"st\";\n                    }\n                    else if (ld === \"2\")\n                    {\n                        suf = \"nd\";\n                    }\n                    else if (ld === \"3\")\n                    {\n                        suf = \"rd\";\n                    }\n                }\n                str_arr[x] += suf;\n            }\n        }\n        str = str_arr.join(' ');\n        return str;\n    };\n}\n"
  },
  {
    "path": "models/README",
    "content": ""
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"express-mvc-bootstrap\",\n  \"description\": \"Express MVC Application Accelerator\",\n  \"version\": \"0.1.2\",\n  \"homepage\": \"http://cliftonc.github.com/express-mvc-bootstrap\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/cliftonc/express-mvc-bootstrap.git\"\n  },\n  \"main\":\"bootstrap\",\n  \"author\": \"Clifton Cunningham <clifton.cunningham@gmail.com> (cliftoncunningham.co.uk)\",  \n  \"directories\": {\n    \"lib\": \"./lib\",\n    \"conf\": \"./conf\",    \n    \"models\": \"./models\",\n    \"controllers\": \"./controllers\",\n    \"views\": \"./views\",\n    \"public\": \"./public\",\n    \"scripts\": \"./scripts\",\n    \"utils\": \"./utils\",    \n    \"tests\": \"./tests\"    \n  },\n  \"repository\" :\n             { \"type\" : \"git\"\n             , \"url\" : \"https://github.com/cliftonc/express-mvc-bootstrap.git\"\n  },  \n  \"engines\" : { \"node\" : \"0.4 || 0.5\" },\n  \"dependencies\" : { \n             \"express\" : \">=2.0.0beta3\",\n             \"connect\" : \">=1.0.3\",\n             \"cluster\" : \">=0.4.0\",\n             \"ejs\" : \">=0.3.1\",\n             \"socket.io\" : \">=0.6.16\",\n             \"mongoose\" : \">=1.1.3\",\n             \"expresso\" : \">=0.7.3\",\n             \"should\" : \">=0.0.4\"              \n  },\n  \"bin\": { \"eb\": \"./eb\" }\n                \n}"
  },
  {
    "path": "public/css/Aristo/jquery-ui-1.8.7.custom.css",
    "content": "/*\n * jQuery UI CSS Framework 1.8.7\n *\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * http://docs.jquery.com/UI/Theming/API\n */\n\n/* Layout helpers\n----------------------------------*/\n.ui-helper-hidden { display: none; }\n.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }\n.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }\n.ui-helper-clearfix:after { content: \".\"; display: block; height: 0; clear: both; visibility: hidden; }\n.ui-helper-clearfix { display: inline-block; }\n/* required comment for clearfix to work in Opera \\*/\n* html .ui-helper-clearfix { height:1%; }\n.ui-helper-clearfix { display:block; }\n/* end clearfix */\n.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }\n\n\n/* Interaction Cues\n----------------------------------*/\n.ui-state-disabled { cursor: default !important; }\n\n\n/* Icons\n----------------------------------*/\n\n/* states and images */\n.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }\n\n\n/* Misc visuals\n----------------------------------*/\n\n/* Overlays */\n.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }\n\n\n/*\n * jQuery UI CSS Framework 1.8.7\n *\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * http://docs.jquery.com/UI/Theming/API\n *\n * To view and modify this theme, visit http://jqueryui.com/themeroller/?ctl=themeroller\n */\n\n\n/* Component containers\n----------------------------------*/\n.ui-widget { font-family: Helvetica,Arial,sans-serif; font-size: 1.1em; }\n.ui-widget .ui-widget { font-size: 1em; }\n.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Helvetica,Arial,sans-serif; font-size: 1em; }\n.ui-widget-content { border: 1px solid #B6B6B6; background: #ffffff; color: #4F4F4F; }\n.ui-widget-content a { color: #4F4F4F; }\n.ui-widget-header { border: 1px solid #B6B6B6; color: #4F4F4F; font-weight: bold; }\n.ui-widget-header {\n\tbackground: url(images/bg_fallback.png) 0 0 repeat-x;\n\tbackground: -webkit-gradient(\n\t\tlinear,\n\t\tleft bottom,\n\t\tleft top,\n\t\tcolor-stop(1, rgb(237,237,237)),\n\t\tcolor-stop(0, rgb(196,196,196))\n\t);\n\tbackground: -moz-linear-gradient(\n\t\tcenter top,\n\t\trgb(237,237,237),\n\t\trgb(196,196,196)\n\t);\n}\n.ui-widget-header a { color: #4F4F4F; }\n\n/* Interaction states\n----------------------------------*/\n.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #B6B6B6; font-weight: normal; color: #4F4F4F; }\n.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { \n\tbackground: url(images/bg_fallback.png) 0 0 repeat-x;\n\tbackground: -webkit-gradient(\n    linear,\n    left bottom,\n    left top,\n    color-stop(1, rgb(237,237,237)),\n    color-stop(0, rgb(196,196,196))\n\t);\n\tbackground: -moz-linear-gradient(\n\t\tcenter top,\n\t\trgb(237,237,237),\n\t\trgb(196,196,196)\n\t);\n\t-webkit-box-shadow: 0 1px 0 rgba(255,255,255,0.6) inset;\n\t-moz-box-shadow: 0 1px 0 rgba(255,255,255,0.6) inset;\n}\n.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #4F4F4F; text-decoration: none; }\n.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #9D9D9D; font-weight: normal; color: #313131; }\n.ui-state-hover a, .ui-state-hover a:hover { color: #313131; text-decoration: none; }\n.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { \n\toutline: none;\n\tcolor: #1c4257; border: 1px solid #7096ab;\n\tbackground: url(images/bg_fallback.png) 0 -50px repeat-x;\n\tbackground: -webkit-gradient(\n    linear,\n    left bottom,\n    left top,\n    color-stop(1, rgb(185,224,245)),\n    color-stop(0, rgb(146,189,214))\n\t);\n\tbackground: -moz-linear-gradient(\n\t\tcenter top,\n\t\trgb(185,224,245),\n\t\trgb(146,189,214)\n\t);\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n}\n.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #313131; text-decoration: none; }\n.ui-widget :active { outline: none; }\n\n/* Interaction Cues\n----------------------------------*/\n.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight  { border: 1px solid #d2dbf4; background: #f4f8fd; color: #0d2054; -moz-border-radius: 0 !important; -webkit-border-radius: 0 !important; border-radius: 0 !important; }\n.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }\n.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error { border: 1px solid #e2d0d0; background: #fcf0f0; color: #280b0b; -moz-border-radius: 0 !important; -webkit-border-radius: 0 !important; border-radius: 0 !important; }\n.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }\n.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }\n.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }\n.ui-priority-secondary, .ui-widget-content .ui-priority-secondary,  .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }\n.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }\n\n/* Icons\n----------------------------------*/\n\n/* states and images */\n.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }\n.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }\n.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }\n.ui-state-default .ui-icon { background-image: url(images/ui-icons_454545_256x240.png); }\n.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }\n.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }\n.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }\n.ui-state-error .ui-icon, .ui-state-error-text .ui-icon { background: url(images/icon_sprite.png) -16px 0 no-repeat !important; }\n.ui-state-highlight .ui-icon, .ui-state-error .ui-icon { margin-top: -1px; }\n\n/* positioning */\n.ui-icon-carat-1-n { background-position: 0 0; }\n.ui-icon-carat-1-ne { background-position: -16px 0; }\n.ui-icon-carat-1-e { background-position: -32px 0; }\n.ui-icon-carat-1-se { background-position: -48px 0; }\n.ui-icon-carat-1-s { background-position: -64px 0; }\n.ui-icon-carat-1-sw { background-position: -80px 0; }\n.ui-icon-carat-1-w { background-position: -96px 0; }\n.ui-icon-carat-1-nw { background-position: -112px 0; }\n.ui-icon-carat-2-n-s { background-position: -128px 0; }\n.ui-icon-carat-2-e-w { background-position: -144px 0; }\n.ui-icon-triangle-1-n { background-position: 0 -16px; }\n.ui-icon-triangle-1-ne { background-position: -16px -16px; }\n.ui-icon-triangle-1-e { background-position: -32px -16px; }\n.ui-icon-triangle-1-se { background-position: -48px -16px; }\n.ui-icon-triangle-1-s { background-position: -64px -16px; }\n.ui-icon-triangle-1-sw { background-position: -80px -16px; }\n.ui-icon-triangle-1-w { background-position: -96px -16px; }\n.ui-icon-triangle-1-nw { background-position: -112px -16px; }\n.ui-icon-triangle-2-n-s { background-position: -128px -16px; }\n.ui-icon-triangle-2-e-w { background-position: -144px -16px; }\n.ui-icon-arrow-1-n { background-position: 0 -32px; }\n.ui-icon-arrow-1-ne { background-position: -16px -32px; }\n.ui-icon-arrow-1-e { background-position: -32px -32px; }\n.ui-icon-arrow-1-se { background-position: -48px -32px; }\n.ui-icon-arrow-1-s { background-position: -64px -32px; }\n.ui-icon-arrow-1-sw { background-position: -80px -32px; }\n.ui-icon-arrow-1-w { background-position: -96px -32px; }\n.ui-icon-arrow-1-nw { background-position: -112px -32px; }\n.ui-icon-arrow-2-n-s { background-position: -128px -32px; }\n.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }\n.ui-icon-arrow-2-e-w { background-position: -160px -32px; }\n.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }\n.ui-icon-arrowstop-1-n { background-position: -192px -32px; }\n.ui-icon-arrowstop-1-e { background-position: -208px -32px; }\n.ui-icon-arrowstop-1-s { background-position: -224px -32px; }\n.ui-icon-arrowstop-1-w { background-position: -240px -32px; }\n.ui-icon-arrowthick-1-n { background-position: 0 -48px; }\n.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }\n.ui-icon-arrowthick-1-e { background-position: -32px -48px; }\n.ui-icon-arrowthick-1-se { background-position: -48px -48px; }\n.ui-icon-arrowthick-1-s { background-position: -64px -48px; }\n.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }\n.ui-icon-arrowthick-1-w { background-position: -96px -48px; }\n.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }\n.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }\n.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }\n.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }\n.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }\n.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }\n.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }\n.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }\n.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }\n.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }\n.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }\n.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }\n.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }\n.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }\n.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }\n.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }\n.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }\n.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }\n.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }\n.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }\n.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }\n.ui-icon-arrow-4 { background-position: 0 -80px; }\n.ui-icon-arrow-4-diag { background-position: -16px -80px; }\n.ui-icon-extlink { background-position: -32px -80px; }\n.ui-icon-newwin { background-position: -48px -80px; }\n.ui-icon-refresh { background-position: -64px -80px; }\n.ui-icon-shuffle { background-position: -80px -80px; }\n.ui-icon-transfer-e-w { background-position: -96px -80px; }\n.ui-icon-transferthick-e-w { background-position: -112px -80px; }\n.ui-icon-folder-collapsed { background-position: 0 -96px; }\n.ui-icon-folder-open { background-position: -16px -96px; }\n.ui-icon-document { background-position: -32px -96px; }\n.ui-icon-document-b { background-position: -48px -96px; }\n.ui-icon-note { background-position: -64px -96px; }\n.ui-icon-mail-closed { background-position: -80px -96px; }\n.ui-icon-mail-open { background-position: -96px -96px; }\n.ui-icon-suitcase { background-position: -112px -96px; }\n.ui-icon-comment { background-position: -128px -96px; }\n.ui-icon-person { background-position: -144px -96px; }\n.ui-icon-print { background-position: -160px -96px; }\n.ui-icon-trash { background-position: -176px -96px; }\n.ui-icon-locked { background-position: -192px -96px; }\n.ui-icon-unlocked { background-position: -208px -96px; }\n.ui-icon-bookmark { background-position: -224px -96px; }\n.ui-icon-tag { background-position: -240px -96px; }\n.ui-icon-home { background-position: 0 -112px; }\n.ui-icon-flag { background-position: -16px -112px; }\n.ui-icon-calendar { background-position: -32px -112px; }\n.ui-icon-cart { background-position: -48px -112px; }\n.ui-icon-pencil { background-position: -64px -112px; }\n.ui-icon-clock { background-position: -80px -112px; }\n.ui-icon-disk { background-position: -96px -112px; }\n.ui-icon-calculator { background-position: -112px -112px; }\n.ui-icon-zoomin { background-position: -128px -112px; }\n.ui-icon-zoomout { background-position: -144px -112px; }\n.ui-icon-search { background-position: -160px -112px; }\n.ui-icon-wrench { background-position: -176px -112px; }\n.ui-icon-gear { background-position: -192px -112px; }\n.ui-icon-heart { background-position: -208px -112px; }\n.ui-icon-star { background-position: -224px -112px; }\n.ui-icon-link { background-position: -240px -112px; }\n.ui-icon-cancel { background-position: 0 -128px; }\n.ui-icon-plus { background-position: -16px -128px; }\n.ui-icon-plusthick { background-position: -32px -128px; }\n.ui-icon-minus { background-position: -48px -128px; }\n.ui-icon-minusthick { background-position: -64px -128px; }\n.ui-icon-close { background-position: -80px -128px; }\n.ui-icon-closethick { background-position: -96px -128px; }\n.ui-icon-key { background-position: -112px -128px; }\n.ui-icon-lightbulb { background-position: -128px -128px; }\n.ui-icon-scissors { background-position: -144px -128px; }\n.ui-icon-clipboard { background-position: -160px -128px; }\n.ui-icon-copy { background-position: -176px -128px; }\n.ui-icon-contact { background-position: -192px -128px; }\n.ui-icon-image { background-position: -208px -128px; }\n.ui-icon-video { background-position: -224px -128px; }\n.ui-icon-script { background-position: -240px -128px; }\n.ui-icon-alert { background-position: 0 -144px; }\n.ui-icon-info { background: url(images/icon_sprite.png) 0 0 no-repeat !important; }\n.ui-icon-notice { background-position: -32px -144px; }\n.ui-icon-help { background-position: -48px -144px; }\n.ui-icon-check { background-position: -64px -144px; }\n.ui-icon-bullet { background-position: -80px -144px; }\n.ui-icon-radio-off { background-position: -96px -144px; }\n.ui-icon-radio-on { background-position: -112px -144px; }\n.ui-icon-pin-w { background-position: -128px -144px; }\n.ui-icon-pin-s { background-position: -144px -144px; }\n.ui-icon-play { background-position: 0 -160px; }\n.ui-icon-pause { background-position: -16px -160px; }\n.ui-icon-seek-next { background-position: -32px -160px; }\n.ui-icon-seek-prev { background-position: -48px -160px; }\n.ui-icon-seek-end { background-position: -64px -160px; }\n.ui-icon-seek-start { background-position: -80px -160px; }\n/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */\n.ui-icon-seek-first { background-position: -80px -160px; }\n.ui-icon-stop { background-position: -96px -160px; }\n.ui-icon-eject { background-position: -112px -160px; }\n.ui-icon-volume-off { background-position: -128px -160px; }\n.ui-icon-volume-on { background-position: -144px -160px; }\n.ui-icon-power { background-position: 0 -176px; }\n.ui-icon-signal-diag { background-position: -16px -176px; }\n.ui-icon-signal { background-position: -32px -176px; }\n.ui-icon-battery-0 { background-position: -48px -176px; }\n.ui-icon-battery-1 { background-position: -64px -176px; }\n.ui-icon-battery-2 { background-position: -80px -176px; }\n.ui-icon-battery-3 { background-position: -96px -176px; }\n.ui-icon-circle-plus { background-position: 0 -192px; }\n.ui-icon-circle-minus { background-position: -16px -192px; }\n.ui-icon-circle-close { background-position: -32px -192px; }\n.ui-icon-circle-triangle-e { background-position: -48px -192px; }\n.ui-icon-circle-triangle-s { background-position: -64px -192px; }\n.ui-icon-circle-triangle-w { background-position: -80px -192px; }\n.ui-icon-circle-triangle-n { background-position: -96px -192px; }\n.ui-icon-circle-arrow-e { background-position: -112px -192px; }\n.ui-icon-circle-arrow-s { background-position: -128px -192px; }\n.ui-icon-circle-arrow-w { background-position: -144px -192px; }\n.ui-icon-circle-arrow-n { background-position: -160px -192px; }\n.ui-icon-circle-zoomin { background-position: -176px -192px; }\n.ui-icon-circle-zoomout { background-position: -192px -192px; }\n.ui-icon-circle-check { background-position: -208px -192px; }\n.ui-icon-circlesmall-plus { background-position: 0 -208px; }\n.ui-icon-circlesmall-minus { background-position: -16px -208px; }\n.ui-icon-circlesmall-close { background-position: -32px -208px; }\n.ui-icon-squaresmall-plus { background-position: -48px -208px; }\n.ui-icon-squaresmall-minus { background-position: -64px -208px; }\n.ui-icon-squaresmall-close { background-position: -80px -208px; }\n.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }\n.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }\n.ui-icon-grip-solid-vertical { background-position: -32px -224px; }\n.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }\n.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }\n.ui-icon-grip-diagonal-se { background-position: -80px -224px; }\n\n\n/* Misc visuals\n----------------------------------*/\n\n/* Corner radius */\n.ui-corner-tl { -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; border-top-left-radius: 3px; }\n.ui-corner-tr { -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; border-top-right-radius: 3px; }\n.ui-corner-bl { -moz-border-radius-bottomleft: 3px; -webkit-border-bottom-left-radius: 3px; border-bottom-left-radius: 3px; }\n.ui-corner-br { -moz-border-radius-bottomright: 3px; -webkit-border-bottom-right-radius: 3px; border-bottom-right-radius: 3px; }\n.ui-corner-top { -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; border-top-left-radius: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; border-top-right-radius: 3px; }\n.ui-corner-bottom { -moz-border-radius-bottomleft: 3px; -webkit-border-bottom-left-radius: 3px; border-bottom-left-radius: 3px; -moz-border-radius-bottomright: 3px; -webkit-border-bottom-right-radius: 3px; border-bottom-right-radius: 3px; }\n.ui-corner-right {  -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 3px; border-top-right-radius: 3px; -moz-border-radius-bottomright: 3px; -webkit-border-bottom-right-radius: 3px; border-bottom-right-radius: 3px; }\n.ui-corner-left { -moz-border-radius-topleft: 3px; -webkit-border-top-left-radius: 3px; border-top-left-radius: 3px; -moz-border-radius-bottomleft: 3px; -webkit-border-bottom-left-radius: 3px; border-bottom-left-radius: 3px; }\n.ui-corner-all { -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; }\n\n/* Overlays */\n.ui-widget-overlay { background: #262b33; opacity: .70;filter:Alpha(Opacity=70); }\n.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #000000; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*\n * jQuery UI Resizable 1.8.7\n *\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * http://docs.jquery.com/UI/Resizable#theming\n */\n.ui-resizable { position: relative;}\n.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}\n.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }\n.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }\n.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }\n.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }\n.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }\n.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }\n.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }\n.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }\n.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*\n * jQuery UI Selectable 1.8.7\n *\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * http://docs.jquery.com/UI/Selectable#theming\n */\n.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }\n/*\n * jQuery UI Accordion 1.8.7\n *\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * http://docs.jquery.com/UI/Accordion#theming\n */\n/* IE/Win - Fix animation bug - #4615 */\n.ui-accordion { width: 100%; }\n.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }\n.ui-accordion .ui-accordion-header, .ui-accordion .ui-accordion-content { -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; }\n.ui-accordion .ui-accordion-li-fix { display: inline; }\n.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }\n.ui-accordion .ui-accordion-header a { display: block; font-size: 12px; font-weight: bold; padding: .5em .5em .5em .7em; }\n.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }\n.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }\n.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }\n.ui-accordion .ui-accordion-content-active { display: block; }/*\n * jQuery UI Autocomplete 1.8.7\n *\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * http://docs.jquery.com/UI/Autocomplete#theming\n */\n.ui-autocomplete {\n\tposition: absolute; cursor: default;\n\t-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;\n\t-moz-box-shadow: 0 1px 5px rgba(0,0,0,0.3);\n\t-webkit-box-shadow: 0 1px 5px rgba(0,0,0,0.3);\n}\t\n\n/* workarounds */\n* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */\n\n/*\n * jQuery UI Menu 1.8.7\n *\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * http://docs.jquery.com/UI/Menu#theming\n */\n.ui-menu {\n\tlist-style:none;\n\tpadding: 2px;\n\tmargin: 0;\n\tdisplay:block;\n\tfloat: left;\n}\n.ui-menu .ui-menu {\n\tmargin-top: -3px;\n}\n.ui-menu .ui-menu-item {\n\tmargin:0;\n\tpadding: 0;\n\tzoom: 1;\n\tfloat: left;\n\tclear: left;\n\twidth: 100%;\n}\n.ui-menu .ui-menu-item a {\n\ttext-decoration:none;\n\tdisplay:block;\n\tpadding:.2em .4em;\n\tline-height:1.5;\n\tzoom:1;\n}\n.ui-menu .ui-menu-item a.ui-state-hover,\n.ui-menu .ui-menu-item a.ui-state-active {\n\tfont-weight: normal;\n\tmargin: -1px;\n\tbackground: #5f83b9;\n\tcolor: #FFFFFF;\n\ttext-shadow: 0px 1px 1px #234386;\n\tborder-color: #466086;\n\t-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;\n}\n/*\n * jQuery UI Button 1.8.7\n *\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * http://docs.jquery.com/UI/Button#theming\n */\n.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */\n.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */\nbutton.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */\n.ui-button-icons-only { width: 3.4em; } \nbutton.ui-button-icons-only { width: 3.7em; } \n\n/*states*/\n.ui-button.ui-state-hover { \n\t-moz-box-shadow: 0 0 8px rgba(0, 0, 0, 0.15), 0 1px 0 rgba(255,255,255,0.8) inset; \n\t-webkit-box-shadow: 0 0 8px rgba(0, 0, 0, 0.15), 0 1px 0 rgba(255,255,255,0.8) inset;\n}\n.ui-button.ui-state-focus {\n\toutline: none;\n\tcolor: #1c4257; border-color: #7096ab;\n\tbackground-image: -webkit-gradient(\n    linear,\n    left bottom,\n    left top,\n    color-stop(1, rgb(185,224,245)),\n    color-stop(0, rgb(146,189,214))\n\t);\n\tbackground-image: -moz-linear-gradient(\n\t\tcenter top,\n\t\trgb(185,224,245),\n\t\trgb(146,189,214)\n\t);\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n}\n \n/*button text element */\n.ui-button .ui-button-text { display: block; line-height: 1.4; font-size: 14px; font-weight: bold; text-shadow: 0 1px 0 rgba(255, 255, 255, 0.6); }\n.ui-button-text-only .ui-button-text { padding: .4em 1em; }\n.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }\n.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }\n.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }\n.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }\n/* no icon support for input elements, provide padding by default */\ninput.ui-button { padding: .4em 1em; }\n\n/*button icon element(s) */\n.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }\n.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }\n.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }\n.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }\n.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }\n\n/*button sets*/\n.ui-buttonset { margin-right: 7px; }\n.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }\n.ui-buttonset .ui-button.ui-state-active { color: #1c4257; border-color: #7096ab; }\n.ui-buttonset .ui-button.ui-state-active {\n\tbackground-image: -webkit-gradient(\n    linear,\n    left bottom,\n    left top,\n    color-stop(1, rgb(185,224,245)),\n    color-stop(0, rgb(146,189,214))\n\t);\n\tbackground-image: -moz-linear-gradient(\n\t\tcenter top,\n\t\trgb(185,224,245),\n\t\trgb(146,189,214)\n\t);\n\t-webkit-box-shadow: none;\n\t-moz-box-shadow: none;\n}\n\n/* workarounds */\nbutton.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */\n/*\n * jQuery UI Dialog 1.8.7\n *\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * http://docs.jquery.com/UI/Dialog#theming\n */\n.ui-dialog { position: absolute; padding: 0; width: 300px; overflow: hidden; }\n.ui-dialog {\n\t-webkit-box-shadow: 0 2px 12px rgba(0,0,0,0.6);\n\t-moz-box-shadow: 0 2px 12px rgba(0,0,0,0.6);\n}\n.ui-dialog .ui-dialog-titlebar { padding: 0.7em 1em 0.6em 1em; position: relative; border: none; border-bottom: 1px solid #979797; -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;  }\n.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; font-size: 14px; text-shadow: 0 1px 0 rgba(255,255,255,0.5); } \n.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .8em; top: 55%; width: 16px; margin: -10px 0 0 0; padding: 0; height: 16px; }\n.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; background: url(images/icon_sprite.png) 0 -16px no-repeat; }\n.ui-dialog .ui-dialog-titlebar-close:hover span { background-position: -16px -16px; }\n.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; border: 0; }\n.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }\n.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }\n.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }\n.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }\n.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }\n.ui-draggable .ui-dialog-titlebar { cursor: move; }\n/*\n * jQuery UI Slider 1.8.7\n *\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * http://docs.jquery.com/UI/Slider#theming\n */\n.ui-slider { position: relative; text-align: left; background: #d7d7d7; }\n.ui-slider { -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.5) inset; }\n.ui-slider .ui-slider-handle { background: url(images/slider_handles.png) 0px -23px no-repeat; position: absolute; z-index: 2; width: 23px; height: 23px; cursor: default; border: none; outline: none; -moz-box-shadow: none; -webkit-box-shadow: none; }\n.ui-slider  .ui-state-hover, .ui-slider  .ui-state-active { background-position: 0 0; }\n.ui-slider .ui-slider-range { background: #a3cae0; position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }\n.ui-slider .ui-slider-range { -moz-box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; -webkit-box-shadow: 0 1px 2px rgba(17,35,45,0.6) inset; }\n\n\n.ui-slider-horizontal { height: 5px; }\n.ui-slider-horizontal .ui-slider-handle { top: -8px; margin-left: -13px; }\n.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }\n.ui-slider-horizontal .ui-slider-range-min { left: 0; }\n.ui-slider-horizontal .ui-slider-range-max { right: 0; }\n\n.ui-slider-vertical { width: 5px; height: 100px; }\n.ui-slider-vertical .ui-slider-handle { left: -8px; margin-left: 0; margin-bottom: -13px; }\n.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }\n.ui-slider-vertical .ui-slider-range-min { bottom: 0; }\n.ui-slider-vertical .ui-slider-range-max { top: 0; }/*\n * jQuery UI Tabs 1.8.7\n *\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * http://docs.jquery.com/UI/Tabs#theming\n */\n.ui-tabs { position: relative; zoom: 1; border: 0; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as \"fixed\") */\n.ui-tabs .ui-tabs-nav { margin: 0; padding: 0; background: transparent; border-width: 0 0 1px 0; }\n.ui-tabs .ui-tabs-nav { \n\t-moz-border-radius: 0;\n\t-webkit-border-radius: 0;\n\tborder-radius: 0;\n}\n.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }\n.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; font-size: 12px; font-weight: bold; text-shadow: 0 1px 0 rgba(255,255,255,0.5); }\n.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; background: #fff; border-color: #B6B6B6; }\n.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; outline: none; }\n.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */\n.ui-tabs .ui-tabs-panel { display: block; border-width: 0 1px 1px 1px; padding: 1em 1.4em; background: none; }\n.ui-tabs .ui-tabs-panel { \n\t-moz-border-radius: 0;\n\t-webkit-border-radius: 0;\n\tborder-radius: 0;\n}\n.ui-tabs .ui-tabs-hide { display: none !important; }\n/*\n * jQuery UI Datepicker 1.8.7\n *\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * http://docs.jquery.com/UI/Datepicker#theming\n */\n.ui-datepicker { width: 17em; padding: 0; display: none; border-color: #DDDDDD; }\n.ui-datepicker {\n\t-moz-box-shadow: 0 4px 8px rgba(0,0,0,0.5);\n\t-webkit-box-shadow: 0 4px 8px rgba(0,0,0,0.5);\n\tbox-shadow: 0 4px 8px rgba(0,0,0,0.5);\n}\n.ui-datepicker .ui-datepicker-header { position:relative; padding:.35em 0; border: none; border-bottom: 1px solid #B6B6B6; -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; }\n.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 6px; width: 1.8em; height: 1.8em; }\n.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { border: 1px none; }\n.ui-datepicker .ui-datepicker-prev { left:2px; }\n.ui-datepicker .ui-datepicker-next { right:2px; }\n.ui-datepicker .ui-datepicker-prev span { background-position: 0px -32px !important; }\n.ui-datepicker .ui-datepicker-next span { background-position: -16px -32px !important; }\n.ui-datepicker .ui-datepicker-prev-hover span { background-position: 0px -48px !important; }\n.ui-datepicker .ui-datepicker-next-hover span { background-position: -16px -48px !important; }\n.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; background: url(images/icon_sprite.png) no-repeat; }\n.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; font-size: 12px; text-shadow: 0 1px 0 rgba(255,255,255,0.6); }\n.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }\n.ui-datepicker select.ui-datepicker-month-year {width: 100%;}\n.ui-datepicker select.ui-datepicker-month, \n.ui-datepicker select.ui-datepicker-year { width: 49%;}\n.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }\n.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0;  }\n.ui-datepicker td { border: 0; padding: 1px; }\n.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }\n.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }\n.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }\n.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }\n.ui-datepicker .ui-state-default { background: transparent; border-color: #FFF; }\n.ui-datepicker .ui-state-active { background: #5F83B9; border-color: #5F83B9; color: #FFF; font-weight: bold; text-shadow: 0 1px 1px #234386; }\n\n/* with multiple calendars */\n.ui-datepicker.ui-datepicker-multi { width:auto; }\n.ui-datepicker-multi .ui-datepicker-group { float:left; }\n.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }\n.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }\n.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }\n.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }\n.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }\n.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }\n.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }\n.ui-datepicker-row-break { clear:both; width:100%; }\n\n/* RTL support */\n.ui-datepicker-rtl { direction: rtl; }\n.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }\n.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }\n.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }\n.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }\n.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }\n.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }\n.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }\n.ui-datepicker-rtl .ui-datepicker-group { float:right; }\n.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }\n.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }\n\n/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */\n.ui-datepicker-cover {\n    display: none; /*sorry for IE5*/\n    display/**/: block; /*sorry for IE5*/\n    position: absolute; /*must have*/\n    z-index: -1; /*must have*/\n    filter: mask(); /*must have*/\n    top: -4px; /*must have*/\n    left: -4px; /*must have*/\n    width: 200px; /*must have*/\n    height: 200px; /*must have*/\n}/*\n * jQuery UI Progressbar 1.8.7\n *\n * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * http://docs.jquery.com/UI/Progressbar#theming\n */\n.ui-progressbar { height: 12px; text-align: left; background: url(images/progress_bar.gif) 0 -14px repeat-x; }\n.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; background: url(images/progress_bar.gif) 0 0 repeat-x; }"
  },
  {
    "path": "public/css/style.css",
    "content": "/*--- Reset ---*/\n* { margin: 0; padding: 0; }\n\nhtml, body { height: 100%; min-height: 100%; background-color: #000000; }\n\n/*--- Layout ---*/\nbody {\n\tfont-family: Helvetica, Arial, sans-serif;\n\tfont-size: 14px;\n\tline-height: 1.5em;\n\tcolor: #0d0d0d;\n\tbackground-color: #fff;\n}\n\n#container {\n\tposition: relative;\n\tpadding: 10px 10%;\n}\n\n/*--- Basics ---*/\nh1, h2, h3, h4, h5, h6 {\n\tfont-weight:normal;\n\tcolor:#111;\n\tline-height: 1;\n\tmargin: 1.5em 0 0.5em 0;\n}\nh1 { font-size: 1.6em; }\nh2, h5 { font-size: 1.3em; color: #666; }\nh3, h6 { font-size: 1.2em; color: #00a8e6; }\nh4 { font-size: 1.1em; }\nh5 { font-size: 1.1em; }\nh6 { font-size: 1em; }\np { margin-bottom: 1em; }\nstrong { font-weight: bold; }\nem { font-style: italic; }\na { text-decoration: none; color: #333; }\na, h1 a, h2 a { text-decoration: none; }\na:hover { color: #232323; }\na:visited:hover { color: #232323; }\na img { border: none; }\n\n/*--- Lists ---*/\nli ul, li ol { margin: 0; }\nul, ol { margin: 0 0 1em 2.75em; }\ndt, dd {\n\tfont-style: italic;\n\tmargin: .5em 0;\n}\ndt {\n\tfont-weight: bold;\n}\ndd {\n\tmargin-left: 1em;\n}\n/*--- Header ---*/\n#header h1 {\n\tmargin: .1em 0;\n\tfont-size: 2.2em;\n}\n#header h2 {\n\twidth: 70%;\n\tmargin: .5em .5em 2em 0;\n\tcolor: #666;\n\tfont-size: 1.3em;\n\tline-height: 22px;\n}\n\n/*--- Tables ---*/\ntable {\n\tclear: both;\n\twidth: 100%;\n\tborder-collapse: collapse;\n\tborder-spacing: 0;\n\tborder: 1px solid #e6e6e6;\n\tbackground: #eaeafa;\n\tmargin: 12px 0;\n}\ntd, th {\n\tpadding: .25em 1em;\n\tborder: 1px solid #a6a6c6;\n\tvertical-align: middle;\n\ttext-align: left;\n\tfont-weight: normal;\n\tcolor: #333;\n\tfont-size: 0.85em;\n}\n\ntable tr {\n\tbackground: #fff;\n}\n\ntable.tabular tr:nth-child(even) {\n\tbackground: #eaeafa;\n}\n\ntfoot td {\n\tbackground: #d3d3f3;\n\tcolor: #333;\n\ttext-align: left;\t\n\tpadding: 1em 0.5em;\n\tfont-size: 0.7em;\n}\n\nth {\n\tbackground: #d3d3f3;\n\tcolor: #333;\n\ttext-align: left;\n\tfont-weight: bold;\n\tpadding: .5em .75em;\n}\n/*--- Forms ---*/\nform {\n\tdisplay: block;\n\tclear: both;\n\tbackground: #eaeafa;\n\tpadding: 1em 2em 2em 2em;\n\tborder: 1px solid #a6a6c6;\n}\nfieldset {\n\tpadding: 2em;\n\tmargin: 0 0 1em 0;\n\tborder: 1px solid #a6a6c6;\n\tbackground: #f3f3f3;\n}\nlegend {\n\tpadding: .5em 1em;\n\tborder: 1px solid #a6a6c6;\n\tbackground: #fff;\n\tfont-size: 22px;\n}\nlabel {\n\tpadding: 0 1em 0 0;\n\tcolor: #454545;\n\tfont-weight: normal;\n}\ninput[type=text],[type=password], textarea {\n\tfont-family: Helvetica, Arial, sans-serif;\n\tpadding: 2px 4px;\n\tborder: 1px solid #a6a6c6;\n\tcolor: #454545;\n\tfont-size: 1em;\n\tline-height: 1.25em;\n}\ninput[type=text], input[type=password], textarea {\n\tclear: both;\n\tdisplay: block;\n\tpadding: .25em .5em;\n}\ninput[type=text], input[type=password], textarea {\n\twidth: 97%;\n\tmax-width: 950px;\n\tmargin: .5em 0 1em 0;\n\tpadding:.5em;\n}\nselect {\n\tclear: both;\n\tdisplay: block;\n\tmargin: .5em 0 1em 0;\n}\ndiv.checkbox {\n\tclear: both;\n\tpadding: 1em 0;\n}\n.checkbox label {\n\tdisplay: inline;\n}\n\ninput[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus {\n\tborder-color: #00a8e6;\n\toutline: none;\n}\n\n/*--- Misc ---*/\nhr {\n\tborder: none;\n\theight: 0;\n\tborder-bottom: 1px solid #e6e6e6;\n\tmargin:1em 0;\n}\nsup, sub {\n\tcolor: #666;\n\tfont-size: .65em;\n}\nacronym {\n\tfont-weight: bold;\n\tfont-style: italic;\n\tcolor: #333;\n}\nabbr {\n\tcolor: #333;\n}\n\nblockquote {\n\tpadding: 0.15em .5em;\n\tmargin: 0.5em 0;\n\tfont-size: 2em;\n\tcolor: #666;\t\n\tdisplay: block;\n\tfont-style: italic;\n}\n\nblockquote:before, blockquote:after {\n\tdisplay: inline;\n\tcolor: #e5e5e5;\n\tfont-size: 3em;\n\tposition: relative;\n\ttop: 0.25em;\n\tleft: -0.1em;\n}\n\nblockquote:before {\n\tcontent: '\\D \\201C';\n}\n\n\nspan.pager-page {\n\tfont-family: Helvetica, Arial, sans-serif;\n\tpadding: 3px 3px;\n\tmargin: 3px 3px 3px 3px;\n\tcolor: #454545;\t\n\tline-height: 1.25em;\t\n}\n\ninput.pager-page {\n\tdisplay: inline !important; \n\twidth: 30px;\n\tfont-family: Helvetica, Arial, sans-serif;\n\tpadding: 2px 2px;\n\tmargin: 3px 3px 3px 3px;\n\tcolor: #454545;\t\n\tline-height: 1.25em;\t\n\tclear: none;\n}\n\na.pager-page {\n\tfont-family: Helvetica, Arial, sans-serif;\n\tpadding: 3px 3px;\n\tmargin: 3px 3px 3px 3px;\t\n\tborder: 1px solid #a6a6c6;\n\tcolor: #454545;\t\n\tline-height: 1.25em;\n\tbackground-color: #efefef;\n}\n\nblockquote:after {\n\tcontent: '\\201D';\n}\n\npre.code {\n\tpadding: 10px;\n\tcolor: white;\n\tbackground-color: #883434;\n\tmargin-top: 10px;\t\n}\n\n/*--- Shadows ---*/\npre.code {\n\t-moz-box-shadow: 0 0 3px rgba(0,0,0,.1);\n\t-webkit-box-shadow: 0 0 3px rgba(0,0,0,.1);\n\tbox-shadow: 0 0 3px rgba(0,0,0,.1);\t\n}\ntable, form {\n\tmargin-top: 0px;\n\tmargin-bottom: 12px;\n}\ntable, form, pre > code, .shadow {\n\t-moz-box-shadow: 2px 2px 12px rgba(0,0,0,.15);\n\t-webkit-box-shadow: 2px 2px 12px rgba(0,0,0,0.15);\n\tbox-shadow: 2px 2px 12px rgba(0,0,0,.15);\n}\nimg.shadow {\n\tborder: 1px solid rgba(255,255,255,.15);\n}\n\ninput[type=text],input[type=password], textarea {\n\t-moz-box-shadow: inset 0 0 5px rgba(0,0,0,.2);\n\t-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,.2);\n\tbox-shadow: inset 0 0 5px rgba(0,0,0,.2);\n}"
  },
  {
    "path": "scripts/create-controller.js",
    "content": "var ejs = require('ejs')\n   , fs = require('fs')\n   , path = require('path')\n   , inflection = require('../lib/inflection');\n\n/** \n * Script to create a default controller, requires the model to exist\n */\nexports.execute = function(params,appPath) {\n\t\t \n\tif(params.length == 0 ) {\n\t\tconsole.log(\"You must specifiy a model name to generate the controller against!\");\n\t\treturn;\n\t}\n\t\n\t/**\n\t * Create the model based on a singular (e.g. people becomes person, users becomes user)\n\t */\n\tvar modelName = params[0].singularize();\t\n\tif(modelName != params[0]) {\n\t\tconsole.log(\"Using model name as singular not plural: \" + modelName);\t\n\t}\n\t\n\t// Capitalise\n\tmodelName = modelName.capitalize();\t\n\t\n\tvar modelFile = appPath + \"/models/\" + modelName + '.js'\n\t\n\tvar controllerName = modelName.pluralize();\n\t\n\tvar controllerFile = appPath + \"/controllers/\" + controllerName + 'Controller.js'\n\tvar controllerTemplate = __dirname + '/templates/create-controller.template.ejs';\n\t\t\n\t// Check if the model exists\n\tvar fileCheck = path.existsSync(modelFile);\n\tif(!fileCheck) {\t\t\n\t\tconsole.log(\"The model you have specified doesn't exist!\");\n\t\tconsole.log(\"You need to create the model first.\");\n\t\tconsole.log(\"e.g. script create-model \" + modelName);\n\t\treturn;\t\t\n\t}\n\n\t// Check if the controller exists\n\tvar fileCheck = path.existsSync(controllerFile);\n\tif(fileCheck) {\t\t\n\t\tif(params[1] != \"force\") {\n\t\t\tconsole.log(\"The controller already exists!\");\n\t\t\tconsole.log(\"Add an additional paramater of 'force' to over write the controller.\");\n\t\t\tconsole.log(\"e.g. script create-controller \" + modelName + \" force\");\n\t\t\treturn;\n\t\t}\n\t}\n\n\t\n\t// Read the template\n\tvar str = fs.readFileSync(controllerTemplate, 'utf8');\t\t\n\t\n\t// Render the model\n\tvar ret = ejs.render(str, {\n\t  locals: {\t\t\n\t    controllerName:controllerName,\n\t    modelName:modelName\n\t  },open: \"<?\",close: \"?>\"\n\t});\n\t\n\t// Write the file\n\tfs.writeFileSync(controllerFile, ret,'utf8');\n\t\n\tconsole.log('Controller for model ' + modelName + ' created in controllers/' + controllerName + 'Controller.js');\n\t\n\t\n};"
  },
  {
    "path": "scripts/create-model.js",
    "content": "var ejs = require('ejs')\n   , fs = require('fs')\n   , path = require('path'),\n   \t inflection = require('../lib/inflection');\n\n/** \n * Script to create a default model\n */\nexports.execute = function(params,appPath) {\n\t\t \n\tif(params.length == 0 ) {\n\t\tconsole.log(\"You must specifiy a model name.\");\n\t\treturn;\n\t}\n\t\n\t/**\n\t * Create the model based on a singular (e.g. people becomes person, users becomes user)\n\t */\n\tvar modelName = params[0].singularize();\t\n\tif(modelName != params[0]) {\n\t\tconsole.log(\"Creating model using singular not plural: \" + modelName);\t\n\t}\n\t\n\t// Capitalise\n\tmodelName = modelName.capitalize();\n\t\n\t// Define the files\n\tvar modelFile = appPath + \"/models/\" + modelName + '.js'\n\tvar modelTemplate = __dirname + '/templates/create-model.template.ejs';\n\t\t\n\t// Check if it already exists\n\tvar fileCheck = path.existsSync(modelFile);\n\tif(fileCheck) {\t\t\n\t\tif(params[1] != \"force\") {\n\t\t\tconsole.log(\"The model already exists!\");\n\t\t\tconsole.log(\"Add an additional paramater of 'force' to over write the model.\");\n\t\t\tconsole.log(\"e.g. script create-model \" + modelName + \" force\");\n\t\t\treturn;\n\t\t}\n\t}\n\t\n\t// Read the template\n\tvar str = fs.readFileSync(modelTemplate, 'utf8');\t\t\n\t\n\t// Render the model\n\tvar ret = ejs.render(str, {\n\t  locals: {\n\t    name:modelName\n\t  },open: \"<?\",close: \"?>\"\n\t});\n\t\n\t// Write the file\n\tfs.writeFileSync(modelFile, ret,'utf8');\n\t\n\tconsole.log('Model ' + modelName + ' created in models/' + modelName + '.js');\n\t\n\t\n};"
  },
  {
    "path": "scripts/create-test.js",
    "content": "var  ejs = require('ejs')\n   , fs = require('fs')\n   , path = require('path')\n   , inflection = require('../lib/inflection');\n\n\n/** \n * Script to create a default test scripts, requires the model to exist\n */\nexports.execute = function(params,appPath) {\n\t\t \n\tif(params.length == 0 ) {\n\t\tconsole.log(\"You must specifiy a model name to generate the tests against!\");\n\t\treturn;\n\t}\n\t\n\t/**\n\t * Create the model based on a singular (e.g. people becomes person, users becomes user)\n\t */\n\tvar modelName = params[0].singularize();\t\n\tif(modelName != params[0]) {\n\t\tconsole.log(\"Using model name as singular not plural: \" + modelName);\t\n\t}\n\t\n\t// Capitalise\n\tmodelName = modelName.capitalize();\t\n\t\n\tvar modelFile = appPath + \"/models/\" + modelName + '.js'\n\t\n\tvar controllerName = modelName.pluralize();\n\t\n\tvar testFolder = appPath + \"/tests/\";\n\t\n\tvar unitTemplate = __dirname + '/templates/create-test.template.unit.ejs';\n\tvar integrationTemplate = __dirname + '/templates/create-test.template.integration.ejs';\n\tvar functionalTemplate = __dirname + '/templates/create-test.template.functional.ejs';\n\t\t\n\t// Check if the model exists\n\tvar fileCheck = path.existsSync(modelFile);\n\tif(!fileCheck) {\t\t\n\t\tconsole.log(\"The model you have specified doesn't exist!\");\n\t\tconsole.log(\"You need to create the model first.\");\n\t\tconsole.log(\"e.g. script create-model \" + modelName);\n\t\treturn;\t\t\n\t}\n\n\t// Check if the unit test exists \n\tvar fileCheck = path.existsSync(testFolder + \"/unit/\" + modelName + '.js');\n\tif(fileCheck) {\t\t\n\t\tif(params[1] != \"force\") {\n\t\t\tconsole.log(\"Tests appear to already exist for this model!\");\n\t\t\tconsole.log(\"Add an additional paramater of 'force' to over write the tests.\");\n\t\t\tconsole.log(\"e.g. script create-test \" + modelName + \" force\");\n\t\t\treturn;\n\t\t}\n\t}\n\t\n\t// Read the template\n\tvar tmpUnit = fs.readFileSync(unitTemplate, 'utf8');\n\tvar tmpIntegration = fs.readFileSync(integrationTemplate, 'utf8');\n\tvar tmpFunctional = fs.readFileSync(functionalTemplate, 'utf8');\n\t\n\t// Render the views\n\tvar retUnit = ejs.render(tmpUnit, { locals: { modelName:modelName, controllerName:controllerName },open: \"<?\",close: \"?>\" });\n\tvar retIntegration = ejs.render(tmpIntegration, { locals: { modelName:modelName, controllerName:controllerName },open: \"<?\",close: \"?>\" });\n\tvar retFunctional = ejs.render(tmpFunctional, { locals: { modelName:modelName, controllerName:controllerName },open: \"<?\",close: \"?>\" });\n\t\n\t// Write the file\n\tfs.writeFileSync(testFolder + \"/unit/\" + modelName + '.js', retUnit,'utf8');\n\tfs.writeFileSync(testFolder + \"/integration/\" + controllerName + 'Controller.js', retIntegration,'utf8');\n\tfs.writeFileSync(testFolder + \"/functional/\" + modelName + '.js', retFunctional,'utf8');\t\n\t\n\tconsole.log('Tests for ' + modelName + ' created in tests.');\n\n\t\n};"
  },
  {
    "path": "scripts/create-view.js",
    "content": "var  ejs = require('ejs')\n   , fs = require('fs')\n   , path = require('path')\n   , inflection = require('../lib/inflection');\n\n\n/** \n * Script to create a default view, requires the model to exist\n */\nexports.execute = function(params,appPath) {\n\t\t \n\tif(params.length == 0 ) {\n\t\tconsole.log(\"You must specifiy a model name to generate the views against!\");\n\t\treturn;\n\t}\n\t\n\t/**\n\t * Create the model based on a singular (e.g. people becomes person, users becomes user)\n\t */\n\tvar modelName = params[0].singularize();\t\n\tif(modelName != params[0]) {\n\t\tconsole.log(\"Using model name as singular not plural: \" + modelName);\t\n\t}\n\t\n\t// Capitalise\n\tmodelName = modelName.capitalize();\t\n\t\n\tvar modelFile = appPath + \"/models/\" + modelName + '.js'\n\t\n\tvar controllerName = modelName.pluralize();\n\t\n\tvar viewFolder = appPath + \"/views/\" + controllerName.toLowerCase();\n\t\n\tvar viewIndexTemplate = __dirname + '/templates/create-view.template.index.ejs';\n\tvar viewEditTemplate = __dirname + '/templates/create-view.template.edit.ejs';\n\tvar viewShowTemplate = __dirname + '/templates/create-view.template.show.ejs';\n\t\t\n\t// Check if the model exists\n\tvar fileCheck = path.existsSync(modelFile);\n\tif(!fileCheck) {\t\t\n\t\tconsole.log(\"The model you have specified doesn't exist!\");\n\t\tconsole.log(\"You need to create the model first.\");\n\t\tconsole.log(\"e.g. script create-model \" + modelName);\n\t\treturn;\t\t\n\t}\n\n\t// Check if the view exists\n\tvar fileCheck = path.existsSync(viewFolder);\n\tif(fileCheck) {\t\t\n\t\tif(params[1] != \"force\") {\n\t\t\tconsole.log(\"The views folder already exists for this model!\");\n\t\t\tconsole.log(\"Add an additional paramater of 'force' to over write the views.\");\n\t\t\tconsole.log(\"e.g. script create-view \" + modelName + \" force\");\n\t\t\treturn;\n\t\t}\n\t} else {\n\t\tfs.mkdirSync(viewFolder,'755');\n\t}\t\n\t\n\t// Read the template\n\tvar tmpIndex = fs.readFileSync(viewIndexTemplate, 'utf8');\n\tvar tmpEdit = fs.readFileSync(viewEditTemplate, 'utf8');\n\tvar tmpShow = fs.readFileSync(viewShowTemplate, 'utf8');\n\t\n\t// Render the views\n\tvar retIndex = ejs.render(tmpIndex, { locals: { modelName:modelName, controllerName:controllerName },open: \"<?\",close: \"?>\" });\n\tvar retEdit = ejs.render(tmpEdit, { locals: { modelName:modelName, controllerName:controllerName },open: \"<?\",close: \"?>\" });\n\tvar retShow = ejs.render(tmpShow, { locals: { modelName:modelName, controllerName:controllerName },open: \"<?\",close: \"?>\" });\n\t\n\t// Write the file\n\tfs.writeFileSync(viewFolder + \"/index.html\", retIndex,'utf8');\n\tfs.writeFileSync(viewFolder + \"/edit.html\", retEdit,'utf8');\n\tfs.writeFileSync(viewFolder + \"/show.html\", retShow,'utf8');\t\n\t\n\tconsole.log('Views ' + modelName + ' created in views/' + modelName.toLowerCase());\n\t\n\t\n};"
  },
  {
    "path": "scripts/generate-all.js",
    "content": "/** \n * Script to create a model, controller and views\n */\nexports.execute = function(params,appPath) {\n\t\t \n\tif(params.length == 0 ) {\n\t\tconsole.log(\"You must specifiy a model name to generate all of the assets for!\");\n\t\treturn;\n\t}\n\t\n\tvar modelScript = require('./create-model');\t\n\tvar controllerScript = require('./create-controller');\n\tvar viewScript = require('./create-view');\n\tvar testScript = require('./create-test');\n\t\n\tmodelScript.execute(params,appPath);\n\tcontrollerScript.execute(params,appPath);\n\tviewScript.execute(params,appPath);\n\ttestScript.execute(params,appPath);\n\t\n};"
  },
  {
    "path": "scripts/help.js",
    "content": "var ejs = require('ejs')\n   , fs = require('fs');\n\n/** \n * Help file\n */\nexports.execute = function(params,appPath) {\n\t\t \t\t\n\t\tif(params.length == 0) {\n\t\t\tvar str = fs.readFileSync(__dirname + '/templates/help.ejs', 'utf8');\t\n\t\t} else {\n\t\t\tvar str = fs.readFileSync(__dirname + '/templates/' + params[0] + '.help.ejs', 'utf8');\n\t\t}\t\t\n\n\t\tvar scripts = [];\n\t\t\n\t\tfs.readdir(__dirname + '/', function(err, files){\t\t    \n\t\t    \n\t\t\tif(err) {\n\t\t\t\tconsole.log(err);\n\t\t\t}\n\t\t\t\n\t\t\tfiles.forEach(function(file){\n\t\t\t   if(file.replace('.js','') != file) {\n\t\t\t\t   scripts.push(file.replace('.js',''));\n\t\t\t   }\t\t       \t\n\t\t    });\t\t\t\n\t\t\t\t\t\t\n\t\t\tvar ret = ejs.render(str, {\n\t\t\t  locals: {\n\t\t\t    params: params,\n\t\t\t    scripts: scripts\n\t\t\t  },open: \"<?\",close: \"?>\"\t\t\t  \n\t\t\t});\n\t\t\t\n\t\t\tconsole.log(ret);\n\t\t\n\t\t});\t\t  \n\t\t\n\t\t\n};"
  },
  {
    "path": "scripts/templates/create-controller.help.ejs",
    "content": "\nExpress MVC Bootstrapper - Version 0.10\nThis is the help file for 'create-controller' command.\n\nCommand format:\nnode app.js script create-controller [MODELNAME]\n\n[MODELNAME]  The name (case sensitive) for the model you want to create a controller for.\n "
  },
  {
    "path": "scripts/templates/create-controller.template.ejs",
    "content": "<?\n\tvar modelVariable = modelName.toLowerCase();\n\tvar basePath = modelName.toLowerCase();\n\tvar basePathPlural = controllerName.toLowerCase();\n?>\n/**\n *  <?= controllerName ?> Controller\n *  Created by create-controller script @ <?= new Date() ?>\n **/\n var mongoose = require('mongoose'),\t\n\t<?= modelName ?> = mongoose.model('<?= modelName ?>'),\n\tpager = require('../utils/pager.js'),\n\tViewTemplatePath = '<?= basePathPlural ?>';\n\nmodule.exports = {\n\n\t/**\n\t * Index action, returns a list either via the views/<?= basePathPlural ?>/index.html view or via json\n\t * Default mapping to GET '/<?= basePathPlural ?>'\n\t * For JSON use '/<?= basePathPlural ?>.json'\n\t **/\n\tindex: function(req, res, next) {\n\t\t  \t \n\t\t  var from = req.params.from ? parseInt(req.params.from) - 1 : 0;\n\t\t  var to = req.params.to ? parseInt(req.params.to) : 10;\n\t      var total = 0;\n\t      \n\t      <?= modelName ?>.count({}, function (err, count) {\n\t    \ttotal = count;  \n\t    \tvar pagerHtml = pager.render(from,to,total,'/<?= basePathPlural ?>');    \t\n\t                  \n\t\t\t  <?= modelName ?>.find({})\n\t\t\t  \t.sort('name', 1)\n\t\t\t  \t.skip(from).limit(to)\n\t\t\t  \t.find(function (err, <?= basePathPlural ?>) {\n\t\t\t\t\n\t\t\t\t  if(err) return next(err);\n\t\t\t\t  \n\t\t\t      switch (req.params.format) {\n\t\t\t        case 'json':\t          \n\t\t\t          res.send(<?= basePathPlural ?>.map(function(u) {\n\t\t\t              return u.toObject();\n\t\t\t          }));\n\t\t\t          break;\n\t\t\n\t\t\t        default:\t\t\t        \t\n\t\t\t        \tres.render(ViewTemplatePath,{<?= basePathPlural ?>:<?= basePathPlural ?>,pagerHtml:pagerHtml});\n\t\t\t      }\n\t\t\t      \n\t\t\t  });\n\t      \n\t      });\n\t      \t  \t\n\t},\n\t\n\t/**\n\t * Show action, returns shows a single item via views/<?= basePathPlural ?>/show.html view or via json\n\t * Default mapping to GET '/<?= basePath ?>/:id'\n\t * For JSON use '/<?= basePath ?>/:id.json'\n\t **/\t\n\tshow: function(req, res, next) {\t  \t\t  \n\t\t\t\n\t\t  <?= modelName ?>.findById(req.params.id, function(err, <?= modelVariable ?>) {\n\t\t\t  \n\t\t\t  if(err) return next(err);\n\t\t\t  \n\t\t      switch (req.params.format) {\n\t\t        case 'json':\n\t\t          res.send(<?= modelVariable ?>.toObject());\n\t\t          break;\n\t\n\t\t        default:\n\t\t        \tres.render(ViewTemplatePath + \"/show\",{<?= modelVariable ?>:<?= modelVariable ?>});\n\t\t      }\n\t\t      \n\t\t  });\n\t\t      \n\t},\n\t\n\t/**\n\t * Edit action, returns a form via views/<?= basePathPlural ?>/edit.html view no JSON view.\n\t * Default mapping to GET '/<?= basePath ?>/:id/edit'\n\t **/  \t  \n\tedit: function(req, res, next){\n\t\t  <?= modelName ?>.findById(req.params.id, function(err, <?= modelVariable ?>) {\n\t\t\t  if(err) return next(err);\n\t\t\t  res.render(ViewTemplatePath + \"/edit\",{<?= modelVariable ?>:<?= modelVariable ?>});\n\t\t});\n\t},\n\t  \n\t/**\n\t * Update action, updates a single item and redirects to Show or returns the object as json\n\t * Default mapping to PUT '/<?= basePath ?>/:id', no GET mapping\t \n\t **/  \n\tupdate: function(req, res, next){\n\t    \n\t    <?= modelName ?>.findById(req.params.id, function(err, <?= modelVariable ?>) {\n\t        \n\t    \tif (!<?= modelVariable ?>) return next(err);\n\t        \n\t    \t<?= modelVariable ?>.name = req.body.<?= modelVariable ?>.name;\n\t    \t\n\t        <?= modelVariable ?>.save(function(err) {\n\t        \n\t    \t  if (err) {\n\t    \t\t  console.log(err);\n\t        \t  req.flash('error','Could not update <?= modelVariable ?>: ' + err);\n\t          \t  res.redirect('/<?= basePathPlural ?>');\n\t          \t  return;\n\t    \t  }\n\t    \t\t\n\t          switch (req.params.format) {\n\t            case 'json':\n\t              res.send(<?= modelVariable ?>.toObject());\n\t              break;\n\t            default:\n\t              req.flash('info', '<?= modelName ?> updated');\n\t              res.redirect('/<?= modelVariable ?>/' + req.params.id);\n\t          }\n\t        });\n\t      });\n\t},\n\t  \n\t/**\n\t * Create action, creates a single item and redirects to Show or returns the object as json\n\t * Default mapping to POST '/<?= basePathPlural ?>', no GET mapping\t \n\t **/  \n\tcreate: function(req, res, next){\n\t\t  \n\t\t  var <?= modelVariable ?> = new <?= modelName ?>(req.body.<?= modelVariable ?>);\n\t\t  \n\t\t  <?= modelVariable ?>.save(function(err) {\n\t\t   \n\t\t\tif (err) {\n\t    \t  req.flash('error','Could not create <?= modelVariable ?>: ' + err);\n\t      \t  res.redirect('/<?= basePathPlural ?>');\n\t      \t  return;\n\t\t\t}\n\t\n\t\t    switch (req.params.format) {\n\t\t      case 'json':\n\t\t        res.send(<?= modelVariable ?>.toObject());\n\t\t        break;\n\t\n\t\t      default:\n\t\t    \t  req.flash('info','<?= modelName ?> created');\n\t\t      \t  res.redirect('/<?= modelVariable ?>/' + <?= modelVariable ?>.id);\n\t\t\t }\n\t\t  });\t  \n\t\t  \n\t},\n\t  \n\t/**\n\t * Delete action, deletes a single item and redirects to index\n\t * Default mapping to DEL '/<?= basePath ?>/:id', no GET mapping\t \n\t **/ \n\tdestroy: function(req, res, next){\n\t\t  \n\t\t  <?= modelName ?>.findById(req.params.id, function(err, <?= modelVariable ?>) {\n\t\t        \n\t\t    \tif (!<?= modelVariable ?>) { \n\t  \t    \t  \treq.flash('error','Unable to locate the <?= modelVariable ?> to delete!');\n\t\t    \t\tres.send('false'); \n\t\t    \t\treturn false; \n\t\t    \t};\n\t\t    \t\t    \n\t\t    \t<?= modelVariable ?>.remove(function(err) {\n\t    \t\t  if(err) {\n\t    \t    \t  req.flash('error','There was an error deleting the <?= modelVariable ?>!');\n\t    \t\t\t  res.send('false');\n\t    \t\t  } else {\n\t    \t    \t  req.flash('info','<?= modelName ?> deleted');\n\t    \t\t\t  res.send('true');\n\t    \t\t  }    \t          \n\t   \t      \t}); \n\t\t  });\n\t\t  \n\t}\n\t\n};"
  },
  {
    "path": "scripts/templates/create-model.help.ejs",
    "content": "\nExpress MVC Bootstrapper - Version 0.10\nThis is the help file for 'create-model' command.\n\nCommand format:\nnode app.js script create-model [MODELNAME]\n\n[MODELNAME]  The name (case sensitive) for the model you want to create.\n "
  },
  {
    "path": "scripts/templates/create-model.template.ejs",
    "content": "/**\n *  <?= name ?> schema\n *  Created by create-model script  \n **/\n \nvar mongoose = require('mongoose'),\n    Schema = mongoose.Schema,\n    ObjectId = Schema.ObjectId;\n\nvar <?= name ?> = new Schema({\n\n\t  // Single default property\n\t  name:{type: String, required: true}\n\t  \n});\n\nmongoose.model('<?= name ?>', <?= name ?>);\n"
  },
  {
    "path": "scripts/templates/create-test.help.ejs",
    "content": "\nExpress MVC Bootstrapper\nThis is the help file for 'create-test' command.\n\nCommand format:\nnode app.js script create-test [MODELNAME]\n\n[MODELNAME]  The name (case sensitive) for the model you want to create tests for.\n "
  },
  {
    "path": "scripts/templates/create-test.template.functional.ejs",
    "content": "<?\n\tvar modelVariable = modelName.toLowerCase();\n\tvar basePath = modelName.toLowerCase();\n\tvar basePathPlural = controllerName.toLowerCase();\n?>\n/**\n *  <?= controllerName ?> Functional Test\n *  Created by create-test script @ <?= new Date() ?>\n **/\n/**\n * Dependencies\n */\nvar     should = require('should');\n\n/**\n * Simple expresso tests for the <?= modelName ?> model\n */\nmodule.exports = {\n\t\t    \n  'Placeholder for a real functional test': function(){\t    \n\t    true.should.be.true;    \n   }\n\n};"
  },
  {
    "path": "scripts/templates/create-test.template.integration.ejs",
    "content": "<?\n\tvar modelVariable = modelName.toLowerCase();\n\tvar basePath = modelName.toLowerCase();\n\tvar basePathPlural = controllerName.toLowerCase();\n?>\n/**\n *  <?= controllerName ?> Integration Test\n *  Created by create-test script @ <?= new Date() ?>\n **/\n/**\n * Dependencies\n */\nvar assert = require('assert'), inflection = require('lib/inflection'), mongoose = require('mongoose'), should = require('should'); \n\n/**\n * Variables to drive testing\n */\nvar model = '<?= modelName.toLowerCase() ?>';\nvar app = require('app').boot();\nvar id;\n\n/**\n * Simple expresso tests for the AppController\n */\nmodule.exports = {\n\t\t    \n\t\t'Shows an index page that contains the container name in the response with a 200 status code': function(done){\t\n\t\t\t\n\t\t\tvar controller = model.pluralize().toLowerCase();\t\t\t\n\t\t\tassert.response(app, {\n\t\t\t    url: '/' + controller ,\n\t\t\t    method: 'GET'\n\t\t\t}, function(res) {\n\t\t\t\tres.statusCode.should.equal(200);\n\t\t\t\tres.body.should.include.string(controller);\n\t\t\t    done();\n\t\t\t});\t\t\t\n\t\t\t\n\t\t},\n\t\t'Adding a new object returns a 302 redirect where the new location contains the id of the newly created object': function(done){\t\t\t\n\t\t\t\n\t\t\tvar controller = model.pluralize().toLowerCase();\n\t\t\tvar data = model + '[name]=OriginalName';\t\t\n\t\t\t\n\t\t\tassert.response(app, {\n\t\t\t    url: '/' + controller,\n\t\t\t    method: 'POST',\n\t\t\t    headers: {'host':'dummyhost','Content-Length': data.length,'Content-Type':'application/x-www-form-urlencoded'},\n\t\t\t    data: data\n\t\t\t}, function(res) {\n\t\t\t\tres.statusCode.should.equal(302);\n\t\t\t\tid = res.headers['location'].split(\"/\")[res.headers['location'].split(\"/\").length-1];\t\t\t\t\n\t\t\t\tdone();\n\t\t\t});\t\n\t\t\t\t\t\t\n\t\t},\n\t\t'Viewing an existing object returns a page that contains the object ID and a 200 status code': function(done){\t\t\t\t\t\t\t\t\t\n\t\t\tassert.response(app, {\n\t\t\t    url: '/' + model + '/' + id,\n\t\t\t    method: 'GET'\n\t\t\t}, function(res) {\n\t\t\t\tres.statusCode.should.equal(200);\n\t\t\t\tres.body.should.include.string(id);\t\t\t\t\n\t\t\t\tdone();\n\t\t\t});\t\t\t\t\t\t\t\n\t\t},\t\t\n\t\t'Viewing a page limited view of the index with .json format returns a JSON list containing the object ID and 200 status code': function(done){\t\t\t\t\t\t\t\t\t\n\n\t\t\tvar controller = model.pluralize().toLowerCase();\n\n\t\t\tassert.response(app, {\n\t\t\t    url: '/' + controller + '/1-100.json',   // Test database should be empty for this test\n\t\t\t    method: 'GET'\n\t\t\t}, function(res) {\n\t\t\t\tres.statusCode.should.equal(200);\n\t\t\t\tres.body.should.include.string(id);\n\t\t\t\tres.headers['content-type'].should.equal('application/json');\n\t\t\t\tdone();\n\t\t\t});\t\t\t\t\t\t\t\n\t\t},\t\t\n\t\t'View existing object with .json format returns a JSON object containing its ID and a 200 status code ': function(done){\t\t\t\t\t\t\t\t\t\n\t\t\tassert.response(app, {\n\t\t\t    url: '/' + model + '/' + id + '.json',\n\t\t\t    method: 'GET'\n\t\t\t}, function(res) {\n\t\t\t\t// Find the ID text on the page\n\t\t\t\tres.statusCode.should.equal(200);\n\t\t\t\tres.body.should.include.string(id);\n\t\t\t\tres.headers['content-type'].should.equal('application/json');\t\t\t\t\n\t\t\t\tdone();\n\t\t\t});\t\t\t\t\t\t\t\n\t\t},\n\t\t'Updating an object redirects to 302 where the new location contains the ID': function(done){\t\t\t\n\t\t\t\n\t\t\tvar data = model + '[name]=ModifiedName';\t\t\t\n\t\t\tassert.response(app, {\n\t\t\t    url: '/' + model + '/' + id,\n\t\t\t    method: 'PUT',\n\t\t\t    headers: {'host':'dummyhost','Content-Length': data.length,'Content-Type':'application/x-www-form-urlencoded'},\n\t\t\t    data: data\n\t\t\t}, function(res) {\n\t\t\t\tres.statusCode.should.equal(302);\n\t\t\t\tres.headers['location'].should.include.string(id);\n\t\t\t\tres.headers['location'].should.equal('http://dummyhost/' + model + '/' + id);\t\t\t\t\n\t\t\t\tdone();\n\t\t\t});\t\n\t\t\t\t\t\t\n\t\t},\n\t\t'Viewing the updated object shows the modified data and a 200 status code': function(done){\t\t\t\n\t\t\t\n\t\t\tassert.response(app, {\n\t\t\t    url: '/' + model + '/' + id,\n\t\t\t    method: 'GET'\n\t\t\t}, function(res) {\t\t\t\t\n\t\t\t\tres.statusCode.should.equal(200);\n\t\t\t\tres.body.should.include.string(id);\n\t\t\t\tres.body.should.include.string('ModifiedName');\n\t\t\t\tdone();\n\t\t\t});\t\t\n\t\t\t\t\t\t\n\t\t},\t\t\n\t\t'Deleting the object returns a 200 status code': function(done){\t\t\t\n\t\t\t\n\t\t\tassert.response(app, {\n\t\t\t    url: '/' + model + '/' + id,\n\t\t\t    method: 'DELETE'\n\t\t\t}, function(res) {\n\t\t\t\tres.statusCode.should.equal(200);\n\t\t\t\tdone();\n\t\t\t});\t\t\n\t\t\t\t\t\t\n\t\t},\n\t\t'Viewing a deleted object returns the default error page': function(done){  // Should this really be a 404???\t\t\t\n\t\t\t\n\t\t\tassert.response(app, {\n\t\t\t    url: '/' + model + '/' + id,\n\t\t\t    method: 'GET'\n\t\t\t}, function(res) {\n\t\t\t\tres.statusCode.should.equal(200);\n\t\t\t\tres.body.should.include.string('Sorry an error has occurred');\n\t\t\t\tdone();\n\t\t\t});\t\n\t\t\t\t\t\t\n\t\t},\n\t\ttearDown: function(done){\n\t\t   mongoose.disconnect();\n\t\t   done();\n\t\t}\n\t\t\n};"
  },
  {
    "path": "scripts/templates/create-test.template.unit.ejs",
    "content": "<?\n\tvar modelVariable = modelName.toLowerCase();\n\tvar basePath = modelName.toLowerCase();\n\tvar basePathPlural = controllerName.toLowerCase();\n?>\n/**\n *  <?= controllerName ?> Unit Test\n *  Created by create-test script @ <?= new Date() ?>\n **/\n/**\n * Dependencies\n */\nvar     should = require('should')\n\t  , mongoose = require('mongoose')\n\t  , example = require('models/<?= modelName ?>')\n\t  , Schema = mongoose.Schema\n\t  , SchemaType = mongoose.SchemaType\n\t  , ValidatorError = SchemaType.ValidatorError\n\t  , DocumentObjectId = mongoose.Types.ObjectId\n\t  , MongooseError = mongoose.Error;\n\n/**\n * Simple expresso tests for the <?= modelName ?> model\n */\nmodule.exports = {\n\t\t    \n  'Test that a model can be created': function(){\n\t    var <?= modelName ?> = mongoose.model('<?= modelName ?>');\n\t    var model = new <?= modelName ?>();\n\t    model.isNew.should.be.true;    \n   },\n  'Test that the model is an instance of a mongoose schema': function(){\n    var <?= modelName ?> = mongoose.model('<?= modelName ?>');\n    <?= modelName ?>.schema.should.be.an.instanceof(Schema);\n    <?= modelName ?>.prototype.schema.should.be.an.instanceof(Schema);\n  },\n  'Test that an <?= modelName ?> has all of the default fields and values': function(){\n    \n    var <?= modelName ?> = mongoose.model('<?= modelName ?>');\n\n    var model = new <?= modelName ?>();\n    model.isNew.should.be.true;\n\n    model.get('_id').should.be.an.instanceof(DocumentObjectId);\n    should.equal(undefined, model.get('name'));\n    \n   },\n  'Test that saving a record with invalid fields returns a validation error': function(){\n\t  \n\t    var <?= modelName ?> = mongoose.model('<?= modelName ?>');\t    \n\t    var model = new <?= modelName ?>();\n\t    model.set('name', '');\n\t    model.save(function(err){\n\t      \n\t      err.should.be.an.instanceof(MongooseError);\n\t      err.should.be.an.instanceof(ValidatorError);\n\t      \n\t      model.set('name', 'I exist!');\n\t      model.save(function(err){\n\t        should.strictEqual(err, null);\n\t      });\n\t      \n\t    });\t    \n\n  }\n\n};"
  },
  {
    "path": "scripts/templates/create-view.help.ejs",
    "content": "\nExpress MVC Bootstrapper - Version 0.10\nThis is the help file for 'create-view' command.\n\nCommand format:\nnode app.js script create-view [MODELNAME]\n\n[MODELNAME]  The name (case sensitive) for the model you want to create views for.\n "
  },
  {
    "path": "scripts/templates/create-view.template.edit.ejs",
    "content": "<?\n\tvar modelVariable = modelName.toLowerCase();\n\tvar basePath = modelName.toLowerCase();\n\tvar basePathPlural = controllerName.toLowerCase();\n?>\n<h1>Editing <?= modelName ?> <%= <?= modelVariable ?>.name %></h1>\n<%- partial('../messages') %>\n<form method=\"post\" action=\"/<?= modelVariable ?>/<%= <?= modelVariable ?>.id %>\">\n  <input type=\"hidden\" name=\"_method\" value=\"put\" />\n  <p>Name: <input type=\"text\" name=\"<?= modelVariable ?>[name]\", value=\"<%= <?= modelVariable ?>.name %>\" /></p>\n  <p>\n  \t<button class=\"button-submit\" type=\"submit\" value=\"Update\">Save</button>\n  \t<a class=\"button-cancel\" href=\"/<?= modelVariable ?>/<%= <?= modelVariable ?>.id %>\">Cancel</a>\n  </p>\n</form>\n"
  },
  {
    "path": "scripts/templates/create-view.template.index.ejs",
    "content": "<?\n\tvar modelVariable = modelName.toLowerCase();\n\tvar basePath = modelName.toLowerCase();\n\tvar basePathPlural = controllerName.toLowerCase();\n?>\n<h1><?= basePathPlural ?></h1>\n<%- partial('../messages') %>\n<div style=\"float: left; width: 60%;\">\n\t<table class=\"tabular\">\n\t\t<tr>\n\t\t\t<th>Name</th>\n\t\t</tr>\n\t\t<% <?= basePathPlural ?>.forEach(function(<?= modelVariable ?>){ %>\n\t\t<tr>\n\t\t\t<td><a href=\"/<?= modelVariable ?>/<%= <?= modelVariable ?>.id %>\"><%= <?= modelVariable ?>.name %></a></td>\n\t\t</tr>\n\t\t<% }) %>\n\t\t<tfoot>\n\t\t\t<tr>\n\t\t\t\t<td colspan='2'><%- pagerHtml %></td>\n\t\t\t</tr>\n\t\t</tfoot>\n\t</table>\n</div>\n<div style=\"float: left; margin-left: 5%; width: 35%;\">\n\t<form method=\"post\" action=\"/<?= basePathPlural ?>\">\n\t\t<input type=\"hidden\" name=\"_method\" value=\"post\" />\n\t\t<p>\n\t\t\tName: <input type=\"text\" name=\"<?= modelVariable ?>[name]\" />\n\t\t</p>\n\t\t<p>\n\t\t\t<button class=\"button-submit\" type=\"submit\" value=\"Create\">Create</button>\n\t\t</p>\n\t</form>\n</div>\n"
  },
  {
    "path": "scripts/templates/create-view.template.show.ejs",
    "content": "<?\n\tvar modelVariable = modelName.toLowerCase();\n\tvar basePath = modelName.toLowerCase();\n\tvar basePathPlural = controllerName.toLowerCase();\n?>\n<h1>Viewing <?= basePath ?></h1>\n<script type=\"text/javascript\">\n\t$(function(){\n\n\t\t// Delete User\n\t\t$('.button-delete').click(function(){\n\t\t\t\n\t\t\tvar <?= modelVariable ?>Id = this.id;\n\t\t\t\n\t\t\t$(\"#dialog-confirm\" ).dialog({\n\t\t\t\tresizable: false,\n\t\t\t\theight:180,\n\t\t\t\twidth:400,\n\t\t\t\tmodal: true,\n\t\t\t\tbuttons: {\n\t\t\t\t\t\"Delete\": function() {\n\t\t\t\t\t\t$( this ).dialog( \"close\" );\n\t\t\t\t\t\t$.ajax({\n\t\t\t\t\t\t\t   type: \"DELETE\",\n\t\t\t\t\t\t\t   url: \"/<?= modelVariable ?>/\" + <?= modelVariable ?>Id,\t\t\t\t   \n\t\t\t\t\t\t\t   success: function(msg) {\t\t\t\t   \t  \n\t\t\t\t\t\t\t\t  window.location.replace(\"/<?= modelVariable ?>s\");\n\t\t\t\t\t\t\t   },\n\t\t\t\t\t\t\t   error: function(msg) {\t\t\t\t\t  \n\t\t\t\t\t\t\t\t  alert(\"I was unable to delete the <?= modelVariable ?> - something has gone wrong, apologies!\");\n\t\t\t\t\t\t\t   }\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tCancel: function() {\n\t\t\t\t\t\t$( this ).dialog( \"close\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\t\t\t\n\t\t\t\n\t\t});\n\t\t\n\t});\n</script>\n<div id=\"dialog-confirm\" style=\"display: none;\" title=\"Delete <?= modelVariable ?>?\">\n\t<p><span class=\"ui-icon ui-icon-alert\" style=\"float:left; margin:0 7px 20px 0;\"></span>This will be permanently deleted and cannot be recovered. Are you sure?</p>\n</div>\n<%- partial('../messages') %>\n<table>\n\t<tr>\n  \t\t<th>ID</th><td><%= <?= modelVariable ?>.id %></td>\n  \t</tr>\n  \t<tr>\n  \t\t<th>Name</th><td><%= <?= modelVariable ?>.name %></td>\n  \t</tr> \t\n</table>\n<a class=\"button-edit\" href=\"<%= <?= modelVariable ?>.id %>/edit\" title=\"Edit <?= modelVariable ?> ...\">\n\tEdit \n</a>\n<button class=\"button-delete\" id=\"<%= <?= modelVariable ?>.id %>\"  title=\"Delete <?= modelVariable ?> ...\">\n\tDelete\n</button>\n<a class=\"button-home\" href=\"/<?= basePathPlural ?>\" title=\"List <?= controllerName ?>\">\n\tList <?= controllerName ?>\n</a>\n"
  },
  {
    "path": "scripts/templates/help.ejs",
    "content": "\nExpress MVC Bootstrapper\n\nThis is the help file for the Express based application bootstrapper.  Parameters marked with * are optional, and are shown with their defaults.\n\nCommand format:\n\neb                                   : Run the application using the cluster module.\neb cluster *server.port=3000         : Run the application using the cluster module.\neb server *server.port=3000          : Run the application as a server.\n\neb test                              : Run all tests.\neb test unit|integration|functional  : Run a particular type of test.\n\neb script help *<name>               : This help script, optional script name for additional help. \neb script <name> *params             : Run a script with <name>, with params.\neb script <name> *params             : Run a script with <name>, with params.\n\nAvailable scripts:\n<? if (scripts.length) { scripts.forEach(function(name){ ?>\n<?= name ?><? }) } ?>\n"
  },
  {
    "path": "tests/functional/README",
    "content": ""
  },
  {
    "path": "tests/functional/SampleTests.js",
    "content": "/**\n * Dependencies\n */\nvar     should = require('should');\n\n/**\n * Simple expresso tests for the Example model\n */\nmodule.exports = {\n\t\t    \n  'Placeholder for a real functional test': function(){\t    \n\t    true.should.be.true;    \n   }\n\n};"
  },
  {
    "path": "tests/integration/AppControllerTests.js",
    "content": "\nvar assert = require('assert'), should = require('should'), mongoose = require('mongoose');\nvar app = require('app').boot();\n\n/**\n * Simple expresso tests for the AppController\n */\nmodule.exports = {\n\t\t\n\t\t'Default route shows the home page with a 200 status code': function(done){\t\t\t\t\t\t\t\t\t\n\t\t\tassert.response(app, {\n\t\t\t    url: '/',\n\t\t\t    method: 'GET'\n\t\t\t}, function(res) {\n\t\t\t\tres.statusCode.should.equal(200);\n\t\t\t\tres.body.should.include.string('Welcome!');\n\t\t\t    done();\n\t\t\t});\t\t\t\t\t\t\n\t\t},\n\t\t'An invalid route shows the 404 Error page': function(done){\t\t\t\n\t\t\tassert.response(app, {\n\t\t\t    url: '/this/is/an/invalid/route',\n\t\t\t}, function(res){\n\t\t\t\tres.statusCode.should.equal(200);\n\t\t\t\tres.body.should.include.string('Cannot find /this/is/an/invalid/route');\t\t\n\t\t\t\tdone();\n\t\t\t});\t\t\t\t\t\t\n\t\t},\n\t\ttearDown: function(done){\n\t\t   mongoose.disconnect();\n\t\t   done();\n\t\t}\n\t\t\n};"
  },
  {
    "path": "tests/unit/README",
    "content": ""
  },
  {
    "path": "tests/unit/SampleTests.js",
    "content": "/**\n * Dependencies\n */\nvar     should = require('should');\n\n/**\n * Simple expresso tests\n */\nmodule.exports = {\n\t\t    \n  'Placeholder for a real unit test': function(){\t    \n\t    true.should.be.true;    \n   }\n\n};"
  },
  {
    "path": "utils/pager.js",
    "content": "\n/**\n * Simple pager - couldn't find one for Express that worked for me.\n */\nexports.version = '0.0.1';\nexports.render = function(skip,limit,total,path){\n\n\tvar totalPages = Math.ceil(total/limit) + 1;\n\tvar currentPage = skip/limit + 1;\n\tvar result = \"\", start, finish;\n\tvar selectedClass = 'page-selected';\n\tvar visiblePages = 5;\n\t\n\t// Remember how many we have\n\tvar totalPageLinks = 0;\n\t\n\tresult += pageSpan(currentPage);\n\t\t\n\tvar additionalForward = currentPage < visiblePages ? visiblePages - currentPage : 0;\t\n\tfor(i=currentPage + 1; (i < currentPage + visiblePages + additionalForward) && (i < totalPages); i++) {\n\t\tstart = (i-1)*limit + 1;\n\t\tresult += pageLink(path,start,limit,i); \t\t\n\t}\n\t\n\tif(currentPage < totalPages - 1) {\n\t\tresult +=pageLink(path,skip + limit + 1,limit,\">\"); \t\t\t\t\n\t\tvar lastPageStart = (totalPages-2)*limit + 1;\n\t\tresult +=pageLink(path,lastPageStart,limit,\">>\"); \t\t\n\t}\n\t\n\tvar additionalBackward = (totalPages - currentPage) < visiblePages ? visiblePages - (totalPages - currentPage) : 0;\n\tfor(i=currentPage - 1; (i > currentPage - visiblePages - additionalBackward) && (i > 0); i--) {\n\t\tstart = (i-1)*limit + 1;\t\t\n\t\t\n\t\tresult = pageLink(path,start,limit,i) + result;\n\t}\n\t\n\tif(currentPage > 1) {\n\t\tresult = pageLink(path,(skip - limit + 1),limit,\"<\") + result;\n\t\tresult = pageLink(path,1,limit,\"<<\") + result;\t\t\t\n\t}\n\t\n\tresult += \"&nbsp;Go To: <input id='pagerGoto' type='text' name='skip' value='' class='pager-page' title='Go to a specific start point, type and enter ...' />\";\n\t\n\tresult += \"<span style='float: right'>\" + (skip + 1) + \" to \" + (skip + limit) + \" of \" + (total) + \"</span>\";\t\t\n\t\n\treturn result\n\t\n}\n\nfunction pageLink(path,skip,limit,page) {\n\treturn \"<a class='pager-page' href='\" + path + \"/\" + skip + \"-\" + limit + \"'>\" + page + \"</a>\";\n}\n\nfunction pageSpan(page) {\n\treturn \"<span class='pager-page'>\" + page + \"</span>\";\n}\n"
  },
  {
    "path": "utils/socketio.js",
    "content": "\n/**\n * \tNOT YET USED \n **/\t\t\n\t\t\nvar io = require('socket.io');\n\nexports.version = '0.0.1';\nexports.initialise = function(app){\n\n\t// socket.io \n\tvar socket = io.listen(app); \n\tsocket.on('connection', function(client){ \n\t  // new client is here! \n\t  console.log(\"Connection: \" . client);\n\t  client.on('message', function(){ \n\t\tconsole.log(\"message\");\t\n\t  }); \n\t  client.on('disconnect', function(){ \n\t\tconsole.log(\"disconnect\")\n\t  }); \n\t});\n\t\n};"
  },
  {
    "path": "views/404.html",
    "content": "<h1>Cannot find <%= request.url %></h1>\n<p>Sorry we failed to locate this page or resource.</p>"
  },
  {
    "path": "views/500.html",
    "content": "<h1>Internal Server Error</h1>\n<p>Sorry an error has occurred, please try refreshing the page or navigate back to <a href=\"/\">home</a>.</p>"
  },
  {
    "path": "views/app/index.html",
    "content": "<h1>Welcome!</h1>\n<p>The following controllers are available:</p>\n\n<% if (controllers.length) { %>\n  <ul>\n    <% controllers.forEach(function(controller){ %>\n      <li><a href=\"/<%= controller %>\"><%= controller %></a></li>\n    <% }) %>\n  </ul>\n<% } else { %>\n<pre class='code'>\nNo controllers available - try 'eb script generate-all ModelName'\n</pre>\n<% } %>\n<br/>\n<pre class='code'>\nYou are viewing the default home page - edit views/app/index.html to edit this page!\n</pre>\n<br/>\n<p>Credits:\n<div style='font-size: 0.8em;'>\n\t<ul>\n\t\t<li><a href=\"http://nodejs.org/\">Node.js</a>: Amazing javascript asynchronous IO library, install manually.</li>\n\t\t<li><a href=\"http://www.mongodb.org/\">MongoDB</a>: NoSQL Database, install manually.</li>\n\t\t<li><a href=\"http://npmjs.org/\">NPM</a>: Node package manager, used to install:\n\t\t\t<ul>\n\t\t\t\t<li><a href=\"http://expressjs.com/\">Express</a>: Application Framework for Node.js</li>\n\t\t\t\t<li><a href=\"http://mongoosejs.com/\">Mongoose</a>: Node.JS ORM for Mongo</li>\n\t\t\t\t<li><a href=\"http://embeddedjs.com/\">EJS</a>: Embedded Javascript Templating Library</li>\n\t\t\t</ul>\n\t\t</li>\n\t\t<li><a href=\"http://jquery.com/\">jQuery</a>: Javascript Library</li>\n\t\t<li><a href=\"http://jqueryui.com/\">jQuery UI</a>: UI Library</li>\n\t\t<li><a href=\"http://taitems.tumblr.com/post/482577430/introducing-aristo-a-jquery-ui-theme\">jQuery Aristo Template</a>: Fantastic looking jQuery UI Template.</li>\n\t</ul>\n</div>\n</p>\n\n\n<p>Contact me via github : <a href=\"https://github.com/cliftonc\" target=\"_new\">Clifton @ Github</a></p>\n"
  },
  {
    "path": "views/layout.html",
    "content": "<html>\n  <head>\n    <title>Sample MVC Application</title>\n    \t<link rel=\"stylesheet\" href=\"/css/style.css\" />\n    \t<link type=\"text/css\" href=\"/css/Aristo/jquery-ui-1.8.7.custom.css\" rel=\"stylesheet\" />\t\n\t\t<script type=\"text/javascript\" src=\"/js/jquery-1.4.4.min.js\"></script>\n\t\t<script type=\"text/javascript\" src=\"/js/jquery-ui-1.8.10.custom.min.js\"></script>\n\t\t<script type=\"text/javascript\">\n\t\t\t$(function(){\n\t\t\n\t\t\t\t// Style default buttons\n\t\t\t\t// TODO: Move this into an application js library\n\t\t\t\t$(\".button-edit\").button({ icons: {\tprimary: 'ui-icon-wrench' }\t});\n\t\t\t\t$(\".button-delete\").button({ icons: { primary: 'ui-icon-trash' } });\n\t\t\t\t$(\".button-home\").button({ icons: {\tprimary: 'ui-icon-home'\t} });\n\t\t\t\t$(\".button-submit\").button({ icons: { primary: 'ui-icon-disk' } });\n\t\t\t\t$(\".button-cancel\").button({ icons: {primary: 'ui-icon-close' } });\n\t\t\t\t\n\t\t\t});\n\t\t\t\n\t\t</script>\n  </head>\n  <body>  \t\n  \t<div id=\"container\">\n\t  \t<div id=\"header\">\n\t\t\t<h1><a href=\"/\">Node.js + ExpressJs + Mongoose : Bootstrap</a></h1>\n  \t\t\t<h2>Simple Application Template and Scripts</h2>\n\t\t</div>\n\t\t<div id=\"content\">\n    \t\t<%- body %>\n    \t</div>\t\t\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "views/messages.html",
    "content": "<% if (hasMessages) { %>\n  <div style=\"float: left; margin-bottom: 20px; padding: 10px; width: 100%;\" class=\"ui-state-highlight ui-corner-all\">  \t\n    <% messages().forEach(function(msg){ %>\n      <span class=\"ui-icon ui-icon-info\" style=\"float: left; margin-right: .7em;\"></span><%- msg %><br/>\n    <% }) %>\n  </div>\n  <div style=\"clear: both;\"/>\n<% } %>"
  }
]