[
  {
    "path": ".gitignore",
    "content": "*.swp\nsrc/node_modules\n"
  },
  {
    "path": "demo/index.htm",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Vogue - Demo Page</title>\n    <link href=\"/styles/reset.css\" type=\"text/css\" rel=\"stylesheet\"/>\n    <link href=\"/styles/demo.css?test=1\" type=\"text/css\" rel=\"stylesheet\"/>\n    <link href=\"/styles/print.css\" type=\"text/css\" rel=\"stylesheet\" media=\"print\"/>\n  </head>\n  <body>\n    <h1>Vogue - Demo Page</h1>\n    <p>This is some demo text for Vogue</p>\n    <p>The vogue client is already added to this page. Try editing the CSS files to see\n    the page update.<p>\n    <script type=\"text/javascript\" src=\"http://localhost:8001/vogue-client.js?base=http://localhost:8001/\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "demo/novogue.htm",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Vogue - Demo Page</title>\n    <link href=\"/styles/reset.css\" type=\"text/css\" rel=\"stylesheet\"/>\n    <link href=\"/styles/demo.css?test=1\" type=\"text/css\" rel=\"stylesheet\"/>\n  </head>\n  <body>\n    <h1>Vogue - Demo Page</h1>\n    <p>This is some demo text for Vogue</p>\n    <p>Vogue has not been loaded into this page. Try using the favlet.</p>\n\n    <script type=\"text/javascript\">\n      // a dummy script to make sure the injected Vogue script can detect itself correctly\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "demo/styles/demo.css",
    "content": "body {\n  background-color: #fff;\n  color: #000;\n  font-family: sans-serif;\n  padding: 10px;\n}\n"
  },
  {
    "path": "demo/styles/print.css",
    "content": "body {\n  background: #f0f; /* something nasty to notice if vogue switches on this style! */\n  color: blue;\n}\n"
  },
  {
    "path": "demo/styles/reset.css",
    "content": "* { padding: 0; margin: 0 }\n"
  },
  {
    "path": "demo/sub/index.htm",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Vogue - Demo Page</title>\n    <link href=\"/styles/reset.css\" type=\"text/css\" rel=\"stylesheet\"/>\n    <link href=\"/styles/demo.css?test=1\" type=\"text/css\" rel=\"stylesheet\"/>\n  </head>\n  <body>\n    <h1>Vogue - Demo Page</h1>\n    <p>This is some demo text for Vogue</p>\n    <p>The vogue client is already added to this page. Try editing the CSS files to see\n    the page update.<p>\n    <script type=\"text/javascript\" src=\"http://localhost:8001/vogue-client.js\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "license.txt",
    "content": "Copyright (c) 2011 Andrew Davey (andrew@equin.co.uk)\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"
  },
  {
    "path": "readme.md",
    "content": "# Vogue\n\nVogue creates a real-time link between your web browser and your file system. When you save \na CSS file, used by the HTML page in your browser, Vogue will make the browser reload the \nstylesheet. Only the stylesheet is reloaded, not the entire page, making it work\neven for very dynamic/ajax pages.\n\nVogue is all javascript. It runs a server on [Node.js](http://nodejs.org/), \nwhich will watch the file system. \nThe server accepts WebSocket connections from the client code \n(which uses [socket.io](http://socket.io/)).\nThe client javascript can be loaded into a HTML page using a single script tag.\n\n## Install using npm\nMake sure you have Node.JS and [npm](http://npmjs.org/) installed.  \nThen run: \n\n    npm install vogue -g\n\n## Usage\nRun the Vogue server.\n\n    vogue --port 8001 /path/to/website\n\n`--port` : The port used for Vogue's HTTP server. Optional, defaults to 8001.\n\n`--rewrite` : A rule in the form of \"regexp:replacement\" (e.g. \"v[0-9]/(.*)$:files/\\$1\" ) to rewrite urls to filesystem paths.\n Submatches such as $1 will probably need to entered in your shell as \\$1 to escape the $. \n\nOpen http://localhost:8001/ to see instructions for loading the Vogue client into your\nweb pages.\n\n## Demo\nVogue runs a separate HTTP server to the one running your website.\nTo run the demo website, for example, do something like this first:\n  \n    cd demo  \n    python -m SimpleHTTPServer\n\nThen, from another terminal session, run Vogue:\n\n    vogue demo\n\nOpen http://localhost:8000 (or whatever the port used by your web server is) \nto view the demo index page. The demo page has the Vogue client javascript already included.\nSo it will connect to the Vogue server and be watching the two CSS files used by the page.\n\nTry editing the CSS files in the `demo/styles` directory. Whenever you save, you will see the \nbrowser update the reflect the changes made. This is done without reloading the entire page.\n\nCopyright &copy; 2011 Andrew Davey (andrew@equin.co.uk)\n"
  },
  {
    "path": "src/README.md",
    "content": "# Vogue\n\nVogue creates a real-time link between your web browser and your file system. When you save \na CSS file, used by the HTML page in your browser, Vogue will make the browser reload the \nstylesheet. Only the stylesheet is reloaded, not the entire page, making it work\neven for very dynamic/ajax pages.\n\n## Usage\nRun the Vogue server.\n\n    vogue --port 8001 /path/to/website\n\n`--port` : The port used for Vogue's HTTP server. Optional, defaults to 8001.\n\n`--rewrite` : A rule in the form of \"regexp:replacement\" (e.g. `v[0-9]/(.*)$:files/\\$1` ) to rewrite urls to filesystem paths.\n Submatches such as $1 will probably need to entered in your shell as \\$1 to escape the $. \n\nOpen http://localhost:8001/ to see instructions for loading the Vogue client into your\nweb pages.\n\n\n"
  },
  {
    "path": "src/VogueClient.js",
    "content": "var fs = require('fs');\n\nexports.VogueClient = VogueClient;\n\n// Encapsulates a web socket client connection from a web browser.\nfunction VogueClient(clientSocket, watcher) {\n  this.socket = clientSocket;\n  this.watcher = watcher;\n  this.watchedFiles = {};\n  clientSocket.on('watch', this.handleMessage.bind(this));\n  clientSocket.on('disconnect', this.disconnect.bind(this));\n}\n\n// Parse an incoming message from the client and dispatch accordingly.\nVogueClient.prototype.handleMessage = function(data) {\n  this.watchFile(data.href);\n};\n\nVogueClient.prototype.watchFile = function(href) {\n  var filename = this.watcher.getFilenameForHref(href);\n  fs.stat(filename, function(err, stats) {\n    if (err) {\n      console.log('Could not read stats for ' + filename);\n      return;\n    }\n    \n    this.watchedFiles[filename] = {\n      href: href,\n      mtime: stats.mtime\n    };\n    this.watcher.startWatching(filename);\n  }.bind(this));\n};\n\nVogueClient.prototype.updateFile = function(filename) {\n  var fileInfo = this.watchedFiles[filename];\n  if (fileInfo) {\n    fs.stat(filename, function(err, stats) {\n      if (err) {\n        console.error('Could not read stats for file: ' + filename);\n        return;\n      }\n      // Only send message to client if the file was modified\n      // since we last saw it.\n      if (fileInfo.mtime < stats.mtime) {\n        this.socket.emit('update', { href: fileInfo.href });\n        fileInfo.mtime = stats.mtime;\n      }\n    }.bind(this));\n  }\n};\n\nVogueClient.prototype.disconnect = function() {\n  for (var filename in this.watchedFiles) {\n    this.watcher.stopWatching(filename);\n  }\n  this.watcher.removeClient(this);\n};\n"
  },
  {
    "path": "src/Watcher.js",
    "content": "var fs   = require('fs')\n  , path = require('path');\n\nexports.Watcher = Watcher;\n\nfunction Watcher(webDirectory, rewrite) {\n  this.webDirectory = webDirectory;\n  // array of VogueClient objects\n  this.clients = [];\n  \n  // filename -> number_of_clients_watching \n  this.fileWatcherCount = {};\n\n  if (rewrite) {\n    this.rewriteUrlToPath = createRewriter(rewrite); \n  }\n\n  function createRewriter(rewrite) {\n    var parts = rewrite.split(':');\n    if (parts.length === 2) {\n      var regex = new RegExp(parts[0]);\n      var replacement = parts[1];\n      return function (str) { \n        return str.replace(regex, replacement);\n      }\n    } else {\n      throw new Error('Rewrite must be of the form \"regex:replacement\".');\n    }\n  }\n}\n\nWatcher.prototype.addClient = function(client) {\n  this.clients.push(client);\n};\n\nWatcher.prototype.removeClient = function(client) {\n  this.clients.splice(this.clients.indexOf(client), 1);\n};\n\nWatcher.prototype.getFilenameForHref = function(href) {\n  if (this.rewriteUrlToPath) {\n    href = this.rewriteUrlToPath(href);\n  }\n  // Remove any querystring junk.\n  // e.g. \"foo/bar.css?abc=123\" --> \"foo/bar.css\"\n  href = href.split('?')[0];\n  var filename = path.join(this.webDirectory, href);\n  return filename;\n};\n\nWatcher.prototype.startWatching = function(filename) {\n  console.log('Watching file: ' + filename);\n  if (filename in this.fileWatcherCount) {\n    // already watching this file, so just increment the client count.\n    this.fileWatcherCount[filename]++;\n  } else {\n    fs.watchFile(\n      filename,\n      { persistent: true, interval: 50 },\n      fileChanged.bind(this)\n    );\n    this.fileWatcherCount[filename] = 1;\n  }\n\n  function fileChanged() {\n    console.log('File changed: ' + filename);\n    this.clients.forEach(function(client) {\n      client.updateFile(filename);\n    });\n  }\n};\n\nWatcher.prototype.stopWatching = function(filename) {\n  if (!(filename in this.fileWatcherCount)) return;\n\n  var watcherCount = --this.fileWatcherCount[filename];\n  if (watcherCount == 0) {\n    delete this.fileWatcherCount[filename];\n    fs.unwatchFile(filename);\n    console.log('Stopped watching file: ' + filename);\n  }\n}\n\n"
  },
  {
    "path": "src/client/about.htm",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Vogue</title>\n  </head>\n  <body>\n    <h1>Vogue</h1>\n    <p>\n    Add this bookmarklet to your bookmarks. It will inject Vogue's scripts\n    into the currently running page.\n    </p>\n    <p>\n      <a id=\"favlet\">Inject Vogue</a>\n    </p>\n    <p>\n    Or, add the following script into your HTML.\n    </p>\n    <pre>&lt;script src=\"http://localhost:{port}/vogue-client.js\" type=\"text/javascript\"&gt;&lt;/script&gt;</pre>\n    <p>Note: This should only appear in development-time code. Remove before going into production.</p>\n    <script type=\"text/javascript\">\n      var favlet = document.getElementById(\"favlet\");\n      favlet.href = \"javascript:(function(){\\\nif (typeof window.__vogue__!=='undefined') return;\\\nwindow.__vogue__ = {\\\nrootUrl:'http://localhost:{port}/',\\\ndomain:'localhost',\\\nport:{port}\\\n};\\\nvar s = document.createElement('script');\\\ns.setAttribute('src', 'http://localhost:{port}/vogue-client.js');\\\ns.setAttribute('type', 'text/javascript');\\\ndocument.getElementsByTagName('head')[0].appendChild(s);\\\n})()\".replace(/\\r\\n|\\r|\\n/g, \"\");\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "src/client/vogue-client.js",
    "content": "// Vogue - Client\n// Copyright (c) 2011 Andrew Davey (andrew@equin.co.uk)\n(function () {\n  var script,\n      hop = Object.prototype.hasOwnProperty,\n      head = document.getElementsByTagName(\"head\")[0];\n\n  function vogue() {\n    var stylesheets,\n        socket = io.connect(script.rootUrl);\n\n    /**\n     * Watch for all available stylesheets.\n     */\n    function watchAllStylesheets() {\n      var href;\n      for (href in stylesheets) {\n        if (hop.call(stylesheets, href)) {\n          socket.emit(\"watch\", {\n            href: href\n          });\n        }\n      }\n    }\n\n    /**\n     * Reload a stylesheet.\n     *\n     * @param {String} href The URL of the stylesheet to be reloaded.\n     */\n    function reloadStylesheet(href) {\n      var newHref = stylesheets[href].href +\n            (href.indexOf(\"?\") >= 0 ? \"&\" : \"?\") +\n            \"_vogue_nocache=\" + (new Date).getTime(),\n          stylesheet;\n      // Check if the appropriate DOM Node is there.\n      if (!stylesheets[href].setAttribute) {\n        // Create the link.\n        stylesheet = document.createElement(\"link\");\n        stylesheet.setAttribute(\"rel\", \"stylesheet\");\n        stylesheet.setAttribute(\"href\", newHref);\n        head.appendChild(stylesheet);\n\n        // Update the reference to the newly created link.\n        stylesheets[href] = stylesheet;\n      } else {\n        // Update the href to the new URL.\n        stylesheets[href].href = newHref;\n      }\n    }\n\n\n    /**\n     * Handle messages from socket.io, and load the appropriate stylesheet.\n     *\n     * @param message Socket.io message object.\n     * @param message.href The url of the stylesheet to be loaded.\n     */\n    function handleMessage(message) {\n      reloadStylesheet(message.href);\n    }\n\n    /**\n     * Fetch all the local stylesheets from the page.\n     *\n     * @returns {Object} The list of local stylesheets keyed by their base URL.\n     */\n    function getLocalStylesheets() {\n\n      /**\n       * Checks if the stylesheet is local.\n       *\n       * @param {Object} link The link to check for.\n       * @returns {Boolean}\n       */\n      function isLocalStylesheet(link) {\n        var href, i, isExternal = true;\n        if (link.getAttribute(\"rel\") !== \"stylesheet\") {\n          return false;\n        }\n        href = link.href;\n\n        for (i = 0; i < script.bases.length; i += 1) {\n          if (href.indexOf(script.bases[i]) > -1) {\n            isExternal = false;\n            break;\n          }\n        }\n\n        return !(isExternal && href.match(/^https?:/));\n      }\n\n      /**\n       * Checks if the stylesheet's media attribute is 'print'\n       *\n       * @param (Object) link The stylesheet element to check.\n       * @returns (Boolean)\n       */\n      function isPrintStylesheet(link) {\n        return link.getAttribute(\"media\") === \"print\";\n      }\n\n      /**\n       * Get the link's base URL.\n       *\n       * @param {String} href The URL to check.\n       * @returns {String|Boolean} The base URL, or false if no matches found.\n       */\n      function getBase(href) {\n        var base, j;\n        for (j = 0; j < script.bases.length; j += 1) {\n          base = script.bases[j];\n          if (href.indexOf(base) > -1) {\n            return href.substr(base.length);\n          }\n        }\n        return false;\n      }\n\n      function getProperty(property) {\n        return this[property];\n      }\n\n      var stylesheets = {},\n          reImport = /@import\\s+url\\([\"']?([^\"'\\)]+)[\"']?\\)/g,\n          links = document.getElementsByTagName(\"link\"),\n          link, href, matches, content, i, m;\n\n      // Go through all the links in the page, looking for stylesheets.\n      for (i = 0, m = links.length; i < m; i += 1) {\n        link = links[i];\n        if (isPrintStylesheet(link)) continue;\n        if (!isLocalStylesheet(link)) continue;\n        // Link is local, get the base URL.\n        href = getBase(link.href);\n        if (href !== false) {\n          stylesheets[href] = link;\n        }\n      }\n\n      // Go through all the style tags, looking for @import tags.\n      links = document.getElementsByTagName(\"style\");\n      for (i = 0, m = links.length; i < m; i += 1) {\n        if (isPrintStylesheet(links[i])) continue;\n        content = links[i].text || links[i].textContent;\n        while ((matches = reImport.exec(content))) {\n          link = {\n            rel: \"stylesheet\",\n            href: matches[1],\n            getAttribute: getProperty\n          };\n          if (isLocalStylesheet(link)) {\n            // Link is local, get the base URL.\n            href = getBase(link.href);\n            if (href !== false) {\n              stylesheets[href] = link;\n            }\n          }\n        }\n      }\n      return stylesheets;\n    }\n\n    stylesheets = getLocalStylesheets();\n    socket.on(\"connect\", watchAllStylesheets);\n    socket.on(\"update\", handleMessage);\n  }\n\n  /**\n   * Load a script into the page, and call a callback when it is loaded.\n   *\n   * @param {String} src The URL of the script to be loaded.\n   * @param {Function} loadedCallback The function to be called when the script is loaded.\n   */\n  function loadScript(src, loadedCallback) {\n    var script = document.createElement(\"script\");\n    script.setAttribute(\"type\", \"text/javascript\");\n    script.setAttribute(\"src\", src);\n\n    // Call the callback when the script is loaded.\n    script.onload = loadedCallback;\n    script.onreadystatechange = function () {\n      if (this.readyState === \"complete\" || this.readyState === \"loaded\") {\n        loadedCallback();\n      }\n    };\n\n    head.appendChild(script);\n  }\n\n  /**\n   * Load scripts into the page, and call a callback when they are loaded.\n   *\n   * @param {Array} scripts The scripts to be loaded.\n   * @param {Function} loadedCallback The function to be called when all the scripts have loaded.\n   */\n  function loadScripts(scripts, loadedCallback) {\n    var srcs = [], property, count, i, src,\n        countDown = function () {\n          count -= 1;\n          if (!count) {\n            loadedCallback();\n          }\n        };\n\n    for (property in scripts) {\n      if (!(property in window)) {\n        srcs.push(scripts[property]);\n      }\n    }\n\n    count = srcs.length;\n    if (!count) {\n      loadedCallback();\n    }\n\n    for (i = 0; i < srcs.length; i += 1) {\n      src = srcs[i];\n      loadScript(src, countDown);\n    }\n  }\n\n  /**\n   * Fetches the info for the vogue client.\n   */\n  function getScriptInfo() {\n    var bases = [ document.location.protocol + \"//\" + document.location.host ],\n        scripts, src, rootUrl, baseMatch;\n    if (typeof window.__vogue__ === \"undefined\") {\n      scripts = document.getElementsByTagName(\"script\");\n      for (var i=0; i < scripts.length; i++) {\n        src = scripts[i].getAttribute(\"src\");\n        if (src && src.slice(-15) === 'vogue-client.js') break;\n      }\n      rootUrl = src.match(/^https?\\:\\/\\/(.*?)\\//)[0];\n      // There is an optional base argument, that can be used.\n      baseMatch = src.match(/\\bbase=(.*)(&|$)/);\n\n      if (baseMatch) {\n        bases = bases.concat(baseMatch[1].split(\",\"));\n      }\n      return {\n        rootUrl: rootUrl,\n        bases: bases\n      };\n    } else {\n      window.__vogue__.bases = bases;\n      return window.__vogue__;\n    }\n  }\n\n  /**\n   * Fetches the port from the URL.\n   *\n   * @param {String} url URL to get the port from\n   * @returns {Number} The port number, or 80 if no port number found or is invalid.\n   */\n  function getPort(url) {\n    // URL may contain the port number after the second colon.\n    // http://domain:1234/\n    var index = url.indexOf(\":\", 6); // skipping 6 characters to ignore first colon\n    return index < 0 ? 80 : parseInt(url.substr(index + 1), 10);\n  }\n\n  script = getScriptInfo();\n  loadScripts({\n    io: script.rootUrl + \"socket.io/socket.io.js\"\n  }, vogue);\n}());\n"
  },
  {
    "path": "src/package.json",
    "content": "{\n  \"name\": \"vogue\",\n  \"description\": \"Auto-reload stylesheets in web browser whenever the CSS files are saved.\",\n  \"version\": \"0.5.0\",\n  \"homepage\": \"http://github.com/andrewdavey/vogue\",\n  \"repository\": \"http://github.com/andrewdavey/vogue.git\",\n  \"author\": \"Andrew Davey <andrew@equin.co.uk> (http://aboutcode.net/)\",\n  \"directories\": {\n    \"lib\": \"\"\n  },\n  \"engines\": {\n    \"node\": \"*\"\n  },\n  \"bin\": {\n    \"vogue\": \"./vogue.js\"\n  },\n  \"dependencies\": {\n    \"socket.io\": \">=0.9.0\",\n    \"parseopt\": \">=1.0.0\"\n  }\n}\n"
  },
  {
    "path": "src/vogue.js",
    "content": "#!/usr/bin/env node\n/* vogue.js\n * A tool for web developers. Vogue watches for changes to CSS files and\n * informs the web browser using them to reload those stylesheets.\n * \n * Created by Andrew Davey ~ http://aboutcode.net \n *\n * Vogue runs on nodeJS and uses socket.io for real-time communication between\n * browser and server.\n */\n\nvar http = require('http')\n  , fs   = require('fs')\n  , path = require('path')\n  , url  = require('url')\n  , opt  = require('parseopt')\n  , io   = require('socket.io');\n\nvar VogueClient = require('./VogueClient').VogueClient\n  , Watcher     = require('./Watcher').Watcher;\n\nvar options = getOptions()\n  , server  = http.createServer(handleHttpRequest)\n  , socket  = io.listen(server)\n  , watcher = new Watcher(options.webDirectory,options.rewrite);\n\nserver.listen(options.port);\nsocket.sockets.on('connection', function(clientSocket) {\n  watcher.addClient(new VogueClient(clientSocket, watcher));\n});\n\nconsole.log('Watching directory: ' + options.webDirectory);\nconsole.log('Listening for clients: http://localhost:' + options.port + '/');\n\n\nfunction handleHttpRequest(request, response) {\n  var pathname = url.parse(request.url).pathname;\n  if (pathname === '/') {\n    sendAboutPage(response);\n  } else if (pathname === '/vogue-client.js') {\n    sendVogueClient(response);\n  }\n}\n\nfunction sendAboutPage(response) {\n  fs.readFile(__dirname + '/client/about.htm', function(e, fileData) {\n    var html = fileData.toString();\n    html = html.replace(/\\{port\\}/g, options.port.toString());\n    response.writeHead(200, { 'Content-Type': 'text/html' });\n    response.write(html);\n    response.end();\n  });\n}\n\nfunction sendVogueClient(response) {\n  fs.readFile(__dirname + '/client/vogue-client.js', function(e, fileData) {\n    var script = fileData.toString();\n    response.writeHead(200, { 'Content-Type': 'text/javascript' });\n    response.write(script);\n    response.end();\n  });\n}\n\nfunction getOptions() {\n  var data = createOptionParser().parse();\n  if (!data) process.exit(1); // Some kind of parsing error\n\n  // The directory to watch is given as the first argument after the options.\n  // So we'll put it into the options we return for simplicity.\n  data.options.webDirectory = getDirectoryToWatch(data.arguments);\n  return data.options;\n\n  function createOptionParser() {\n    var parser = new opt.OptionParser({\n      options: [\n        {\n          name: ['--port', '-p'],\n          type: 'int',\n          help: 'Port to run Vogue server on',\n          'default': 8001\n        },\n        {\n          name: ['--rewrite', '-r'],\n          type: 'string',\n          help: 'Expression of the form \"regexp:replacement\" rewrites a URL path into a file system path, relative to the website root directory. For example: --rewrite \"v[0-9]/(.*)$:files/\\\\$1\" would change \"v1/demo.css\" to \"files/demo.css\".',\n          'default': null\n        },\n        {\n          name: ['--help','-h','-?'],\n          type: 'flag',\n          help: 'Show this help message',\n          onOption: function (value) {\n            if (value) {\n              parser.usage('First argument after options should be the path to the website\\'s root directory. Otherwise the current directory is used.\\ne.g. vogue -p 8001 ./myweb');\n            }\n            // returning true cancels any further option parsing\n            // and parser.parse() returns null\n            return value;\n          }\n        }\n      ]\n    });\n    return parser;\n  }\n\n  function getDirectoryToWatch(arguments) {\n    var dir;\n    if (arguments.length > 0) {\n      if (/^\\//.test(arguments[0])) {\n        dir = arguments[0];\n      } else {\n        dir = path.join(process.cwd(), arguments[0]);\n      }\n    } else {\n      dir = process.cwd();\n    }\n\n    try {\n      var stats = fs.statSync(dir);\n      if (!stats.isDirectory()) {\n        console.error('Path is not a directory: ' + dir);\n        process.exit(1);\n      }\n    } catch (e) {\n      console.error('Path not found: ' + dir);\n      process.exit(1);\n    }\n\n    return dir;\n  }\n}\n"
  }
]