<commit_before>"use strict";

require('es6-collections');

var yaml = require('js-yaml');
var fs = Promise.promisifyAll(require('fs'));
var util = require('util');

var swaggerRouter = require('swagger-router');
var Node = swaggerRouter.Node;
var URI = swaggerRouter.URI;
var SwaggerRouter = swaggerRouter.Router;

function Router (options) {
    this._options = options || {};
    this._nodes = new Map();
    this._modules = new Map();
    this.router = new SwaggerRouter();
}

Router.prototype._readSpec = function(path) {
    // XXX: make the spec path configurable?
    var fsPath = __dirname + '/../specs/' + path + '.yaml';
    // Let errors bubble up for now. Fail loud & early.
    return fs.readFileAsync(fsPath)
    .then(function(yamlString) {
        return yaml.safeLoad(yamlString);
    });
};

// Extend an existing route tree with a new path by walking the existing tree
// and inserting new subtrees at the desired location.
Router.prototype._buildPath = function route(node, path) {
    var params = {};
    for (var i = 0; i < path.length; i++) {
        var nextNode = node.getChild(path[i], params);
        if (!nextNode) {
            nextNode = new Node();
            node.setChild(path[i], nextNode);
            node = nextNode;
        } else {
            node = nextNode;
        }
    }
    return node;
};

Router.prototype._loadModule = function (modDef, symbols) {
    var self = this;
    var loadPath;
    // determine the module's load path
    switch (modDef.type) {
        case 'file':
            if (modDef.path && /^\//.test(modDef.path)) {
                // absolute path
                loadPath = modDef.path;
            } else {
                // relative path or missing
                loadPath = __dirname + '/../mods/';
                if (modDef.path) {
                    // the path has been provided, use it
                    loadPath += modDef.path;
                } else {
                    // no path given, so assume the file
                    // name matches the module name
                    loadPath += modDef.name;
                }
            }
            break;
        case 'npm':
            loadPath = modDef.name;
            break;
        default:
            throw new Error('unknown module type ' + modDef.type + ' (for module ' + modDef.name + ').');
    }
    // append the log property to module options, if it is not present
    modDef.options = modDef.options || {};
    if (!modDef.options.log) {
        modDef.options.log = this._options.log || function() {};
    }
    // let the error propagate in case the module cannot be loaded
    var modObj = require(loadPath);
    if (!modObj) {
        return Promise.reject("Loading module " + loadPath + " failed.");
    }
    // Call if it's a function
    if (modObj instanceof Function) {
        modObj = modObj(modDef.options);
    }
    if (!(modObj instanceof Promise)) {
        // wrap
        modObj = Promise.resolve(modObj);
    }
    return modObj.then(function(mod) {
        //console.log(loadPath, mod);
        self._modules.set(modDef, mod);
        Object.keys(mod).forEach(function(symbol) {
            // check for duplicate symbols
            if (symbol === 'module_info') {
                // skip the module info, as it should
                // be exported by each module
                return;
            } else if (symbols[symbol]) {
                throw new Error("Duplicate symbol " + symbol + " in module " + modDef.name);
            } else {
                symbols[symbol] = mod[symbol];
            }
        });
        return mod;
    });
};

function makeRequestTemplate(spec) {
    var uri = new URI(spec.uri, {}, true);
    return function (restbase, req) {
        // FIXME:
        // - Better way to get a URI clone with parameters expanded, without
        //   going via a string.
        // - Template other request parts
        return restbase.request({
            uri: new URI(uri.bind(req.params)).toString(),
            method: req.method,
            body: req.body,
            headers: req.headers,
            query: req.query
        });
    };
};

// handle one spec path
Router.prototype._handleRESTBasePathSpec = function(node, subspec, symbols, uri) {
    var self = this;
    var xrb = subspec['x-restbase'];
    var xRestbasePromise;
    if (xrb) {
        symbols = symbols || {};
        xRestbasePromise = Promise.all(
            // modules
            (xrb.modules || []).map(function(m) {
                // load each module
                // Share modules
                if (!self._modules.has(m)) {
                    return self._loadModule(m, symbols)
                    .then(function(module) {
                        //console.log(module);
                        if (module && module.module_info && module.module_info.resources) {
                            node.value.resources = (node.value.resources || [])
                                .concat(module.module_info.resources);
                        }
                    });
                }
            })
        )
        .then(function() {
            // specs / interfaces
            if (Array.isArray(xrb.specs)) {
                return Promise.all(
                    xrb.specs.map(function(subSpecOrPath) {
                        var subSpecPromise;
                        if (subSpecOrPath instanceof Object) {
                            // Inline sub-spec: return directly
                            subSpecPromise = Promise.resolve(subSpecOrPath);
                        } else {
                            subSpecPromise = self._readSpec(subSpecOrPath);
                        }
                        return subSpecPromise
                        .then(function(subSpec) {
                            return self._handleRESTBaseSpec(node, subSpec, symbols, uri);
                        });
                    })
                );
            }
        });
    } else {
        // nothing to do
        xRestbasePromise = Promise.resolve();
    }

    return xRestbasePromise
    .then(function() {
        Object.keys(subspec).forEach(function(methodName) {
            if (methodName === 'x-restbase') {
                return;
            }
            // Other methods
            var method = subspec[methodName];
            var mxrb = method['x-restbase'];
            if (mxrb && mxrb.service) {
                // set up a handler
                // XXX: share?
                var templatedReq = makeRequestTemplate(mxrb.service);
                node.value.methods[methodName] = function (restbase, req) {
                    return templatedReq(restbase, req);
                };
            } else if (method.operationId) {
                var handler = symbols[method.operationId];
                if (handler) {
                    node.value.methods[methodName] = handler;
                    node.value.m = [node.value.m, methodName];
                    //console.log(method.operationId, node.value);
                } else {
                    throw new Error('No known handler associated with operationId ' + method.operationId);
                }
            }
        });
    });
};

Router.prototype._handleRESTBaseSpec = function (rootNode, spec, modules, uri) {
    var self = this;
    function handlePaths (paths) {
        if (!paths || !Object.keys(paths).length) {
            // no paths here, nothing to do
            return Promise.resolve();
        }
        // handle paths
        return Promise.all(Object.keys(paths).map(function(pathPattern) {
            var pathSpec = paths[pathPattern];
            var pathURI = new URI(pathPattern, {}, true);
            var path = pathURI.path;
            // Expected to return
            // - rootNode for single-element path
            // - a subnode for longer paths
            var branchNode = self._buildPath(rootNode, path.slice(0, path.length - 1));
            // Check if we can share the path spec
            var subtree = self._nodes.get(pathSpec);
            var specPromise;
            if (!subtree) {
                //console.log('not shared:', pathPattern);
                // Build a new tree
                subtree = new Node();
                // Set up our specific value object
                subtree.value = {
                    methods: {}
                };
                // Assign the node before building the tree, so that sharing
                // opportunities with the same spec are discovered while doing so
                self._nodes.set(pathSpec, subtree);

                // Keep track of the nesting level
                uri.pushSuffix(pathURI);
                // Handle the path spec
                specPromise = self._handleRESTBasePathSpec(subtree, pathSpec, modules, uri);
                uri.popSuffix(pathURI);
            } else {
                //console.log('shared:', pathPattern);
                subtree = subtree.clone();
                specPromise = Promise.resolve();
            }
            return specPromise
            .then(function() {

                // XXX: Set ACLs and other value properties for path
                // subtree.value.acls = ...;

                // XXX: check for conflicts!
                branchNode.setChild(path[path.length - 1], subtree);
            });
        }));
    }

    // TODO: handle global spec settings

    return handlePaths(spec.paths || {});
};

Router.prototype.handleResources = function(restbase) {
    var self = this;
    return this.tree.visitAsync(function(value, path) {
        if (value && Array.isArray(value.resources)) {
            return Promise.resolve(value.resources)
            .each(function(req) {
                if (!req.uri) {
                    throw new Error("Missing resource URI in spec for "
                            + JSON.stringify(path));
                }
                req.uri = new URI(req.uri, {
                    domain: path[0]
                }, true);
                req.method = req.method || 'put';
                //console.log(path, req);
                return restbase.request(req);
            });
        } else {
            return Promise.resolve();
        }
    });
};

Router.prototype.loadSpec = function(spec, restbase) {
    var self = this;
    var rootNode = new Node();
    var specPromise;
    if (spec && spec.constructor === String) {
        specPromise = this._readSpec(spec);
    } else {
        specPromise = Promise.resolve(spec);
    }
    return specPromise
    .then(function(spec) {
        return self._handleRESTBaseSpec(rootNode, spec, {}, new URI([]));
    })
    .then(function() {
        // Only set the tree after loading everything
        self.tree = rootNode;
        //console.log(JSON.stringify(rootNode, null, 2));
        self.router.setTree(rootNode);
        return self.handleResources(restbase);
    })
    .then(function() {
        return self;
    });
};

Router.prototype.route = function (uri) {
    return this.router.lookup(uri);
};

module.exports = Router;
<commit_msg>Fix a bug in tree building<commit_after>"use strict";

require('es6-collections');

var yaml = require('js-yaml');
var fs = Promise.promisifyAll(require('fs'));
var util = require('util');

var swaggerRouter = require('swagger-router');
var Node = swaggerRouter.Node;
var URI = swaggerRouter.URI;
var SwaggerRouter = swaggerRouter.Router;

function Router (options) {
    this._options = options || {};
    this._nodes = new Map();
    this._modules = new Map();
    this.router = new SwaggerRouter();
}

Router.prototype._readSpec = function(path) {
    // XXX: make the spec path configurable?
    var fsPath = __dirname + '/../specs/' + path + '.yaml';
    // Let errors bubble up for now. Fail loud & early.
    return fs.readFileAsync(fsPath)
    .then(function(yamlString) {
        return yaml.safeLoad(yamlString);
    });
};

// Extend an existing route tree with a new path by walking the existing tree
// and inserting new subtrees at the desired location.
Router.prototype._buildPath = function route(node, path) {
    var params = {};
    for (var i = 0; i < path.length; i++) {
        var nextNode = node.getChild(path[i], params);
        if (!nextNode) {
            nextNode = new Node();
            node.setChild(path[i], nextNode);
            node = nextNode;
        } else {
            node = nextNode;
        }
    }
    return node;
};

Router.prototype._loadModule = function (modDef, symbols) {
    var self = this;
    var loadPath;
    // determine the module's load path
    switch (modDef.type) {
        case 'file':
            if (modDef.path && /^\//.test(modDef.path)) {
                // absolute path
                loadPath = modDef.path;
            } else {
                // relative path or missing
                loadPath = __dirname + '/../mods/';
                if (modDef.path) {
                    // the path has been provided, use it
                    loadPath += modDef.path;
                } else {
                    // no path given, so assume the file
                    // name matches the module name
                    loadPath += modDef.name;
                }
            }
            break;
        case 'npm':
            loadPath = modDef.name;
            break;
        default:
            throw new Error('unknown module type ' + modDef.type + ' (for module ' + modDef.name + ').');
    }
    // append the log property to module options, if it is not present
    modDef.options = modDef.options || {};
    if (!modDef.options.log) {
        modDef.options.log = this._options.log || function() {};
    }
    // let the error propagate in case the module cannot be loaded
    var modObj = require(loadPath);
    if (!modObj) {
        return Promise.reject("Loading module " + loadPath + " failed.");
    }
    // Call if it's a function
    if (modObj instanceof Function) {
        modObj = modObj(modDef.options);
    }
    if (!(modObj instanceof Promise)) {
        // wrap
        modObj = Promise.resolve(modObj);
    }
    return modObj.then(function(mod) {
        //console.log(loadPath, mod);
        self._modules.set(modDef, mod);
        Object.keys(mod).forEach(function(symbol) {
            // check for duplicate symbols
            if (symbol === 'module_info') {
                // skip the module info, as it should
                // be exported by each module
                return;
            } else if (symbols[symbol]) {
                throw new Error("Duplicate symbol " + symbol + " in module " + modDef.name);
            } else {
                symbols[symbol] = mod[symbol];
            }
        });
        return mod;
    });
};

function makeRequestTemplate(spec) {
    var uri = new URI(spec.uri, {}, true);
    return function (restbase, req) {
        // FIXME:
        // - Better way to get a URI clone with parameters expanded, without
        //   going via a string.
        // - Template other request parts
        return restbase.request({
            uri: new URI(uri.bind(req.params)).toString(),
            method: req.method,
            body: req.body,
            headers: req.headers,
            query: req.query
        });
    };
};

// handle one spec path
Router.prototype._handleRESTBasePathSpec = function(node, subspec, symbols, uri) {
    var self = this;
    var xrb = subspec['x-restbase'];
    var xRestbasePromise;
    if (xrb) {
        symbols = symbols || {};
        xRestbasePromise = Promise.all(
            // modules
            (xrb.modules || []).map(function(m) {
                // load each module
                // Share modules
                if (!self._modules.has(m)) {
                    return self._loadModule(m, symbols)
                    .then(function(module) {
                        //console.log(module);
                        if (module && module.module_info && module.module_info.resources) {
                            node.value.resources = (node.value.resources || [])
                                .concat(module.module_info.resources);
                        }
                    });
                }
            })
        )
        .then(function() {
            // specs / interfaces
            if (Array.isArray(xrb.specs)) {
                return Promise.all(
                    xrb.specs.map(function(subSpecOrPath) {
                        var subSpecPromise;
                        if (subSpecOrPath instanceof Object) {
                            // Inline sub-spec: return directly
                            subSpecPromise = Promise.resolve(subSpecOrPath);
                        } else {
                            subSpecPromise = self._readSpec(subSpecOrPath);
                        }
                        return subSpecPromise
                        .then(function(subSpec) {
                            return self._handleRESTBaseSpec(node, subSpec, symbols);
                        });
                    })
                );
            }
        });
    } else {
        // nothing to do
        xRestbasePromise = Promise.resolve();
    }

    return xRestbasePromise
    .then(function() {
        Object.keys(subspec).forEach(function(methodName) {
            if (methodName === 'x-restbase') {
                return;
            }
            // Other methods
            var method = subspec[methodName];
            var mxrb = method && method['x-restbase'];
            if (mxrb && mxrb.service) {
                //console.log(mxrb.service);
                // set up a handler
                var templatedReq = makeRequestTemplate(mxrb.service);
                node.value.methods[methodName] = function (restbase, req) {
                    //console.log('template', req);
                    return templatedReq(restbase, req);
                };
            } else if (method.operationId) {
                var handler = symbols[method.operationId];
                if (handler) {
                    node.value.methods[methodName] = handler;
                    //console.log(method.operationId, node.value);
                } else {
                    throw new Error('No known handler associated with operationId ' + method.operationId);
                }
            }
        });
    });
};

Router.prototype._handleRESTBaseSpec = function (rootNode, spec, modules) {
    var self = this;
    function handlePaths (paths) {
        if (!paths || !Object.keys(paths).length) {
            // no paths here, nothing to do
            return Promise.resolve();
        }
        // handle paths
        return Promise.all(Object.keys(paths).map(function(pathPattern) {
            var pathSpec = paths[pathPattern];
            var pathURI = new URI(pathPattern, {}, true);
            var path = pathURI.path;
            // Expected to return
            // - rootNode for single-element path
            // - a subnode for longer paths
            var branchNode = self._buildPath(rootNode, path.slice(0, path.length - 1));

            // Check if we can share the path spec
            var subtree = self._nodes.get(pathSpec);
            var specPromise;
            if (!subtree) {
                //console.log('not shared:', pathPattern);
                // Build a new tree
                subtree = new Node();
                // Set up our specific value object
                subtree.value = {
                    methods: {}
                };
                // XXX: Set ACLs and other value properties for path
                // subtree.value.acls = ...;

                // Assign the node before building the tree, so that sharing
                // opportunities with the same spec are discovered while doing so
                self._nodes.set(pathSpec, subtree);

                // Handle the path spec
                specPromise = self._handleRESTBasePathSpec(subtree, pathSpec, modules);
            } else {
                //console.log('shared:', pathPattern);
                subtree = subtree.clone();
                specPromise = Promise.resolve();
            }
            branchNode.setChild(path[path.length - 1], subtree);
            return specPromise;
        }));
    }

    // TODO: handle global spec settings

    return handlePaths(spec.paths || {});
};

Router.prototype.handleResources = function(restbase) {
    var self = this;
    return this.tree.visitAsync(function(value, path) {
        if (value && Array.isArray(value.resources)) {
            return Promise.resolve(value.resources)
            .each(function(req) {
                if (!req.uri) {
                    throw new Error("Missing resource URI in spec for "
                            + JSON.stringify(path));
                }
                req.uri = new URI(req.uri, {
                    domain: path[0]
                }, true);
                req.method = req.method || 'put';
                //console.log(path, req);
                return restbase.request(req);
            });
        } else {
            return Promise.resolve();
        }
    });
};

Router.prototype.loadSpec = function(spec, restbase) {
    var self = this;
    var rootNode = new Node();
    var specPromise;
    if (spec && spec.constructor === String) {
        specPromise = this._readSpec(spec);
    } else {
        specPromise = Promise.resolve(spec);
    }
    return specPromise
    .then(function(spec) {
        return self._handleRESTBaseSpec(rootNode, spec, {}, new URI([]));
    })
    .then(function() {
        // Only set the tree after loading everything
        self.tree = rootNode;
        //console.log(JSON.stringify(rootNode, null, 2));
        self.router.setTree(rootNode);
        return self.handleResources(restbase);
    })
    .then(function() {
        return self;
    });
};

Router.prototype.route = function (uri) {
    return this.router.lookup(uri);
};

module.exports = Router;
<|endoftext|>


<commit_before>/**
 * @overview ccm component for exercises
 * @author André Kless <andre.kless@web.de> 2016
 * @license The MIT License (MIT)
 */

ccm.component( /** @lends ccm.components.exercise */ {

  /*-------------------------------------------- public component members --------------------------------------------*/

  /**
   * @summary component index
   * @type {ccm.types.index}
   */
  index: 'exercise',

  /**
   * @summary default instance configuration
   * @type {ccm.components.exercise.types.config}
   */
  config: {

    data:  {
      store: [ ccm.store, '../exercise/datastore.json' ],
      key:   'demo'
    },
    edit:  {
      store: [ ccm.store ],
      key:   'demo'
    },
    input: [ ccm.component, '../input/ccm.input.js', { style: null } ]

  },

  /*-------------------------------------------- public component classes --------------------------------------------*/

  /**
   * @summary constructor for creating ccm instances out of this component
   * @class
   */
  Instance: function () {

    /*------------------------------------- private and public instance members --------------------------------------*/

    /**
     * @summary own context
     * @private
     */
    var self = this;

    /**
     * @summary contains privatized config members
     * @type {ccm.components.exercise.types.config}
     * @private
     */
    var my;

    /*------------------------------------------- public instance methods --------------------------------------------*/

    /**
     * @summary when ccm instance is ready
     * @description
     * Called one-time when this ccm instance and dependent ccm components, instances and datastores are initialized and ready.
     * This method will be removed by ccm after the one-time call.
     * @param {function} callback - callback when this instance is ready
     * @ignore
     */
    this.ready = function ( callback ) {

      // privatize security relevant config members
      my = ccm.helper.privatize( self, 'data', 'edit', 'deadline', 'onFinish', 'user', 'input', 'bigdata' );

      // convert deadline from string to number
      if ( typeof my.deadline === 'string' ) my.deadline = new Date( my.deadline.replace( /-/g, '/' ) ).getTime();

      // perform callback
      callback();

    };

    /**
     * @summary render content in own website area
     * @param {function} [callback] - callback when content is rendered
     */
    this.render = function ( callback ) {

      /**
       * website area for own content
       * @type {ccm.types.element}
       */
      var $element = ccm.helper.element( self );

      // get dataset for rendering
      ccm.helper.dataset( my.data, function ( dataset ) {

        // clear own website area
        $element.html( '' );

        // render title
        renderTitle();

        // render description
        renderDescription();

        // render inputs
        renderInputs();

        // perform callback
        if ( callback ) callback();

        /**
         * render exercise title
         */
        function renderTitle() {

          // render title
          if ( my.title || dataset.title ) $element.innerHTML += '
' + dataset.title + '
';

        }

        /**
         * render exercise description
         */
        function renderDescription() {

          // append container for description
          $element.append( '

' );

          /**
           * container for description
           * @type {ccm.types.element}
           */
          var $desc = ccm.helper.find( self, '.description' );

          // append content for own website area
          if ( my.description ) $desc.append( ccm.helper.html( my.description ) );

          // append content for own website area
          if ( dataset.description ) $desc.append( ccm.helper.html( dataset.description ) );

          // put already existing inner HTML structure in website area for own content
          if ( self.childNodes ) self.childNodes.map( function ( child ) {
            $desc[ 0 ].appendChild( child );
          } );

        }

        /**
         * render inputs for exercise solution
         */
        function renderInputs() {

          /**
           * DOM ID of container for inputs
           * @type {string}
           */
          var id = self.index + '_inputs';

          // append container for inputs
          $element.append( '

' );

          // render input instance
          my.input.render( {
            element: jQuery( '#' + id ),
            data: { inputs: dataset.inputs },
            edit: my.edit,
            onFinish: my.onFinish,
            user: my.user,
            bigdata: my.bigdata,
            form: !my.deadline || Date.now() < my.deadline
          } );
        }

      } );

    };

  }

  /*------------------------------------------------ type definitions ------------------------------------------------*/

  /**
   * @namespace ccm.components.exercise
   */

  /**
   * @namespace ccm.components.exercise.types
   */

  /**
   * @summary ccm instance configuration
   * @typedef {ccm.types.config} ccm.components.exercise.types.config
   * @property {ccm.types.element} element - ccm instance website area
   * @property {ccm.types.dependency} style - CSS for own website area
   * @property {string} classes - HTML classes for own website area
   * ...
   */

  /**
   * @external ccm.types
   * @see {@link http://akless.github.io/ccm-developer/api/ccm/ccm.types.html}
   */

} );<commit_msg>bugfix for exercise title<commit_after>/**
 * @overview ccm component for exercises
 * @author André Kless <andre.kless@web.de> 2016
 * @license The MIT License (MIT)
 */

ccm.component( /** @lends ccm.components.exercise */ {

  /*-------------------------------------------- public component members --------------------------------------------*/

  /**
   * @summary component index
   * @type {ccm.types.index}
   */
  index: 'exercise',

  /**
   * @summary default instance configuration
   * @type {ccm.components.exercise.types.config}
   */
  config: {

    data:  {
      store: [ ccm.store, '../exercise/datastore.json' ],
      key:   'demo'
    },
    edit:  {
      store: [ ccm.store ],
      key:   'demo'
    },
    input: [ ccm.component, '../input/ccm.input.js', { style: null } ]

  },

  /*-------------------------------------------- public component classes --------------------------------------------*/

  /**
   * @summary constructor for creating ccm instances out of this component
   * @class
   */
  Instance: function () {

    /*------------------------------------- private and public instance members --------------------------------------*/

    /**
     * @summary own context
     * @private
     */
    var self = this;

    /**
     * @summary contains privatized config members
     * @type {ccm.components.exercise.types.config}
     * @private
     */
    var my;

    /*------------------------------------------- public instance methods --------------------------------------------*/

    /**
     * @summary when ccm instance is ready
     * @description
     * Called one-time when this ccm instance and dependent ccm components, instances and datastores are initialized and ready.
     * This method will be removed by ccm after the one-time call.
     * @param {function} callback - callback when this instance is ready
     * @ignore
     */
    this.ready = function ( callback ) {

      // privatize security relevant config members
      my = ccm.helper.privatize( self, 'data', 'edit', 'deadline', 'onFinish', 'user', 'input', 'bigdata' );

      // convert deadline from string to number
      if ( typeof my.deadline === 'string' ) my.deadline = new Date( my.deadline.replace( /-/g, '/' ) ).getTime();

      // perform callback
      callback();

    };

    /**
     * @summary render content in own website area
     * @param {function} [callback] - callback when content is rendered
     */
    this.render = function ( callback ) {

      /**
       * website area for own content
       * @type {ccm.types.element}
       */
      var $element = ccm.helper.element( self );

      // get dataset for rendering
      ccm.helper.dataset( my.data, function ( dataset ) {

        // clear own website area
        $element.html( '' );

        // render title
        renderTitle();

        // render description
        renderDescription();

        // render inputs
        renderInputs();

        // perform callback
        if ( callback ) callback();

        /**
         * render exercise title
         */
        function renderTitle() {

          // render title
          if ( my.title || dataset.title ) $element[ 0 ].innerHTML += '
' + dataset.title + '
';

        }

        /**
         * render exercise description
         */
        function renderDescription() {

          // append container for description
          $element.append( '

' );

          /**
           * container for description
           * @type {ccm.types.element}
           */
          var $desc = ccm.helper.find( self, '.description' );

          // append content for own website area
          if ( my.description ) $desc.append( ccm.helper.html( my.description ) );

          // append content for own website area
          if ( dataset.description ) $desc.append( ccm.helper.html( dataset.description ) );

          // put already existing inner HTML structure in website area for own content
          if ( self.childNodes ) self.childNodes.map( function ( child ) {
            $desc[ 0 ].appendChild( child );
          } );

        }

        /**
         * render inputs for exercise solution
         */
        function renderInputs() {

          /**
           * DOM ID of container for inputs
           * @type {string}
           */
          var id = self.index + '_inputs';

          // append container for inputs
          $element.append( '

' );

          // render input instance
          my.input.render( {
            element: jQuery( '#' + id ),
            data: { inputs: dataset.inputs },
            edit: my.edit,
            onFinish: my.onFinish,
            user: my.user,
            bigdata: my.bigdata,
            form: !my.deadline || Date.now() < my.deadline
          } );
        }

      } );

    };

  }

  /*------------------------------------------------ type definitions ------------------------------------------------*/

  /**
   * @namespace ccm.components.exercise
   */

  /**
   * @namespace ccm.components.exercise.types
   */

  /**
   * @summary ccm instance configuration
   * @typedef {ccm.types.config} ccm.components.exercise.types.config
   * @property {ccm.types.element} element - ccm instance website area
   * @property {ccm.types.dependency} style - CSS for own website area
   * @property {string} classes - HTML classes for own website area
   * ...
   */

  /**
   * @external ccm.types
   * @see {@link http://akless.github.io/ccm-developer/api/ccm/ccm.types.html}
   */

} );<|endoftext|>


<commit_before>// ajax
var $module = (function($B){

eval($B.InjectBuiltins())
var $N = $B.builtins.None,
    _b_ = $B.builtins

var add_to_res = function(res, key, val) {
    if(isinstance(val, list)){
        for (j = 0; j < val.length; j++) {
            add_to_res(res, key, val[j])
        }
    }else if (val instanceof File || val instanceof Blob){
        res.append(key, val)
    }else{res.append(key,str.$factory(val))}
}

function set_timeout(self, timeout){
    if(timeout.seconds !== undefined){
        self.js.$requestTimer = setTimeout(
            function() {
                self.js.abort()
                if(timeout.func){
                    timeout.func()
                }
            },
            timeout.seconds * 1000)
    }
}

function handle_kwargs(self, kw, method){
    var data,
        headers,
        cache,
        timeout = {}
    for(var key in kw.$string_dict){
        if(key == "data"){
            var params = kw.$string_dict[key]
            if(typeof params == "string"){
                data = params
            }else{
                if(params.__class__ !== _b_.dict){
                    throw _b_.TypeError.$factory("wrong type for data, " +
                        "expected dict or str, got " + $B.class_name(params))
                }
                params = params.$string_dict
                var items = []
                for(var key in params){
                    items.push(encodeURIComponent(key) + "=" +
                               encodeURIComponent(params[key]))
                }
                data = items.join("&")
            }
        }else if(key=="headers"){
            headers = kw.$string_dict[key].$string_dict
            for(var key in headers){
                self.js.setRequestHeader(key, headers[key])
            }
        }else if(key.startsWith("on")){
            var event = key.substr(2)
            if(event == "timeout"){
                timeout.func = kw.$string_dict[key]
            }else{
                ajax.bind(self, event, kw.$string_dict[key])
            }
        }else if(key == "timeout"){
            timeout.seconds = kw.$string_dict[key]
        }else if(key == "cache"){
            cache = kw.$string_dict[key]
        }
    }
    if(method == "post" && ! headers){
        // For POST requests, set default header
        self.js.setRequestHeader("Content-type",
                                 "application/x-www-form-urlencoded")
    }
    return {cache: cache, data:data, timeout: timeout}
}

var ajax = {
    __class__: _b_.type,
    __mro__: [$B.JSObject, _b_.object],

    __getattribute__ : function(self, attr){
        // Special case for send : accept dict as parameters
        if(attr == 'send'){
            return function(params){
                return ajax.send(self, params)
            }
        }
        // Otherwise default to JSObject method
        return $B.JSObject.__getattribute__(self, attr)
    },

    __repr__ : function(self){return '<object Ajax>'},
    __str__ : function(self){return '<object Ajax>'},

    $infos: {
        __module__: "builtins",
        __name__: "ajax"
    },

    bind : function(self, evt, func){
        // req.bind(evt,func) is the same as req.onevt = func
        self.js['on' + evt] = function(){
            try{
                return func.apply(null, arguments)
            }catch(err){
                if(err.__class__ !== undefined){
                    var msg = _b_.getattr(err, 'info') +
                        '\n' + err.__class__.$infos.__name__
                    if(err.args){msg += ': ' + err.args[0]}
                    try{getattr($B.stderr, "write")(msg)}
                    catch(err){console.log(msg)}
                }else{
                    try{getattr($B.stderr, "write")(err)}
                    catch(err1){console.log(err)}
                }
            }
        }
        return $N
    },

    send : function(self, params){
        // params can be Python dictionary or string
        var res = ''
        if(!params){
            self.js.send()
            return $N
        }else if(isinstance(params, str)){
            res = params
        }else if(isinstance(params, dict)){
            if(self.headers['content-type'] == 'multipart/form-data'){
                // The FormData object serializes the data in the 'multipart/form-data'
                // content-type so we may as well override that header if it was set
                // by the user.
                res = new FormData()
                var items = _b_.list.$factory(_b_.dict.items(params))
                for(var i = 0, len = items.length; i < len; i++){
                    add_to_res(res, str.$factory(items[i][0]), items[i][1])
                }
            }else{
                var items = _b_.list.$factory(_b_.dict.items(params))
                for(var i = 0, len = items.length; i < len; i++){
                    var key = encodeURIComponent(str.$factory(items[i][0]));
                    if(isinstance(items[i][1], list)){
                        for (j = 0; j < items[i][1].length; j++) {
                            res += key +'=' +
                                encodeURIComponent(str.$factory(items[i][1][j])) + '&'
                        }
                    }else{
                        res += key + '=' +
                            encodeURIComponent(str.$factory(items[i][1])) + '&'
                    }
                }
                res = res.substr(0, res.length - 1)
            }
        }else{
            throw _b_.TypeError("send() argument must be string or dictionary, not '" +
                str.$factory(params.__class__) + "'")
        }
        self.js.send(res)
        return $N
    },

    set_header : function(self,key,value){
        self.js.setRequestHeader(key,value)
        self.headers[key.toLowerCase()] = value.toLowerCase()
    },

    set_timeout : function(self, seconds, func){
        self.js.$requestTimer = setTimeout(
            function() {self.js.abort();func()},
            seconds * 1000)
    }
}

ajax.$factory = function(){

    if(window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
        var xmlhttp = new XMLHttpRequest()
    }else{// code for IE6, IE5
        var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP")
    }
    xmlhttp.onreadystatechange = function(){
        // here, "this" refers to xmlhttp
        var state = this.readyState
        if(this.responseType == "" || this.responseType == "text"){
            res.js.text = this.responseText
        }
        var timer = this.$requestTimer
        if(state == 0 && this.onuninitialized){this.onuninitialized(res)}
        else if(state == 1 && this.onloading){this.onloading(res)}
        else if(state == 2 && this.onloaded){this.onloaded(res)}
        else if(state == 3 && this.oninteractive){this.oninteractive(res)}
        else if(state == 4 && this.oncomplete){
            if(timer !== null){window.clearTimeout(timer)}
            this.oncomplete(res)
        }
    }
    var res = {
        __class__: ajax,
        js: xmlhttp,
        headers: {}
    }
    return res
}

function get(){
    var $ = $B.args("get", 2, {url: null, async: null},
            ["url", "async"], arguments, {async: true},
            null, "kw"),
        url = $.url,
        async = $.async,
        kw = $.kw
    var self = ajax.$factory(),
        items = handle_kwargs(self, kw, "get"),
        qs = items.data,
        timeout = items.timeout
    set_timeout(self, timeout)
    if(qs){
        url += "?" + qs
    }
    if(! (items.cache === true)){
        url += (qs ? "&" : "?") + (new Date()).getTime()
    }
    self.js.open("GET", url, async)
    self.js.send()
}

function post(){
    var $ = $B.args("get", 2, {url: null, async: null},
            ["url", "async"], arguments, {async: true},
            null, "kw"),
        url = $.url,
        async = $.async,
        kw = $.kw,
        data
    var self = ajax.$factory()
    self.js.open("POST", url, async)
    var items = handle_kwargs(self, kw, "post"),
        data = items.data,
        timeout = items.timeout
    set_timeout(self, timeout)
    self.js.send(data)
}

$B.set_func_names(ajax)

return {ajax: ajax, Ajax: ajax, get: get, post: post}

})(__BRYTHON__)
<commit_msg>Restore attribute "xml" of Ajax objects (alias for responseXML)<commit_after>// ajax
var $module = (function($B){

eval($B.InjectBuiltins())
var $N = $B.builtins.None,
    _b_ = $B.builtins

var add_to_res = function(res, key, val) {
    if(isinstance(val, list)){
        for (j = 0; j < val.length; j++) {
            add_to_res(res, key, val[j])
        }
    }else if (val instanceof File || val instanceof Blob){
        res.append(key, val)
    }else{res.append(key,str.$factory(val))}
}

function set_timeout(self, timeout){
    if(timeout.seconds !== undefined){
        self.js.$requestTimer = setTimeout(
            function() {
                self.js.abort()
                if(timeout.func){
                    timeout.func()
                }
            },
            timeout.seconds * 1000)
    }
}

function handle_kwargs(self, kw, method){
    var data,
        headers,
        cache,
        timeout = {}
    for(var key in kw.$string_dict){
        if(key == "data"){
            var params = kw.$string_dict[key]
            if(typeof params == "string"){
                data = params
            }else{
                if(params.__class__ !== _b_.dict){
                    throw _b_.TypeError.$factory("wrong type for data, " +
                        "expected dict or str, got " + $B.class_name(params))
                }
                params = params.$string_dict
                var items = []
                for(var key in params){
                    items.push(encodeURIComponent(key) + "=" +
                               encodeURIComponent(params[key]))
                }
                data = items.join("&")
            }
        }else if(key=="headers"){
            headers = kw.$string_dict[key].$string_dict
            for(var key in headers){
                self.js.setRequestHeader(key, headers[key])
            }
        }else if(key.startsWith("on")){
            var event = key.substr(2)
            if(event == "timeout"){
                timeout.func = kw.$string_dict[key]
            }else{
                ajax.bind(self, event, kw.$string_dict[key])
            }
        }else if(key == "timeout"){
            timeout.seconds = kw.$string_dict[key]
        }else if(key == "cache"){
            cache = kw.$string_dict[key]
        }
    }
    if(method == "post" && ! headers){
        // For POST requests, set default header
        self.js.setRequestHeader("Content-type",
                                 "application/x-www-form-urlencoded")
    }
    return {cache: cache, data:data, timeout: timeout}
}

var ajax = {
    __class__: _b_.type,
    __mro__: [$B.JSObject, _b_.object],

    __getattribute__ : function(self, attr){
        // Special case for send : accept dict as parameters
        if(attr == 'send'){
            return function(params){
                return ajax.send(self, params)
            }
        }else if(attr == 'xml'){ // alias
            attr = 'responseXML'
        }
        // Otherwise default to JSObject method
        return $B.JSObject.__getattribute__(self, attr)
    },

    __repr__ : function(self){return '<object Ajax>'},
    __str__ : function(self){return '<object Ajax>'},

    $infos: {
        __module__: "builtins",
        __name__: "ajax"
    },

    bind : function(self, evt, func){
        // req.bind(evt,func) is the same as req.onevt = func
        self.js['on' + evt] = function(){
            try{
                return func.apply(null, arguments)
            }catch(err){
                if(err.__class__ !== undefined){
                    var msg = _b_.getattr(err, 'info') +
                        '\n' + err.__class__.$infos.__name__
                    if(err.args){msg += ': ' + err.args[0]}
                    try{getattr($B.stderr, "write")(msg)}
                    catch(err){console.log(msg)}
                }else{
                    try{getattr($B.stderr, "write")(err)}
                    catch(err1){console.log(err)}
                }
            }
        }
        return $N
    },

    send : function(self, params){
        // params can be Python dictionary or string
        var res = ''
        if(!params){
            self.js.send()
            return $N
        }else if(isinstance(params, str)){
            res = params
        }else if(isinstance(params, dict)){
            if(self.headers['content-type'] == 'multipart/form-data'){
                // The FormData object serializes the data in the 'multipart/form-data'
                // content-type so we may as well override that header if it was set
                // by the user.
                res = new FormData()
                var items = _b_.list.$factory(_b_.dict.items(params))
                for(var i = 0, len = items.length; i < len; i++){
                    add_to_res(res, str.$factory(items[i][0]), items[i][1])
                }
            }else{
                var items = _b_.list.$factory(_b_.dict.items(params))
                for(var i = 0, len = items.length; i < len; i++){
                    var key = encodeURIComponent(str.$factory(items[i][0]));
                    if(isinstance(items[i][1], list)){
                        for (j = 0; j < items[i][1].length; j++) {
                            res += key +'=' +
                                encodeURIComponent(str.$factory(items[i][1][j])) + '&'
                        }
                    }else{
                        res += key + '=' +
                            encodeURIComponent(str.$factory(items[i][1])) + '&'
                    }
                }
                res = res.substr(0, res.length - 1)
            }
        }else{
            throw _b_.TypeError("send() argument must be string or dictionary, not '" +
                str.$factory(params.__class__) + "'")
        }
        self.js.send(res)
        return $N
    },

    set_header : function(self,key,value){
        self.js.setRequestHeader(key,value)
        self.headers[key.toLowerCase()] = value.toLowerCase()
    },

    set_timeout : function(self, seconds, func){
        self.js.$requestTimer = setTimeout(
            function() {self.js.abort();func()},
            seconds * 1000)
    }
}

ajax.$factory = function(){

    if(window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
        var xmlhttp = new XMLHttpRequest()
    }else{// code for IE6, IE5
        var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP")
    }
    xmlhttp.onreadystatechange = function(){
        // here, "this" refers to xmlhttp
        var state = this.readyState
        if(this.responseType == "" || this.responseType == "text"){
            res.js.text = this.responseText
        }
        var timer = this.$requestTimer
        if(state == 0 && this.onuninitialized){this.onuninitialized(res)}
        else if(state == 1 && this.onloading){this.onloading(res)}
        else if(state == 2 && this.onloaded){this.onloaded(res)}
        else if(state == 3 && this.oninteractive){this.oninteractive(res)}
        else if(state == 4 && this.oncomplete){
            if(timer !== null){window.clearTimeout(timer)}
            this.oncomplete(res)
        }
    }
    var res = {
        __class__: ajax,
        js: xmlhttp,
        headers: {}
    }
    return res
}

function get(){
    var $ = $B.args("get", 2, {url: null, async: null},
            ["url", "async"], arguments, {async: true},
            null, "kw"),
        url = $.url,
        async = $.async,
        kw = $.kw
    var self = ajax.$factory(),
        items = handle_kwargs(self, kw, "get"),
        qs = items.data,
        timeout = items.timeout
    set_timeout(self, timeout)
    if(qs){
        url += "?" + qs
    }
    if(! (items.cache === true)){
        url += (qs ? "&" : "?") + (new Date()).getTime()
    }
    self.js.open("GET", url, async)
    self.js.send()
}

function post(){
    var $ = $B.args("get", 2, {url: null, async: null},
            ["url", "async"], arguments, {async: true},
            null, "kw"),
        url = $.url,
        async = $.async,
        kw = $.kw,
        data
    var self = ajax.$factory()
    self.js.open("POST", url, async)
    var items = handle_kwargs(self, kw, "post"),
        data = items.data,
        timeout = items.timeout
    set_timeout(self, timeout)
    self.js.send(data)
}

$B.set_func_names(ajax)

return {ajax: ajax, Ajax: ajax, get: get, post: post}

})(__BRYTHON__)
<|endoftext|>


<commit_before>/**
 *
 */
require.config({
  paths: {
    'jquery': 'libs/jquery',
    'jqueryxpath': 'libs/jquery.xpath',
    'leaflet': 'http://cdn.leafletjs.com/leaflet-0.6.4/leaflet',
    'jqueryui': 'http://code.jquery.com/ui/1.11.1/jquery-ui.min',
    'underscore': 'https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min',
    'text': 'libs/text',
    'bootstrap': 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min'
  }
});
require(['modules/tosplit']);<commit_msg>make sure jquery loads before bootstrap<commit_after>/**
 *
 */
require.config({

  shim: {
    "bootstrap": {
      "deps": ['jquery']
    }
  },
  paths: {
    'jquery': 'libs/jquery',
    'jqueryxpath': 'libs/jquery.xpath',
    'leaflet': 'http://cdn.leafletjs.com/leaflet-0.6.4/leaflet',
    'jqueryui': 'http://code.jquery.com/ui/1.11.1/jquery-ui.min',
    'underscore': 'https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min',
    'text': 'libs/text',
    'bootstrap': 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min'
  }
});
require(['modules/tosplit']);<|endoftext|>


<commit_before>/*
File generated by js-routes GEM_VERSION
Based on Rails routes of APP_CLASS
 */

(function() {
  var NodeTypes, ParameterMissing, Utils, createGlobalJsRoutesObject, defaults, root,
    hasProp = {}.hasOwnProperty;

  root = typeof exports !== "undefined" && exports !== null ? exports : this;

  ParameterMissing = function(message) {
    this.message = message;
  };

  ParameterMissing.prototype = new Error();

  defaults = {
    prefix: "PREFIX",
    default_url_options: DEFAULT_URL_OPTIONS
  };

  NodeTypes = NODE_TYPES;

  Utils = {
    serialize: function(object, prefix) {
      var element, i, j, key, len, prop, result, s;
      if (prefix == null) {
        prefix = null;
      }
      if (!object) {
        return "";
      }
      if (!prefix && !(this.get_object_type(object) === "object")) {
        throw new Error("Url parameters should be a javascript hash");
      }
      if (root.jQuery) {
        result = root.jQuery.param(object);
        return (!result ? "" : result);
      }
      s = [];
      switch (this.get_object_type(object)) {
        case "array":
          for (i = j = 0, len = object.length; j < len; i = ++j) {
            element = object[i];
            s.push(this.serialize(element, prefix + "[]"));
          }
          break;
        case "object":
          for (key in object) {
            if (!hasProp.call(object, key)) continue;
            prop = object[key];
            if (!(prop != null)) {
              continue;
            }
            if (prefix != null) {
              key = prefix + "[" + key + "]";
            }
            s.push(this.serialize(prop, key));
          }
          break;
        default:
          if (object) {
            s.push((encodeURIComponent(prefix.toString())) + "=" + (encodeURIComponent(object.toString())));
          }
      }
      if (!s.length) {
        return "";
      }
      return s.join("&");
    },
    clean_path: function(path) {
      var last_index;
      path = path.split("://");
      last_index = path.length - 1;
      path[last_index] = path[last_index].replace(/\/+/g, "/");
      return path.join("://");
    },
    set_default_url_options: function(optional_parts, options) {
      var i, j, len, part, results;
      results = [];
      for (i = j = 0, len = optional_parts.length; j < len; i = ++j) {
        part = optional_parts[i];
        if (!options.hasOwnProperty(part) && defaults.default_url_options.hasOwnProperty(part)) {
          results.push(options[part] = defaults.default_url_options[part]);
        }
      }
      return results;
    },
    extract_anchor: function(options) {
      var anchor;
      anchor = "";
      if (options.hasOwnProperty("anchor")) {
        anchor = "#" + options.anchor;
        delete options.anchor;
      }
      return anchor;
    },
    extract_trailing_slash: function(options) {
      var trailing_slash;
      trailing_slash = false;
      if (defaults.default_url_options.hasOwnProperty("trailing_slash")) {
        trailing_slash = defaults.default_url_options.trailing_slash;
      }
      if (options.hasOwnProperty("trailing_slash")) {
        trailing_slash = options.trailing_slash;
        delete options.trailing_slash;
      }
      return trailing_slash;
    },
    extract_options: function(number_of_params, args) {
      var last_el;
      last_el = args[args.length - 1];
      if (args.length > number_of_params || ((last_el != null) && "object" === this.get_object_type(last_el) && !this.look_like_serialized_model(last_el))) {
        return args.pop();
      } else {
        return {};
      }
    },
    look_like_serialized_model: function(object) {
      return "id" in object || "to_param" in object;
    },
    path_identifier: function(object) {
      var property;
      if (object === 0) {
        return "0";
      }
      if (!object) {
        return "";
      }
      property = object;
      if (this.get_object_type(object) === "object") {
        if ("to_param" in object) {
          property = object.to_param;
        } else if ("id" in object) {
          property = object.id;
        } else {
          property = object;
        }
        if (this.get_object_type(property) === "function") {
          property = property.call(object);
        }
      }
      return property.toString();
    },
    clone: function(obj) {
      var attr, copy, key;
      if ((obj == null) || "object" !== this.get_object_type(obj)) {
        return obj;
      }
      copy = obj.constructor();
      for (key in obj) {
        if (!hasProp.call(obj, key)) continue;
        attr = obj[key];
        copy[key] = attr;
      }
      return copy;
    },
    prepare_parameters: function(required_parameters, actual_parameters, options) {
      var i, j, len, result, val;
      result = this.clone(options) || {};
      for (i = j = 0, len = required_parameters.length; j < len; i = ++j) {
        val = required_parameters[i];
        if (i < actual_parameters.length) {
          result[val] = actual_parameters[i];
        }
      }
      return result;
    },
    build_path: function(required_parameters, optional_parts, route, args) {
      var anchor, opts, parameters, result, trailing_slash, url, url_params;
      args = Array.prototype.slice.call(args);
      opts = this.extract_options(required_parameters.length, args);
      if (args.length > required_parameters.length) {
        throw new Error("Too many parameters provided for path");
      }
      parameters = this.prepare_parameters(required_parameters, args, opts);
      if (gon.default_url_params) {
        parameters.push(gon.default_url_params)
      }
      this.set_default_url_options(optional_parts, parameters);
      anchor = this.extract_anchor(parameters);
      trailing_slash = this.extract_trailing_slash(parameters);
      result = "" + (this.get_prefix()) + (this.visit(route, parameters));
      url = Utils.clean_path("" + result);
      if (trailing_slash === true) {
        url = url.replace(/(.*?)[\/]?$/, "$1/");
      }
      if ((url_params = this.serialize(parameters)).length) {
        url += "?" + url_params;
      }
      url += anchor;
      return url;
    },
    visit: function(route, parameters, optional) {
      var left, left_part, right, right_part, type, value;
      if (optional == null) {
        optional = false;
      }
      type = route[0], left = route[1], right = route[2];
      switch (type) {
        case NodeTypes.GROUP:
          return this.visit(left, parameters, true);
        case NodeTypes.STAR:
          return this.visit_globbing(left, parameters, true);
        case NodeTypes.LITERAL:
        case NodeTypes.SLASH:
        case NodeTypes.DOT:
          return left;
        case NodeTypes.CAT:
          left_part = this.visit(left, parameters, optional);
          right_part = this.visit(right, parameters, optional);
          if (optional && !(left_part && right_part)) {
            return "";
          }
          return "" + left_part + right_part;
        case NodeTypes.SYMBOL:
          value = parameters[left];
          if (value != null) {
            delete parameters[left];
            return this.path_identifier(value);
          }
          if (optional) {
            return "";
          } else {
            throw new ParameterMissing("Route parameter missing: " + left);
          }
          break;
        default:
          throw new Error("Unknown Rails node type");
      }
    },
    build_path_spec: function(route, wildcard) {
      var left, right, type;
      if (wildcard == null) {
        wildcard = false;
      }
      type = route[0], left = route[1], right = route[2];
      switch (type) {
        case NodeTypes.GROUP:
          return "(" + (this.build_path_spec(left)) + ")";
        case NodeTypes.CAT:
          return "" + (this.build_path_spec(left)) + (this.build_path_spec(right));
        case NodeTypes.STAR:
          return this.build_path_spec(left, true);
        case NodeTypes.SYMBOL:
          if (wildcard === true) {
            return "" + (left[0] === '*' ? '' : '*') + left;
          } else {
            return ":" + left;
          }
          break;
        case NodeTypes.SLASH:
        case NodeTypes.DOT:
        case NodeTypes.LITERAL:
          return left;
        default:
          throw new Error("Unknown Rails node type");
      }
    },
    visit_globbing: function(route, parameters, optional) {
      var left, right, type, value;
      type = route[0], left = route[1], right = route[2];
      if (left.replace(/^\*/i, "") !== left) {
        route[1] = left = left.replace(/^\*/i, "");
      }
      value = parameters[left];
      if (value == null) {
        return this.visit(route, parameters, optional);
      }
      parameters[left] = (function() {
        switch (this.get_object_type(value)) {
          case "array":
            return value.join("/");
          default:
            return value;
        }
      }).call(this);
      return this.visit(route, parameters, optional);
    },
    get_prefix: function() {
      var prefix;
      prefix = defaults.prefix;
      if (prefix !== "") {
        prefix = (prefix.match("/$") ? prefix : prefix + "/");
      }
      return prefix;
    },
    route: function(required_parts, optional_parts, route_spec) {
      var path_fn;
      path_fn = function() {
        return Utils.build_path(required_parts, optional_parts, route_spec, arguments);
      };
      path_fn.required_params = required_parts;
      path_fn.toString = function() {
        return Utils.build_path_spec(route_spec);
      };
      return path_fn;
    },
    _classToTypeCache: null,
    _classToType: function() {
      var j, len, name, ref;
      if (this._classToTypeCache != null) {
        return this._classToTypeCache;
      }
      this._classToTypeCache = {};
      ref = "Boolean Number String Function Array Date RegExp Object Error".split(" ");
      for (j = 0, len = ref.length; j < len; j++) {
        name = ref[j];
        this._classToTypeCache["[object " + name + "]"] = name.toLowerCase();
      }
      return this._classToTypeCache;
    },
    get_object_type: function(obj) {
      if (root.jQuery && (root.jQuery.type != null)) {
        return root.jQuery.type(obj);
      }
      if (obj == null) {
        return "" + obj;
      }
      if (typeof obj === "object" || typeof obj === "function") {
        return this._classToType()[Object.prototype.toString.call(obj)] || "object";
      } else {
        return typeof obj;
      }
    }
  };

  createGlobalJsRoutesObject = function() {
    var namespace;
    namespace = function(mainRoot, namespaceString) {
      var current, parts;
      parts = (namespaceString ? namespaceString.split(".") : []);
      if (!parts.length) {
        return;
      }
      current = parts.shift();
      mainRoot[current] = mainRoot[current] || {};
      return namespace(mainRoot[current], parts.join("."));
    };
    namespace(root, "NAMESPACE");
    root.NAMESPACE = ROUTES;
    root.NAMESPACE.options = defaults;
    return root.NAMESPACE;
  };

  if (typeof define === "function" && define.amd) {
    define([], function() {
      return createGlobalJsRoutesObject();
    });
  } else {
    createGlobalJsRoutesObject();
  }

}).call(this);
<commit_msg>change adding custom parameters<commit_after>/*
File generated by js-routes GEM_VERSION
Based on Rails routes of APP_CLASS
 */

(function() {
  var NodeTypes, ParameterMissing, Utils, createGlobalJsRoutesObject, defaults, root,
    hasProp = {}.hasOwnProperty;

  root = typeof exports !== "undefined" && exports !== null ? exports : this;

  ParameterMissing = function(message) {
    this.message = message;
  };

  ParameterMissing.prototype = new Error();

  defaults = {
    prefix: "PREFIX",
    default_url_options: DEFAULT_URL_OPTIONS
  };

  NodeTypes = NODE_TYPES;

  Utils = {
    serialize: function(object, prefix) {
      var element, i, j, key, len, prop, result, s;
      if (prefix == null) {
        prefix = null;
      }
      if (!object) {
        return "";
      }
      if (!prefix && !(this.get_object_type(object) === "object")) {
        throw new Error("Url parameters should be a javascript hash");
      }
      if (root.jQuery) {
        result = root.jQuery.param(object);
        return (!result ? "" : result);
      }
      s = [];
      switch (this.get_object_type(object)) {
        case "array":
          for (i = j = 0, len = object.length; j < len; i = ++j) {
            element = object[i];
            s.push(this.serialize(element, prefix + "[]"));
          }
          break;
        case "object":
          for (key in object) {
            if (!hasProp.call(object, key)) continue;
            prop = object[key];
            if (!(prop != null)) {
              continue;
            }
            if (prefix != null) {
              key = prefix + "[" + key + "]";
            }
            s.push(this.serialize(prop, key));
          }
          break;
        default:
          if (object) {
            s.push((encodeURIComponent(prefix.toString())) + "=" + (encodeURIComponent(object.toString())));
          }
      }
      if (!s.length) {
        return "";
      }
      return s.join("&");
    },
    clean_path: function(path) {
      var last_index;
      path = path.split("://");
      last_index = path.length - 1;
      path[last_index] = path[last_index].replace(/\/+/g, "/");
      return path.join("://");
    },
    set_default_url_options: function(optional_parts, options) {
      var i, j, len, part, results;
      results = [];
      for (i = j = 0, len = optional_parts.length; j < len; i = ++j) {
        part = optional_parts[i];
        if (!options.hasOwnProperty(part) && defaults.default_url_options.hasOwnProperty(part)) {
          results.push(options[part] = defaults.default_url_options[part]);
        }
      }
      return results;
    },
    extract_anchor: function(options) {
      var anchor;
      anchor = "";
      if (options.hasOwnProperty("anchor")) {
        anchor = "#" + options.anchor;
        delete options.anchor;
      }
      return anchor;
    },
    extract_trailing_slash: function(options) {
      var trailing_slash;
      trailing_slash = false;
      if (defaults.default_url_options.hasOwnProperty("trailing_slash")) {
        trailing_slash = defaults.default_url_options.trailing_slash;
      }
      if (options.hasOwnProperty("trailing_slash")) {
        trailing_slash = options.trailing_slash;
        delete options.trailing_slash;
      }
      return trailing_slash;
    },
    extract_options: function(number_of_params, args) {
      var last_el;
      last_el = args[args.length - 1];
      if (args.length > number_of_params || ((last_el != null) && "object" === this.get_object_type(last_el) && !this.look_like_serialized_model(last_el))) {
        return args.pop();
      } else {
        return {};
      }
    },
    look_like_serialized_model: function(object) {
      return "id" in object || "to_param" in object;
    },
    path_identifier: function(object) {
      var property;
      if (object === 0) {
        return "0";
      }
      if (!object) {
        return "";
      }
      property = object;
      if (this.get_object_type(object) === "object") {
        if ("to_param" in object) {
          property = object.to_param;
        } else if ("id" in object) {
          property = object.id;
        } else {
          property = object;
        }
        if (this.get_object_type(property) === "function") {
          property = property.call(object);
        }
      }
      return property.toString();
    },
    clone: function(obj) {
      var attr, copy, key;
      if ((obj == null) || "object" !== this.get_object_type(obj)) {
        return obj;
      }
      copy = obj.constructor();
      for (key in obj) {
        if (!hasProp.call(obj, key)) continue;
        attr = obj[key];
        copy[key] = attr;
      }
      return copy;
    },
    prepare_parameters: function(required_parameters, actual_parameters, options) {
      var i, j, len, result, val;
      result = this.clone(options) || {};
      for (i = j = 0, len = required_parameters.length; j < len; i = ++j) {
        val = required_parameters[i];
        if (i < actual_parameters.length) {
          result[val] = actual_parameters[i];
        }
      }
      return result;
    },
    build_path: function(required_parameters, optional_parts, route, args) {
      var anchor, opts, parameters, result, trailing_slash, url, url_params;
      args = Array.prototype.slice.call(args);
      opts = this.extract_options(required_parameters.length, args);
      if (args.length > required_parameters.length) {
        throw new Error("Too many parameters provided for path");
      }
      parameters = this.prepare_parameters(required_parameters, args, opts);
      if (gon.default_url_params) {
        for (var key in Object.keys(gon.default_url_params)) parameters[key] = gon.default_url_params[key];
      }
      this.set_default_url_options(optional_parts, parameters);
      anchor = this.extract_anchor(parameters);
      trailing_slash = this.extract_trailing_slash(parameters);
      result = "" + (this.get_prefix()) + (this.visit(route, parameters));
      url = Utils.clean_path("" + result);
      if (trailing_slash === true) {
        url = url.replace(/(.*?)[\/]?$/, "$1/");
      }
      if ((url_params = this.serialize(parameters)).length) {
        url += "?" + url_params;
      }
      url += anchor;
      return url;
    },
    visit: function(route, parameters, optional) {
      var left, left_part, right, right_part, type, value;
      if (optional == null) {
        optional = false;
      }
      type = route[0], left = route[1], right = route[2];
      switch (type) {
        case NodeTypes.GROUP:
          return this.visit(left, parameters, true);
        case NodeTypes.STAR:
          return this.visit_globbing(left, parameters, true);
        case NodeTypes.LITERAL:
        case NodeTypes.SLASH:
        case NodeTypes.DOT:
          return left;
        case NodeTypes.CAT:
          left_part = this.visit(left, parameters, optional);
          right_part = this.visit(right, parameters, optional);
          if (optional && !(left_part && right_part)) {
            return "";
          }
          return "" + left_part + right_part;
        case NodeTypes.SYMBOL:
          value = parameters[left];
          if (value != null) {
            delete parameters[left];
            return this.path_identifier(value);
          }
          if (optional) {
            return "";
          } else {
            throw new ParameterMissing("Route parameter missing: " + left);
          }
          break;
        default:
          throw new Error("Unknown Rails node type");
      }
    },
    build_path_spec: function(route, wildcard) {
      var left, right, type;
      if (wildcard == null) {
        wildcard = false;
      }
      type = route[0], left = route[1], right = route[2];
      switch (type) {
        case NodeTypes.GROUP:
          return "(" + (this.build_path_spec(left)) + ")";
        case NodeTypes.CAT:
          return "" + (this.build_path_spec(left)) + (this.build_path_spec(right));
        case NodeTypes.STAR:
          return this.build_path_spec(left, true);
        case NodeTypes.SYMBOL:
          if (wildcard === true) {
            return "" + (left[0] === '*' ? '' : '*') + left;
          } else {
            return ":" + left;
          }
          break;
        case NodeTypes.SLASH:
        case NodeTypes.DOT:
        case NodeTypes.LITERAL:
          return left;
        default:
          throw new Error("Unknown Rails node type");
      }
    },
    visit_globbing: function(route, parameters, optional) {
      var left, right, type, value;
      type = route[0], left = route[1], right = route[2];
      if (left.replace(/^\*/i, "") !== left) {
        route[1] = left = left.replace(/^\*/i, "");
      }
      value = parameters[left];
      if (value == null) {
        return this.visit(route, parameters, optional);
      }
      parameters[left] = (function() {
        switch (this.get_object_type(value)) {
          case "array":
            return value.join("/");
          default:
            return value;
        }
      }).call(this);
      return this.visit(route, parameters, optional);
    },
    get_prefix: function() {
      var prefix;
      prefix = defaults.prefix;
      if (prefix !== "") {
        prefix = (prefix.match("/$") ? prefix : prefix + "/");
      }
      return prefix;
    },
    route: function(required_parts, optional_parts, route_spec) {
      var path_fn;
      path_fn = function() {
        return Utils.build_path(required_parts, optional_parts, route_spec, arguments);
      };
      path_fn.required_params = required_parts;
      path_fn.toString = function() {
        return Utils.build_path_spec(route_spec);
      };
      return path_fn;
    },
    _classToTypeCache: null,
    _classToType: function() {
      var j, len, name, ref;
      if (this._classToTypeCache != null) {
        return this._classToTypeCache;
      }
      this._classToTypeCache = {};
      ref = "Boolean Number String Function Array Date RegExp Object Error".split(" ");
      for (j = 0, len = ref.length; j < len; j++) {
        name = ref[j];
        this._classToTypeCache["[object " + name + "]"] = name.toLowerCase();
      }
      return this._classToTypeCache;
    },
    get_object_type: function(obj) {
      if (root.jQuery && (root.jQuery.type != null)) {
        return root.jQuery.type(obj);
      }
      if (obj == null) {
        return "" + obj;
      }
      if (typeof obj === "object" || typeof obj === "function") {
        return this._classToType()[Object.prototype.toString.call(obj)] || "object";
      } else {
        return typeof obj;
      }
    }
  };

  createGlobalJsRoutesObject = function() {
    var namespace;
    namespace = function(mainRoot, namespaceString) {
      var current, parts;
      parts = (namespaceString ? namespaceString.split(".") : []);
      if (!parts.length) {
        return;
      }
      current = parts.shift();
      mainRoot[current] = mainRoot[current] || {};
      return namespace(mainRoot[current], parts.join("."));
    };
    namespace(root, "NAMESPACE");
    root.NAMESPACE = ROUTES;
    root.NAMESPACE.options = defaults;
    return root.NAMESPACE;
  };

  if (typeof define === "function" && define.amd) {
    define([], function() {
      return createGlobalJsRoutesObject();
    });
  } else {
    createGlobalJsRoutesObject();
  }

}).call(this);
<|endoftext|>


<commit_before>'use strict';

var Controllers = require('./controllers')();

/**
* Routing definitions.
* @namespace routes
*/

/**
* Registers all API routes available
* @param {express} app - Application to register API routes with.
* @function routes.route
*/
module.exports.route = function (app) {

  // ================================
  // Login Routes
  // ================================

  /**
  * @apiDefine auth
  * @apiParam (GET) {string} [token] Token from the current session. Not needed when the openjub_session cookie is available.
  * @apiParam (COOKIE) {string} [openjub_session] Session cookie containing a logged in session. If not given, the GET parameter token is mandatory.
  */

  /**
   * @api {get} /auth/isoncampus On Campus location
   * @apiDescription Check it the request in On or Off Campus.
   * @apiGroup Authentication
   *
   * @apiVersion 0.1.0
   * @apiSuccess {String} on_campus Is the user on or off campus?
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *      "on_campus": true
   *    }
   */
  app.get('/auth/isoncampus', Controllers.Auth.checkCampus);

  /**
   * @api {post} /auth/signin CampusNet Authentication
   * @apiDescription Login with CampusNet details.
   * @apiGroup Authentication
   *
   * @apiParam {String} username CampusNet/LDAP username
   * @apiParam {String} password CampusNet/LDAP password
   *
   * @apiSuccess {String} token Login Token
   * @apiSuccess {String} user Username
   *
   * @apiVersion 0.1.0
   * @apiUse InvalidRequest
   * @apiUse InvalidAuthentication
   * @apiUse AlreadyAuthenticated
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *      "token": "<token>",
   *      "user": "ex.ample"
   *    }
   */
  app.post('/auth/signin', Controllers.Auth.signin);

  /**
   * @api {get} /auth/signout Signout
   * @apiDescription Logout of a session.
   * @apiGroup Authentication
   *
   * @apiSuccess {Boolean} success indicating if the logout was successfull.
   *
   * @apiVersion 0.1.0
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse UnknownError
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *      "success": true
   *    }
   */
  app.get('/auth/signout', Controllers.Auth.need, Controllers.Auth.signout);

  /**
   * @api {post} /auth/status Login Status
   * @apiDescription If logged in, check the login status.
   * @apiGroup Authentication
   *
   * @apiSuccess {String} token Login Token
   * @apiSuccess {String} user Username or False when using on-Campus authentication.
   *
   * @apiVersion 0.1.0
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *      "token": "<token>",
   *      "user": "ex.ample"
   *    }
   */
  app.get('/auth/status', Controllers.Auth.need, Controllers.Auth.status);

  // ================================
  // Getting info about a single user
  // ================================

  /**
   * @api {get} /user/me Get info about the current user.
   * @apiDescription Get info about the current user
   * @apiGroup Users
   *
   * @apiParam (GET) {String[]} [fields] Fields to return. Defaults to all fields.
   *
   * @apiVersion 0.1.0
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   * @apiUse UserNotFound
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *      "token": "<token>",
   *      "user": "ex.ample"
   *    }
   */
  app.get('/user/me', Controllers.Auth.need, Controllers.User.me);

  /**
   * @api {get} /user/name/:username Get info about a user by username
   * @apiDescription Get info about a user by username
   * @apiGroup Users
   * @apiVersion 0.1.0
   *
   * @apiParam (GET) {String[]} [fields] Fields to return. Defaults to all fields.
   * @apiParam {String} username Username of user to get info about
   *
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   * @apiUse UserNotFound
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *      "token": "<token>",
   *      "user": "ex.ample"
   *    }
   */
  app.get('/user/name/:username', Controllers.Auth.need, Controllers.User.username);

  /**
   * @api {get} /user/id/:id Get info about a user by id
   * @apiDescription Get info about a user by id
   * @apiGroup Users
   * @apiVersion 0.1.0
   *
   * @apiParam (GET) {String[]} [fields] Fields to return. Defaults to all fields.
   * @apiParam {String} id Id of user to get info about
   *
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   * @apiUse UserNotFound
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *      "token": "<token>",
   *      "user": "ex.ample"
   *    }
   */
  app.get('/user/id/:id', Controllers.Auth.need, Controllers.User.id);

  //we're not a goat
  app.get('/user/me/isagoat', function(req, res){
    res.status(200).jsonp({
      "isAGoat": false
    });
  })

  // ================================
  // Searches
  // ================================

  /**
   * @api {get} /query/:q Quickly searches for a machine-readable query
   * @apiDescription Quickly searches for a machine-readable query
   * @apiGroup Searcg
   * @apiVersion 0.1.0
   *
   * @apiParam (GET) {String[]} [fields] Fields to return. Defaults to all fields.
   * @apiParam (GET) {number} [limit] - Maximal number of entries to display
   * @apiParam (GET) {number} [skip] - Skip, number of entries to skip at the beginning
   *
   * @apiParam {String} q The query to search for
   *
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   * @apiUse UserNotFound
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    [{
   *      "token": "<token>",
   *      "user": "ex.ample"
   *    }]
   */
  app.get('/query/:q', Controllers.Auth.need, Controllers.User.query);

  /**
   * @api {get} /search/:q Searches for a query
   * @apiDescription Searches for a query
   * @apiGroup Searcg
   * @apiVersion 0.1.0
   *
   * @apiParam (GET) {String[]} [fields] Fields to return. Defaults to all fields.
   * @apiParam (GET) {number} [limit] - Maximal number of entries to display
   * @apiParam (GET) {number} [skip] - Skip, number of entries to skip at the beginning
   *
   * @apiParam {String} q The query to search for
   *
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   * @apiUse UserNotFound
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    [{
   *      "token": "<token>",
   *      "user": "ex.ample"
   *    }]
   */
  app.get('/search/:q', Controllers.Auth.need, Controllers.User.search);

  /**
   * @api {get} /user/image/:account/image.jpg Get the image of a user
   * @apiDescription Get the image of a user
   * @apiGroup Search
   * @apiVersion 0.1.0
   *
   * @apiParam {String} account User to display image for
   *
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   * @apiUse UserNotFound
   */
  app.get("/user/image/:account/image.jpg", Controllers.Auth.need, Controllers.User.image);

  // ================================
  // Everything else
  // ================================

  app.get('/*', function (req, res) {
    res.errorJson('RequestNotFound');
  });
  app.post('/*', function (req, res) {
    res.errorJson('RequestNotFound');
  });
  app.put('/*', function (req, res) {
    res.errorJson('RequestNotFound');
  });
  app.delete('/*', function (req, res) {
    res.errorJson('RequestNotFound');
  });
};
<commit_msg>Update doc<commit_after>'use strict';

var Controllers = require('./controllers')();

/**
* Routing definitions.
* @namespace routes
*/

/**
* Registers all API routes available
* @param {express} app - Application to register API routes with.
* @function routes.route
*/
module.exports.route = function (app) {

  // ================================
  // Login Routes
  // ================================

  /**
  * @apiDefine auth
  * @apiParam (GET) {string} [token] Token from the current session. Not needed when the openjub_session cookie is available.
  * @apiParam (COOKIE) {string} [openjub_session] Session cookie containing a logged in session. If not given, the GET parameter token is mandatory.
  */

  /**
   * @api {get} /auth/isoncampus On Campus location
   * @apiDescription Check it the request in On or Off Campus.
   * @apiGroup Authentication
   *
   * @apiVersion 0.1.0
   * @apiSuccess {String} on_campus Is the user on or off campus?
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *      "on_campus": true
   *    }
   */
  app.get('/auth/isoncampus', Controllers.Auth.checkCampus);

  /**
   * @api {post} /auth/signin CampusNet Authentication
   * @apiDescription Login with CampusNet details.
   * @apiGroup Authentication
   *
   * @apiParam {String} username CampusNet/LDAP username
   * @apiParam {String} password CampusNet/LDAP password
   *
   * @apiSuccess {String} token Login Token
   * @apiSuccess {String} user Username
   *
   * @apiVersion 0.1.0
   * @apiUse InvalidRequest
   * @apiUse InvalidAuthentication
   * @apiUse AlreadyAuthenticated
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *      "token": "<token>",
   *      "user": "ex.ample"
   *    }
   */
  app.post('/auth/signin', Controllers.Auth.signin);

  /**
   * @api {get} /auth/signout Signout
   * @apiDescription Logout of a session.
   * @apiGroup Authentication
   *
   * @apiSuccess {Boolean} success indicating if the logout was successfull.
   *
   * @apiVersion 0.1.0
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse UnknownError
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *      "success": true
   *    }
   */
  app.get('/auth/signout', Controllers.Auth.need, Controllers.Auth.signout);

  /**
   * @api {post} /auth/status Login Status
   * @apiDescription If logged in, check the login status.
   * @apiGroup Authentication
   *
   * @apiSuccess {String} token Login Token
   * @apiSuccess {String} user Username or False when using on-Campus authentication.
   *
   * @apiVersion 0.1.0
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *      "token": "<token>",
   *      "user": "ex.ample"
   *    }
   */
  app.get('/auth/status', Controllers.Auth.need, Controllers.Auth.status);

  // ================================
  // Getting info about a single user
  // ================================

  /**
   * @api {get} /user/me Get info about the current user
   * @apiDescription Get info about the current user
   * @apiGroup Users
   *
   * @apiParam (GET) {String[]} [fields] Fields to return. Defaults to all fields.
   *
   * @apiVersion 0.1.0
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   * @apiUse UserNotFound
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *       "firstName": "Dominik",
   *       "lastName": "Kundel",
   *       "eid": "22850",
   *       "type": "Student",
   *       "email": "d.kundel@jacobs-university.de",
   *       "username": "dkundel",
   *       "major": "Computer Science",
   *       "country": "Germany",
   *       "description": "ug 14 CS"
   *     }
   */
  app.get('/user/me', Controllers.Auth.need, Controllers.User.me);

  /**
   * @api {get} /user/name/:username Get info about a user by username
   * @apiDescription Get info about a user by username
   * @apiGroup Users
   * @apiVersion 0.1.0
   *
   * @apiParam (GET) {String[]} [fields] Fields to return. Defaults to all fields.
   * @apiParam {String} username Username of user to get info about
   *
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   * @apiUse UserNotFound
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *       "firstName": "Dominik",
   *       "lastName": "Kundel",
   *       "eid": "22850",
   *       "type": "Student",
   *       "email": "d.kundel@jacobs-university.de",
   *       "username": "dkundel",
   *       "major": "Computer Science",
   *       "country": "Germany",
   *       "description": "ug 14 CS"
   *     }
   */
  app.get('/user/name/:username', Controllers.Auth.need, Controllers.User.username);

  /**
   * @api {get} /user/id/:id Get info about a user by id
   * @apiDescription Get info about a user by id
   * @apiGroup Users
   * @apiVersion 0.1.0
   *
   * @apiParam (GET) {String[]} [fields] Fields to return. Defaults to all fields.
   * @apiParam {String} id Id of user to get info about
   *
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   * @apiUse UserNotFound
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *       "firstName": "Dominik",
   *       "lastName": "Kundel",
   *       "eid": "22850",
   *       "type": "Student",
   *       "email": "d.kundel@jacobs-university.de",
   *       "username": "dkundel",
   *       "major": "Computer Science",
   *       "country": "Germany",
   *       "description": "ug 14 CS"
   *     }
   */
  app.get('/user/id/:id', Controllers.Auth.need, Controllers.User.id);

  /**
   * @api {get} /user/image/:account/image.jpg Get the image of a user
   * @apiDescription Get the image of a user
   * @apiGroup Users
   * @apiVersion 0.1.0
   *
   * @apiParam {String} account User to display image for
   *
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   * @apiUse UserNotFound
   */
  app.get("/user/image/:account/image.jpg", Controllers.Auth.need, Controllers.User.image);

  //we're not a goat
  app.get('/user/me/isagoat', function(req, res){
    res.status(200).jsonp({
      "isAGoat": false
    });
  })

  // ================================
  // Searches
  // ================================

  /**
   * @api {get} /query/:q Quickly searches for a machine-readable query
   * @apiDescription Quickly searches for a machine-readable query
   * @apiGroup Search
   * @apiVersion 0.1.0
   *
   * @apiParam (GET) {String[]} [fields] Fields to return. Defaults to all fields.
   * @apiParam (GET) {number} [limit] - Maximal number of entries to display
   * @apiParam (GET) {number} [skip] - Skip, number of entries to skip at the beginning
   *
   * @apiParam {String} q The query to search for
   *
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   * @apiUse UserNotFound
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *       "data": [
   *       {
   *         "firstName": "Dominik",
   *         "lastName": "Kundel",
   *         "eid": "22850",
   *         "type": "Student",
   *         "email": "d.kundel@jacobs-university.de",
   *         "username": "dkundel",
   *         "major": "Computer Science",
   *         "country": "Germany",
   *         "description": "ug 14 CS"
   *       }
   *       ],
   *       "next": "",
   *       "prev": ""
   *     }
   */
  app.get('/query/:q', Controllers.Auth.need, Controllers.User.query);

  /**
   * @api {get} /search/:q Searches for a query
   * @apiDescription Searches for a query
   * @apiGroup Search
   * @apiVersion 0.1.0
   *
   * @apiParam (GET) {String[]} [fields] Fields to return. Defaults to all fields.
   * @apiParam (GET) {number} [limit] - Maximal number of entries to display
   * @apiParam (GET) {number} [skip] - Skip, number of entries to skip at the beginning
   *
   * @apiParam {String} q The query to search for
   *
   * @apiUse auth
   * @apiUse TokenNotFound
   * @apiUse InvalidRequest
   * @apiUse UserNotFound
   *
   * @apiSuccessExample Success-Response
   *    HTTP/1.1 200 OK
   *    {
   *       "data": [
   *       {
   *         "firstName": "Dominik",
   *         "lastName": "Kundel",
   *         "eid": "22850",
   *         "type": "Student",
   *         "email": "d.kundel@jacobs-university.de",
   *         "username": "dkundel",
   *         "major": "Computer Science",
   *         "country": "Germany",
   *         "description": "ug 14 CS"
   *       }
   *       ],
   *       "next": "",
   *       "prev": ""
   *     }
   */
  app.get('/search/:q', Controllers.Auth.need, Controllers.User.search);

  // ================================
  // Everything else
  // ================================

  app.get('/*', function (req, res) {
    res.errorJson('RequestNotFound');
  });
  app.post('/*', function (req, res) {
    res.errorJson('RequestNotFound');
  });
  app.put('/*', function (req, res) {
    res.errorJson('RequestNotFound');
  });
  app.delete('/*', function (req, res) {
    res.errorJson('RequestNotFound');
  });
};
<|endoftext|>


<commit_before>var path = require('path')
var fs = require('fs')
var express = require('express')
var hide = require('hide-property')
var debug = require('debug')('bleh:routes')
var getViewName = require('./get-view-name')
var Page = require('./express-page')
var Promise = require('bluebird')

// opts.root
// opts.helpers
// opts.dist
module.exports = function (opts) {
  var dist = opts.dist || 'public/dist'
  var app = express()
  var filename = path.join(opts.root, dist, 'controllers.json')
  var config = JSON.parse(fs.readFileSync(filename)).controllers
  Object.keys(config).forEach(function (name) {
    var needle = 'pages/'
    if (name.substring(0, needle.length) !== needle) {
      return
    }
    var uri = name.substring(needle.length - 1)
    uri = uri.split('$').join(':')

    if (uri === opts.home) {
      app.get(uri, function (req, res) {
        res.redirect('/')
      })
      uri = '/'
    }

    var controllerPath = path.join(opts.root, config[name].path)
    app.all(uri, function (req, res, next) {
      var controller = require(controllerPath)

      var helpers = opts.helpers || {}
      helpers.get = function (fn) {
        if (this.req.method === 'GET') {
          fn()
        }
      }
      helpers.post = function (fn) {
        if (this.req.method === 'POST') {
          fn()
        }
      }
      helpers.session = req.session
      helpers.query = req.query
      helpers.body = req.body
      helpers.send = function (data) {
        this.res.send(data)
      }
      helpers.error = function (err) {
        if (!err) return
        this.res.status(400).send(err)
      }
      helpers.view = function (name) {
        this.setView(name)
      }

      helpers.js = []
      if (config[name].js) {
        helpers.js.push(req.baseUrl + '/dist/' + name + '.js')
      }
      helpers.css = []
      if (config[name].css) {
        helpers.css.push(req.baseUrl + '/dist/' + name + '.css')
      }

      var page = Page(controller, helpers, req, res)
      page.setView(name)
      // make url params available as this.$param
      parseParams.call(page)
      hide(page, 'req')
      hide(page, 'res')
      hide(page, 'templates')
      hide(page, '_layout')
      hide(page, '_layouts')
      hide(page, '_view')
      return Promise.resolve()
      .then(function () {
        return page.run()
      })
      .catch(next)
    })
  })
  return app
}

function parseParams () {
  var self = this
  Object.keys(self.req.params).forEach(function (param) {
    self['$' + param] = self.req.params[param]
  })
}<commit_msg>Update routes.js<commit_after>var path = require('path')
var fs = require('fs')
var express = require('express')
var hide = require('hide-property')
var debug = require('debug')('bleh:routes')
var getViewName = require('./get-view-name')
var Page = require('./express-page')
var Promise = require('bluebird')

// opts.root
// opts.helpers
// opts.dist
module.exports = function (opts) {
  var dist = opts.dist || 'public/dist'
  var app = express()
  var filename = path.join(opts.root, dist, 'controllers.json')
  var config = JSON.parse(fs.readFileSync(filename)).controllers
  Object.keys(config).forEach(function (name) {
    var needle = 'pages/'
    if (name.substring(0, needle.length) !== needle) {
      return
    }
    var uri = name.substring(needle.length - 1)
    uri = uri.split('$').join(':')

    if (uri === opts.home) {
      app.get(uri, function (req, res) {
        res.redirect('/')
      })
      uri = '/'
    }

    var controllerPath = path.join(opts.root, config[name].path)
    app.all(uri, function (req, res, next) {
      var controller = require(controllerPath)

      var helpers = opts.helpers || {}
      helpers.get = function (fn) {
        if (this.req.method === 'GET') {
          fn()
        }
      }
      helpers.post = function (fn) {
        if (this.req.method === 'POST') {
          fn()
        }
      }
      helpers.session = req.session
      helpers.query = req.query
      helpers.body = req.body
      helpers.send = function (data) {
        this.res.send(data)
      }
      helpers.error = function (err) {
        if (!err) return
        this.res.status(400).send(err)
      }
      helpers.view = function (name) {
        this.setView(name)
      }

      helpers.js = []
      if (config[name].js) {
        helpers.js.push(req.baseUrl + '/dist/' + name + '.js')
      }
      helpers.css = []
      if (config[name].css) {
        helpers.css.push(req.baseUrl + '/dist/' + name + '.css')
      }

      var page = Page(controller, helpers, req, res, next)
      page.setView(name)
      // make url params available as this.$param
      parseParams.call(page)
      hide(page, 'req')
      hide(page, 'res')
      hide(page, 'next')
      hide(page, 'templates')
      hide(page, '_layout')
      hide(page, '_layouts')
      hide(page, '_view')
      return Promise.resolve()
      .then(function () {
        return page.run()
      })
      .catch(next)
    })
  })
  return app
}

function parseParams () {
  var self = this
  Object.keys(self.req.params).forEach(function (param) {
    self['$' + param] = self.req.params[param]
  })
}
<|endoftext|>


<commit_before>const path = require('path')

module.exports = {
  type: "react-component",
  npm: {
    esModules: true,
    umd: false
  },
  webpack: {
    uglify: false,
    aliases: {
       // **** You can comment one or more of these in to override an npm module with a local module. *****
      // **** Just be sure to comment them back out before committing! *****
      // "ve-range-utils":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../ve-range-utils/src/"),
      // "ve-sequence-utils":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../ve-sequence-utils/src/"),
      // "bio-parsers":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../ve-sequence-parsers/src/parsers/"),
      // "open-vector-editor":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../openVectorEditor/src/"),
      // "teselagen-react-components":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../teselagen-react-components/src/"),
      // "@teselagen/platform-ux":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../teselagen-platform-ux/src/"),
      // "@teselagen/apollo-methods":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../teselagen-common/apollo-methods/src/"),

      //don't comment this out!
      react: path.resolve("node_modules/react")
    },
    extra: {

      devtool: "source-map",
      module: {
        rules: [{ test: /demo\/src\/examples\//, loader: "raw-loader" }]
      }
    }
  }
};

// webpack: {
//     extra: {
//         devtool: 'inline-source-map'
//     }
// }
<commit_msg>updating nwb<commit_after>const path = require('path')

module.exports = {
  type: "react-component",
  npm: {
    esModules: true,
    umd: false
  },
  webpack: {
    uglify: false,
    aliases: {
       // **** You can comment one or more of these in to override an npm module with a local module. *****
      // **** Just be sure to comment them back out before committing! *****
      // "ve-range-utils":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../ve-range-utils/src/"),
      // "ve-sequence-utils":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../ve-sequence-utils/src/"),
      // "bio-parsers":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../ve-sequence-parsers/src/parsers/"),
      // "open-vector-editor":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../openVectorEditor/src/"),
      // "teselagen-react-components":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../teselagen-react-components/src/"),
      // "@teselagen/platform-ux":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../teselagen-platform-ux/src/"),
      // "@teselagen/apollo-methods":
      //   console.log("comment me back out!") ||
      //   path.resolve("../../teselagen-common/apollo-methods/src/"),

      //don't comment this out!
      react: path.resolve(__dirname, "node_modules/react")
    },
    extra: {

      devtool: "source-map",
      module: {
        rules: [{ test: /demo\/src\/examples\//, loader: "raw-loader" }]
      }
    }
  }
};

// webpack: {
//     extra: {
//         devtool: 'inline-source-map'
//     }
// }
<|endoftext|>