<commit_before>var express    = require('express'),
    flatten    = require('flatten').flatten,
    hogan      = require('hogan.js'),
    gobo       = require('gobo'),
    path       = require('path'),
    fs         = require('fs'),
    app        = express(),
    errors     = require('./errors'),
    options    = require('./config'),
    store      = require('./store')(options.store),
    models     = require('./models'),
    handlers   = require('./handlers'),
    middleware = require('./middleware'),
    binHandler = new handlers.BinHandler(),
    sessionHandler = new handlers.SessionHandler(),
    flattened;

app.store  = store;
app.models = models.createModels(store);
app.templates = {};

app.PRODUCTION  = 'production';
app.DEVELOPMENT = 'development';

// Apply the keys from the config file. All nested properties are
// space delimited to match the express style.
//
// For example, app.set('url prefix'); //=> '/'
flattened = flatten(options, ' ');
Object.getOwnPropertyNames(flattened).forEach(function (key) {
  app.set(key, flattened[key]);
});

app.set('root', path.resolve(path.join(__dirname, '..')));
app.set('version', require('../package').version);
app.set('url full', (options.url.ssl ? 'https://' : 'http://') + options.url.host + options.url.prefix);

// Register all the middleware.
app.use(express.logger());
app.use(express.static(path.join(app.set('root'), 'public')));
app.use(express.cookieParser(app.set('session secret')));
app.use(express.cookieSession({key: 'jsbin'}));
app.use(express.bodyParser());
app.use(express.csrf());
app.use(middleware.noslashes());
app.use(middleware.ajax());
app.use(middleware.cors());
app.use(middleware.jsonp());
app.use(middleware.helpers(app));

// Create a Hogan/Mustache handler for templates.
app.engine('html', function (path, options, fn) {
  fs.readFile(path, 'utf8', function (err, template) {
    if (err) {
      return fn(err);
    }

    try {
      var compiled = app.templates[path];
      if (!compiled) {
        compiled = app.templates[path] = hogan.compile(template);
      }

      fn(null, compiled.render(options));
    } catch (error) {
      fn(error);
    }
  });
});

// Configure the template engine.
app.set('view engine', 'html');
app.set('views', path.join(app.set('root'), 'views'));

// Define some generic template variables.
app.locals({
  root: app.set('url full'),
  version: app.set('version')
});

// Load the bin from the store when encountered in the url. Also handles the
// "latest" url action.
app.param('bin', binHandler.loadBin);

// Set up the routes.
app.get('/', binHandler.getDefault);

// Login/Create account.
app.post('/sethome', sessionHandler.loadUser, sessionHandler.loginUser, sessionHandler.createUser);
app.post('/logout', sessionHandler.logoutUser);

// List
app.get('/list', binHandler.getUserBins);

// Latest
app.get('/:bin/latest((.|\/):format)?', binHandler.redirectToLatest);
app.get('/:bin/latest/edit', binHandler.redirectToLatest);

// Edit
app.get('/:bin/:rev?/edit', binHandler.getBin);

// Save
app.post('/save', binHandler.createBin);
app.post('/:bin/:rev?/save', binHandler.createRevision);

// Source
app.get('/:bin/:rev?/source', binHandler.getBinSource);
app.get('/:bin/:rev?.:format(js|json|css|html)', binHandler.getBinSourceFile);
app.get('/:bin/:rev?/:format(js)', function (req, res) {
  // Redirect legacy /js suffix to the new .js extension.
  res.redirect(301, req.path.replace(/\/js$/, '.js'));
});

// Preview<commit_msg>Add download endpoint<commit_after>var express    = require('express'),
    flatten    = require('flatten').flatten,
    hogan      = require('hogan.js'),
    gobo       = require('gobo'),
    path       = require('path'),
    fs         = require('fs'),
    app        = express(),
    errors     = require('./errors'),
    options    = require('./config'),
    store      = require('./store')(options.store),
    models     = require('./models'),
    handlers   = require('./handlers'),
    middleware = require('./middleware'),
    binHandler = new handlers.BinHandler(),
    sessionHandler = new handlers.SessionHandler(),
    flattened;

app.store  = store;
app.models = models.createModels(store);
app.templates = {};

app.PRODUCTION  = 'production';
app.DEVELOPMENT = 'development';

// Apply the keys from the config file. All nested properties are
// space delimited to match the express style.
//
// For example, app.set('url prefix'); //=> '/'
flattened = flatten(options, ' ');
Object.getOwnPropertyNames(flattened).forEach(function (key) {
  app.set(key, flattened[key]);
});

app.set('root', path.resolve(path.join(__dirname, '..')));
app.set('version', require('../package').version);
app.set('url full', (options.url.ssl ? 'https://' : 'http://') + options.url.host + options.url.prefix);

// Register all the middleware.
app.use(express.logger());
app.use(express.static(path.join(app.set('root'), 'public')));
app.use(express.cookieParser(app.set('session secret')));
app.use(express.cookieSession({key: 'jsbin'}));
app.use(express.bodyParser());
app.use(express.csrf());
app.use(middleware.noslashes());
app.use(middleware.ajax());
app.use(middleware.cors());
app.use(middleware.jsonp());
app.use(middleware.helpers(app));

// Create a Hogan/Mustache handler for templates.
app.engine('html', function (path, options, fn) {
  fs.readFile(path, 'utf8', function (err, template) {
    if (err) {
      return fn(err);
    }

    try {
      var compiled = app.templates[path];
      if (!compiled) {
        compiled = app.templates[path] = hogan.compile(template);
      }

      fn(null, compiled.render(options));
    } catch (error) {
      fn(error);
    }
  });
});

// Configure the template engine.
app.set('view engine', 'html');
app.set('views', path.join(app.set('root'), 'views'));

// Define some generic template variables.
app.locals({
  root: app.set('url full'),
  version: app.set('version')
});

// Load the bin from the store when encountered in the url. Also handles the
// "latest" url action.
app.param('bin', binHandler.loadBin);

// Set up the routes.
app.get('/', binHandler.getDefault);

// Login/Create account.
app.post('/sethome', sessionHandler.loadUser, sessionHandler.loginUser, sessionHandler.createUser);
app.post('/logout', sessionHandler.logoutUser);

// List
app.get('/list', binHandler.getUserBins);

// Latest
app.get('/:bin/latest((.|\/):format)?', binHandler.redirectToLatest);
app.get('/:bin/latest/edit', binHandler.redirectToLatest);

// Edit
app.get('/:bin/:rev?/edit', binHandler.getBin);

// Save
app.post('/save', binHandler.createBin);
app.post('/:bin/:rev?/save', binHandler.createRevision);

// Download
app.post('/download', binHandler.downloadBin);

// Source
app.get('/:bin/:rev?/source', binHandler.getBinSource);
app.get('/:bin/:rev?.:format(js|json|css|html)', binHandler.getBinSourceFile);
app.get('/:bin/:rev?/:format(js)', function (req, res) {
  // Redirect legacy /js suffix to the new .js extension.
  res.redirect(301, req.path.replace(/\/js$/, '.js'));
});

// Preview
{'fraction_non_alphanumeric': 0.19775376741541087, 'fraction_numerical': 0.0011373329542223485, 'mean_word_length': 3.8752598752598755, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2161834', 'n_tokens_mistral': 2268, 'n_tokens_neox': 2257, 'n_words': 456}