<commit_before>class LwsCli {
  constructor (options) {
    options = options || {}
    this.logError = options.logError || console.error
    this.log = options.log || console.log
  }

  start (argv) {
    try {
      const options = this.getOptions(argv)
      const server = this.execute(options)
      if (server) {
        server.on('error', err => {
          this.printError(err)
        })
      }
      return server
    } catch (err) {
      this.printError(err)
    }
  }

  printError (err) {
    const util = require('./util')
    util.printError(err, '', this.logError)
    process.exitCode = 1
  }

  partialDefinitions () {
    return require('./cli-args')
  }

  usage () {
    const sections = [
      {
        header: 'lws',
        content: 'The modular web server for productive full-stack development.'
      },
      {
        header: 'Synopsis',
        content: [
          '$ lws <options>',
          '$ lws {underline command} <options>'
        ]
      },
      {
        header: 'Server Options',
        content: 'Options set on the server.'
      },
      {
        optionList: this.partialDefinitions().filter(def => def.section === 'server'),
        reverseNameOrder: true
      },
      {
        content: 'HTTPS/TLS specific options.'
      },
      {
        optionList: this.partialDefinitions().filter(def => def.section === 'tls'),
        reverseNameOrder: true
      },
      {
        header: 'Extension Options'
      },
      {
        optionList: this.partialDefinitions().filter(def => def.section === 'extension'),
        reverseNameOrder: true
      },
      {
        header: 'Middleware stack',
        content: this.stack.length
          ? this.stack.map(mw => ({
            name: '↓ ' + mw.constructor.name,
            desc: mw.description && mw.description()
          }))
          : '{italic Stack empty, supply one or more middlewares using --stack.}'
      }
    ]
    const stackOptionDefinitions = this.stack.getOptionDefinitions()
    if (stackOptionDefinitions.length) {
      sections.push({
        header: 'Middleware options',
        optionList: stackOptionDefinitions,
        reverseNameOrder: true
      })
    }
    const viewOptionDefinitions = this.view.optionDefinitions()
    if (viewOptionDefinitions.length) {
      sections.push({
        header: 'View options',
        optionList: viewOptionDefinitions,
        reverseNameOrder: true
      })
    }
    sections.push(
      {
        header: 'Misc Options'
      },
      {
        optionList: this.partialDefinitions().filter(def => def.section === 'core'),
        reverseNameOrder: true
      }
    )
    sections.push({
      content: 'Project home: {underline https://github.com/lwsjs/lws}'
    })
    return sections
  }

  getDefaultOptions () {
    return {
      moduleDir: [ '.' ],
      modulePrefix: 'lws-'
    }
  }

  /**
   * Load and merge options
   */
  getOptions (argv) {
    const util = require('./util')
    const commandLineArgs = require('command-line-args')
    /* get builtIn command-line options */
    let cliOptions = commandLineArgs(this.partialDefinitions(), { argv, partial: true, camelCase: true })
    const storedConfig = util.getStoredConfig(cliOptions.configFile)

    let options = util.deepMerge(this.getDefaultOptions(), storedConfig, cliOptions)

    /* load middleware stack */
    const MiddlewareStack = require('./middleware-stack')
    const stack = MiddlewareStack.from(options.stack, {
      paths: options.moduleDir,
      prefix: options.modulePrefix
    })
    this.stack = stack // required by usage()
    const stackDefinitions = stack.getOptionDefinitions()

    /* default view */
    let view
    if (options.view) {
      view = options.view
    } else {
      const CliView = require('./view/cli-view')
      view = new CliView({
        log: options.log || this.log,
        logError: options.logError || this.logError
      })
    }

    this.view = view // required by usage()
    const viewDefinitions = view.optionDefinitions ? view.optionDefinitions() : []

    /* now we have the stack and view definitions, parse command-line */
    const allDefinitions = [ ...this.partialDefinitions(), ...viewDefinitions, ...stackDefinitions ]
    cliOptions = commandLineArgs(allDefinitions, { argv, camelCase: true })
    options = util.deepMerge(options, storedConfig, cliOptions)
    options.stack = stack
    options.view = view
    return options
  }

  /**
   * @params {object} - Lws config.
   * @returns {HTTPServer}
   */
  execute (config) {
    if (config.help) {
      this.showUsage()
    } else if (config.config) {
      this.showConfig(config)
    } else if (config.version) {
      this.showVersion()
    } else {
      return this.launchServer(config)
    }
  }

  launchServer (options) {
    const Lws = require('../')
    const lws = Lws.create(options)

    const server = lws.server

    if (options.open) {
      const open = require('open')
      const tls = require('tls')
      const protocol = server instanceof tls.Server ? 'https' : 'http'
      const host = options.hostname || '127.0.0.1'
      open(`${protocol}://${host}:${options.port}`)
    }

    return server
  }

  showConfig (options) {
    options = Object.assign({}, options)
    delete options.config
    delete options.moduleDir
    delete options.modulePrefix
    const util = require('util')
    for (const middleware of options.stack) {
      middleware[util.inspect.custom] = function (depth, options) {
        return options.stylize(this.constructor.name, 'special')
      }
    }
    this.log(require('util').inspect(options, { depth: 1, colors: true }))
  }

  showVersion () {
    const path = require('path')
    const pkg = require(path.resolve(__dirname, '..', 'package.json'))
    this.log(pkg.version)
  }

  showUsage () {
    const commandLineUsage = require('command-line-usage')
    this.log(commandLineUsage(this.usage()))
  }
}

module.exports = LwsCli
<commit_msg>fix port passed to --open<commit_after>class LwsCli {
  constructor (options) {
    options = options || {}
    this.logError = options.logError || console.error
    this.log = options.log || console.log
  }

  start (argv) {
    try {
      const options = this.getOptions(argv)
      const server = this.execute(options)
      if (server) {
        server.on('error', err => {
          this.printError(err)
        })
      }
      return server
    } catch (err) {
      this.printError(err)
    }
  }

  printError (err) {
    const util = require('./util')
    util.printError(err, '', this.logError)
    process.exitCode = 1
  }

  partialDefinitions () {
    return require('./cli-args')
  }

  usage () {
    const sections = [
      {
        header: 'lws',
        content: 'The modular web server for productive full-stack development.'
      },
      {
        header: 'Synopsis',
        content: [
          '$ lws <options>',
          '$ lws {underline command} <options>'
        ]
      },
      {
        header: 'Server Options',
        content: 'Options set on the server.'
      },
      {
        optionList: this.partialDefinitions().filter(def => def.section === 'server'),
        reverseNameOrder: true
      },
      {
        content: 'HTTPS/TLS specific options.'
      },
      {
        optionList: this.partialDefinitions().filter(def => def.section === 'tls'),
        reverseNameOrder: true
      },
      {
        header: 'Extension Options'
      },
      {
        optionList: this.partialDefinitions().filter(def => def.section === 'extension'),
        reverseNameOrder: true
      },
      {
        header: 'Middleware stack',
        content: this.stack.length
          ? this.stack.map(mw => ({
            name: '↓ ' + mw.constructor.name,
            desc: mw.description && mw.description()
          }))
          : '{italic Stack empty, supply one or more middlewares using --stack.}'
      }
    ]
    const stackOptionDefinitions = this.stack.getOptionDefinitions()
    if (stackOptionDefinitions.length) {
      sections.push({
        header: 'Middleware options',
        optionList: stackOptionDefinitions,
        reverseNameOrder: true
      })
    }
    const viewOptionDefinitions = this.view.optionDefinitions()
    if (viewOptionDefinitions.length) {
      sections.push({
        header: 'View options',
        optionList: viewOptionDefinitions,
        reverseNameOrder: true
      })
    }
    sections.push(
      {
        header: 'Misc Options'
      },
      {
        optionList: this.partialDefinitions().filter(def => def.section === 'core'),
        reverseNameOrder: true
      }
    )
    sections.push({
      content: 'Project home: {underline https://github.com/lwsjs/lws}'
    })
    return sections
  }

  getDefaultOptions () {
    return {
      moduleDir: [ '.' ],
      modulePrefix: 'lws-'
    }
  }

  /**
   * Load and merge options
   */
  getOptions (argv) {
    const util = require('./util')
    const commandLineArgs = require('command-line-args')
    /* get builtIn command-line options */
    let cliOptions = commandLineArgs(this.partialDefinitions(), { argv, partial: true, camelCase: true })
    const storedConfig = util.getStoredConfig(cliOptions.configFile)

    let options = util.deepMerge(this.getDefaultOptions(), storedConfig, cliOptions)

    /* load middleware stack */
    const MiddlewareStack = require('./middleware-stack')
    const stack = MiddlewareStack.from(options.stack, {
      paths: options.moduleDir,
      prefix: options.modulePrefix
    })
    this.stack = stack // required by usage()
    const stackDefinitions = stack.getOptionDefinitions()

    /* default view */
    let view
    if (options.view) {
      view = options.view
    } else {
      const CliView = require('./view/cli-view')
      view = new CliView({
        log: options.log || this.log,
        logError: options.logError || this.logError
      })
    }

    this.view = view // required by usage()
    const viewDefinitions = view.optionDefinitions ? view.optionDefinitions() : []

    /* now we have the stack and view definitions, parse command-line */
    const allDefinitions = [ ...this.partialDefinitions(), ...viewDefinitions, ...stackDefinitions ]
    cliOptions = commandLineArgs(allDefinitions, { argv, camelCase: true })
    options = util.deepMerge(options, storedConfig, cliOptions)
    options.stack = stack
    options.view = view
    return options
  }

  /**
   * @params {object} - Lws config.
   * @returns {HTTPServer}
   */
  execute (config) {
    if (config.help) {
      this.showUsage()
    } else if (config.config) {
      this.showConfig(config)
    } else if (config.version) {
      this.showVersion()
    } else {
      return this.launchServer(config)
    }
  }

  launchServer (config) {
    const Lws = require('../')
    const lws = Lws.create(config)
    config = lws.config
    const server = lws.server

    if (config.open) {
      const open = require('open')
      const tls = require('tls')
      const protocol = server instanceof tls.Server ? 'https' : 'http'
      const host = config.hostname || '127.0.0.1'
      const url = `${protocol}://${host}:${config.port}`
      lws.emit('verbose', 'open', url)
      open(url)
    }

    return server
  }

  showConfig (options) {
    options = Object.assign({}, options)
    delete options.config
    delete options.moduleDir
    delete options.modulePrefix
    const util = require('util')
    for (const middleware of options.stack) {
      middleware[util.inspect.custom] = function (depth, options) {
        return options.stylize(this.constructor.name, 'special')
      }
    }
    this.log(require('util').inspect(options, { depth: 1, colors: true }))
  }

  showVersion () {
    const path = require('path')
    const pkg = require(path.resolve(__dirname, '..', 'package.json'))
    this.log(pkg.version)
  }

  showUsage () {
    const commandLineUsage = require('command-line-usage')
    this.log(commandLineUsage(this.usage()))
  }
}

module.exports = LwsCli
<|endoftext|>


<commit_before>/* global Blob chrome clobber:true */
var clobber = {};
(function(){
function removeDirectoryContents(dirEntry) {
  return new Promise(function(resolve, reject) {
    var dirReader = dirEntry.createReader();
    var entriesToRemove = 0;
    var allEntriesRead = false;
    function entryRemovalCallback() {
      --entriesToRemove;
      if (entriesToRemove == 0 && allEntriesRead) return resolve();
    }
    function removeEntry(entry) {
      ++entriesToRemove;
      return entry.isDirectory
        ? entry.removeRecursively(entryRemovalCallback)
        : entry.remove(entryRemovalCallback);
    }
    function removeAndRecurse(results) {
      if (results.length > 0) {
        results.forEach(removeEntry);
        return readDirEntries();
      } else if (entriesToRemove == 0) {
        return resolve();
      } else {
        allEntriesRead = true;
      }
    }
    function readDirEntries(results) {
      dirReader.readEntries(removeAndRecurse, reject);
    }
    readDirEntries();
  });
}
function createDir(rootDirEntry, path) {
  if (typeof path == 'string') path = path.split('/');
  return new Promise(function (resolve, reject) {
    function createDirs(parentDirEntry, folders) {
      // Throw out './' or '/' and move on
      // to prevent something like '/foo/.//bar'.
      while (folders[0] == '.' || folders[0] == '') {
        folders.unshift();
      }
      // Recursively add the new subfolder
      // (if we still have another to create).
      if (folders.length) {
        parentDirEntry.getDirectory(folders[0], {create: true},
          function(dirEntry) {
            return createDirs(dirEntry, folders.slice(1));
          }, reject);
      } else resolve(parentDirEntry);
    }
    return createDirs(rootDirEntry, path);
  });
}
function createFile(parentDirEntry, name, data) {
  return new Promise(function(resolve, reject) {
    return parentDirEntry.getFile(name, {create: true}, function(fileEntry) {
      return fileEntry.createWriter(function(fileWriter) {
        fileWriter.onwriteend = resolve;
        fileWriter.onerror = reject;
        fileWriter.write(data);
      }, reject);
    }, reject);
  });
}
function extractZipToDirectory(zip, dirEntry) {
  var names = Object.keys(zip.files);
  var fsOpPromises = names.map(function (name) {
    var file = zip.files[name];
    if (file.dir) {
      return createDir(dirEntry, name);
    } else {
      var filePath = name.split('/');
      var filename = filePath.pop();
      return createDir(dirEntry, filePath).then(function (parentDirEntry) {
        return createFile(parentDirEntry, filename,
          new Blob(file.asArrayBuffer()));
      });
    }
  });
  return Promise.all(fsOpPromises).then(function(results) {
    return dirEntry;
  });
}
function clobberDirectoryFromZip(dirEntry, zip) {
  return removeDirectoryContents(dirEntry)
    .then(extractZipToDirectory.bind(null, zip, dirEntry));
}
clobber.dirFromZip = clobberDirectoryFromZip;
})();
<commit_msg>Shift, not unshift<commit_after>/* global Blob chrome clobber:true */
var clobber = {};
(function(){
function removeDirectoryContents(dirEntry) {
  return new Promise(function(resolve, reject) {
    var dirReader = dirEntry.createReader();
    var entriesToRemove = 0;
    var allEntriesRead = false;
    function entryRemovalCallback() {
      --entriesToRemove;
      if (entriesToRemove == 0 && allEntriesRead) return resolve();
    }
    function removeEntry(entry) {
      ++entriesToRemove;
      return entry.isDirectory
        ? entry.removeRecursively(entryRemovalCallback)
        : entry.remove(entryRemovalCallback);
    }
    function removeAndRecurse(results) {
      if (results.length > 0) {
        results.forEach(removeEntry);
        return readDirEntries();
      } else if (entriesToRemove == 0) {
        return resolve();
      } else {
        allEntriesRead = true;
      }
    }
    function readDirEntries(results) {
      dirReader.readEntries(removeAndRecurse, reject);
    }
    readDirEntries();
  });
}
function createDir(rootDirEntry, path) {
  if (typeof path == 'string') path = path.split('/');
  return new Promise(function (resolve, reject) {
    function createDirs(parentDirEntry, folders) {
      // Throw out './' or '/' and move on
      // to prevent something like '/foo/.//bar'.
      while (folders[0] == '.' || folders[0] == '') {
        folders.shift();
      }
      // Recursively add the new subfolder
      // (if we still have another to create).
      if (folders.length) {
        parentDirEntry.getDirectory(folders[0], {create: true},
          function(dirEntry) {
            return createDirs(dirEntry, folders.slice(1));
          }, reject);
      } else resolve(parentDirEntry);
    }
    return createDirs(rootDirEntry, path);
  });
}
function createFile(parentDirEntry, name, data) {
  return new Promise(function(resolve, reject) {
    return parentDirEntry.getFile(name, {create: true}, function(fileEntry) {
      return fileEntry.createWriter(function(fileWriter) {
        fileWriter.onwriteend = resolve;
        fileWriter.onerror = reject;
        fileWriter.write(data);
      }, reject);
    }, reject);
  });
}
function extractZipToDirectory(zip, dirEntry) {
  var names = Object.keys(zip.files);
  var fsOpPromises = names.map(function (name) {
    var file = zip.files[name];
    if (file.dir) {
      return createDir(dirEntry, name);
    } else {
      var filePath = name.split('/');
      var filename = filePath.pop();
      return createDir(dirEntry, filePath).then(function (parentDirEntry) {
        return createFile(parentDirEntry, filename,
          new Blob(file.asArrayBuffer()));
      });
    }
  });
  return Promise.all(fsOpPromises).then(function(results) {
    return dirEntry;
  });
}
function clobberDirectoryFromZip(dirEntry, zip) {
  return removeDirectoryContents(dirEntry)
    .then(extractZipToDirectory.bind(null, zip, dirEntry));
}
clobber.dirFromZip = clobberDirectoryFromZip;
})();
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var Mustache = require('mustache');
var beautify = require('js-beautify').js_beautify;
var lint = require('jshint').JSHINT;
var _ = require('lodash');

var camelCase = function(id) {
    var tokens = [];
    id.split('-').forEach(function(token, index){
        if(index === 0) {
            tokens.push(token[0].toLowerCase() + token.substring(1));
        } else {
            tokens.push(token[0].toUpperCase() + token.substring(1));
        }
    });
    return tokens.join('');
};

var getPathToMethodName = function(m, path){
    var segments = path.split('/').slice(1);
    segments = _.transform(segments, function(result, segment){
        if(segment[0] === '{' && segment[segment.length - 1] === '}') {
            segment = 'by' + segment[1].toUpperCase() + segment.substring(2, segment.length - 1);
        }
        result.push(segment);
    });
    var result = camelCase(segments.join('-'));
    return m.toLowerCase() + result[0].toUpperCase() + result.substring(1);
};

var getViewForSwagger2 = function(opts, type){
    var swagger = opts.swagger;
    var authorizedMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'COPY', 'HEAD', 'OPTIONS', 'LINK', 'UNLIK', 'PURGE', 'LOCK', 'UNLOCK', 'PROPFIND'];
    var data = {
        isNode: type === 'node',
        description: swagger.info.description,
        moduleName: opts.moduleName,
        className: opts.className,
        methods: []
    };

    _.forEach(swagger.paths, function(api, path){
        var globalParams = [];
        _.forEach(api, function(op, m){
            if(m.toLowerCase() === 'parameters') {
                globalParams = op;
            }
        });
        _.forEach(api, function(op, m){
            if(authorizedMethods.indexOf(m.toUpperCase()) === -1) {
                return;
            }
            var method = {
                path: path,
                className: opts.className,
                methodName: op['x-swagger-js-method-name'] ? op['x-swagger-js-method-name'] : (op.operationId ? op.operationId : getPathToMethodName(m, path)),
                method: m.toUpperCase(),
                isGET: m.toUpperCase() === 'GET',
                summary: op.description,
                parameters: []
            };
            var params = [];
            if(_.isArray(op.parameters)) {
                params = op.parameters;
            }
            params = params.concat(globalParams);
            _.chain(params).forEach(function(parameter) {
                if (_.isString(parameter.$ref)) {
                    var segments = parameter.$ref.split('/');
                    parameter = swagger.parameters[segments.length === 1 ? segments[0] : segments[2] ];
                }
                parameter.camelCaseName = camelCase(parameter.name);
                if(parameter.enum && parameter.enum.length === 1) {
                    parameter.isSingleton = true;
                    parameter.singleton = parameter.enum[0];
                }
                if(parameter.in === 'body'){
                    parameter.isBodyParameter = true;
                } else if(parameter.in === 'path'){
                    parameter.isPathParameter = true;
                } else if(parameter.in === 'query'){
                    if(parameter.pattern){
                        parameter.isPatternType = true;
                    }
                    parameter.isQueryParameter = true;
                } else if(parameter.in === 'header'){
                    parameter.isHeaderParameter = true;
                } else if(parameter.paramType === 'form'){
                    parameter.isFormParameter = true;
                }
                method.parameters.push(parameter);
            });
            data.methods.push(method);
        });
    });
    return data;
};

var getViewForSwagger1 = function(opts, type){
    var swagger = opts.swagger;
    var data = {
        isNode: type === 'node',
        description: swagger.description,
        moduleName: opts.moduleName,
        className: opts.className,
        methods: []
    };
    swagger.apis.forEach(function(api){
        api.operations.forEach(function(op){
            var method = {
                path: api.path,
                className: opts.className,
                methodName: op.nickname,
                method: op.method,
                isGET: op.method === 'GET',
                summary: op.summary,
                parameters: op.parameters
            };
            op.parameters = op.parameters ? op.parameters : [];
            op.parameters.forEach(function(parameter) {
                parameter.camelCaseName = camelCase(parameter.name);
                if(parameter.enum && parameter.enum.length === 1) {
                    parameter.isSingleton = true;
                    parameter.singleton = parameter.enum[0];
                }
                if(parameter.paramType === 'body'){
                    parameter.isBodyParameter = true;
                } else if(parameter.paramType === 'path'){
                    parameter.isPathParameter = true;
                } else if(parameter.paramType === 'query'){
                    if(parameter.pattern){
                        parameter.isPatternType = true;
                    }
                    parameter.isQueryParameter = true;
                } else if(parameter.paramType === 'header'){
                    parameter.isHeaderParameter = true;
                } else if(parameter.paramType === 'form'){
                    parameter.isFormParameter = true;
                }
            });
            data.methods.push(method);
        });
    });
    return data;
};

var getCode = function(opts, type) {
    var tpl, method, request;
    // For Swagger Specification version 2.0 value of field 'swagger' must be a string '2.0'
    var data = opts.swagger.swagger === '2.0' ? getViewForSwagger2(opts, type) : getViewForSwagger1(opts, type);
    if(type === 'custom') {
        if(!_.isObject(opts.template) || !_.isString(opts.template.class)  || !_.isString(opts.template.method) || !_.isString(opts.template.request)) {
            throw new Error('Unprovided custom template. Please use the following template: template: { class: "...", method: "...", request: "..." }');
        }
        tpl = opts.template.class;
        method = opts.template.method;
        request = opts.template.request;
    } else {
        tpl = fs.readFileSync(__dirname + '/../templates/' + type + '-class.mustache', 'utf-8');
        method = fs.readFileSync(__dirname + '/../templates/method.mustache', 'utf-8');
        request = fs.readFileSync(__dirname + '/../templates/' + type + '-request.mustache', 'utf-8');
    }
    var source = Mustache.render(tpl, data, {
        method: method,
        request: request
    });
    lint(source, {
        node: type === 'node' || type === 'custom',
        browser: type === 'angular' || type === 'custom',
        undef: true,
        strict: true,
        trailing: true,
        smarttabs: true
    });
    lint.errors.forEach(function(error){
        if(error.code[0] === 'E') {
            throw new Error(lint.errors[0].reason + ' in ' + lint.errors[0].evidence);
        }
    });
    return beautify(source, { indent_size: 4, max_preserve_newlines: 2 });
};

exports.CodeGen = {
    getAngularCode: function(opts){
        return getCode(opts, 'angular');
    },
    getNodeCode: function(opts){
        return getCode(opts, 'node');
    },
    getCustomCode: function(opts){
        return getCode(opts, 'custom');
    }
};
<commit_msg>Update codegen.js<commit_after>'use strict';

var fs = require('fs');
var Mustache = require('mustache');
var beautify = require('js-beautify').js_beautify;
var lint = require('jshint').JSHINT;
var _ = require('lodash');

var camelCase = function(id) {
    var tokens = [];
    id.split('-').forEach(function(token, index){
        if(index === 0) {
            tokens.push(token[0].toLowerCase() + token.substring(1));
        } else {
            tokens.push(token[0].toUpperCase() + token.substring(1));
        }
    });
    return tokens.join('');
};

var getPathToMethodName = function(m, path){
    var segments = path.split('/').slice(1);
    segments = _.transform(segments, function(result, segment){
        if(segment[0] === '{' && segment[segment.length - 1] === '}') {
            segment = 'by' + segment[1].toUpperCase() + segment.substring(2, segment.length - 1);
        }
        result.push(segment);
    });
    var result = camelCase(segments.join('-'));
    return m.toLowerCase() + result[0].toUpperCase() + result.substring(1);
};

var getViewForSwagger2 = function(opts, type){
    var swagger = opts.swagger;
    var authorizedMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'COPY', 'HEAD', 'OPTIONS', 'LINK', 'UNLIK', 'PURGE', 'LOCK', 'UNLOCK', 'PROPFIND'];
    var data = {
        isNode: type === 'node',
        description: swagger.info.description,
        moduleName: opts.moduleName,
        className: opts.className,
        methods: []
    };

    _.forEach(swagger.paths, function(api, path){
        var globalParams = [];
        _.forEach(api, function(op, m){
            if(m.toLowerCase() === 'parameters') {
                globalParams = op;
            }
        });
        _.forEach(api, function(op, m){
            if(authorizedMethods.indexOf(m.toUpperCase()) === -1) {
                return;
            }
            var method = {
                path: path,
                className: opts.className,
                methodName: op['x-swagger-js-method-name'] ? op['x-swagger-js-method-name'] : (op.operationId ? op.operationId : getPathToMethodName(m, path)),
                method: m.toUpperCase(),
                isGET: m.toUpperCase() === 'GET',
                summary: op.description,
                parameters: []
            };
            var params = [];
            if(_.isArray(op.parameters)) {
                params = op.parameters;
            }
            params = params.concat(globalParams);
            _.chain(params).forEach(function(parameter) {
                if (_.isString(parameter.$ref)) {
                    var segments = parameter.$ref.split('/');
                    parameter = swagger.parameters[segments.length === 1 ? segments[0] : segments[2] ];
                }
                parameter.camelCaseName = camelCase(parameter.name);
                if(parameter.enum && parameter.enum.length === 1) {
                    parameter.isSingleton = true;
                    parameter.singleton = parameter.enum[0];
                }
                if(parameter.in === 'body'){
                    parameter.isBodyParameter = true;
                } else if(parameter.in === 'path'){
                    parameter.isPathParameter = true;
                } else if(parameter.in === 'query'){
                    if(parameter.pattern){
                        parameter.isPatternType = true;
                    }
                    parameter.isQueryParameter = true;
                } else if(parameter.in === 'header'){
                    parameter.isHeaderParameter = true;
                } else if(parameter.in === 'form'){
                    parameter.isFormParameter = true;
                }
                method.parameters.push(parameter);
            });
            data.methods.push(method);
        });
    });
    return data;
};

var getViewForSwagger1 = function(opts, type){
    var swagger = opts.swagger;
    var data = {
        isNode: type === 'node',
        description: swagger.description,
        moduleName: opts.moduleName,
        className: opts.className,
        methods: []
    };
    swagger.apis.forEach(function(api){
        api.operations.forEach(function(op){
            var method = {
                path: api.path,
                className: opts.className,
                methodName: op.nickname,
                method: op.method,
                isGET: op.method === 'GET',
                summary: op.summary,
                parameters: op.parameters
            };
            op.parameters = op.parameters ? op.parameters : [];
            op.parameters.forEach(function(parameter) {
                parameter.camelCaseName = camelCase(parameter.name);
                if(parameter.enum && parameter.enum.length === 1) {
                    parameter.isSingleton = true;
                    parameter.singleton = parameter.enum[0];
                }
                if(parameter.paramType === 'body'){
                    parameter.isBodyParameter = true;
                } else if(parameter.paramType === 'path'){
                    parameter.isPathParameter = true;
                } else if(parameter.paramType === 'query'){
                    if(parameter.pattern){
                        parameter.isPatternType = true;
                    }
                    parameter.isQueryParameter = true;
                } else if(parameter.paramType === 'header'){
                    parameter.isHeaderParameter = true;
                } else if(parameter.paramType === 'form'){
                    parameter.isFormParameter = true;
                }
            });
            data.methods.push(method);
        });
    });
    return data;
};

var getCode = function(opts, type) {
    var tpl, method, request;
    // For Swagger Specification version 2.0 value of field 'swagger' must be a string '2.0'
    var data = opts.swagger.swagger === '2.0' ? getViewForSwagger2(opts, type) : getViewForSwagger1(opts, type);
    if(type === 'custom') {
        if(!_.isObject(opts.template) || !_.isString(opts.template.class)  || !_.isString(opts.template.method) || !_.isString(opts.template.request)) {
            throw new Error('Unprovided custom template. Please use the following template: template: { class: "...", method: "...", request: "..." }');
        }
        tpl = opts.template.class;
        method = opts.template.method;
        request = opts.template.request;
    } else {
        tpl = fs.readFileSync(__dirname + '/../templates/' + type + '-class.mustache', 'utf-8');
        method = fs.readFileSync(__dirname + '/../templates/method.mustache', 'utf-8');
        request = fs.readFileSync(__dirname + '/../templates/' + type + '-request.mustache', 'utf-8');
    }
    var source = Mustache.render(tpl, data, {
        method: method,
        request: request
    });
    lint(source, {
        node: type === 'node' || type === 'custom',
        browser: type === 'angular' || type === 'custom',
        undef: true,
        strict: true,
        trailing: true,
        smarttabs: true
    });
    lint.errors.forEach(function(error){
        if(error.code[0] === 'E') {
            throw new Error(lint.errors[0].reason + ' in ' + lint.errors[0].evidence);
        }
    });
    return beautify(source, { indent_size: 4, max_preserve_newlines: 2 });
};

exports.CodeGen = {
    getAngularCode: function(opts){
        return getCode(opts, 'angular');
    },
    getNodeCode: function(opts){
        return getCode(opts, 'node');
    },
    getCustomCode: function(opts){
        return getCode(opts, 'custom');
    }
};
<|endoftext|>


<commit_before>var fieldNames ={
    "census_id"                      : "Census ID"                              ,
    "gov_name"                       : "Name"                                   ,
    "special_district_function_code" : "Special Purpose District Function Code" ,
    "gov_type"                       : "Government Type"                        ,
    "census_contact"                 : "Census Contact"                         ,
    "address1"                       : "Address Line 1"                         ,
    "address2"                       : "Address Line 2"                         ,
    "city"                           : "City"                                   ,
    "state"                          : "State"                                  ,
    "zip"                            : "Zip Code"                               ,
    "web_site"                       : "Web Site Address"                       ,
    "population"                     : "Population"                             ,
    //No label; place value in parenthesis next to Population"                  ,
    "population_as_of_year"          : ""                                       ,
    "enrollment"                     : "Enrollment"                             ,
    //No label; place value in parenthesis next to Enrollment"                  ,
    "enrollment_as_of_year"          : ""                                       ,
    "fips_state"                     : "FIPS State Code"                        ,
    "fips_county"                    : "FIPS County Code"                       ,
    "fips_place"                     : "FIPS Place Code"                        ,
    "county_area_name"               : "County (or County Equivalent) Name"
}
var substringMatcher = function(strs) {
    return function findMatches(q, cb) {
        var matches, substrRegex;

        // an array that will be populated with substring matches
        matches = [];

        // regex used to determine if a string contains the substring `q`
        substrRegex = new RegExp(q, 'i');

        // iterate through the pool of strings and for any string that
        // contains the substring `q`, add it to the `matches` array
        //var counter=0;
        $.each(strs, function(i, str) {
            if (substrRegex.test(str.gov_name)) {
                //  the typeahead jQuery plugin expects suggestions to a
                // JavaScript object, refer to typeahead docs for more info
                matches.push(str);
                if (matches.length >= 14) return false;
            }
        });

        cb(matches);
    };
};

var suggestionTemplate = Handlebars.compile('
{{gov_name}} {{state}}  {{zip}}
');

var ta;

function startSuggestion(){

    $('.typeahead').attr('placeholder',"GOVERNMENT NAME");
    ta = $('.typeahead').typeahead({
        hint: true,
        highlight: true,
        minLength: 1
    }, {
        name: 'gov_name',
        displayKey: 'gov_name',
        source: substringMatcher(govs),
        templates: {
            suggestion: suggestionTemplate
        }
    });

    function link(v){
        return ((""+v).indexOf("http://") == -1)? v : ''+v+'';
    }

    function makeFieldHtml(n,v){
        var s="";
        if (v){
            s+='
'+ fieldNames[n] +'';
            s+='   '+link(v)+'

';
        }
        return s;
    }

    function makeRecordHtml(data){
        var s="";
        for (n in data){
            s+= makeFieldHtml(n,data[n])
        }
        $('#details').html(s);
    }

    // Attach initialized event to it
    ta.on('typeahead:selected', function(evt, data, name) { makeRecordHtml(data);});

}

$.ajax({
      url:"../../data/govs.js",
      dataType: "script",
      cache: true,
      success: startSuggestion
});

<commit_msg>field names<commit_after>var fieldNames ={
    "census_id"                      : "Census ID"                              ,
    "gov_name"                       : "Name"                                   ,
    "special_district_function_code" : "Special Purpose District Function Code" ,
    "gov_type"                       : "Government Type"                        ,
    "census_contact"                 : "Census Contact"                         ,
    "address1"                       : "Address Line 1"                         ,
    "address2"                       : "Address Line 2"                         ,
    "city"                           : "City"                                   ,
    "state"                          : "State"                                  ,
    "zip"                            : "Zip Code"                               ,
    "web_site"                       : "Web Site Address"                       ,
    "population"                     : "Population"                             ,
    //No label; place value in parenthesis next to Population"                  ,
    "population_as_of_year"          : ""                                       ,
    "enrollment"                     : "Enrollment"                             ,
    //No label; place value in parenthesis next to Enrollment"                  ,
    "enrollment_as_of_year"          : ""                                       ,
    "fips_state"                     : "FIPS State Code"                        ,
    "fips_county"                    : "FIPS County Code"                       ,
    "fips_place"                     : "FIPS Place Code"                        ,
    "county_area_name"               : "County (or County Equivalent) Name"     ,
    "county_area_type"               : "County Type"

}
var substringMatcher = function(strs) {
    return function findMatches(q, cb) {
        var matches, substrRegex;

        // an array that will be populated with substring matches
        matches = [];

        // regex used to determine if a string contains the substring `q`
        substrRegex = new RegExp(q, 'i');

        // iterate through the pool of strings and for any string that
        // contains the substring `q`, add it to the `matches` array
        //var counter=0;
        $.each(strs, function(i, str) {
            if (substrRegex.test(str.gov_name)) {
                //  the typeahead jQuery plugin expects suggestions to a
                // JavaScript object, refer to typeahead docs for more info
                matches.push(str);
                if (matches.length >= 14) return false;
            }
        });

        cb(matches);
    };
};

var suggestionTemplate = Handlebars.compile('
{{gov_name}} {{state}}  {{zip}}
');

var ta;

function startSuggestion(){

    $('.typeahead').attr('placeholder',"GOVERNMENT NAME");
    ta = $('.typeahead').typeahead({
        hint: true,
        highlight: true,
        minLength: 1
    }, {
        name: 'gov_name',
        displayKey: 'gov_name',
        source: substringMatcher(govs),
        templates: {
            suggestion: suggestionTemplate
        }
    });

    function link(v){
        return ((""+v).indexOf("http://") == -1)? v : ''+v+'';
    }

    function makeFieldHtml(n,v){
        var s="";
        if (v){
            s+='
'+ fieldNames[n] +'';
            s+='   '+link(v)+'

';
        }
        return s;
    }

    function makeRecordHtml(data){
        var s="";
        for (n in data){
            s+= makeFieldHtml(n,data[n])
        }
        $('#details').html(s);
    }

    // Attach initialized event to it
    ta.on('typeahead:selected', function(evt, data, name) { makeRecordHtml(data);});

}

$.ajax({
      url:"../../data/govs.js",
      dataType: "script",
      cache: true,
      success: startSuggestion
});

<|endoftext|>


<commit_before>// @flow

import React, { Component, Children, cloneElement, type ReactElement } from 'react';
import { View, Animated, StyleSheet, ScrollView, Dimensions } from 'react-native';
import AnimatedOverlay from 'react-native-animated-overlay';
import _ from 'lodash';

import Separator from './Separator';
import Animation from './Animation';

const { width: WIDTH, height: HEIGHT } = Dimensions.get('window');

// action sheet states
const ACTION_SHEET_OPENING: string = 'opening';
const ACTION_SHEET_OPENED: string = 'opened';
const ACTION_SHEET_CLOSING: string = 'closing';
const ACTION_SHEET_CLOSED: string = 'closed';

const DEFAULT_ANIMATION_DURATION: number = 250;

const INITIAL_TOP_POSITION: number = -180;
const INITIAL_BOTTOM_POSITION: number = HEIGHT * -1;

const styles = StyleSheet.create({
  container: {
    position: 'absolute',
    top: 0,
    left: 0,
    backgroundColor: 'white',
  },
  contentContainer: {
    width: WIDTH,
    position: 'absolute',
    backgroundColor: 'white',
  },
  scrollView: {
  },
  hidden: {
    top: -10000,
    left: 0,
    height: 0,
    width: 0,
  },
});

type Props = {
  onShow?: () => void;
  onHide?: () => void;
  show?: boolean;
  animationDuration?: number;
  overlayOpacity?: number;
  position?: 'top' | 'bottom';
  onChange?: () => void;
  multiple?: boolean;
  showSparator?: boolean;
  value?: any;
  defaultValue?: any;
  hideOnSelceted?: boolean;
  children?: any;
};

const defaultProps = {
  onShow: () => {},
  onHide: () => {},
  show: false,
  animationDuration: DEFAULT_ANIMATION_DURATION,
  overlayOpacity: 0.3,
  position: 'top',
  onChange: () => {},
  multiple: false,
  showSparator: true,
  value: null,
  defaultValue: null,
  hideOnSelceted: true,
  children: null,
};

class ActionSheet extends Component {
  props: Props

  static defaultProps = defaultProps

  constructor(props: Props) {
    super(props);

    let initValue = (props.value || props.defaultValue);
    initValue = Array.isArray(initValue)
      ? initValue
      : (initValue === null && []) || [initValue];

    this.state = {
      show: props.show,
      selectedData: initValue,
      actionSheetState: ACTION_SHEET_CLOSED,
      actionSheetAnimation: new Animation(this.hideActionSheetPosition),
    };
  }

  componentDidMount() {
    if (this.props.show) {
      this.show();
    }
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.position !== nextProps.position) {
      this.setState({ actionSheetAnimation: new Animation(this.hideActionSheetPosition) });
    }

    if (this.props.show !== nextProps.show) {
      if (nextProps.show) {
        this.show();
      } else {
        this.hide();
      }
    }

    if (!_.isEqual(this.props.value, nextProps.value)) {
      const selectedData = [];
      nextProps.value.forEach((value) => {
        if (!this.props.multiple && selectedData.length !== 0) {
          return;
        }
        selectedData.push(value);
      });
      this.setState({ selectedData });
    }
  }

  get showActionSheetPosition(): string {
    const { position } = this.props;
    if (position === 'top') {
      return INITIAL_TOP_POSITION * -1;
    }
    return 0;
  }

  get hideActionSheetPosition(): string {
    const { position } = this.props;
    if (position === 'top') {
      return INITIAL_TOP_POSITION;
    }
    return INITIAL_BOTTOM_POSITION * -1;
  }

  onOverlayPress = (): void => {
    this.hide();
  }

  setActionSheetState(toValue: number, callback?: Function = () => {}): void {
    const { animationDuration } = this.props;
    const isClosed = (this.state.actionSheetState === ACTION_SHEET_CLOSED);

    let actionSheetState = isClosed ? ACTION_SHEET_OPENING : ACTION_SHEET_CLOSING;

    this.setState({ actionSheetState });

    this.state.actionSheetAnimation.toValue(toValue, animationDuration, () => {
      const isClosing = (this.state.actionSheetState === ACTION_SHEET_CLOSING);
      actionSheetState = isClosing ? ACTION_SHEET_CLOSED : ACTION_SHEET_OPENED;

      this.setState({ actionSheetState });
      callback();
    });
  }

  show = (callback?: Function = () => {}): void => {
    if ([ACTION_SHEET_OPENING, ACTION_SHEET_OPENED].includes(this.state.actionSheetState)) {
      return;
    }

    const { onShow } = this.props;

    this.setState({ show: true });
    this.setActionSheetState(this.showActionSheetPosition);
    onShow();
    callback();
  }

  hide = (callback?: Function = () => {}): void => {
    if ([ACTION_SHEET_CLOSING, ACTION_SHEET_CLOSED].includes(this.state.actionSheetState)) {
      return;
    }

    const { onHide } = this.props;

    this.setState({ show: false });
    this.setActionSheetState(this.hideActionSheetPosition);
    onHide();
    callback();
  }

  onItemPress(value, index): void {
    const { hideOnSelceted } = this.props;
    if (hideOnSelceted) {
      this.hide();
    }

    if (Object.values(this.state.selectedData).includes(value)) {
      this.unselectItem(value, index);
      return;
    }

    this.selectItem(value, index);
  }

  selectItem(value, index) {
    const { multiple: isMultiSelect, onChange } = this.props;
    let selectedData = [];

    if (isMultiSelect) {
      selectedData = [...this.state.selectedData];
    }

    selectedData.push(value);
    this.setState({ selectedData });
    onChange(value, index, selectedData);
  }

  unselectItem(value, index) {
    const { multiple: isMultiSelect, onChange } = this.props;
    let selectedData = [];

    if (isMultiSelect) {
      selectedData = [...this.state.selectedData];
      selectedData.splice(index, 1);
    }

    this.setState({ selectedData });
    onChange(value, index, selectedData);
  }

  isItemSelected(index): boolean {
    return !!this.state.selectedData[index];
  }

  renderItems(): ReactElement {
    const { children, showSparator } = this.props;
    const separator = showSparator ? <Separator /> : null;

    return Children.map(children, (child) => {
      const index = this.state.selectedData.indexOf(child.value);
      const item = cloneElement(child, {
        index,
        selected: this.state.selectedData.includes(child.props.value),
        onPress: (selectedValue, selectedIndex) => {
          child.props.onPress(selectedValue, selectedIndex);
          this.onItemPress(selectedValue, selectedIndex);
        },
      });

      return (
        <View style={{ flex: 1 }}>
          {item}
          {separator}
        </View>
      );
    });
  }

  render() {
    const { animationDuration, overlayOpacity, position } = this.props;
    const { actionSheetState, actionSheetAnimation: { animations } } = this.state;

    const overlayShow = [ACTION_SHEET_OPENED, ACTION_SHEET_OPENING].includes(actionSheetState);
    const pointerEvents = (actionSheetState === ACTION_SHEET_OPENED) ? 'auto' : 'none';
    const hidden = actionSheetState === ACTION_SHEET_CLOSED && styles.hidden;

    const contentPosition = (position === 'top')
      ? { top: INITIAL_TOP_POSITION }
      : { bottom: INITIAL_BOTTOM_POSITION };

    const scrollView = (position === 'top')
      ? { paddingTop: 30 }
      : null;

    return (
      <View style={[styles.container, hidden]}>
        <AnimatedOverlay
          onPress={this.onOverlayPress}
          overlayShow={overlayShow}
          duration={animationDuration}
          opacity={overlayOpacity}
          pointerEvents={pointerEvents}
        />
        <Animated.View
          style={[styles.contentContainer, contentPosition, animations]}
        >
          <ScrollView style={[styles.scrollView, scrollView]}>
            {this.renderItems()}
          </ScrollView>
        </Animated.View>
      </View>
    );
  }
}

export default ActionSheet;
<commit_msg>code refactoring -  better naming conversion<commit_after>// @flow

import React, { Component, Children, cloneElement, type ReactElement } from 'react';
import { View, Animated, StyleSheet, ScrollView, Dimensions } from 'react-native';
import AnimatedOverlay from 'react-native-animated-overlay';
import _ from 'lodash';

import Separator from './Separator';
import Animation from './Animation';

const { width: WIDTH, height: HEIGHT } = Dimensions.get('window');

// action sheet states
const ACTION_SHEET_OPENING: string = 'opening';
const ACTION_SHEET_OPENED: string = 'opened';
const ACTION_SHEET_CLOSING: string = 'closing';
const ACTION_SHEET_CLOSED: string = 'closed';

const DEFAULT_ANIMATION_DURATION: number = 250;

const INITIAL_TOP_POSITION: number = -180;
const INITIAL_BOTTOM_POSITION: number = HEIGHT * -1;

const styles = StyleSheet.create({
  container: {
    position: 'absolute',
    top: 0,
    left: 0,
    backgroundColor: 'white',
  },
  contentContainer: {
    width: WIDTH,
    position: 'absolute',
    backgroundColor: 'white',
  },
  scrollView: {
  },
  hidden: {
    top: -10000,
    left: 0,
    height: 0,
    width: 0,
  },
});

type Props = {
  onShow?: () => void;
  onHide?: () => void;
  show?: boolean;
  animationDuration?: number;
  overlayOpacity?: number;
  position?: 'top' | 'bottom';
  onChange?: () => void;
  multiple?: boolean;
  showSparator?: boolean;
  value?: any;
  defaultValue?: any;
  hideOnSelceted?: boolean;
  children?: any;
};

const defaultProps = {
  onShow: () => {},
  onHide: () => {},
  show: false,
  animationDuration: DEFAULT_ANIMATION_DURATION,
  overlayOpacity: 0.3,
  position: 'top',
  onChange: () => {},
  multiple: false,
  showSparator: true,
  value: null,
  defaultValue: null,
  hideOnSelceted: true,
  children: null,
};

class ActionSheet extends Component {
  props: Props

  static defaultProps = defaultProps

  constructor(props: Props) {
    super(props);

    let initValue = (props.value || props.defaultValue);
    initValue = Array.isArray(initValue)
      ? initValue
      : (initValue === null && []) || [initValue];

    this.state = {
      show: props.show,
      selectedData: initValue,
      actionSheetState: ACTION_SHEET_CLOSED,
      actionSheetAnimation: new Animation(this.hideActionSheetPosition),
    };
  }

  componentDidMount() {
    if (this.props.show) {
      this.show();
    }
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.position !== nextProps.position) {
      this.setState({ actionSheetAnimation: new Animation(this.hideActionSheetPosition) });
    }

    if (this.props.show !== nextProps.show) {
      if (nextProps.show) {
        this.show();
      } else {
        this.hide();
      }
    }

    if (!_.isEqual(this.props.value, nextProps.value)) {
      const selectedData = [];
      nextProps.value.forEach((value) => {
        if (!this.props.multiple && selectedData.length !== 0) {
          return;
        }
        selectedData.push(value);
      });
      this.setState({ selectedData });
    }
  }

  get showActionSheetPosition(): string {
    const { position } = this.props;
    if (position === 'top') {
      return INITIAL_TOP_POSITION * -1;
    }
    return 0;
  }

  get hideActionSheetPosition(): string {
    const { position } = this.props;
    if (position === 'top') {
      return INITIAL_TOP_POSITION;
    }
    return INITIAL_BOTTOM_POSITION * -1;
  }

  onOverlayPress = (): void => {
    this.hide();
  }

  setActionSheetState(toValue: number, callback?: Function = () => {}): void {
    const { animationDuration } = this.props;
    const isClosed = (this.state.actionSheetState === ACTION_SHEET_CLOSED);

    let actionSheetState = isClosed ? ACTION_SHEET_OPENING : ACTION_SHEET_CLOSING;

    this.setState({ actionSheetState });

    this.state.actionSheetAnimation.toValue(toValue, animationDuration, () => {
      const isClosing = (this.state.actionSheetState === ACTION_SHEET_CLOSING);
      actionSheetState = isClosing ? ACTION_SHEET_CLOSED : ACTION_SHEET_OPENED;

      this.setState({ actionSheetState });
      callback();
    });
  }

  show = (callback?: Function = () => {}): void => {
    if ([ACTION_SHEET_OPENING, ACTION_SHEET_OPENED].includes(this.state.actionSheetState)) {
      return;
    }

    const { onShow } = this.props;

    this.setState({ show: true });
    this.setActionSheetState(this.showActionSheetPosition);
    onShow();
    callback();
  }

  hide = (callback?: Function = () => {}): void => {
    if ([ACTION_SHEET_CLOSING, ACTION_SHEET_CLOSED].includes(this.state.actionSheetState)) {
      return;
    }

    const { onHide } = this.props;

    this.setState({ show: false });
    this.setActionSheetState(this.hideActionSheetPosition);
    onHide();
    callback();
  }

  onItemPress(value, index): void {
    const { hideOnSelceted } = this.props;
    if (hideOnSelceted) {
      this.hide();
    }

    if (Object.values(this.state.selectedData).includes(value)) {
      this.unselectItem(value, index);
      return;
    }

    this.selectItem(value, index);
  }

  selectItem(value, index) {
    const { multiple: isMultiSelect, onChange } = this.props;
    let selectedData = [];

    if (isMultiSelect) {
      selectedData = [...this.state.selectedData];
    }

    selectedData.push(value);
    this.setState({ selectedData });
    onChange(value, index, selectedData);
  }

  unselectItem(value, index) {
    const { multiple: isMultiSelect, onChange } = this.props;
    let selectedData = [];

    if (isMultiSelect) {
      selectedData = [...this.state.selectedData];
      selectedData.splice(index, 1);
    }

    this.setState({ selectedData });
    onChange(value, index, selectedData);
  }

  isItemSelected(index): boolean {
    return !!this.state.selectedData[index];
  }

  renderItems(): ReactElement {
    const { children, showSparator } = this.props;
    const separator = showSparator ? <Separator /> : null;

    return Children.map(children, (child) => {
      const index = this.state.selectedData.indexOf(child.value);
      const item = cloneElement(child, {
        index,
        selected: this.state.selectedData.includes(child.props.value),
        onPress: (selectedValue, selectedIndex) => {
          child.props.onPress(selectedValue, selectedIndex);
          this.onItemPress(selectedValue, selectedIndex);
        },
      });

      return (
        <View style={{ flex: 1 }}>
          {item}
          {separator}
        </View>
      );
    });
  }

  render() {
    const { animationDuration, overlayOpacity, position } = this.props;
    const { actionSheetState, actionSheetAnimation: { animations } } = this.state;

    const overlayShow = [ACTION_SHEET_OPENED, ACTION_SHEET_OPENING].includes(actionSheetState);
    const pointerEvents = (actionSheetState === ACTION_SHEET_OPENED) ? 'auto' : 'none';
    const hidden = actionSheetState === ACTION_SHEET_CLOSED && styles.hidden;

    const actionSheetPosition = (position === 'top')
      ? { top: INITIAL_TOP_POSITION }
      : { bottom: INITIAL_BOTTOM_POSITION };

    const scrollView = (position === 'top')
      ? { paddingTop: 30 }
      : null;

    return (
      <View style={[styles.container, hidden]}>
        <AnimatedOverlay
          onPress={this.onOverlayPress}
          overlayShow={overlayShow}
          duration={animationDuration}
          opacity={overlayOpacity}
          pointerEvents={pointerEvents}
        />
        <Animated.View
          style={[styles.contentContainer, actionSheetPosition, animations]}
        >
          <ScrollView style={[styles.scrollView, scrollView]}>
            {this.renderItems()}
          </ScrollView>
        </Animated.View>
      </View>
    );
  }
}

export default ActionSheet;
<|endoftext|>


<commit_before>var events = require('events');
var util = require('util');

module.exports = Command;

/**
 * Base command class for Presto.
 *
 * All commands should inherit from this command. It provides the following:
 *
 * - Integration into the Pronto events system
 * - Basic flow control
 * - Error capturing
 */
function Command() {}
util.inherits(Command, events.EventEmitter);

/**
 * Initialize the command.
 *
 * When overriding, make sure you call the parent init(name) to
 * execute this.
 */
Command.prototype.init = function(name) {
  this.name = name;
}

/**
 * Override this to provide your command with a task.
 *
 * This is the entry point for a command. It is executed exactly
 * once. When it is at the point where it should return control
 * to the command processor, it should call this.done().
 *
 * Anything stored in the context will be accessible to subsequent
 * commands in the chain.
 *
 *
 */
Command.prototype.execute = function(cxt, params) {
  this.done();
}

/**
 * Wraps calls to execute().
 *
 * The wrapper monitors execution of the command, emitting
 * any necessary events. This offloads responsibility from
 * commands. (For example, a command does not need to
 * manually emit 'continue' and 'complete'.)
 *
 * This function does the following:
 *
 * - Fires execCommand event before executing the command
 * - Executes the command's execute() method
 * - Catches any errors and emits them as 'error'
 * - Emits 'continue' if necessary
 * - Emits 'complete' when the command is done
 */
Command.prototype.executionWrapper = function(cxt, params) {
  this.hasContinued = false;
  this.cxt = cxt;
  this.emit('execCommand', cxt, params);
  try {
    this.execute(cxt, params);
  } catch (err) {
    // Event: error is given the Error object.
    this.emit('error', err);
  }

  // Event: complete fired when command is 100% done. Note that this may be well
  // after the command has 'continued'.
  //this.done(cxt);
}

/**
 * Provided just in case you need to this.keepCalmAnd().carryOn();
 */
Command.prototype.keepCalmAnd = function () {
  return this;
}

/**
 * Instruct the runner that it can continue on to the next command.
 *
 * However, the current command can continue performing operations,
 * though the order in which they are executed is indeterminent.
 *
 * This is useful for simulating background processing.
 */
Command.prototype.carryOn = function() {
  this.hasContinued = true;
  this.emit('continue');
}

/**
 * Notify Pronto that this command is done.
 *
 * This will allow Pronto to continue executing the chain of
 * commands. Not that you can call done, and then continue processing, but
 * the execution order after calling done() is not insured. For example,
 * a logging command can call done() before inserting a message into the log.
 * That message may not be inserted into the log until the rest of the commands
 * have completed (MAY be, not WILL be -- the order is determined by the node runtime).
 */
Command.prototype.done = function(value) {

  if (value != undefined) {
    this.store(value);
  }

  if (!this.hasContinued) {
    this.hasContinued = true;
    this.emit('continue');
  }

  // Event: continue
  this.emit('complete', this.cxt);
}

/**
 * Emit an error.
 *
 * @param {Error} The error caused.
 */
Command.prototype.error = function(error) {
  this.emit('error', err);
}

/**
 * Store a value in the context.
 *
 * Store a value in the context, with the command name being the key.
 *
 * If a prefix is provided, then the command name will be prefixed. Example:
 * if `prefix` is 'foo' and `this.name` is 'myCommand', then the key will
 * be `foo-myCommand`.
 */
Command.prototype.store = function(value, prefix) {
  var key = prefix == undefined ? this.name : prefix + '-' + this.name;
  this.cxt.add(key, value);
}

Command.prototype.required = function(params, names) {
  for (var i = 0; i < names.length; ++i) {
    if (params[names[i]] == undefined || params[names[i]] == null) {
      console.log('Emitting an error');
      this.emit('error', new Error(params[names[i]] + ' is a required parameter for ' + this.name));
    }
  }
}<commit_msg>Fixed error reporting.<commit_after>var events = require('events');
var util = require('util');

module.exports = Command;

/**
 * Base command class for Presto.
 *
 * All commands should inherit from this command. It provides the following:
 *
 * - Integration into the Pronto events system
 * - Basic flow control
 * - Error capturing
 */
function Command() {}
util.inherits(Command, events.EventEmitter);

/**
 * Initialize the command.
 *
 * When overriding, make sure you call the parent init(name) to
 * execute this.
 */
Command.prototype.init = function(name) {
  this.name = name;
}

/**
 * Override this to provide your command with a task.
 *
 * This is the entry point for a command. It is executed exactly
 * once. When it is at the point where it should return control
 * to the command processor, it should call this.done().
 *
 * Anything stored in the context will be accessible to subsequent
 * commands in the chain.
 *
 *
 */
Command.prototype.execute = function(cxt, params) {
  this.done();
}

/**
 * Wraps calls to execute().
 *
 * The wrapper monitors execution of the command, emitting
 * any necessary events. This offloads responsibility from
 * commands. (For example, a command does not need to
 * manually emit 'continue' and 'complete'.)
 *
 * This function does the following:
 *
 * - Fires execCommand event before executing the command
 * - Executes the command's execute() method
 * - Catches any errors and emits them as 'error'
 * - Emits 'continue' if necessary
 * - Emits 'complete' when the command is done
 */
Command.prototype.executionWrapper = function(cxt, params) {
  this.hasContinued = false;
  this.cxt = cxt;
  this.emit('execCommand', cxt, params);
  try {
    this.execute(cxt, params);
  } catch (err) {
    // Event: error is given the Error object.
    this.emit('error', err);
  }

  // Event: complete fired when command is 100% done. Note that this may be well
  // after the command has 'continued'.
  //this.done(cxt);
}

/**
 * Provided just in case you need to this.keepCalmAnd().carryOn();
 */
Command.prototype.keepCalmAnd = function () {
  return this;
}

/**
 * Instruct the runner that it can continue on to the next command.
 *
 * However, the current command can continue performing operations,
 * though the order in which they are executed is indeterminent.
 *
 * This is useful for simulating background processing.
 */
Command.prototype.carryOn = function() {
  this.hasContinued = true;
  this.emit('continue');
}

/**
 * Notify Pronto that this command is done.
 *
 * This will allow Pronto to continue executing the chain of
 * commands. Not that you can call done, and then continue processing, but
 * the execution order after calling done() is not insured. For example,
 * a logging command can call done() before inserting a message into the log.
 * That message may not be inserted into the log until the rest of the commands
 * have completed (MAY be, not WILL be -- the order is determined by the node runtime).
 */
Command.prototype.done = function(value) {

  if (value != undefined) {
    this.store(value);
  }

  if (!this.hasContinued) {
    this.hasContinued = true;
    this.emit('continue');
  }

  // Event: continue
  this.emit('complete', this.cxt);
}

/**
 * Emit an error.
 *
 * @param {Error} The error caused.
 */
Command.prototype.error = function(error) {
  this.emit('error', err);
}

/**
 * Store a value in the context.
 *
 * Store a value in the context, with the command name being the key.
 *
 * If a prefix is provided, then the command name will be prefixed. Example:
 * if `prefix` is 'foo' and `this.name` is 'myCommand', then the key will
 * be `foo-myCommand`.
 */
Command.prototype.store = function(value, prefix) {
  var key = prefix == undefined ? this.name : prefix + '-' + this.name;
  this.cxt.add(key, value);
}

Command.prototype.required = function(params, names) {
  for (var i = 0; i < names.length; ++i) {
    if (params[names[i]] == undefined || params[names[i]] == null) {
      //console.log('Emitting an error');
      this.emit('error', new Error(names[i] + ' is a required parameter for ' + this.name));
    }
  }
}<|endoftext|>


<commit_before>import boundary from './boundary'

export default function average(x, y, factor) {
  factor = boundary(factor, 0, 1)
  return Math.floor(((1 - factor) * x + 2 * factor * y) / 2)
}

<commit_msg>Fix averaging / mixing of colours<commit_after>import boundary from './boundary'

export default function average(x, y, factor) {
  factor = boundary(factor, 0, 1)
  return Math.floor((1 - factor) * x + factor * y)
}

<|endoftext|>


<commit_before>/* eslint no-constant-condition: "off" */

const d3 = require('d3')
const _ = {
  map: require('lodash/map'),
  uniqBy: require('lodash/uniqBy'),
  capitalize: require('lodash/capitalize'),
  each: require('lodash/each'),
}

const InputSanitizer = require('./inputSanitizer')
const Radar = require('../models/radar')
const Quadrant = require('../models/quadrant')
const Ring = require('../models/ring')
const Blip = require('../models/blip')
const GraphingRadar = require('../graphing/radar')
const QueryParams = require('./queryParamProcessor')
const MalformedDataError = require('../exceptions/malformedDataError')
const SheetNotFoundError = require('../exceptions/sheetNotFoundError')
const ContentValidator = require('./contentValidator')
const Sheet = require('./sheet')
const ExceptionMessages = require('./exceptionMessages')
const GoogleAuth = require('./googleAuth')

const plotRadar = function (title, blips, currentRadarName, alternativeRadars) {
  if (title.endsWith('.csv')) {
    title = title.substring(0, title.length - 4)
  }
  document.title = title
  d3.selectAll('.loading').remove()

  var rings = _.map(_.uniqBy(blips, 'ring'), 'ring')
  var ringMap = {}
  var maxRings = 4

  _.each(rings, function (ringName, i) {
    if (i === maxRings) {
      throw new MalformedDataError(ExceptionMessages.TOO_MANY_RINGS)
    }
    ringMap[ringName] = new Ring(ringName, i)
  })

  var quadrants = {}
  _.each(blips, function (blip) {
    if (!quadrants[blip.quadrant]) {
      quadrants[blip.quadrant] = new Quadrant(_.capitalize(blip.quadrant))
    }
    quadrants[blip.quadrant].add(
      new Blip(blip.name, ringMap[blip.ring], blip.isNew.toLowerCase() === 'true', blip.topic, blip.description),
    )
  })

  var radar = new Radar()
  _.each(quadrants, function (quadrant) {
    radar.addQuadrant(quadrant)
  })

  if (alternativeRadars !== undefined || true) {
    alternativeRadars.forEach(function (sheetName) {
      radar.addAlternative(sheetName)
    })
  }

  if (currentRadarName !== undefined || true) {
    radar.setCurrentSheet(currentRadarName)
  }

  var size = window.innerHeight - 133 < 620 ? 620 : window.innerHeight - 133

  new GraphingRadar(size, radar).init().plot()
}

const GoogleSheet = function (sheetReference, sheetName) {
  var self = {}

  self.build = function () {
    var sheet = new Sheet(sheetReference)
    sheet.validate(function (error, apiKeyEnabled) {
      if (error instanceof SheetNotFoundError) {
        plotErrorMessage(error)
        return
      }

      self.authenticate(false, apiKeyEnabled)
    })
  }

  function createBlipsForProtectedSheet (documentTitle, values, sheetNames) {
    if (!sheetName) {
      sheetName = sheetNames[0]
    }
    values.forEach(function (value) {
      var contentValidator = new ContentValidator(values[0])
      contentValidator.verifyContent()
      contentValidator.verifyHeaders()
    })

    const all = values
    const header = all.shift()
    var blips = _.map(all, blip => new InputSanitizer().sanitizeForProtectedSheet(blip, header))
    plotRadar(documentTitle + ' - ' + sheetName, blips, sheetName, sheetNames)
  }

  self.authenticate = function (force = false, apiKeyEnabled, callback) {
    if (!apiKeyEnabled) {
      GoogleAuth.loadGoogle(function (e) {
        GoogleAuth.login(_ => {
          var sheet = new Sheet(sheetReference)
          sheet.processSheetResponse(sheetName, createBlipsForProtectedSheet, error => {
            if (error.status === 403) {
              plotUnauthorizedErrorMessage()
            } else {
              plotErrorMessage(error)
            }
          })
          if (callback) {
            callback()
          }
        }, force)
      })
    } else {
      GoogleAuth.loadGoogle(function (e) {
        var sheet = new Sheet(sheetReference)
        sheet.processSheetResponse(sheetName, createBlipsForProtectedSheet, error => {
          if (error.status === 403) {
            plotUnauthorizedErrorMessage()
          } else {
            plotErrorMessage(error)
          }
        })
        if (callback) {
          callback()
        }
      })
    }
  }

  self.init = function () {
    plotLoading()
    return self
  }

  return self
}

const CSVDocument = function (url) {
  var self = {}

  self.build = function () {
    d3.csv(url).then(createBlips)
  }

  var createBlips = function (data) {
    try {
      var columnNames = data.columns
      delete data.columns
      var contentValidator = new ContentValidator(columnNames)
      contentValidator.verifyContent()
      contentValidator.verifyHeaders()
      var blips = _.map(data, new InputSanitizer().sanitize)
      plotRadar(FileName(url), blips, 'CSV File', [])
    } catch (exception) {
      plotErrorMessage(exception)
    }
  }

  self.init = function () {
    plotLoading()
    return self
  }

  return self
}

const JSONFile = function (data) {
  //TODO: Somehow get json from url rather than pass in directly
  var self = {}

  self.build = function () {

    createBlips(data);
  }

  var createBlips = function (data) {
    try {
      var columnNames = Object.keys(data[0])
      var contentValidator = new ContentValidator(columnNames)
      contentValidator.verifyContent()
      contentValidator.verifyHeaders()
      var blips = _.map(data, new InputSanitizer().sanitize)
      //TODO: Use name of json as title of tech radar
      plotRadar("Tech Radar from a json", blips, 'JSON File', [])
    } catch (exception) {
      plotErrorMessage(exception)
    }
  }

  self.init = function () {
    plotLoading()
    return self
  }

  return self
}

const DomainName = function (url) {
  var search = /.+:\/\/([^\\/]+)/
  var match = search.exec(decodeURIComponent(url.replace(/\+/g, ' ')))
  return match == null ? null : match[1]
}

const FileName = function (url) {
  var search = /([^\\/]+)$/
  var match = search.exec(decodeURIComponent(url.replace(/\+/g, ' ')))
  if (match != null) {
    var str = match[1]
    return str
  }
  return url
}

const GoogleSheetInput = function () {
  var self = {}
  var sheet

  self.build = function () {
    var domainName = DomainName(window.location.search.substring(1))
    var queryString = window.location.href.match(/sheetId(.*)/)
    var queryParams = queryString ? QueryParams(queryString[0]) : {}

    if (domainName && queryParams.sheetId.endsWith('.csv')) {
      sheet = CSVDocument(queryParams.sheetId)
      sheet.init().build()
    } else if (domainName && domainName.endsWith('google.com') && queryParams.sheetId) {
      sheet = GoogleSheet(queryParams.sheetId, queryParams.sheetName)
      console.log(queryParams.sheetName)

      sheet.init().build()
    } else {
      var content = d3
        .select('body')
        .append('div')
        .attr('class', 'input-sheet')
      setDocumentTitle()

      plotLogo(content)

      var bannerText =
        '

Build your own radar

Once you\'ve created your Radar, you can use this service' +
        ' to generate an
interactive version of your Technology Radar. Not sure how? Read this first.

'

      plotBanner(content, bannerText)

      plotForm(content)

      plotFooter(content)
    }
  }

  return self
}

function setDocumentTitle () {
  document.title = 'Build your own Radar'
}

function plotLoading (content) {
  content = d3
    .select('body')
    .append('div')
    .attr('class', 'loading')
    .append('div')
    .attr('class', 'input-sheet')

  setDocumentTitle()

  plotLogo(content)

  var bannerText = '
Building your radar...

Your Technology Radar will be available in just a few seconds
'
  plotBanner(content, bannerText)
  plotFooter(content)
}

function plotLogo (content) {
  content
    .append('div')
    .attr('class', 'input-sheet__logo')
    .html('')
}

function plotFooter (content) {
  content
    .append('div')
    .attr('id', 'footer')
    .append('div')
    .attr('class', 'footer-content')
    .append('p')
    .html(
      'Powered by  Thoughtworks. ' +
        'By using this service you agree to Thoughtworks\' terms of use. ' +
        'You also agree to our privacy policy, which describes how we will gather, use and protect any personal data contained in your public Google Sheet. ' +
        'This software is open source and available for download and self-hosting.',
    )
}

function plotBanner (content, text) {
  content
    .append('div')
    .attr('class', 'input-sheet__banner')
    .html(text)
}

function plotForm (content) {
  content
    .append('div')
    .attr('class', 'input-sheet__form')
    .append('p')
    .html(
      'Enter the URL of your Google Sheet or CSV file below…',
    )

  var form = content
    .select('.input-sheet__form')
    .append('form')
    .attr('method', 'get')

  form
    .append('input')
    .attr('type', 'text')
    .attr('name', 'sheetId')
    .attr('placeholder', 'e.g. https://docs.google.com/spreadsheets/d/<sheetid> or hosted CSV file')
    .attr('required', '')

  form
    .append('button')
    .attr('type', 'submit')
    .append('a')
    .attr('class', 'button')
    .text('Build my radar')

  form.append('p').html("Need help?")
}

function plotErrorMessage (exception) {
  var message = 'Oops! It seems like there are some problems with loading your data. '

  var content = d3
    .select('body')
    .append('div')
    .attr('class', 'input-sheet')
  setDocumentTitle()

  plotLogo(content)

  var bannerText =
    '

Build your own radar

Once you\'ve created your Radar, you can use this service' +
    ' to generate an
interactive version of your Technology Radar. Not sure how? Read this first.

'

  plotBanner(content, bannerText)

  d3.selectAll('.loading').remove()
  message = "Oops! We can't find the Google Sheet you've entered"
  var faqMessage =
    'Please check FAQs for possible solutions.'
  if (exception instanceof MalformedDataError) {
    message = message.concat(exception.message)
  } else if (exception instanceof SheetNotFoundError) {
    message = exception.message
  } else {
    console.error(exception)
  }

  const container = content.append('div').attr('class', 'error-container')
  var errorContainer = container.append('div').attr('class', 'error-container__message')
  errorContainer
    .append('div')
    .append('p')
    .html(message)
  errorContainer
    .append('div')
    .append('p')
    .html(faqMessage)

  var homePageURL = window.location.protocol + '//' + window.location.hostname
  homePageURL += window.location.port === '' ? '' : ':' + window.location.port
  var homePage = 'GO BACK'

  errorContainer
    .append('div')
    .append('p')
    .html(homePage)

  plotFooter(content)
}

function plotUnauthorizedErrorMessage () {
  var content = d3
    .select('body')
    .append('div')
    .attr('class', 'input-sheet')
  setDocumentTitle()

  plotLogo(content)

  var bannerText = '

Build your own radar

'

  plotBanner(content, bannerText)

  d3.selectAll('.loading').remove()
  const currentUser = GoogleAuth.geEmail()
  let homePageURL = window.location.protocol + '//' + window.location.hostname
  homePageURL += window.location.port === '' ? '' : ':' + window.location.port
  const goBack = 'GO BACK'
  const message = `<strong>Oops!</strong> Looks like you are accessing this sheet using <b>${currentUser}</b>, which does not have permission.Try switching to another account.`

  const container = content.append('div').attr('class', 'error-container')

  const errorContainer = container.append('div').attr('class', 'error-container__message')

  errorContainer
    .append('div')
    .append('p')
    .attr('class', 'error-title')
    .html(message)

  const button = errorContainer
    .append('button')
    .attr('class', 'button switch-account-button')
    .text('SWITCH ACCOUNT')

  errorContainer
    .append('div')
    .append('p')
    .attr('class', 'error-subtitle')
    .html(`or ${goBack} to try a different sheet.`)

  button.on('click', _ => {
    var queryString = window.location.href.match(/sheetId(.*)/)
    var queryParams = queryString ? QueryParams(queryString[0]) : {}
    const sheet = GoogleSheet(queryParams.sheetId, queryParams.sheetName)
    sheet.authenticate(true, false, _ => {
      content.remove()
    })
  })
}

module.exports = GoogleSheetInput
<commit_msg>use json path like csv<commit_after>/* eslint no-constant-condition: "off" */

const d3 = require('d3')
const _ = {
  map: require('lodash/map'),
  uniqBy: require('lodash/uniqBy'),
  capitalize: require('lodash/capitalize'),
  each: require('lodash/each'),
}

const InputSanitizer = require('./inputSanitizer')
const Radar = require('../models/radar')
const Quadrant = require('../models/quadrant')
const Ring = require('../models/ring')
const Blip = require('../models/blip')
const GraphingRadar = require('../graphing/radar')
const QueryParams = require('./queryParamProcessor')
const MalformedDataError = require('../exceptions/malformedDataError')
const SheetNotFoundError = require('../exceptions/sheetNotFoundError')
const ContentValidator = require('./contentValidator')
const Sheet = require('./sheet')
const ExceptionMessages = require('./exceptionMessages')
const GoogleAuth = require('./googleAuth')

const plotRadar = function (title, blips, currentRadarName, alternativeRadars) {
  if (title.endsWith('.csv')) {
    title = title.substring(0, title.length - 4)
  }
  document.title = title
  d3.selectAll('.loading').remove()

  var rings = _.map(_.uniqBy(blips, 'ring'), 'ring')
  var ringMap = {}
  var maxRings = 4

  _.each(rings, function (ringName, i) {
    if (i === maxRings) {
      throw new MalformedDataError(ExceptionMessages.TOO_MANY_RINGS)
    }
    ringMap[ringName] = new Ring(ringName, i)
  })

  var quadrants = {}
  _.each(blips, function (blip) {
    if (!quadrants[blip.quadrant]) {
      quadrants[blip.quadrant] = new Quadrant(_.capitalize(blip.quadrant))
    }
    quadrants[blip.quadrant].add(
      new Blip(blip.name, ringMap[blip.ring], blip.isNew.toLowerCase() === 'true', blip.topic, blip.description),
    )
  })

  var radar = new Radar()
  _.each(quadrants, function (quadrant) {
    radar.addQuadrant(quadrant)
  })

  if (alternativeRadars !== undefined || true) {
    alternativeRadars.forEach(function (sheetName) {
      radar.addAlternative(sheetName)
    })
  }

  if (currentRadarName !== undefined || true) {
    radar.setCurrentSheet(currentRadarName)
  }

  var size = window.innerHeight - 133 < 620 ? 620 : window.innerHeight - 133

  new GraphingRadar(size, radar).init().plot()
}

const GoogleSheet = function (sheetReference, sheetName) {
  var self = {}

  self.build = function () {
    var sheet = new Sheet(sheetReference)
    sheet.validate(function (error, apiKeyEnabled) {
      if (error instanceof SheetNotFoundError) {
        plotErrorMessage(error)
        return
      }

      self.authenticate(false, apiKeyEnabled)
    })
  }

  function createBlipsForProtectedSheet (documentTitle, values, sheetNames) {
    if (!sheetName) {
      sheetName = sheetNames[0]
    }
    values.forEach(function (value) {
      var contentValidator = new ContentValidator(values[0])
      contentValidator.verifyContent()
      contentValidator.verifyHeaders()
    })

    const all = values
    const header = all.shift()
    var blips = _.map(all, blip => new InputSanitizer().sanitizeForProtectedSheet(blip, header))
    plotRadar(documentTitle + ' - ' + sheetName, blips, sheetName, sheetNames)
  }

  self.authenticate = function (force = false, apiKeyEnabled, callback) {
    if (!apiKeyEnabled) {
      GoogleAuth.loadGoogle(function (e) {
        GoogleAuth.login(_ => {
          var sheet = new Sheet(sheetReference)
          sheet.processSheetResponse(sheetName, createBlipsForProtectedSheet, error => {
            if (error.status === 403) {
              plotUnauthorizedErrorMessage()
            } else {
              plotErrorMessage(error)
            }
          })
          if (callback) {
            callback()
          }
        }, force)
      })
    } else {
      GoogleAuth.loadGoogle(function (e) {
        var sheet = new Sheet(sheetReference)
        sheet.processSheetResponse(sheetName, createBlipsForProtectedSheet, error => {
          if (error.status === 403) {
            plotUnauthorizedErrorMessage()
          } else {
            plotErrorMessage(error)
          }
        })
        if (callback) {
          callback()
        }
      })
    }
  }

  self.init = function () {
    plotLoading()
    return self
  }

  return self
}

const CSVDocument = function (url) {
  var self = {}

  self.build = function () {
    d3.csv(url).then(createBlips)
  }

  var createBlips = function (data) {
    try {
      var columnNames = data.columns
      delete data.columns
      var contentValidator = new ContentValidator(columnNames)
      contentValidator.verifyContent()
      contentValidator.verifyHeaders()
      var blips = _.map(data, new InputSanitizer().sanitize)
      plotRadar(FileName(url), blips, 'CSV File', [])
    } catch (exception) {
      plotErrorMessage(exception)
    }
  }

  self.init = function () {
    plotLoading()
    return self
  }

  return self
}

const JSONFile = function (url) {
  var self = {}

  self.build = function () {
    d3.json(url).then(createBlips)
  }

  var createBlips = function (data) {
    try {
      var columnNames = Object.keys(data[0])
      var contentValidator = new ContentValidator(columnNames)
      contentValidator.verifyContent()
      contentValidator.verifyHeaders()
      var blips = _.map(data, new InputSanitizer().sanitize)
      plotRadar(FileName(url), blips, 'JSON File', [])
    } catch (exception) {
      plotErrorMessage(exception)
    }
  }

  self.init = function () {
    plotLoading()
    return self
  }

  return self
}

const DomainName = function (url) {
  var search = /.+:\/\/([^\\/]+)/
  var match = search.exec(decodeURIComponent(url.replace(/\+/g, ' ')))
  return match == null ? null : match[1]
}

const FileName = function (url) {
  var search = /([^\\/]+)$/
  var match = search.exec(decodeURIComponent(url.replace(/\+/g, ' ')))
  if (match != null) {
    var str = match[1]
    return str
  }
  return url
}

const GoogleSheetInput = function () {
  var self = {}
  var sheet

  self.build = function () {
    var domainName = DomainName(window.location.search.substring(1))
    var queryString = window.location.href.match(/sheetId(.*)/)
    var queryParams = queryString ? QueryParams(queryString[0]) : {}

    if (domainName && queryParams.sheetId.endsWith('.csv')) {
      sheet = CSVDocument(queryParams.sheetId)
      sheet.init().build()
    } else if (domainName && domainName.endsWith('google.com') && queryParams.sheetId) {
      sheet = GoogleSheet(queryParams.sheetId, queryParams.sheetName)
      console.log(queryParams.sheetName)

      sheet.init().build()
    } else {
      var content = d3
        .select('body')
        .append('div')
        .attr('class', 'input-sheet')
      setDocumentTitle()

      plotLogo(content)

      var bannerText =
        '

Build your own radar

Once you\'ve created your Radar, you can use this service' +
        ' to generate an
interactive version of your Technology Radar. Not sure how? Read this first.

'

      plotBanner(content, bannerText)

      plotForm(content)

      plotFooter(content)
    }
  }

  return self
}

function setDocumentTitle () {
  document.title = 'Build your own Radar'
}

function plotLoading (content) {
  content = d3
    .select('body')
    .append('div')
    .attr('class', 'loading')
    .append('div')
    .attr('class', 'input-sheet')

  setDocumentTitle()

  plotLogo(content)

  var bannerText = '
Building your radar...

Your Technology Radar will be available in just a few seconds
'
  plotBanner(content, bannerText)
  plotFooter(content)
}

function plotLogo (content) {
  content
    .append('div')
    .attr('class', 'input-sheet__logo')
    .html('')
}

function plotFooter (content) {
  content
    .append('div')
    .attr('id', 'footer')
    .append('div')
    .attr('class', 'footer-content')
    .append('p')
    .html(
      'Powered by  Thoughtworks. ' +
        'By using this service you agree to Thoughtworks\' terms of use. ' +
        'You also agree to our privacy policy, which describes how we will gather, use and protect any personal data contained in your public Google Sheet. ' +
        'This software is open source and available for download and self-hosting.',
    )
}

function plotBanner (content, text) {
  content
    .append('div')
    .attr('class', 'input-sheet__banner')
    .html(text)
}

function plotForm (content) {
  content
    .append('div')
    .attr('class', 'input-sheet__form')
    .append('p')
    .html(
      'Enter the URL of your Google Sheet or CSV file below…',
    )

  var form = content
    .select('.input-sheet__form')
    .append('form')
    .attr('method', 'get')

  form
    .append('input')
    .attr('type', 'text')
    .attr('name', 'sheetId')
    .attr('placeholder', 'e.g. https://docs.google.com/spreadsheets/d/<sheetid> or hosted CSV file')
    .attr('required', '')

  form
    .append('button')
    .attr('type', 'submit')
    .append('a')
    .attr('class', 'button')
    .text('Build my radar')

  form.append('p').html("Need help?")
}

function plotErrorMessage (exception) {
  var message = 'Oops! It seems like there are some problems with loading your data. '

  var content = d3
    .select('body')
    .append('div')
    .attr('class', 'input-sheet')
  setDocumentTitle()

  plotLogo(content)

  var bannerText =
    '

Build your own radar

Once you\'ve created your Radar, you can use this service' +
    ' to generate an
interactive version of your Technology Radar. Not sure how? Read this first.

'

  plotBanner(content, bannerText)

  d3.selectAll('.loading').remove()
  message = "Oops! We can't find the Google Sheet you've entered"
  var faqMessage =
    'Please check FAQs for possible solutions.'
  if (exception instanceof MalformedDataError) {
    message = message.concat(exception.message)
  } else if (exception instanceof SheetNotFoundError) {
    message = exception.message
  } else {
    console.error(exception)
  }

  const container = content.append('div').attr('class', 'error-container')
  var errorContainer = container.append('div').attr('class', 'error-container__message')
  errorContainer
    .append('div')
    .append('p')
    .html(message)
  errorContainer
    .append('div')
    .append('p')
    .html(faqMessage)

  var homePageURL = window.location.protocol + '//' + window.location.hostname
  homePageURL += window.location.port === '' ? '' : ':' + window.location.port
  var homePage = 'GO BACK'

  errorContainer
    .append('div')
    .append('p')
    .html(homePage)

  plotFooter(content)
}

function plotUnauthorizedErrorMessage () {
  var content = d3
    .select('body')
    .append('div')
    .attr('class', 'input-sheet')
  setDocumentTitle()

  plotLogo(content)

  var bannerText = '

Build your own radar

'

  plotBanner(content, bannerText)

  d3.selectAll('.loading').remove()
  const currentUser = GoogleAuth.geEmail()
  let homePageURL = window.location.protocol + '//' + window.location.hostname
  homePageURL += window.location.port === '' ? '' : ':' + window.location.port
  const goBack = 'GO BACK'
  const message = `<strong>Oops!</strong> Looks like you are accessing this sheet using <b>${currentUser}</b>, which does not have permission.Try switching to another account.`

  const container = content.append('div').attr('class', 'error-container')

  const errorContainer = container.append('div').attr('class', 'error-container__message')

  errorContainer
    .append('div')
    .append('p')
    .attr('class', 'error-title')
    .html(message)

  const button = errorContainer
    .append('button')
    .attr('class', 'button switch-account-button')
    .text('SWITCH ACCOUNT')

  errorContainer
    .append('div')
    .append('p')
    .attr('class', 'error-subtitle')
    .html(`or ${goBack} to try a different sheet.`)

  button.on('click', _ => {
    var queryString = window.location.href.match(/sheetId(.*)/)
    var queryParams = queryString ? QueryParams(queryString[0]) : {}
    const sheet = GoogleSheet(queryParams.sheetId, queryParams.sheetName)
    sheet.authenticate(true, false, _ => {
      content.remove()
    })
  })
}

module.exports = GoogleSheetInput
<|endoftext|>


<commit_before>(function () {
if (typeof(window) === 'undefined') {
    var nearley = require('../lib/nearley.js');
} else {
    var nearley = window.nearley;
}
var Compile = function (structure, opts) {
    var uns = {};

    function unique(name) {
        var un = uns[name] = (uns[name] || 0) + 1;
        return name + '$' + un;
    }

    function joiner(d) {
        return d.join('');
    }

    var outputRules = [];
    var body = []; // @directives list

    function buildProcessedRule(ruleName, rule) {
        var tokenList = [];

        rule.tokens.forEach(function(token) {
            if (token.literal) {
                var str = token.literal;
                if (str.length > 1) {
                    var rules = str.split("").map(function(d) {
                        return {
                            literal: d
                        };
                    });

                    var newname = unique(ruleName + "$string");
                    buildProcessedRule(newname, {
                        tokens: rules,
                        postprocess: joiner
                    });
                    tokenList.push(newname);
                } else if (str.length === 1) {
                    tokenList.push({
                        literal: str
                    });
                }
            } else if (token.subexpression) {
                var data = token.subexpression;
                var name = unique(ruleName + "$subexpression");
                structure.push({"name": name, "rules": data});
                tokenList.push(name);
            } else if (token.ebnf) {
                var data = token.ebnf;
                var modifier = token.modifier;
                var name = unique(ruleName + "$ebnf");
                var arrconcat = (function(d) {
                    return [d[0]].concat(d[1]);
                }).toString();

                switch (modifier) {
                    case ":+":
                        structure.push({
                            "name": name,
                            "rules": [{
                                "tokens": [data],
                            }, {
                                "tokens": [data, name],
                                "postprocess": arrconcat
                            }]
                        });
                        tokenList.push(name);
                        break;
                    case ":*":
                        structure.push({
                            "name": name,
                            "rules": [{
                                "tokens": [],
                            }, {
                                "tokens": [data, name],
                                "postprocess": arrconcat
                            }]
                        });
                        tokenList.push(name);
                        break;
                    case ":?":
                        structure.push({
                            "name": name,
                            "rules": [{
                                "tokens": [data],
                                "postprocess": "id"
                            }, {
                                "tokens": [],
                                "postprocess": "function(d) {return null;}"
                            }]
                        });
                        tokenList.push(name);
                        break;
                }
            } else if (typeof(token) === 'string') {
                if (token !== 'null') tokenList.push(token);
            } else if (token instanceof RegExp) {
                tokenList.push(token);
            } else {
                throw new Error("Should never get here");
            }
        });

        var out = new nearley.Rule(
            ruleName,
            tokenList,
            (opts.nojs ? null : rule.postprocess)
        );

        outputRules.push(out);
    }

    var firstName;

    var i=0;
    while (i<structure.length) {
        var productionRule = structure[i];
        if (productionRule.body) {
            // This isn't a rule, it's an @directive.
            if (!opts.nojs) body.push(productionRule.body);
        } else {
            var rules = productionRule.rules;
            if (!firstName) firstName = productionRule.name;
            rules.forEach(function(rule) {
                buildProcessedRule(productionRule.name, rule);
            });
        }
        i++;
    }

    return {
        rules: outputRules,
        body: body,
        start: firstName
    };
}

if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
    module.exports = Compile;
} else {
    window.Compile = Compile;
}
})();
<commit_msg>lib/compile: just name the function<commit_after>(function () {
if (typeof(window) === 'undefined') {
    var nearley = require('../lib/nearley.js');
} else {
    var nearley = window.nearley;
}

function Compile(structure, opts) {
    var uns = {};

    function unique(name) {
        var un = uns[name] = (uns[name] || 0) + 1;
        return name + '$' + un;
    }

    function joiner(d) {
        return d.join('');
    }

    var outputRules = [];
    var body = []; // @directives list

    function buildProcessedRule(ruleName, rule) {
        var tokenList = [];

        rule.tokens.forEach(function(token) {
            if (token.literal) {
                var str = token.literal;
                if (str.length > 1) {
                    var rules = str.split("").map(function(d) {
                        return {
                            literal: d
                        };
                    });

                    var newname = unique(ruleName + "$string");
                    buildProcessedRule(newname, {
                        tokens: rules,
                        postprocess: joiner
                    });
                    tokenList.push(newname);
                } else if (str.length === 1) {
                    tokenList.push({
                        literal: str
                    });
                }
            } else if (token.subexpression) {
                var data = token.subexpression;
                var name = unique(ruleName + "$subexpression");
                structure.push({"name": name, "rules": data});
                tokenList.push(name);
            } else if (token.ebnf) {
                var data = token.ebnf;
                var modifier = token.modifier;
                var name = unique(ruleName + "$ebnf");
                var arrconcat = (function(d) {
                    return [d[0]].concat(d[1]);
                }).toString();

                switch (modifier) {
                    case ":+":
                        structure.push({
                            "name": name,
                            "rules": [{
                                "tokens": [data],
                            }, {
                                "tokens": [data, name],
                                "postprocess": arrconcat
                            }]
                        });
                        tokenList.push(name);
                        break;
                    case ":*":
                        structure.push({
                            "name": name,
                            "rules": [{
                                "tokens": [],
                            }, {
                                "tokens": [data, name],
                                "postprocess": arrconcat
                            }]
                        });
                        tokenList.push(name);
                        break;
                    case ":?":
                        structure.push({
                            "name": name,
                            "rules": [{
                                "tokens": [data],
                                "postprocess": "id"
                            }, {
                                "tokens": [],
                                "postprocess": "function(d) {return null;}"
                            }]
                        });
                        tokenList.push(name);
                        break;
                }
            } else if (typeof(token) === 'string') {
                if (token !== 'null') tokenList.push(token);
            } else if (token instanceof RegExp) {
                tokenList.push(token);
            } else {
                throw new Error("Should never get here");
            }
        });

        var out = new nearley.Rule(
            ruleName,
            tokenList,
            (opts.nojs ? null : rule.postprocess)
        );

        outputRules.push(out);
    }

    var firstName;

    var i=0;
    while (i<structure.length) {
        var productionRule = structure[i];
        if (productionRule.body) {
            // This isn't a rule, it's an @directive.
            if (!opts.nojs) body.push(productionRule.body);
        } else {
            var rules = productionRule.rules;
            if (!firstName) firstName = productionRule.name;
            rules.forEach(function(rule) {
                buildProcessedRule(productionRule.name, rule);
            });
        }
        i++;
    }

    return {
        rules: outputRules,
        body: body,
        start: firstName
    };
}

if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
    module.exports = Compile;
} else {
    window.Compile = Compile;
}
})();
<|endoftext|>