text: process.env.DEBUG = 'app:*';
  const debug = require('debug')('app:demos');
  const commander = require('commander');
  const connect = require('connect');
  const getPort = require('get-port');
  const http = require('http');
  const open = require('open');
  const serveStatic = require('serve-static');
  const parseurl = require('parseurl');
  const assign = require('lodash').assign;
  const path = require('path');
  const resolve = path.resolve;
  const extname = path.extname;
  const basename = path.basename;
  const join = path.join;
  const fs = require('fs');
  const statSync = fs.statSync;
  const lstatSync = fs.lstatSync;
  const readdirSync = fs.readdirSync;
  const readFileSync = fs.readFileSync;
  const mkdirSync = fs.mkdirSync;
  const nunjucks = require('nunjucks');
  const renderString = nunjucks.renderString;
  const pkg = require('../package.json');
  
  function isFile(source) {
    return lstatSync(source).isFile();
  }
  
  function getFiles(source) {
    return readdirSync(source).map(function(name) {
      return join(source, name);
    }).filter(isFile);
  }
  
  const screenshotsPath = join(process.cwd(), './demos/assets/screenshots');
  try {
    statSync(screenshotsPath);
  } catch (e) {
    mkdirSync(screenshotsPath);
  }
  
  commander
    .version(pkg.version)
    .option('-w, --web')
    .option('-p, --port <port>', 'specify a port number to run on', parseInt)
    .parse(process.argv);
  
  function startService(port) {
    const server = connect();
    server.use((req, res, next) => {
      if (req.method === 'GET') {
        const pathname = parseurl(req).pathname;
        if (pathname === '/demos/index.html') {
          const demoFiles = getFiles(__dirname)
            .filter(filename => {
              return extname(filename) === '.html';
            })
            .map(filename => {
              const bn = basename(filename, '.html');
              const file = {
                screenshot: `/demos/assets/screenshots/${bn}.png`,
                basename: bn,
                content: readFileSync(filename),
                filename
              };
              return file;
            });
          const template = readFileSync(join(__dirname, './index.njk'), 'utf8');
          res.end(renderString(template, {
            demoFiles
          }));
        } else {
          next();
        }
      } else {
        next();
      }
    });
    server.use(serveStatic(process.cwd()));
    http.createServer(server).listen(port);
  
    const url = `http://127.0.0.1:${port}/demos/index.html`;
    debug(`server started, demos available! ${url}`);
  
    if (commander.web) {
      debug('running on web!');
      open(url);
    } else {
      debug('running on electron!');
      const app = require('electron').app;
      const BrowserWindow = require('electron').BrowserWindow;
      const watch = require('torchjs/lib/watch');
      const windowBoundsConfig = require('torchjs/lib/windowBoundsConfig')(
        resolve(app.getPath('userData'), './g6-demos-config.json')
      );
  
      let win;
      app.once('ready', () => {
        win = new BrowserWindow(assign({
          // transparent: true
          webPreferences: {
            nodeIntegration: false
          }
        }, windowBoundsConfig.get('demos')));
        win.loadURL(url);
        win.openDevTools();
  
        win.on('close', () => {
          windowBoundsConfig.set('demos', win.getBounds());
        });
        win.on('closed', () => {
          win = null;
        });
        watch([
          'demos/**/*.*',
          'src/**/*.*'
        ], () => {
          win.webContents.reloadIgnoringCache();
        });
      });
      app.on('window-all-closed', () => {
        app.quit();
      });
    }
  }
  
  if (commander.port) {
    startService(commander.port);
  } else {
    getPort().then(port => {
      startService(port);
    });
  }
  