<commit_before>// Copyright 2013 Joyent, Inc.  All rights reserved.

var assert = require('assert');
var fs = require('fs');
var http = require('http');
var path = require('path');
var sprintf = require('util').format;

var Logger = require('bunyan');
var ldap = require('ldapjs');
var nopt = require('nopt');
var restify = require('restify');
var uuid = require('node-uuid');

var customers = require('./capi/customers');
var keys = require('./capi/keys');
var login = require('./capi/login');
var limits = require('./capi/limits');
var metadata = require('./capi/metadata');
var utils = require('./capi/util');

function entitify(str) {
    str = '' + str;
    /* BEGIN JSSTYLED */
    str = str.replace(/&/g, '&').replace(/</g, '<')
        .replace(/>/g, '>').replace(/'/g, ''')
        .replace(/"/g, '"');
    /* END JSSTYLED */
    return str;
}

function toXml(elm) {
    var xml = '';
    if (Array.isArray(elm)) {
        xml += elm.map(function (e) {
            return (toXml(e));
        }).join('\n');
    } else if (typeof (elm) === 'object' && Object.keys(elm)) {
        Object.keys(elm).forEach(function (k) {
            if (elm[k]) {
                xml += sprintf('<%s>%s</%s>', k, toXml(elm[k]), k);
            }
        });
    } else {
        xml += entitify(elm);
    }
    return (xml);
}

///--- Globals

var opts = {
    'certificate': String,
    'config': String,
    'debug': Boolean,
    'file': String,
    'key': String,
    'port': Number,
    'ufds': String,
    'help': Boolean
};

var shortOpts = {
    'c': ['--certiifcate'],
    'd': ['--debug'],
    'f': ['--file'],
    'k': ['--key'],
    'p': ['--port'],
    'h': ['--help'],
    'u': ['--ufds']
};

///--- Helpers

function usage(code, message) {
    var _opts = '';
    Object.keys(shortOpts).forEach(function (k) {
        var longOpt = shortOpts[k][0].replace('--', '');
        var type = opts[longOpt].name || 'string';
        if (type && type === 'boolean') type = '';
        type = type.toLowerCase();

        _opts += ' [--' + longOpt + ' ' + type + ']';
    });
    _opts += ' dn attribute value(s)';

    var msg = (message ? message + '\n' : '') +
        'usage: ' + path.basename(process.argv[1]) + _opts;

    process.stderr.write(msg + '\n');
    process.exit(code);
}

///--- CAPI shim

function CAPI(config) {

    var log = new Logger({
        name: 'capi',
        level: config.logLevel,
        stream: process.stdout,
        serializers: restify.bunyan.serializers
    });

    function before(req, res, next) {

        res.sendError = function sendError(errors) {
            if (req.xml) {
                errors = { errors: { error: errors } };
            } else {
                errors = { errors: errors };
            }
            log.warn({errors: errors}, 'These are the errors');
            res.send(409, errors);
        };

        req.ldap = ldap.createClient({
            url: config.ufds,
            log: log
        });

        req.ldap.once('error', function (err) {
            req.ldap = null;
            next(err);
        });

        req.ldap.once('connect', function () {
            log.debug('LDAP Client Connected');
            req.ldap.bind(config.rootDN, config.rootPassword, function (err) {
                if (err) {
                    log.error(err, 'Unable to bind to UFDS');
                    return next(err);
                }
                log.debug('Bound to UFDS');
                return next();
            });
        });
    }

    var server = restify.createServer({
        name: 'capi',
        log: log,
        formatters: {
            'application/xml': function formatXml(req, res, body) {
                var o;
                var xml = '<?xml version="1.0" encoding="utf-8"?>\n';
                if (body instanceof Error) {
                    o = { errors: { error: body.body } };
                } else if (Buffer.isBuffer(body)) {
                    o = JSON.parse(body.toString('base64'));
                } else {
                    o = body;
                }

                xml += toXml(o);

                res.setHeader('Content-Length', Buffer.byteLength(xml));
                return xml;
            }
        }
    });

    server.use(restify.acceptParser(server.acceptable));
    server.use(restify.dateParser());
    server.use(restify.queryParser());
    server.use(restify.bodyParser());
    server.use(restify.fullResponse());

    server.on('after', restify.auditLogger({log: log}));

    server.use(before);
    server.on('after', function (req, res, route, err) {
        if (req.ldap) {
            req.ldap.unbind(function (err1) {
                if (err1) {
                    log.error(err1, 'Unable to unbind LDAP client');
                }
                log.debug('LDAP client unbound');
            });
        }
    });

    // Show
    server.get('/customers', customers.list);
    server.head('/customers', customers.list);

    // CreateCustomer
    server.post('/customers', customers.create);

    // UpdateCustomer
    server.put('/customers/:uuid', before, utils.loadCustomer,
            customers.update, utils.loadCustomer,
            function respond(req, res, next) {
                var customer = utils.translateCustomer(
                    req.customer.toObject());
                res.send(200, customer);
                return next();
            });

    // GetCustomer
    server.get('/customers/:uuid', utils.loadCustomer, customers.get);
    server.head('/customers/:uuid', utils.loadCustomer, customers.get);

    // DeleteCustomer
    server.del('/customers/:uuid', utils.loadCustomer, customers.del);

    // GetSalt
    server.get('/login/:login', login.getSalt);
    server.head('/login/:login', login.getSalt);

    // Login
    server.post('/login', login.login);

    // ForgotPassword
    server.post('/auth/forgot_password', login.forgotPassword);

    server.use(utils.loadCustomer);

    /// Metadata
    server.get('/auth/customers/:uuid/metadata/:appkey', metadata.list);
    server.put('/auth/customers/:uuid/metadata/:appkey/:key', metadata.put);
    server.get('/auth/customers/:uuid/metadata/:appkey/:key', metadata.get);
    server.del('/auth/customers/:uuid/metadata/:appkey/:key', metadata.del);

    /// Keys
    server.post('/customers/:uuid/keys', keys.post);
    server.get('/customers/:uuid/keys', keys.list);
    server.get('/customers/:uuid/keys/:id', keys.get);
    server.put('/customers/:uuid/keys/:id', keys.put);
    server.del('/customers/:uuid/keys/:id', keys.del);

    /// Smartlogin

    server.post('/customers/:uuid/ssh_sessions', keys.smartlogin);

    /// Limits

    server.get('/customers/:uuid/limits', limits.list);
    server.put('/customers/:uuid/limits/:dc/:dataset', limits.put);
    server.del('/customers/:uuid/limits/:dc/:dataset', limits.del);

    ///-- Start up

    function connect() {
        server.listen(config.port, function () {
            console.error('CAPI listening on port %d', config.port);
        });
    }

    return {
        server: server,
        log: log,
        connect: connect
    };
}

function processConfig() {

    var _config;
    var parsed = nopt(opts, shortOpts, process.argv, 2);
    var file = parsed.file || __dirname + '/etc/ufds.config.json';

    if (parsed.help) {
        usage(0);
    }

    try {

        _config = JSON.parse(fs.readFileSync(file, 'utf8'));

    } catch (e) {
        console.error('Unable to parse configuration file: ' + e.message);
        process.exit(1);
    }

    if (!_config.ufds) {
        _config.ufds = 'ldaps://127.0.0.1';
        if (_config.port) {
            _config.ufds += ':' + parsed.port;
        }
    }

    if (parsed.debug) {
        _config.logLevel = 'debug';
    }

    if (!_config.logLevel) {
        _config.logLevel = 'info';
    }

    // We need to override config.port here, b/c the port in config is for LDAP
    _config.port = (process.env.PORT) ? process.env.PORT : 8080;

    return _config;
}

var cfg = processConfig();

var capi = CAPI(cfg);

capi.connect();

// Increase/decrease loggers levels using SIGUSR2/SIGUSR1:
var sigyan = require('sigyan');
sigyan.add([capi.log]);
<commit_msg>CAPI-231: res.sendError returning false + missing else<commit_after>// Copyright 2013 Joyent, Inc.  All rights reserved.

var assert = require('assert');
var fs = require('fs');
var http = require('http');
var path = require('path');
var sprintf = require('util').format;

var Logger = require('bunyan');
var ldap = require('ldapjs');
var nopt = require('nopt');
var restify = require('restify');
var uuid = require('node-uuid');

var customers = require('./capi/customers');
var keys = require('./capi/keys');
var login = require('./capi/login');
var limits = require('./capi/limits');
var metadata = require('./capi/metadata');
var utils = require('./capi/util');

function entitify(str) {
    str = '' + str;
    /* BEGIN JSSTYLED */
    str = str.replace(/&/g, '&').replace(/</g, '<')
        .replace(/>/g, '>').replace(/'/g, ''')
        .replace(/"/g, '"');
    /* END JSSTYLED */
    return str;
}

function toXml(elm) {
    var xml = '';
    if (Array.isArray(elm)) {
        xml += elm.map(function (e) {
            return (toXml(e));
        }).join('\n');
    } else if (typeof (elm) === 'object' && Object.keys(elm)) {
        Object.keys(elm).forEach(function (k) {
            if (elm[k]) {
                xml += sprintf('<%s>%s</%s>', k, toXml(elm[k]), k);
            }
        });
    } else {
        xml += entitify(elm);
    }
    return (xml);
}

///--- Globals

var opts = {
    'certificate': String,
    'config': String,
    'debug': Boolean,
    'file': String,
    'key': String,
    'port': Number,
    'ufds': String,
    'help': Boolean
};

var shortOpts = {
    'c': ['--certiifcate'],
    'd': ['--debug'],
    'f': ['--file'],
    'k': ['--key'],
    'p': ['--port'],
    'h': ['--help'],
    'u': ['--ufds']
};

///--- Helpers

function usage(code, message) {
    var _opts = '';
    Object.keys(shortOpts).forEach(function (k) {
        var longOpt = shortOpts[k][0].replace('--', '');
        var type = opts[longOpt].name || 'string';
        if (type && type === 'boolean') type = '';
        type = type.toLowerCase();

        _opts += ' [--' + longOpt + ' ' + type + ']';
    });
    _opts += ' dn attribute value(s)';

    var msg = (message ? message + '\n' : '') +
        'usage: ' + path.basename(process.argv[1]) + _opts;

    process.stderr.write(msg + '\n');
    process.exit(code);
}

///--- CAPI shim

function CAPI(config) {

    var log = new Logger({
        name: 'capi',
        level: config.logLevel,
        stream: process.stdout,
        serializers: restify.bunyan.serializers
    });

    function before(req, res, next) {

        res.sendError = function sendError(errors) {
            if (req.xml) {
                errors = { errors: { error: errors } };
            } else {
                errors = { errors: errors };
            }
            log.warn({errors: errors}, 'These are the errors');
            res.send(409, errors);
            return (false);
        };

        req.ldap = ldap.createClient({
            url: config.ufds,
            log: log
        });

        req.ldap.once('error', function (err) {
            req.ldap = null;
            next(err);
        });

        req.ldap.once('connect', function () {
            log.debug('LDAP Client Connected');
            req.ldap.bind(config.rootDN, config.rootPassword, function (err) {
                if (err) {
                    log.error(err, 'Unable to bind to UFDS');
                    return next(err);
                }
                log.debug('Bound to UFDS');
                return next();
            });
        });
    }

    var server = restify.createServer({
        name: 'capi',
        log: log,
        formatters: {
            'application/xml': function formatXml(req, res, body) {
                var o;
                var xml = '<?xml version="1.0" encoding="utf-8"?>\n';
                if (body instanceof Error) {
                    o = { errors: { error: body.body } };
                } else if (Buffer.isBuffer(body)) {
                    o = JSON.parse(body.toString('base64'));
                } else {
                    o = body;
                }

                xml += toXml(o);

                res.setHeader('Content-Length', Buffer.byteLength(xml));
                return xml;
            }
        }
    });

    server.use(restify.acceptParser(server.acceptable));
    server.use(restify.dateParser());
    server.use(restify.queryParser());
    server.use(restify.bodyParser());
    server.use(restify.fullResponse());

    server.on('after', restify.auditLogger({log: log}));

    server.use(before);
    server.on('after', function (req, res, route, err) {
        if (req.ldap) {
            req.ldap.unbind(function (err1) {
                if (err1) {
                    log.error(err1, 'Unable to unbind LDAP client');
                } else {
                    log.debug('LDAP client unbound');
                }
            });
        }
    });

    // Show
    server.get('/customers', customers.list);
    server.head('/customers', customers.list);

    // CreateCustomer
    server.post('/customers', customers.create);

    // UpdateCustomer
    server.put('/customers/:uuid', before, utils.loadCustomer,
            customers.update, utils.loadCustomer,
            function respond(req, res, next) {
                var customer = utils.translateCustomer(
                    req.customer.toObject());
                res.send(200, customer);
                return next();
            });

    // GetCustomer
    server.get('/customers/:uuid', utils.loadCustomer, customers.get);
    server.head('/customers/:uuid', utils.loadCustomer, customers.get);

    // DeleteCustomer
    server.del('/customers/:uuid', utils.loadCustomer, customers.del);

    // GetSalt
    server.get('/login/:login', login.getSalt);
    server.head('/login/:login', login.getSalt);

    // Login
    server.post('/login', login.login);

    // ForgotPassword
    server.post('/auth/forgot_password', login.forgotPassword);

    server.use(utils.loadCustomer);

    /// Metadata
    server.get('/auth/customers/:uuid/metadata/:appkey', metadata.list);
    server.put('/auth/customers/:uuid/metadata/:appkey/:key', metadata.put);
    server.get('/auth/customers/:uuid/metadata/:appkey/:key', metadata.get);
    server.del('/auth/customers/:uuid/metadata/:appkey/:key', metadata.del);

    /// Keys
    server.post('/customers/:uuid/keys', keys.post);
    server.get('/customers/:uuid/keys', keys.list);
    server.get('/customers/:uuid/keys/:id', keys.get);
    server.put('/customers/:uuid/keys/:id', keys.put);
    server.del('/customers/:uuid/keys/:id', keys.del);

    /// Smartlogin

    server.post('/customers/:uuid/ssh_sessions', keys.smartlogin);

    /// Limits

    server.get('/customers/:uuid/limits', limits.list);
    server.put('/customers/:uuid/limits/:dc/:dataset', limits.put);
    server.del('/customers/:uuid/limits/:dc/:dataset', limits.del);

    ///-- Start up

    function connect() {
        server.listen(config.port, function () {
            console.error('CAPI listening on port %d', config.port);
        });
    }

    return {
        server: server,
        log: log,
        connect: connect
    };
}

function processConfig() {

    var _config;
    var parsed = nopt(opts, shortOpts, process.argv, 2);
    var file = parsed.file || __dirname + '/etc/ufds.config.json';

    if (parsed.help) {
        usage(0);
    }

    try {

        _config = JSON.parse(fs.readFileSync(file, 'utf8'));

    } catch (e) {
        console.error('Unable to parse configuration file: ' + e.message);
        process.exit(1);
    }

    if (!_config.ufds) {
        _config.ufds = 'ldaps://127.0.0.1';
        if (_config.port) {
            _config.ufds += ':' + parsed.port;
        }
    }

    if (parsed.debug) {
        _config.logLevel = 'debug';
    }

    if (!_config.logLevel) {
        _config.logLevel = 'info';
    }

    // We need to override config.port here, b/c the port in config is for LDAP
    _config.port = (process.env.PORT) ? process.env.PORT : 8080;

    return _config;
}

var cfg = processConfig();

var capi = CAPI(cfg);

capi.connect();

// Increase/decrease loggers levels using SIGUSR2/SIGUSR1:
var sigyan = require('sigyan');
sigyan.add([capi.log]);
<|endoftext|>


<commit_before>var DEBUG = false;

var dpr = Math.min(window.devicePixelRatio || 1, 2);
var width = window.innerWidth;
var height = window.innerHeight;

var scene = new THREE.Scene();

var camera = new THREE.PerspectiveCamera(105, (width / 2) / height, 1, 1000);
camera.position.x = 0.1;

var renderer = new THREE.WebGLRenderer({
  antialias: true,
  devicePixelRatio: dpr
});
renderer.setSize(width, height);
renderer.autoClear = false;

var pipeline = new THREE.StereoPipeline(renderer, dpr, width, height);

renderer.setSize(width, height);

var meshes = [];

var placeId = location.hash.replace(/[#,\/]*/, '');
if (!placeId) location.url = '/selection.html';
var place = Places[placeId];

var leftTexture = [THREE.ImageUtils.loadTexture(place.left)];
var rightTexture = [THREE.ImageUtils.loadTexture(place.right)];

var sphere = new StereoMesh(leftTexture, rightTexture, new THREE.SphereGeometry(100, 20, 20));

sphere.scaleLeft.x = -1;
sphere.scaleRight.x = -1;

meshes.push(sphere);

var fframe;

for (var i = place.frames.length - 1; i >= 0; i--) {
  var frame = place.frames[i];

  var left = [];

  for (var tex in frame.left) {
    left.push(THREE.ImageUtils.loadTexture(frame.left[tex]));
  }
  var right = [];

  for (var tex in frame.right) {
    right.push(THREE.ImageUtils.loadTexture(frame.right[tex]));
  }

  var frameMesh = new StereoMesh(left, right, new THREE.CircleGeometry(10, 20));
  frameMesh.positionLeft = new THREE.Vector3(frame.positionL[0], frame.positionL[1], frame.positionL[2]);
  frameMesh.rotationLeft = new THREE.Euler(frame.rotationL[0], frame.rotationL[1], frame.rotationL[2], "XYZ");
  frameMesh.scaleLeft = new THREE.Vector3(frame.scaleL[0], frame.scaleL[1], frame.scaleL[2]);

  frameMesh.positionRight = new THREE.Vector3(frame.positionR[0], frame.positionR[1], frame.positionR[2]);
  frameMesh.rotationRight = new THREE.Euler(frame.rotationR[0], frame.rotationR[1], frame.rotationR[2], "XYZ");
  frameMesh.scaleRight = new THREE.Vector3(frame.scaleR[0], frame.scaleR[1], frame.scaleR[2]);

  meshes.push(frameMesh);
  fframe = frameMesh;
}

meshes.forEach(function(m) {
  scene.add(m.mesh);
});

var controls;

if (DEBUG) {
  controls = new THREE.OrbitControls(camera);
  controls.noPan = true;
  controls.noZoom = true;
  controls.autoRotate = true;
  controls.autoRotateSpeed = 0.5;

  document.addEventListener('keydown', moveFrame, false);
} else {
  controls = new THREE.DeviceOrientationControls(camera, true);
  controls.connect();
  controls.update();

  window.addEventListener('click', toggleFullscreen, false);
  window.addEventListener('touchmove', reload, false);
}

var leftPrerender = function() {
  for (var i = meshes.length - 1; i >= 0; i--) {
    meshes[i].beforeRenderLeft();
  }
};

var rightPrerender = function() {
  for (var i = meshes.length - 1; i >= 0; i--) {
    meshes[i].beforeRenderRight();
  }
};

render();

function render() {
  controls.update();
  pipeline.render(scene, camera, leftPrerender, rightPrerender);
  requestAnimationFrame(render);
}

function resize() {

  width = window.innerWidth;
  height = window.innerHeight;

  camera.aspect = (width / 2) / height;
  camera.updateProjectionMatrix();

  renderer.setSize(width, height);
  pipeline.setSize(dpr, width, height);

}

function toggleFullscreen() {
  if (document.mozFullScreen || document.webkitIsFullScreen) {
    if (document.exitFullscreen) {
      document.exitFullscreen();
    } else if (document.msExitFullscreen) {
      document.msExitFullscreen();
    } else if (document.mozCancelFullScreen) {
      document.mozCancelFullScreen();
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen();
    }
  } else {
    if (element.requestFullscreen) {
      element.requestFullscreen();
    } else if (element.msRequestFullscreen) {
      element.msRequestFullscreen();
    } else if (element.mozRequestFullScreen) {
      element.mozRequestFullScreen();
    } else if (element.webkitRequestFullscreen) {
      element.webkitRequestFullscreen();
    }
  }
}

function reload() {
  location.reload();
}

function moveFrame(event) {
  if (event.keyCode == 37) {
    fframe.mesh.position.x += 0.5;
  }
  if (event.keyCode == 39) {
    fframe.mesh.position.x -= 0.5;
  }
  if (event.keyCode == 38) {
    fframe.mesh.position.z += 0.5;
  }
  if (event.keyCode == 40) {
    fframe.mesh.position.z -= 0.5;
  }

  if (event.keyCode == 79) { //O
    fframe.mesh.position.y += 0.5;
  }
  if (event.keyCode == 76) { //L
    fframe.mesh.position.y -= 0.5;
  }

  if (event.keyCode == 65) { //A
    fframe.mesh.rotation.y += 0.1;
  }
  if (event.keyCode == 68) { //D
    fframe.mesh.rotation.y -= 0.1;
  }

  if (event.keyCode == 87) { //W
    fframe.mesh.rotation.x += 0.1;
  }
  if (event.keyCode == 83) { //S
    fframe.mesh.rotation.x -= 0.1;
  }
  if (event.keyCode == 81) { //Q
    fframe.mesh.rotation.z += 0.1;
  }

  if (event.keyCode == 69) { //E
    fframe.mesh.rotation.z -= 0.1;
  }
  if (event.keyCode == 73) { //i
    fframe.mesh.scale.z += 0.1;
    fframe.mesh.scale.x += 0.1;
    fframe.mesh.scale.y += 0.1;
  }
  if (event.keyCode == 75) { //k
    fframe.mesh.scale.z -= 0.1;
    fframe.mesh.scale.x -= 0.1;
    fframe.mesh.scale.y -= 0.1;
  }
};

window.addEventListener('resize', resize, false);

var element = renderer.domElement;
document.body.appendChild(element);
<commit_msg>fix url<commit_after>var DEBUG = false;

var dpr = Math.min(window.devicePixelRatio || 1, 2);
var width = window.innerWidth;
var height = window.innerHeight;

var scene = new THREE.Scene();

var camera = new THREE.PerspectiveCamera(105, (width / 2) / height, 1, 1000);
camera.position.x = 0.1;

var renderer = new THREE.WebGLRenderer({
  antialias: true,
  devicePixelRatio: dpr
});
renderer.setSize(width, height);
renderer.autoClear = false;

var pipeline = new THREE.StereoPipeline(renderer, dpr, width, height);

renderer.setSize(width, height);

var meshes = [];

var placeId = location.hash.replace(/[#,\/]*/, '');
if (!placeId) location.url = 'selection.html';
var place = Places[placeId];

var leftTexture = [THREE.ImageUtils.loadTexture(place.left)];
var rightTexture = [THREE.ImageUtils.loadTexture(place.right)];

var sphere = new StereoMesh(leftTexture, rightTexture, new THREE.SphereGeometry(100, 20, 20));

sphere.scaleLeft.x = -1;
sphere.scaleRight.x = -1;

meshes.push(sphere);

var fframe;

for (var i = place.frames.length - 1; i >= 0; i--) {
  var frame = place.frames[i];

  var left = [];

  for (var tex in frame.left) {
    left.push(THREE.ImageUtils.loadTexture(frame.left[tex]));
  }
  var right = [];

  for (var tex in frame.right) {
    right.push(THREE.ImageUtils.loadTexture(frame.right[tex]));
  }

  var frameMesh = new StereoMesh(left, right, new THREE.CircleGeometry(10, 20));
  frameMesh.positionLeft = new THREE.Vector3(frame.positionL[0], frame.positionL[1], frame.positionL[2]);
  frameMesh.rotationLeft = new THREE.Euler(frame.rotationL[0], frame.rotationL[1], frame.rotationL[2], "XYZ");
  frameMesh.scaleLeft = new THREE.Vector3(frame.scaleL[0], frame.scaleL[1], frame.scaleL[2]);

  frameMesh.positionRight = new THREE.Vector3(frame.positionR[0], frame.positionR[1], frame.positionR[2]);
  frameMesh.rotationRight = new THREE.Euler(frame.rotationR[0], frame.rotationR[1], frame.rotationR[2], "XYZ");
  frameMesh.scaleRight = new THREE.Vector3(frame.scaleR[0], frame.scaleR[1], frame.scaleR[2]);

  meshes.push(frameMesh);
  fframe = frameMesh;
}

meshes.forEach(function(m) {
  scene.add(m.mesh);
});

var controls;

if (DEBUG) {
  controls = new THREE.OrbitControls(camera);
  controls.noPan = true;
  controls.noZoom = true;
  controls.autoRotate = true;
  controls.autoRotateSpeed = 0.5;

  document.addEventListener('keydown', moveFrame, false);
} else {
  controls = new THREE.DeviceOrientationControls(camera, true);
  controls.connect();
  controls.update();

  window.addEventListener('click', toggleFullscreen, false);
  window.addEventListener('touchmove', reload, false);
}

var leftPrerender = function() {
  for (var i = meshes.length - 1; i >= 0; i--) {
    meshes[i].beforeRenderLeft();
  }
};

var rightPrerender = function() {
  for (var i = meshes.length - 1; i >= 0; i--) {
    meshes[i].beforeRenderRight();
  }
};

render();

function render() {
  controls.update();
  pipeline.render(scene, camera, leftPrerender, rightPrerender);
  requestAnimationFrame(render);
}

function resize() {

  width = window.innerWidth;
  height = window.innerHeight;

  camera.aspect = (width / 2) / height;
  camera.updateProjectionMatrix();

  renderer.setSize(width, height);
  pipeline.setSize(dpr, width, height);

}

function toggleFullscreen() {
  if (document.mozFullScreen || document.webkitIsFullScreen) {
    if (document.exitFullscreen) {
      document.exitFullscreen();
    } else if (document.msExitFullscreen) {
      document.msExitFullscreen();
    } else if (document.mozCancelFullScreen) {
      document.mozCancelFullScreen();
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen();
    }
  } else {
    if (element.requestFullscreen) {
      element.requestFullscreen();
    } else if (element.msRequestFullscreen) {
      element.msRequestFullscreen();
    } else if (element.mozRequestFullScreen) {
      element.mozRequestFullScreen();
    } else if (element.webkitRequestFullscreen) {
      element.webkitRequestFullscreen();
    }
  }
}

function reload() {
  location.reload();
}

function moveFrame(event) {
  if (event.keyCode == 37) {
    fframe.mesh.position.x += 0.5;
  }
  if (event.keyCode == 39) {
    fframe.mesh.position.x -= 0.5;
  }
  if (event.keyCode == 38) {
    fframe.mesh.position.z += 0.5;
  }
  if (event.keyCode == 40) {
    fframe.mesh.position.z -= 0.5;
  }

  if (event.keyCode == 79) { //O
    fframe.mesh.position.y += 0.5;
  }
  if (event.keyCode == 76) { //L
    fframe.mesh.position.y -= 0.5;
  }

  if (event.keyCode == 65) { //A
    fframe.mesh.rotation.y += 0.1;
  }
  if (event.keyCode == 68) { //D
    fframe.mesh.rotation.y -= 0.1;
  }

  if (event.keyCode == 87) { //W
    fframe.mesh.rotation.x += 0.1;
  }
  if (event.keyCode == 83) { //S
    fframe.mesh.rotation.x -= 0.1;
  }
  if (event.keyCode == 81) { //Q
    fframe.mesh.rotation.z += 0.1;
  }

  if (event.keyCode == 69) { //E
    fframe.mesh.rotation.z -= 0.1;
  }
  if (event.keyCode == 73) { //i
    fframe.mesh.scale.z += 0.1;
    fframe.mesh.scale.x += 0.1;
    fframe.mesh.scale.y += 0.1;
  }
  if (event.keyCode == 75) { //k
    fframe.mesh.scale.z -= 0.1;
    fframe.mesh.scale.x -= 0.1;
    fframe.mesh.scale.y -= 0.1;
  }
};

window.addEventListener('resize', resize, false);

var element = renderer.domElement;
document.body.appendChild(element);
<|endoftext|>


<commit_before>var express = require('express'),
    app = express(),
    mu = require('mu2'),
    util = require('util'),
    path = require( 'path'),
    FB = require('fb'),
    MongoClient = require('mongodb').MongoClient,
    format = util.format;

mu.root = __dirname;

app.configure(function () {
    var staticPath = path.resolve ( __dirname + '/../static' );
    app.use( express.static( staticPath ) );

    app.use( express.logger() );
});

app.use(express.static(__dirname + '/static'));

// app.get('/', function(req, res) {
//     console.log('get request to /');
//     var homePage = mu.compileAndRender('../templates/home.html', {});
//     console.log('homePage is', homePage);
//     util.pump(homePage, res);
// });

MongoClient.connect(process.env.MONGOHQ_URL || 'mongodb://127.0.0.1:27017/test', function(err, db) {
    if(err) throw err;

    var collection = db.collection('test_insert');
    collection.insert({a:2}, function(err, docs) {

      collection.count(function(err, count) {
        console.log(format("count = %s", count));
      });

      // Locate all the entries using find
      collection.find().toArray(function(err, results) {
        console.dir(results);
        // Let's close the db
        db.close();
      });
    });
});

var FB = require('fb');

FB.api('4', function (res) {
  if(!res || res.error) {
   console.log(!res ? 'error occurred' : res.error);
   return;
  }
  console.log(res.id);
  console.log(res.name);
});

app.listen(process.env.PORT || 5000);<commit_msg>- Added test FB intergration<commit_after>var express = require('express'),
    app = express(),
    mu = require('mu2'),
    util = require('util'),
    path = require( 'path'),
    FB = require('fb'),
    MongoClient = require('mongodb').MongoClient,
    format = util.format;

mu.root = __dirname;

app.configure(function () {
    var staticPath = path.resolve ( __dirname + '/../static' );
    app.use( express.static( staticPath ) );

    app.use( express.logger() );
});

app.use(express.static(__dirname + '/static'));

// app.get('/', function(req, res) {
//     console.log('get request to /');
//     var homePage = mu.compileAndRender('../templates/home.html', {});
//     console.log('homePage is', homePage);
//     util.pump(homePage, res);
// });

MongoClient.connect(process.env.MONGOHQ_URL || 'mongodb://127.0.0.1:27017/test', function(err, db) {
    if(err) throw err;

    var collection = db.collection('test_insert');
    collection.insert({a:2}, function(err, docs) {

      collection.count(function(err, count) {
        console.log(format("count = %s", count));
      });

      // Locate all the entries using find
      collection.find().toArray(function(err, results) {
        console.dir(results);
        // Let's close the db
        db.close();
      });
    });
});

var FB = require('fb');
FB.setAccessToken('CAACEdEose0cBAAzozsRWD94OmCU4fPOsZB0giNexYxuOe5WY082LAYoEZBDsedj8mmZBAdRV79BAjczrMKDO2T3j7vUvLX3mQE7dqxkC6CFY6LGxehuG3ETPc2IvxKt8ni1onwVcIs4gWAQgfkBovpBSz0hcSQKGmdaOK5MFOAr2qIIdjfGEqtyEZBrvZCM1DQJ5Rypsl7gZDZD');

FB.api('fql', { q: 'SELECT src FROM photo WHERE owner=100001237688606' }, function (res) {
  if(!res || res.error) {
    console.log(!res ? 'error occurred' : res.error);
    return;
  }
  console.log(res.data);
});

app.listen(process.env.PORT || 5000);<|endoftext|>


<commit_before>var gulp = require('gulp'),
		wiredep = require('wiredep').stream,
		useref = require('gulp-useref'),
    gulpif = require('gulp-if'),
    uglify = require('gulp-uglify'),
    minifyCss = require('gulp-minify-css'),
    jade = require('gulp-jade'),
    sass = require('gulp-sass'),
		browserSync = require('browser-sync'),
		clean = require('gulp-clean');

gulp.task('clean', function () {
	return gulp.src('dist', {read: false})
		.pipe(clean());
});

var sassOptions = {
  outputStyle: 'expanded'
};

gulp.task('browserSync', function() {
    browserSync({
    	server : {
    		baseDir : 'app'
    	}
    })
});

gulp.task('bower', function () {
  gulp.src('./app/**/*.jade')
    .pipe(wiredep({
      directory : "app/bower_components"
    }))
    .pipe(gulp.dest('./app'));
});

gulp.task('jade', function() {
    gulp.src('app/**/*.jade')
      .pipe(jade({
      	pretty : true
      }))
      .pipe(gulp.dest('app'))
      .pipe(browserSync.reload({
      	stream: true
      }));
});

gulp.task('sass', function() {
    gulp.src('app/style/**/*.scss')
      .pipe(sass(sassOptions))
      .pipe(gulp.dest('app/style'))
      .pipe(browserSync.reload({
      	stream: true
      }));
});

gulp.task('html', function () {
  gulp.src('app/*.html')
  	.pipe(useref())
  	.pipe(gulpif('*.js', uglify()))
    .pipe(gulpif('*.css', minifyCss()))
    .pipe(gulp.dest('dist'));
});

gulp.task('watch', function() {
    gulp.watch('app/style/**/*.scss', ['sass']);
    gulp.watch('app/**/*.jade', ['jade']);
});

gulp.task('default',['bower','sass', 'jade', 'browserSync','watch']);

gulp.task('build',['clean', 'html']);
<commit_msg>gulp<commit_after>var gulp = require('gulp'),
		wiredep = require('wiredep').stream,
		useref = require('gulp-useref'),
    gulpif = require('gulp-if'),
    uglify = require('gulp-uglify'),
    minifyCss = require('gulp-minify-css'),
    jade = require('gulp-jade'),
    sass = require('gulp-sass'),
		browserSync = require('browser-sync'),
		clean = require('gulp-clean'),
    ghPages = require('gulp-gh-pages');

gulp.task('deploy', function() {
  return gulp.src('./dist/**/*')
    .pipe(ghPages());
});;

gulp.task('clean', function () {
	return gulp.src('dist', {read: false})
		.pipe(clean());
});

var sassOptions = {
  outputStyle: 'expanded'
};

gulp.task('browserSync', function() {
    browserSync({
    	server : {
    		baseDir : 'app'
    	}
    })
});

gulp.task('bower', function () {
  gulp.src('./app/**/*.jade')
    .pipe(wiredep({
      directory : "app/bower_components"
    }))
    .pipe(gulp.dest('./app'));
});

gulp.task('jade', function() {
    gulp.src('app/**/*.jade')
      .pipe(jade({
      	pretty : true
      }))
      .pipe(gulp.dest('app'))
      .pipe(browserSync.reload({
      	stream: true
      }));
});

gulp.task('sass', function() {
    gulp.src('app/style/**/*.scss')
      .pipe(sass(sassOptions))
      .pipe(gulp.dest('app/style'))
      .pipe(browserSync.reload({
      	stream: true
      }));
});

gulp.task('html', function () {
  gulp.src('app/*.html')
  	.pipe(useref())
  	.pipe(gulpif('*.js', uglify()))
    .pipe(gulpif('*.css', minifyCss()))
    .pipe(gulp.dest('dist'));
});

gulp.task('watch', function() {
    gulp.watch('app/style/**/*.scss', ['sass']);
    gulp.watch('app/**/*.jade', ['jade']);
});

gulp.task('default',['bower','sass', 'jade', 'browserSync','watch']);

gulp.task('build',['clean', 'html']);
<|endoftext|>


<commit_before>var
  // load config from file
  bodyParser = require('body-parser'),
  config = require('./local_modules/config'),
  express = require('express'),
  fs = require('fs'),
  helmet = require('helmet'),
  Mailgun = require('mailgun-js');
  SmidManger = require('./local_modules/smid-manager.js').SmidManger,
  OcridOAuthUtil = require('./local_modules/orcid-oauth-util.js').OcridOAuthUtil;

var smidManger = new SmidManger(config.MONGO_CONNECTION_STRING);
var mailgunPriv = Mailgun({apiKey: config.MAILGUN_PRIV_API_KEY, domain: config.MAILGUN_DOMAIN});
var mailgunPub = Mailgun({apiKey: config.MAILGUN_PUB_API_KEY, domain: config.MAILGUN_DOMAIN});

var ooau = new OcridOAuthUtil(
  config.CLIENT_ID,
  config.CLIENT_SECRET,
  config.ORCID_URL);

// Init express
var app = express();
var path = require('path');
var distDir = __dirname + "/dist/";
var index_file = distDir + "index.html"
var PAGE_404 = distDir + "assets/404.html"
var PAGE_500 = distDir + "assets/500.html"
app.use(express.static(distDir));
app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(bodyParser.json());
//app.use(helmet());
app.set('json spaces', 2);
app.set('json replacer', null);

app.listen(config.PORT_HTTP, function() {
  console.log('listening on port: ' + config.PORT_HTTP)
})

// Custom console for orcid logging
var orcidOutput = fs.createWriteStream('./orcidout.log');
var orcidErrorOutput = fs.createWriteStream('./orciderr.log');
var orcidLogger = new console.Console(orcidOutput, orcidErrorOutput);

//Endpoints
var CONFIG = '/config';
var CREATE_SMID_AUTHORIZE = '/create-smid-authorize';
var CONFIG = '/config';
var CREATE_SMID_URI = '/create-smid-redirect';
var COLLECTION_DETAILS = '/:publicKey/details';
var COLLECTION_DETAILS_DOWNLOAD = '/:publicKey/details/download';
var COLLECTION_DETAILS_FORM = '/:publicKey/details/:privateKey/details/form';
var EMAIL_SMID = '/email-smid';
var ADD_ID_AUTHORIZE = '/add-id-authorize/:publicKey';
var ADD_ID_REDIRECT = '/add-id-redirect';
var ADD_ID_SUCCESS = '/:publicKey/orcid/:orcid';
var ADD_ID_ERROR = '/:publicKey/add-id-error';
var COLLECTION_EDIT = '/:publicKey/edit/:privateKey';
var COLLECTION_SHARE = '/:publicKey';

function rmTab(str) {
  if (str !== undefined && str != null)
    return str.replace(/\t/g, '');
  return str;
}

function dateToStr(date) {
  return date.toISOString();
}

function smidToTxt(doc) {
  if (doc === undefined || doc == null) return null;
  var csv = `${rmTab(doc.form.title)}\n`;
  csv += 'dateRecorded             \towner orcid        \towner fullOrcidId                            \towner name\n';
  csv += `${dateToStr(doc.owner.dateRecorded)}\t${doc.owner.orcid}\t${doc.owner.fullOrcidId}\t${rmTab(doc.owner.name)}\n`;
  csv += "\n";
  csv += "Share my iD results\n";
  csv += 'dateRecorded             \torcid              \tfullOrcidId                                   \tname\n';
  doc.authenticated_orcids.forEach(function(row) {
    csv += `${dateToStr(row.dateRecorded)}\t${row.orcid}\t${row.fullOrcidId}\t${rmTab(row.name)}\n`;
  })
  return csv;
}

app.get(CONFIG, function(req, res) {
  return res.status(200).json({
    'ORCID_URL': config.ORCID_URL
  });
});

app.get(CONFIG, function(req, res) {
  return res.status(200).json({
    'ORCID_URL': config.ORCID_URL
  });
});

//Create new id collection
app.get(CREATE_SMID_URI, function(req, res) { // Redeem code URL
  var state = req.query.state;
  if (req.query.error == 'access_denied') {
    // User denied access
    console.log("error: " + req.query.error);
    res.json(req.query);
  } else if (req.query.code === undefined) {
    res.json(req.query);
  } else {
    // exchange code
    // function to render page after making request
    var exchangingCallback = function(err, token) {
      if (err != null)
        res.sendFile(PAGE_500);
      else { // No errors! we have a token :-)
        var date = new Date();
        //Log ORCID info to file
        orcidLogger.log(date, token.name, token.orcid, req.query.state);
        console.log("creating smid for " + token.orcid);
        var orcidRecord = smidManger.createOrcidRecord(token.orcid, ooau.fullOrcid(token.orcid), token.name);
        smidManger.addOwnerOrcidRecord(orcidRecord, req.query.state, function(err, doc) {
          if (err) res.send(err)
          else {
            var collection = JSON.parse(JSON.stringify(doc, null, 2));
            var private_key = collection.private_key;
            var public_key = collection.public_key;
            res.redirect('/' + public_key + '/edit/' + private_key);
          }
        });
      }
    };
    ooau.exchangeCode(req.query.code, exchangingCallback);
  }

});

//Get collection details
app.get(COLLECTION_DETAILS, function(req, res) {
  smidManger.getDetails(req.params.publicKey, function(err, doc) {
    if (err)
      res.send(err)
    else if (doc === undefined || doc == null)
      res.sendFile(PAGE_404);
    else
      res.status(200).json(doc);
  });
});

//Get collection details
app.get(COLLECTION_DETAILS_DOWNLOAD, function(req, res) {
  smidManger.getDetails(req.params.publicKey, function(err, doc) {
    if (err)
      res.send(err)
    else if (doc === undefined || doc == null)
      res.sendFile(PAGE_404);
    else {
      try {
        var txt = smidToTxt(doc);
        res.set({
          "Content-Disposition": `attachment; filename="${doc.form.title}_tab_separated.txt"`
        });
        res.status(200).send(txt);
      } catch (e) {
        res.sendFile(PAGE_500);
      }
    }
  });
});

//Update collection details form fields
app.put(COLLECTION_DETAILS_FORM, function(req, res) {
  var data = req.body;
  smidManger.updateForm(req.params.privateKey, data.form, function(err, doc) {
    if (err) res.status(400).json({'error':err})
    else {
      res.status(200).json(doc);
    }
  });
});

// create and email smid
app.post(EMAIL_SMID, function(req, res) {
  var data = req.body;
  mailgunPub.validate(data.email, function (error, body) {
    if(body && body.is_valid) {
      console.log("email is valid");
      smidManger.createSmid(function(err, doc) {
        var mailData = {
          from: 'No Reply <noreply@share-my-id.orcid.org>',
          to: data.email,
          subject: 'Share My iD links',
          text: `Thanks for creating a ORCID iD collection.\n`
          + `\n`
          + `\n`
          + `Administration Link\n`
          + `Use this link to edit collection details: \n`
          + `${config.HOST}/${doc.public_key}/edit/${doc.private_key}\n`
          + `\n`
          + `\n`
          + `Share Link\n`
          + `Share this link with anyone whose iD you want to collect, or display this page on a laptop/tablet at your event:`
          + `${config.HOST}/${doc.public_key}`
          + `\n`
          + `\n`
          + `Thanks,\n`
          + `The Share My iD Team`
        };
        var create_smid_authorization_uri = ooau.getAuthUrl(config.HOST + CREATE_SMID_URI, doc.private_key);
        mailgunPriv.messages().send(mailData, function (error, body) {
          if (error != null) {
            console.log("mailgun error:");
            console.log(error);
            if (body != null && body.message != null && body.message.includes("Great job"))
              res.status(200).json({'email': data.email, 'redirect': create_smid_authorization_uri }); // using test credentials
            else
              res.status(400).json({'error':error, 'body': body});
          } else {
            console.log("mailgun body:");
            console.log(body);
            res.status(200).json({'email': data.email});
          }
        });
      });
    } else {
      res.status(400).json({'error':"Email failed to pass validation", 'body': body});
    }
  });
});

//Add iD oauth sign into ORCID
app.get(ADD_ID_AUTHORIZE, function(req, res) {
  var add_id_authorization_uri = ooau.getAuthUrl(config.HOST + ADD_ID_REDIRECT, req.params.publicKey);
  res.redirect(add_id_authorization_uri);
});

//Add id to collection
app.get(ADD_ID_REDIRECT, function(req, res) { // Redeem code URL
  var state = req.query.state;
  if (req.query.error == 'access_denied') {
    // User denied access
    console.log("error: " + req.query.error);
    res.redirect( /* make ADD_ID_ERROR url */ '/' + state + "/add-id-error");
  } else {
    // exchange code
    // function to render page after making request
    var exchangingCallback = function(error, token) {
      if (error != null)
        res.sendFile(PAGE_500);
      else { // No errors! we have a token :-)
        var date = new Date();
        //Log ORCID info to file
        orcidLogger.log(date, token.name, token.orcid, req.query.state);
        //state maps to smid public key
        console.log("Got user id: " + token.orcid);
        var orcidRecord = smidManger.createOrcidRecord(token.orcid, ooau.fullOrcid(token.orcid), token.name);
        smidManger.addOrcidRecord(orcidRecord, req.query.state, function(err, doc) {
          if (err) res.send(err)
          else {
            //res.redirect('/' + req.query.state);
            res.redirect( /* make ADD_ID_SUCCESS url */ '/' + state + '/orcid/' + token.orcid);
          }
        });
      }
    };
    ooau.exchangeCode(req.query.code, exchangingCallback);
  }
});

app.get([COLLECTION_EDIT], function(req, res) { // Index page
  smidManger.smidExist(req.params.publicKey, req.params.privateKey, function(err, bool) {
    if (bool == true)
      res.status(200).sendFile(index_file);
    else
      res.sendFile(PAGE_404);
  });
});

app.get([COLLECTION_SHARE, ADD_ID_SUCCESS, ADD_ID_ERROR], function(req, res) { // Index page
  smidManger.detailsExist(req.params.publicKey, function(err, bool) {
    if (bool == true)
      res.status(200).sendFile(index_file);
    else
      res.sendFile(PAGE_404);
  });
});

app.get('/', function(req, res) { // Index page
  res.status(200).sendFile(index_file);
});<commit_msg>suggestion from Laura<commit_after>var
  // load config from file
  bodyParser = require('body-parser'),
  config = require('./local_modules/config'),
  express = require('express'),
  fs = require('fs'),
  helmet = require('helmet'),
  Mailgun = require('mailgun-js');
  SmidManger = require('./local_modules/smid-manager.js').SmidManger,
  OcridOAuthUtil = require('./local_modules/orcid-oauth-util.js').OcridOAuthUtil;

var smidManger = new SmidManger(config.MONGO_CONNECTION_STRING);
var mailgunPriv = Mailgun({apiKey: config.MAILGUN_PRIV_API_KEY, domain: config.MAILGUN_DOMAIN});
var mailgunPub = Mailgun({apiKey: config.MAILGUN_PUB_API_KEY, domain: config.MAILGUN_DOMAIN});

var ooau = new OcridOAuthUtil(
  config.CLIENT_ID,
  config.CLIENT_SECRET,
  config.ORCID_URL);

// Init express
var app = express();
var path = require('path');
var distDir = __dirname + "/dist/";
var index_file = distDir + "index.html"
var PAGE_404 = distDir + "assets/404.html"
var PAGE_500 = distDir + "assets/500.html"
app.use(express.static(distDir));
app.use(bodyParser.urlencoded({
  extended: true
}));
app.use(bodyParser.json());
//app.use(helmet());
app.set('json spaces', 2);
app.set('json replacer', null);

app.listen(config.PORT_HTTP, function() {
  console.log('listening on port: ' + config.PORT_HTTP)
})

// Custom console for orcid logging
var orcidOutput = fs.createWriteStream('./orcidout.log');
var orcidErrorOutput = fs.createWriteStream('./orciderr.log');
var orcidLogger = new console.Console(orcidOutput, orcidErrorOutput);

//Endpoints
var CONFIG = '/config';
var CREATE_SMID_AUTHORIZE = '/create-smid-authorize';
var CONFIG = '/config';
var CREATE_SMID_URI = '/create-smid-redirect';
var COLLECTION_DETAILS = '/:publicKey/details';
var COLLECTION_DETAILS_DOWNLOAD = '/:publicKey/details/download';
var COLLECTION_DETAILS_FORM = '/:publicKey/details/:privateKey/details/form';
var EMAIL_SMID = '/email-smid';
var ADD_ID_AUTHORIZE = '/add-id-authorize/:publicKey';
var ADD_ID_REDIRECT = '/add-id-redirect';
var ADD_ID_SUCCESS = '/:publicKey/orcid/:orcid';
var ADD_ID_ERROR = '/:publicKey/add-id-error';
var COLLECTION_EDIT = '/:publicKey/edit/:privateKey';
var COLLECTION_SHARE = '/:publicKey';

function rmTab(str) {
  if (str !== undefined && str != null)
    return str.replace(/\t/g, '');
  return str;
}

function dateToStr(date) {
  return date.toISOString();
}

function smidToTxt(doc) {
  if (doc === undefined || doc == null) return null;
  var csv = `${rmTab(doc.form.title)}\n`;
  csv += `Created by ${doc.owner.name} (${doc.owner.fullOrcidId})\n`;
  csv += `\n`;
  csv += `Collected iDs as of ${dateToStr(new Date())}\n`;
  csv += `Date Collected            \tORCID              \tFull ORCID iD                               \tCollected Name\n`;
  doc.authenticated_orcids.forEach(function(row) {
    csv += `${dateToStr(row.dateRecorded)}\t${row.orcid}\t${row.fullOrcidId}\t${rmTab(row.name)}\n`;
  })
  return csv;
}

app.get(CONFIG, function(req, res) {
  return res.status(200).json({
    'ORCID_URL': config.ORCID_URL
  });
});

app.get(CONFIG, function(req, res) {
  return res.status(200).json({
    'ORCID_URL': config.ORCID_URL
  });
});

//Create new id collection
app.get(CREATE_SMID_URI, function(req, res) { // Redeem code URL
  var state = req.query.state;
  if (req.query.error == 'access_denied') {
    // User denied access
    console.log("error: " + req.query.error);
    res.json(req.query);
  } else if (req.query.code === undefined) {
    res.json(req.query);
  } else {
    // exchange code
    // function to render page after making request
    var exchangingCallback = function(err, token) {
      if (err != null)
        res.sendFile(PAGE_500);
      else { // No errors! we have a token :-)
        var date = new Date();
        //Log ORCID info to file
        orcidLogger.log(date, token.name, token.orcid, req.query.state);
        console.log("creating smid for " + token.orcid);
        var orcidRecord = smidManger.createOrcidRecord(token.orcid, ooau.fullOrcid(token.orcid), token.name);
        smidManger.addOwnerOrcidRecord(orcidRecord, req.query.state, function(err, doc) {
          if (err) res.send(err)
          else {
            var collection = JSON.parse(JSON.stringify(doc, null, 2));
            var private_key = collection.private_key;
            var public_key = collection.public_key;
            res.redirect('/' + public_key + '/edit/' + private_key);
          }
        });
      }
    };
    ooau.exchangeCode(req.query.code, exchangingCallback);
  }

});

//Get collection details
app.get(COLLECTION_DETAILS, function(req, res) {
  smidManger.getDetails(req.params.publicKey, function(err, doc) {
    if (err)
      res.send(err)
    else if (doc === undefined || doc == null)
      res.sendFile(PAGE_404);
    else
      res.status(200).json(doc);
  });
});

//Get collection details
app.get(COLLECTION_DETAILS_DOWNLOAD, function(req, res) {
  smidManger.getDetails(req.params.publicKey, function(err, doc) {
    if (err)
      res.send(err)
    else if (doc === undefined || doc == null)
      res.sendFile(PAGE_404);
    else {
      try {
        var txt = smidToTxt(doc);
        res.set({
          "Content-Disposition": `attachment; filename="${doc.form.title}_tab_separated.txt"`
        });
        res.status(200).send(txt);
      } catch (e) {
        res.sendFile(PAGE_500);
      }
    }
  });
});

//Update collection details form fields
app.put(COLLECTION_DETAILS_FORM, function(req, res) {
  var data = req.body;
  smidManger.updateForm(req.params.privateKey, data.form, function(err, doc) {
    if (err) res.status(400).json({'error':err})
    else {
      res.status(200).json(doc);
    }
  });
});

// create and email smid
app.post(EMAIL_SMID, function(req, res) {
  var data = req.body;
  mailgunPub.validate(data.email, function (error, body) {
    if(body && body.is_valid) {
      console.log("email is valid");
      smidManger.createSmid(function(err, doc) {
        var mailData = {
          from: 'No Reply <noreply@share-my-id.orcid.org>',
          to: data.email,
          subject: 'Share My iD links',
          text: `Thanks for creating a ORCID iD collection.\n`
          + `\n`
          + `\n`
          + `Administration Link\n`
          + `Use this link to edit collection details: \n`
          + `${config.HOST}/${doc.public_key}/edit/${doc.private_key}\n`
          + `\n`
          + `\n`
          + `Share Link\n`
          + `Share this link with anyone whose iD you want to collect, or display this page on a laptop/tablet at your event:`
          + `${config.HOST}/${doc.public_key}`
          + `\n`
          + `\n`
          + `Thanks,\n`
          + `The Share My iD Team`
        };
        var create_smid_authorization_uri = ooau.getAuthUrl(config.HOST + CREATE_SMID_URI, doc.private_key);
        mailgunPriv.messages().send(mailData, function (error, body) {
          if (error != null) {
            console.log("mailgun error:");
            console.log(error);
            if (body != null && body.message != null && body.message.includes("Great job"))
              res.status(200).json({'email': data.email, 'redirect': create_smid_authorization_uri }); // using test credentials
            else
              res.status(400).json({'error':error, 'body': body});
          } else {
            console.log("mailgun body:");
            console.log(body);
            res.status(200).json({'email': data.email});
          }
        });
      });
    } else {
      res.status(400).json({'error':"Email failed to pass validation", 'body': body});
    }
  });
});

//Add iD oauth sign into ORCID
app.get(ADD_ID_AUTHORIZE, function(req, res) {
  var add_id_authorization_uri = ooau.getAuthUrl(config.HOST + ADD_ID_REDIRECT, req.params.publicKey);
  res.redirect(add_id_authorization_uri);
});

//Add id to collection
app.get(ADD_ID_REDIRECT, function(req, res) { // Redeem code URL
  var state = req.query.state;
  if (req.query.error == 'access_denied') {
    // User denied access
    console.log("error: " + req.query.error);
    res.redirect( /* make ADD_ID_ERROR url */ '/' + state + "/add-id-error");
  } else {
    // exchange code
    // function to render page after making request
    var exchangingCallback = function(error, token) {
      if (error != null)
        res.sendFile(PAGE_500);
      else { // No errors! we have a token :-)
        var date = new Date();
        //Log ORCID info to file
        orcidLogger.log(date, token.name, token.orcid, req.query.state);
        //state maps to smid public key
        console.log("Got user id: " + token.orcid);
        var orcidRecord = smidManger.createOrcidRecord(token.orcid, ooau.fullOrcid(token.orcid), token.name);
        smidManger.addOrcidRecord(orcidRecord, req.query.state, function(err, doc) {
          if (err) res.send(err)
          else {
            //res.redirect('/' + req.query.state);
            res.redirect( /* make ADD_ID_SUCCESS url */ '/' + state + '/orcid/' + token.orcid);
          }
        });
      }
    };
    ooau.exchangeCode(req.query.code, exchangingCallback);
  }
});

app.get([COLLECTION_EDIT], function(req, res) { // Index page
  smidManger.smidExist(req.params.publicKey, req.params.privateKey, function(err, bool) {
    if (bool == true)
      res.status(200).sendFile(index_file);
    else
      res.sendFile(PAGE_404);
  });
});

app.get([COLLECTION_SHARE, ADD_ID_SUCCESS, ADD_ID_ERROR], function(req, res) { // Index page
  smidManger.detailsExist(req.params.publicKey, function(err, bool) {
    if (bool == true)
      res.status(200).sendFile(index_file);
    else
      res.sendFile(PAGE_404);
  });
});

app.get('/', function(req, res) { // Index page
  res.status(200).sendFile(index_file);
});<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      cons<commit_msg>Fixed a typo<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      conso<|endoftext|>


<commit_before>$(function(){
    $('#map_layer_toggle').on('click', function(e){
        e.preventDefault();
        var $t = $(this), text = $t.text();
        if (text == translation_strings.map_map) {
            $t.text(translation_strings.map_satellite);
            fixmystreet.map.setBaseLayer(fixmystreet.map.layers[0]);
        } else {
            $t.text(translation_strings.map_map);
            fixmystreet.map.setBaseLayer(fixmystreet.map.layers[1]);
        }
    });
    if (typeof fixmystreet_google_default !== 'undefined' && fixmystreet_google_default == 'satellite') {
        $('#map_layer_toggle').click();
    }
});

fixmystreet.maps.config = function() {
    var permalink_id;
    if ($('#map_permalink').length) {
        permalink_id = 'map_permalink';
    }

    fixmystreet.controls = [
        new OpenLayers.Control.ArgParser(),
        new OpenLayers.Control.Navigation(),
        new OpenLayers.Control.PermalinkFMS(permalink_id),
        new OpenLayers.Control.PanZoomFMS({id: 'fms_pan_zoom' })
    ];

    fixmystreet.map_type = OpenLayers.Layer.Google;
    fixmystreet.map_options = {
        zoomDuration: 10
    };

    fixmystreet.layer_options = [
        {},
        { type: google.maps.MapTypeId.HYBRID }
    ];
};
<commit_msg>Add ability to override Google Maps road style.<commit_after>$(function(){
    $('#map_layer_toggle').on('click', function(e){
        e.preventDefault();
        var $t = $(this), text = $t.text();
        if (text == translation_strings.map_map) {
            $t.text(translation_strings.map_satellite);
            fixmystreet.map.setBaseLayer(fixmystreet.map.layers[0]);
        } else {
            $t.text(translation_strings.map_map);
            fixmystreet.map.setBaseLayer(fixmystreet.map.layers[1]);
        }
    });
    if (typeof fixmystreet_google_default !== 'undefined' && fixmystreet_google_default == 'satellite') {
        $('#map_layer_toggle').click();
    }
});

fixmystreet.maps.config = function() {
    var permalink_id;
    if ($('#map_permalink').length) {
        permalink_id = 'map_permalink';
    }

    fixmystreet.controls = [
        new OpenLayers.Control.ArgParser(),
        new OpenLayers.Control.Navigation(),
        new OpenLayers.Control.PermalinkFMS(permalink_id),
        new OpenLayers.Control.PanZoomFMS({id: 'fms_pan_zoom' })
    ];

    fixmystreet.map_type = OpenLayers.Layer.Google;
    fixmystreet.map_options = {
        zoomDuration: 10
    };

    var road_layer = {}; // Empty object defaults to standard road layer

    function apply_map_styles() {
        var styledMapType = new google.maps.StyledMapType(fixmystreet_google_maps_custom_style);
        this.mapObject.mapTypes.set('styled', styledMapType);
        this.mapObject.setMapTypeId('styled');
    }
    // If you want to apply a custom style to the road map (for example from
    // a service such as snazzymaps.com) then define that style as a top-level
    // variable called fixmystreet_google_maps_custom_style (you might have to
    // override the maps/google-ol.html template to include your own JS file)
    // and it'll automatically be applied.
    if (typeof fixmystreet_google_maps_custom_style !== 'undefined') {
        road_layer = { type: 'styled', eventListeners: { added: apply_map_styles } };
    }

    fixmystreet.layer_options = [
        road_layer,
        { type: google.maps.MapTypeId.HYBRID }
    ];
};
<|endoftext|>


<commit_before>AutoForm.addInputType("selectize", {
  template: "afSelectize",
  valueOut: function () {
    // FIXME: may be related https://github.com/aldeed/meteor-autoform/issues/569
    if (this[0].selectize) {
      return this[0].selectize.getValue();
    }
  },
  valueConverters: {
    "stringArray": function (val) {
      if (_.isArray(val)) {
        return _.map(val, function (item) {
          return $.trim(item);
        });
      }
      return val;
    },
    "number": AutoForm.Utility.stringToNumber,
    "numberArray": function (val) {
      if (_.isArray(val)) {
        return _.map(val, function (item) {
          item = $.trim(item);
          return AutoForm.Utility.stringToNumber(item);
        });
      }
      return val;
    },
    "boolean": AutoForm.Utility.stringToBool,
    "booleanArray": function (val) {
      if (_.isArray(val)) {
        return _.map(val, function (item) {
          item = $.trim(item);
          return AutoForm.Utility.stringToBool(item);
        });
      }
      return val;
    },
    "date": AutoForm.Utility.stringToDate,
    "dateArray": function (val) {
      if (_.isArray(val)) {
        return _.map(val, function (item) {
          item = $.trim(item);
          return AutoForm.Utility.stringToDate(item);
        });
      }
      return val;
    }
  },
  contextAdjust: function (context) {
    //can fix issues with some browsers selecting the firstOption instead of the selected option
    context.atts.autocomplete = 'off';

    var itemAtts = _.omit(context.atts, 'firstOption');
    var firstOption = context.atts.firstOption;

    // build items list
    context.items = [];

    // If a firstOption was provided, add that to the items list first
    if (firstOption === false) {
      // nothing
    } else if (typeof firstOption === 'string' || typeof _defaults.firstOption === "string") {
      context.items.push({
        name: context.name,
        label: (typeof firstOption === 'string' ? firstOption : _defaults.firstOption),
        value: '',
        // _id must be included because it is a special property that
        // #each uses to track unique list items when adding and removing them
        // See https://github.com/meteor/meteor/issues/2174
        //
        // Setting this to an empty string caused problems if option with value
        // 1 was in the options list because Spacebars evaluates "" to 1 and
        // considers that a duplicate.
        // See https://github.com/aldeed/meteor-autoform/issues/656
        _id: 'AUTOFORM_EMPTY_FIRST_OPTION',
        selected: false,
        // atts: itemAtts
      });
    }

    var fetchOpt = function fetchOpt(opt) {
      return {
        name: context.name,
        label: opt.label,
        value: opt.value,
        // _id must be included because it is a special property that
        // #each uses to track unique list items when adding and removing them
        // See https://github.com/meteor/meteor/issues/2174
        _id: opt.value,
        selected: _.isArray(context.value) ?
          _.includes(context.value, opt.value) : (opt.value === context.value),
        // atts: itemAtts
      };
    };

    // Add all defined options
    _.each(context.selectOptions, function(opt) {
      if (opt.optgroup) {
        context.items.push({
          optgroup: opt.optgroup,
          items: _.map(opt.options, fetchOpt)
        });
      } else {
        context.items.push(fetchOpt(opt));
      }
    });

    return context;
  }
});

Template.afSelectize.helpers({
  optionAtts: function () {
    var item = this
    var atts = {
      value: item.value
    };
    if (item.selected) {
      atts.selected = '';
    }
    return atts;
  },
  atts: function () {
    var atts = _.clone(this.atts);
    // TODO: if (style == 'bootstrap3') ...
    // Add bootstrap class
    atts = AutoForm.Utility.addClass(atts, 'form-control');
    delete atts.selectizeOptions;
    delete atts.isReactiveOptions;
    return atts;
  },
  isReactiveOptions: function () {
    var isReactiveOptions;
    if (_.has(this.atts, 'isReactiveOptions')) {
      isReactiveOptions = this.atts.isReactiveOptions;
    } else {
      isReactiveOptions = _defaults.isReactiveOptions;
    }
    return isReactiveOptions;
  }
});

Template.afSelectize.events({
  "click .selectized": function (event) {
    // TODO: https://github.com/selectize/selectize.js/issues/658
    $(event.toElement).next().children(":first-child").children("input:first").focus();
  }
});

Template.afSelectize.rendered = function () {
  var selectizeOptions = this.data.atts.selectizeOptions || {};
  // selectize rearranges one option from the middle of the list
  // https://github.com/selectize/selectize.js/issues/640#issuecomment-71788203
  if (!selectizeOptions.sortField) {
    selectizeOptions.sortField = 'text';
  }
  // instanciate selectize
  this.$('select').selectize(selectizeOptions);

  var isReactiveOptions;
  if (_.has(this.data.atts, 'isReactiveOptions')) {
    isReactiveOptions = this.data.atts.isReactiveOptions;
  } else {
    isReactiveOptions = _defaults.isReactiveOptions;
  }

  if (isReactiveOptions) {
    var test = false;
    var selectize = this.$('select')[0].selectize;
    this.autorun(function () {
      var items = Template.currentData().items;
      // FIXED double autorun
      test = !test;
      if (test) {
        _refreshSelectizeOptions(selectize, items);
      }
    });
  }
};

Template.afSelectize.destroyed = function () {
  this.$('select')[0].selectize.destroy();
};

var _defaults = {
  firstOption: 'Select an option',
  isReactiveOptions: false
};

AutoForm.Selectize = {};
AutoForm.Selectize.setDefaults = function (o) {
  if (_.has(o, 'firstOption')) {
    _defaults.firstOption = o.firstOption;
  }
  if (_.has(o, 'isReactiveOptions')) {
    _defaults.isReactiveOptions = o.isReactiveOptions;
  }
}

var _refreshSelectizeOptions = function (selectize, options) {
  var items = selectize.items;

  selectize.clearOptions();

  _.each(options, function (option) {
    if (option.optgroup) {
      selectize.addOptionGroup(option.optgroup, {label: option.optgroup});
      _.each(option.items, function (groupOption) {
        selectize.addOption({value: groupOption.value, text: groupOption.label, optgroup: option.optgroup});
        if (groupOption.selected) {
          selectize.addItem(groupOption.value, true);
        }
      });
    } else if (option.value) {
      selectize.addOption({value: option.value, text: option.label});
      if (option.selected) {
        selectize.addItem(option.value, true);
      }
    }
  });

  _.each(items, function (item) {
    selectize.addItem(item, true);
  });
};
<commit_msg>TODO may be firstRun<commit_after>AutoForm.addInputType("selectize", {
  template: "afSelectize",
  valueOut: function () {
    // FIXME: may be related https://github.com/aldeed/meteor-autoform/issues/569
    if (this[0].selectize) {
      return this[0].selectize.getValue();
    }
  },
  valueConverters: {
    "stringArray": function (val) {
      if (_.isArray(val)) {
        return _.map(val, function (item) {
          return $.trim(item);
        });
      }
      return val;
    },
    "number": AutoForm.Utility.stringToNumber,
    "numberArray": function (val) {
      if (_.isArray(val)) {
        return _.map(val, function (item) {
          item = $.trim(item);
          return AutoForm.Utility.stringToNumber(item);
        });
      }
      return val;
    },
    "boolean": AutoForm.Utility.stringToBool,
    "booleanArray": function (val) {
      if (_.isArray(val)) {
        return _.map(val, function (item) {
          item = $.trim(item);
          return AutoForm.Utility.stringToBool(item);
        });
      }
      return val;
    },
    "date": AutoForm.Utility.stringToDate,
    "dateArray": function (val) {
      if (_.isArray(val)) {
        return _.map(val, function (item) {
          item = $.trim(item);
          return AutoForm.Utility.stringToDate(item);
        });
      }
      return val;
    }
  },
  contextAdjust: function (context) {
    //can fix issues with some browsers selecting the firstOption instead of the selected option
    context.atts.autocomplete = 'off';

    var itemAtts = _.omit(context.atts, 'firstOption');
    var firstOption = context.atts.firstOption;

    // build items list
    context.items = [];

    // If a firstOption was provided, add that to the items list first
    if (firstOption === false) {
      // nothing
    } else if (typeof firstOption === 'string' || typeof _defaults.firstOption === "string") {
      context.items.push({
        name: context.name,
        label: (typeof firstOption === 'string' ? firstOption : _defaults.firstOption),
        value: '',
        // _id must be included because it is a special property that
        // #each uses to track unique list items when adding and removing them
        // See https://github.com/meteor/meteor/issues/2174
        //
        // Setting this to an empty string caused problems if option with value
        // 1 was in the options list because Spacebars evaluates "" to 1 and
        // considers that a duplicate.
        // See https://github.com/aldeed/meteor-autoform/issues/656
        _id: 'AUTOFORM_EMPTY_FIRST_OPTION',
        selected: false,
        // atts: itemAtts
      });
    }

    var fetchOpt = function fetchOpt(opt) {
      return {
        name: context.name,
        label: opt.label,
        value: opt.value,
        // _id must be included because it is a special property that
        // #each uses to track unique list items when adding and removing them
        // See https://github.com/meteor/meteor/issues/2174
        _id: opt.value,
        selected: _.isArray(context.value) ?
          _.includes(context.value, opt.value) : (opt.value === context.value),
        // atts: itemAtts
      };
    };

    // Add all defined options
    _.each(context.selectOptions, function(opt) {
      if (opt.optgroup) {
        context.items.push({
          optgroup: opt.optgroup,
          items: _.map(opt.options, fetchOpt)
        });
      } else {
        context.items.push(fetchOpt(opt));
      }
    });

    return context;
  }
});

Template.afSelectize.helpers({
  optionAtts: function () {
    var item = this
    var atts = {
      value: item.value
    };
    if (item.selected) {
      atts.selected = '';
    }
    return atts;
  },
  atts: function () {
    var atts = _.clone(this.atts);
    // TODO: if (style == 'bootstrap3') ...
    // Add bootstrap class
    atts = AutoForm.Utility.addClass(atts, 'form-control');
    delete atts.selectizeOptions;
    delete atts.isReactiveOptions;
    return atts;
  },
  isReactiveOptions: function () {
    var isReactiveOptions;
    if (_.has(this.atts, 'isReactiveOptions')) {
      isReactiveOptions = this.atts.isReactiveOptions;
    } else {
      isReactiveOptions = _defaults.isReactiveOptions;
    }
    return isReactiveOptions;
  }
});

Template.afSelectize.events({
  "click .selectized": function (event) {
    // TODO: https://github.com/selectize/selectize.js/issues/658
    $(event.toElement).next().children(":first-child").children("input:first").focus();
  }
});

Template.afSelectize.rendered = function () {
  var selectizeOptions = this.data.atts.selectizeOptions || {};
  // selectize rearranges one option from the middle of the list
  // https://github.com/selectize/selectize.js/issues/640#issuecomment-71788203
  if (!selectizeOptions.sortField) {
    selectizeOptions.sortField = 'text';
  }
  // instanciate selectize
  this.$('select').selectize(selectizeOptions);

  var isReactiveOptions;
  if (_.has(this.data.atts, 'isReactiveOptions')) {
    isReactiveOptions = this.data.atts.isReactiveOptions;
  } else {
    isReactiveOptions = _defaults.isReactiveOptions;
  }

  if (isReactiveOptions) {
    var test = false;
    var selectize = this.$('select')[0].selectize;
    this.autorun(function () {
      var items = Template.currentData().items;
      // FIXED double autorun
      // TODO may be computation.firstRun?
      test = !test;
      if (test) {
        console.log('test', items);
        _refreshSelectizeOptions(selectize, items);
      }
    });
  }
};

Template.afSelectize.destroyed = function () {
  this.$('select')[0].selectize.destroy();
};

var _defaults = {
  firstOption: 'Select an option',
  isReactiveOptions: false
};

AutoForm.Selectize = {};
AutoForm.Selectize.setDefaults = function (o) {
  if (_.has(o, 'firstOption')) {
    _defaults.firstOption = o.firstOption;
  }
  if (_.has(o, 'isReactiveOptions')) {
    _defaults.isReactiveOptions = o.isReactiveOptions;
  }
}

var _refreshSelectizeOptions = function (selectize, options) {
  var items = selectize.items;

  selectize.clearOptions();

  _.each(options, function (option) {
    if (option.optgroup) {
      selectize.addOptionGroup(option.optgroup, {label: option.optgroup});
      _.each(option.items, function (groupOption) {
        selectize.addOption({value: groupOption.value, text: groupOption.label, optgroup: option.optgroup});
        if (groupOption.selected) {
          selectize.addItem(groupOption.value, true);
        }
      });
    } else if (option.value) {
      selectize.addOption({value: option.value, text: option.label});
      if (option.selected) {
        selectize.addItem(option.value, true);
      }
    }
  });

  _.each(items, function (item) {
    selectize.addItem(item, true);
  });
};
<|endoftext|>


<commit_before>/*eslint no-undef: "off"*/
/* eslint import/no-extraneous-dependencies: "off" */

import React from 'react';
import {shallow} from 'enzyme';
import Footer from "../Footer";

describe('Footer', () => {
  function setup() {
    return shallow(<Footer />);
  }

  it('should render top level div with className "footer-container"',() => {
    const divElement = setup().find('div').first();
    expect(divElement.hasClass("footer-container")).toBeTruthy();
  });

  it('should contain 1 SocialMediaLinkList element',() => {
    const forumList = setup().find('Connect(SocialMediaLinkList)');
    expect(forumList.length).toEqual(1);
  });
});
<commit_msg>fix uncleared variable name in test<commit_after>/*eslint no-undef: "off"*/
/* eslint import/no-extraneous-dependencies: "off" */

import React from 'react';
import {shallow} from 'enzyme';
import Footer from "../Footer";

describe('Footer', () => {
  function setup() {
    return shallow(<Footer />);
  }

  it('should render top level div with className "footer-container"',() => {
    const divElement = setup().find('div').first();
    expect(divElement.hasClass("footer-container")).toBeTruthy();
  });

  it('should contain 1 SocialMediaLinkList element',() => {
    const socialMediaLinkListElement = setup().find('Connect(SocialMediaLinkList)');
    expect(socialMediaLinkListElement.length).toEqual(1);
  });
});
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
const packageConfig = require('./package');

const importCoreModules = [];
Object.entries(packageConfig.dependencies).forEach(([pkg]) => {
  if (/@superset-ui/.test(pkg)) {
    importCoreModules.push(pkg);
  }
});

// ignore files in production mode
let ignorePatterns = [];
if (process.env.NODE_ENV === 'production') {
  ignorePatterns = [
    '*.test.{js,ts,jsx,tsx}',
    'plugins/**/test/**/*',
    'packages/**/test/**/*',
    'packages/generator-superset/**/*',
  ];
}

module.exports = {
  extends: [
    'airbnb',
    'prettier',
    'prettier/react',
    'plugin:react-hooks/recommended',
  ],
  parser: '@babel/eslint-parser',
  parserOptions: {
    ecmaFeatures: {
      experimentalObjectRestSpread: true,
    },
  },
  env: {
    browser: true,
    node: true,
  },
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
        // resolve modules from `/superset_frontend/node_modules` and `/superset_frontend`
        moduleDirectory: ['node_modules', '.'],
      },
    },
    // only allow import from top level of module
    'import/core-modules': importCoreModules,
    react: {
      version: 'detect',
    },
  },
  plugins: [
    'prettier',
    'react',
    'file-progress',
    'theme-colors',
    'translation-vars',
  ],
  overrides: [
    {
      files: ['*.ts', '*.tsx'],
      parser: '@typescript-eslint/parser',
      extends: [
        'airbnb',
        'plugin:@typescript-eslint/recommended',
        'prettier',
        'prettier/@typescript-eslint',
        'prettier/react',
      ],
      plugins: ['@typescript-eslint/eslint-plugin', 'prettier', 'react'],
      rules: {
        '@typescript-eslint/ban-ts-ignore': 0,
        '@typescript-eslint/ban-ts-comment': 0, // disabled temporarily
        '@typescript-eslint/ban-types': 0, // disabled temporarily
        '@typescript-eslint/no-empty-function': 0,
        '@typescript-eslint/no-explicit-any': 0,
        '@typescript-eslint/no-use-before-define': 1, // disabled temporarily
        '@typescript-eslint/no-non-null-assertion': 0, // disabled temporarily
        '@typescript-eslint/explicit-function-return-type': 0,
        '@typescript-eslint/explicit-module-boundary-types': 0, // re-enable up for discussion
        camelcase: 0,
        'class-methods-use-this': 0,
        'func-names': 0,
        'guard-for-in': 0,
        'import/no-cycle': 0, // re-enable up for discussion, might require some major refactors
        'import/extensions': [
          'error',
          {
            '.ts': 'always',
            '.tsx': 'always',
            '.json': 'always',
          },
        ],
        'import/no-named-as-default-member': 0,
        'import/prefer-default-export': 0,
        indent: 0,
        'jsx-a11y/anchor-is-valid': 1,
        'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion
        'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion
        'new-cap': 0,
        'no-bitwise': 0,
        'no-continue': 0,
        'no-mixed-operators': 0,
        'no-multi-assign': 0,
        'no-multi-spaces': 0,
        'no-nested-ternary': 0,
        'no-prototype-builtins': 0,
        'no-restricted-properties': 0,
        'no-shadow': 0, // re-enable up for discussion
        'no-use-before-define': 0, // disabled temporarily
        'padded-blocks': 0,
        'prefer-arrow-callback': 0,
        'prefer-destructuring': ['error', { object: true, array: false }],
        'react/destructuring-assignment': 0, // re-enable up for discussion
        'react/forbid-prop-types': 0,
        'react/jsx-filename-extension': [1, { extensions: ['.jsx', '.tsx'] }],
        'react/jsx-fragments': 1,
        'react/jsx-no-bind': 0,
        'react/jsx-props-no-spreading': 0, // re-enable up for discussion
        'react/no-array-index-key': 0,
        'react/no-string-refs': 0,
        'react/no-unescaped-entities': 0,
        'react/no-unused-prop-types': 0,
        'react/prop-types': 0,
        'react/require-default-props': 0,
        'react/sort-comp': 0, // TODO: re-enable in separate PR
        'react/static-property-placement': 0, // re-enable up for discussion
        'prettier/prettier': 'error',
        'file-progress/activate': 1,
      },
      settings: {
        'import/resolver': {
          typescript: {},
        },
        react: {
          version: 'detect',
        },
      },
    },
    {
      files: [
        '*.test.ts',
        '*.test.tsx',
        '*.test.js',
        '*.test.jsx',
        '*.stories.tsx',
        '*.stories.jsx',
        'fixtures.*',
      ],
      excludedFiles: 'cypress-base/cypress/**/*',
      plugins: ['jest', 'jest-dom', 'no-only-tests', 'testing-library'],
      env: {
        'jest/globals': true,
      },
      settings: {
        jest: {
          version: 'detect',
        },
      },
      extends: [
        'plugin:jest/recommended',
        'plugin:jest-dom/recommended',
        'plugin:testing-library/react',
      ],
      rules: {
        'import/no-extraneous-dependencies': [
          'error',
          { devDependencies: true },
        ],
        'no-only-tests/no-only-tests': 'error',
        'max-classes-per-file': 0,
      },
    },
    {
      files: [
        '*.test.ts',
        '*.test.tsx',
        '*.test.js',
        '*.test.jsx',
        '*.stories.tsx',
        '*.stories.jsx',
        'fixtures.*',
        'cypress-base/cypress/**/*',
        'Stories.tsx',
        'packages/superset-ui-core/src/style/index.tsx',
      ],
      rules: {
        'theme-colors/no-literal-colors': 0,
        'translation-vars/no-template-vars': 0,
        'no-restricted-imports': 0,
      },
    },
  ],
  rules: {
    'theme-colors/no-literal-colors': 1,
    'translation-vars/no-template-vars': ['error', true],
    camelcase: [
      'error',
      {
        allow: ['^UNSAFE_'],
        properties: 'never',
      },
    ],
    'class-methods-use-this': 0,
    curly: 2,
    'func-names': 0,
    'guard-for-in': 0,
    'import/extensions': [
      'error',
      {
        '.js': 'always',
        '.jsx': 'always',
        '.ts': 'always',
        '.tsx': 'always',
        '.json': 'always',
      },
    ],
    'import/no-cycle': 0, // re-enable up for discussion, might require some major refactors
    'import/prefer-default-export': 0,
    indent: 0,
    'jsx-a11y/anchor-is-valid': 1,
    'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion
    'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion
    'new-cap': 0,
    'no-bitwise': 0,
    'no-continue': 0,
    'no-mixed-operators': 0,
    'no-multi-assign': 0,
    'no-multi-spaces': 0,
    'no-nested-ternary': 0,
    'no-prototype-builtins': 0,
    'no-restricted-properties': 0,
    'no-restricted-imports': [
      'warn',
      {
        paths: [
          {
            name: 'antd',
            message:
              'Please import Ant components from the index of src/components',
          },
          {
            name: '@superset-ui/core',
            importNames: ['supersetTheme'],
            message:
              'Please use the theme directly from the ThemeProvider rather than importing supersetTheme.',
          },
        ],
      },
    ],
    'no-shadow': 0, // re-enable up for discussion
    'padded-blocks': 0,
    'prefer-arrow-callback': 0,
    'prefer-object-spread': 1,
    'prefer-destructuring': ['error', { object: true, array: false }],
    'react/destructuring-assignment': 0, // re-enable up for discussion
    'react/forbid-prop-types': 0,
    'react/jsx-filename-extension': [1, { extensions: ['.jsx', '.tsx'] }],
    'react/jsx-fragments': 1,
    'react/jsx-no-bind': 0,
    'react/jsx-props-no-spreading': 0, // re-enable up for discussion
    'react/no-array-index-key': 0,
    'react/no-string-refs': 0,
    'react/no-unescaped-entities': 0,
    'react/no-unused-prop-types': 0,
    'react/prop-types': 0,
    'react/require-default-props': 0,
    'react/sort-comp': 0, // TODO: re-enable in separate PR
    'react/static-property-placement': 0, // disabled temporarily
    'prettier/prettier': 'error',
  },
  ignorePatterns,
};
<commit_msg>chore: Changes the no-literal-colors lint rule to throw errors instead of warnings (#20034)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
const packageConfig = require('./package');

const importCoreModules = [];
Object.entries(packageConfig.dependencies).forEach(([pkg]) => {
  if (/@superset-ui/.test(pkg)) {
    importCoreModules.push(pkg);
  }
});

// ignore files in production mode
let ignorePatterns = [];
if (process.env.NODE_ENV === 'production') {
  ignorePatterns = [
    '*.test.{js,ts,jsx,tsx}',
    'plugins/**/test/**/*',
    'packages/**/test/**/*',
    'packages/generator-superset/**/*',
  ];
}

module.exports = {
  extends: [
    'airbnb',
    'prettier',
    'prettier/react',
    'plugin:react-hooks/recommended',
  ],
  parser: '@babel/eslint-parser',
  parserOptions: {
    ecmaFeatures: {
      experimentalObjectRestSpread: true,
    },
  },
  env: {
    browser: true,
    node: true,
  },
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
        // resolve modules from `/superset_frontend/node_modules` and `/superset_frontend`
        moduleDirectory: ['node_modules', '.'],
      },
    },
    // only allow import from top level of module
    'import/core-modules': importCoreModules,
    react: {
      version: 'detect',
    },
  },
  plugins: [
    'prettier',
    'react',
    'file-progress',
    'theme-colors',
    'translation-vars',
  ],
  overrides: [
    {
      files: ['*.ts', '*.tsx'],
      parser: '@typescript-eslint/parser',
      extends: [
        'airbnb',
        'plugin:@typescript-eslint/recommended',
        'prettier',
        'prettier/@typescript-eslint',
        'prettier/react',
      ],
      plugins: ['@typescript-eslint/eslint-plugin', 'prettier', 'react'],
      rules: {
        '@typescript-eslint/ban-ts-ignore': 0,
        '@typescript-eslint/ban-ts-comment': 0, // disabled temporarily
        '@typescript-eslint/ban-types': 0, // disabled temporarily
        '@typescript-eslint/no-empty-function': 0,
        '@typescript-eslint/no-explicit-any': 0,
        '@typescript-eslint/no-use-before-define': 1, // disabled temporarily
        '@typescript-eslint/no-non-null-assertion': 0, // disabled temporarily
        '@typescript-eslint/explicit-function-return-type': 0,
        '@typescript-eslint/explicit-module-boundary-types': 0, // re-enable up for discussion
        camelcase: 0,
        'class-methods-use-this': 0,
        'func-names': 0,
        'guard-for-in': 0,
        'import/no-cycle': 0, // re-enable up for discussion, might require some major refactors
        'import/extensions': [
          'error',
          {
            '.ts': 'always',
            '.tsx': 'always',
            '.json': 'always',
          },
        ],
        'import/no-named-as-default-member': 0,
        'import/prefer-default-export': 0,
        indent: 0,
        'jsx-a11y/anchor-is-valid': 1,
        'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion
        'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion
        'new-cap': 0,
        'no-bitwise': 0,
        'no-continue': 0,
        'no-mixed-operators': 0,
        'no-multi-assign': 0,
        'no-multi-spaces': 0,
        'no-nested-ternary': 0,
        'no-prototype-builtins': 0,
        'no-restricted-properties': 0,
        'no-shadow': 0, // re-enable up for discussion
        'no-use-before-define': 0, // disabled temporarily
        'padded-blocks': 0,
        'prefer-arrow-callback': 0,
        'prefer-destructuring': ['error', { object: true, array: false }],
        'react/destructuring-assignment': 0, // re-enable up for discussion
        'react/forbid-prop-types': 0,
        'react/jsx-filename-extension': [1, { extensions: ['.jsx', '.tsx'] }],
        'react/jsx-fragments': 1,
        'react/jsx-no-bind': 0,
        'react/jsx-props-no-spreading': 0, // re-enable up for discussion
        'react/no-array-index-key': 0,
        'react/no-string-refs': 0,
        'react/no-unescaped-entities': 0,
        'react/no-unused-prop-types': 0,
        'react/prop-types': 0,
        'react/require-default-props': 0,
        'react/sort-comp': 0, // TODO: re-enable in separate PR
        'react/static-property-placement': 0, // re-enable up for discussion
        'prettier/prettier': 'error',
        'file-progress/activate': 1,
      },
      settings: {
        'import/resolver': {
          typescript: {},
        },
        react: {
          version: 'detect',
        },
      },
    },
    {
      files: [
        '*.test.ts',
        '*.test.tsx',
        '*.test.js',
        '*.test.jsx',
        '*.stories.tsx',
        '*.stories.jsx',
        'fixtures.*',
      ],
      excludedFiles: 'cypress-base/cypress/**/*',
      plugins: ['jest', 'jest-dom', 'no-only-tests', 'testing-library'],
      env: {
        'jest/globals': true,
      },
      settings: {
        jest: {
          version: 'detect',
        },
      },
      extends: [
        'plugin:jest/recommended',
        'plugin:jest-dom/recommended',
        'plugin:testing-library/react',
      ],
      rules: {
        'import/no-extraneous-dependencies': [
          'error',
          { devDependencies: true },
        ],
        'no-only-tests/no-only-tests': 'error',
        'max-classes-per-file': 0,
      },
    },
    {
      files: [
        '*.test.ts',
        '*.test.tsx',
        '*.test.js',
        '*.test.jsx',
        '*.stories.tsx',
        '*.stories.jsx',
        'fixtures.*',
        'cypress-base/cypress/**/*',
        'Stories.tsx',
        'packages/superset-ui-core/src/style/index.tsx',
      ],
      rules: {
        'theme-colors/no-literal-colors': 0,
        'translation-vars/no-template-vars': 0,
        'no-restricted-imports': 0,
      },
    },
  ],
  rules: {
    'theme-colors/no-literal-colors': 'error',
    'translation-vars/no-template-vars': ['error', true],
    camelcase: [
      'error',
      {
        allow: ['^UNSAFE_'],
        properties: 'never',
      },
    ],
    'class-methods-use-this': 0,
    curly: 2,
    'func-names': 0,
    'guard-for-in': 0,
    'import/extensions': [
      'error',
      {
        '.js': 'always',
        '.jsx': 'always',
        '.ts': 'always',
        '.tsx': 'always',
        '.json': 'always',
      },
    ],
    'import/no-cycle': 0, // re-enable up for discussion, might require some major refactors
    'import/prefer-default-export': 0,
    indent: 0,
    'jsx-a11y/anchor-is-valid': 1,
    'jsx-a11y/click-events-have-key-events': 0, // re-enable up for discussion
    'jsx-a11y/mouse-events-have-key-events': 0, // re-enable up for discussion
    'new-cap': 0,
    'no-bitwise': 0,
    'no-continue': 0,
    'no-mixed-operators': 0,
    'no-multi-assign': 0,
    'no-multi-spaces': 0,
    'no-nested-ternary': 0,
    'no-prototype-builtins': 0,
    'no-restricted-properties': 0,
    'no-restricted-imports': [
      'warn',
      {
        paths: [
          {
            name: 'antd',
            message:
              'Please import Ant components from the index of src/components',
          },
          {
            name: '@superset-ui/core',
            importNames: ['supersetTheme'],
            message:
              'Please use the theme directly from the ThemeProvider rather than importing supersetTheme.',
          },
        ],
      },
    ],
    'no-shadow': 0, // re-enable up for discussion
    'padded-blocks': 0,
    'prefer-arrow-callback': 0,
    'prefer-object-spread': 1,
    'prefer-destructuring': ['error', { object: true, array: false }],
    'react/destructuring-assignment': 0, // re-enable up for discussion
    'react/forbid-prop-types': 0,
    'react/jsx-filename-extension': [1, { extensions: ['.jsx', '.tsx'] }],
    'react/jsx-fragments': 1,
    'react/jsx-no-bind': 0,
    'react/jsx-props-no-spreading': 0, // re-enable up for discussion
    'react/no-array-index-key': 0,
    'react/no-string-refs': 0,
    'react/no-unescaped-entities': 0,
    'react/no-unused-prop-types': 0,
    'react/prop-types': 0,
    'react/require-default-props': 0,
    'react/sort-comp': 0, // TODO: re-enable in separate PR
    'react/static-property-placement': 0, // disabled temporarily
    'prettier/prettier': 'error',
  },
  ignorePatterns,
};
<|endoftext|>