<commit_before>var _ = require('lodash'),
    Exporter = require('./exporter'),
    ramlHelper = require('../helpers/raml'),
    jsonHelper = require('../utils/json'),
    YAML = require('js-yaml');

function RAMLDefinition(title, env) {
  this.title = title;
  //TODO anyway to know version?
  this.version = env.Version;
  this.baseUri = env.Host + env.BasePath;

  this.protocols = mapProtocols(env.Protocols);
}

RAMLDefinition.prototype.addMethod = function(resource, methodURIs, methodKey, method) {
  if (!methodURIs) {
    return;
  }

  if (methodURIs.length <= 0) {
    //reach the leaf of tree
    //TODO optional: check same method existence
    if(!resource.uriParameters) {
      resource.uriParameters = {};
    }
    for (var attrname in method.uriParameters) {
      //uri not available, so check with displayName, which is same
      var isURIParamExist = resource.displayName.split(attrname).length - 1;
      if (isURIParamExist) {
        resource.uriParameters[attrname] = method.uriParameters[attrname];
      }
    }
    delete method.uriParameters;
    resource[methodKey] = method;
  }
  else {
    var currentURI = '/' + methodURIs[0];
    if (!resource[currentURI]) {
      resource[currentURI] = {
        displayName: methodURIs[0],
        description: ''
      };
      //TODO uriParams?!?
    }
    methodURIs.splice(0, 1);
    this.addMethod(resource[currentURI], methodURIs, methodKey, method);
  }
};

function RAML() {
  this.metadata = null;
}

RAML.prototype = new Exporter();

RAML.prototype._mapSecurityScheme = function(slSecuritySchemes) {
  var ramlSecuritySchemes = {};

  if (slSecuritySchemes.hasOwnProperty('oauth2')) {
    var name = slSecuritySchemes.oauth2.name || 'oauth2';
    //missing describedBy, description

    ramlSecuritySchemes[name] = {
      type: 'OAuth 2.0',
      settings: {
        authorizationUri: slSecuritySchemes.oauth2.authorizationUrl,
        accessTokenUri: slSecuritySchemes.oauth2.tokenUrl,
        authorizationGrants: this.mapAuthorizationGrants(slSecuritySchemes.oauth2.flow)
      }
    };
  }

  if (slSecuritySchemes.hasOwnProperty('basic')) {
    var basicName = slSecuritySchemes.basic.name;
    if (basicName) {
      ramlSecuritySchemes[basicName] = {
        type: 'Basic Authentication',
        description: slSecuritySchemes.basic.description || ''
      };
    }
  }

  return ramlSecuritySchemes;
};

RAML.prototype._validateParam = function(params) {
  var acceptedTypes = ['string', 'number', 'integer', 'date', 'boolean', 'file'];
  for(var key in params) {
    var param = params[key];
    for (var prop in param) {
      switch (prop) {
        case 'type':
          var type = params[key].type;
          if (acceptedTypes.indexOf(type) < 0) {
            //not supported type, delete param
            delete params[key];
            continue;
          }
          break;
        case 'enum':
        case 'pattern':
        case 'minLength':
        case 'maxLength':
          if (params[key].type !== 'string') {
            delete params[key][prop];
          }
          break;
        case 'minimum':
        case 'maximum':
          var type = params[key].type.toLowerCase();
          if (type !== 'integer' && type !== 'number') {
            delete params[key][prop];
          }
          break;
        case 'required':
        case 'displayName':
        case 'description':
        case 'example':
        case 'repeat':
        case 'default':
          break;
        default:
          //not supported types
          if (params[key]) {
            delete params[key][prop];
          }
      }
    }
  }

  return params;
};

RAML.prototype._mapRequestBody = function(bodyData, mimeType){
  var body = {};
  if (bodyData.body) {
    if (mimeType === '') {
      return body;
    }

    switch(mimeType) {
      case 'application/json':
        body[mimeType] = this.mapRequestBodyJson(bodyData);
        break;
      case 'multipart/form-data':
      case 'application/x-www-form-urlencoded':
        var parsedBody = jsonHelper.parse(bodyData.body);
        body[mimeType] = this.mapRequestBodyForm(parsedBody);
        break;
      default:
        //unsuported format
        //TODO
    }
  }
  return body;
};

RAML.prototype._mapNamedParams = function(params){
  var newParams = {};
  for(var key in params.properties) {
    newParams[key] = ramlHelper.setParameterFields(params.properties[key], {});
    if(params.required && params.required.indexOf(key) > -1){
      newParams[key].required = true;
    }
    newParams[key] = jsonHelper.orderByKeys(newParams[key], ['type', 'description']);
  }
  return this._validateParam(newParams);
};

RAML.prototype._mapResponseBody = function(responseData, mimeType){
  var responses = {};

  for(var i in responseData) {
    var resBody = responseData[i];
    if(resBody.codes && _.isArray(resBody.codes) && resBody.codes.length>0) {
      var code = resBody.codes[0];
      if (code === 'default' || parseInt(code) == 'NaN') {
        continue;
      }

      responses[code] = {
        body: {}
      };

      if (resBody.description) {
        responses[code]['description'] = resBody.description;
      }

      var type = mimeType;
      if (type) {
        responses[code]['body'][type] = this.mapResponseBody(resBody);
      } else {
        responses[code] = {};
      }

      if (!jsonHelper.isEmptySchema(resBody.headers)) {
        responses[code]['body'][type].headers = this._mapNamedParams(resBody.headers);
      }
    }
  }
  return responses;
};

//TODO: Stoplight doesn't support seperate path params completely yet
RAML.prototype._mapURIParams = function(pathParamData) {
  var pathParams = {};
  if(!pathParamData.properties || Object.keys(pathParamData.properties).length == 0) {
    return pathParams;
  }

  for(var key in pathParamData.properties) {
    var prop = pathParamData.properties[key];

    pathParams[key] = ramlHelper.setParameterFields(prop, {});
    if(prop.description) {
      pathParams[key].displayName = prop.description;
    }

    pathParams[key].type = pathParams[key].type || 'string';
  }

  return this._validateParam(pathParams);
};

function mapProtocols(protocols) {
  if (!protocols || !protocols.length) {
    return [];
  }

  return protocols.reduce(function(res, p) {
    var protocol = p.toUpperCase();

    // RAML supports only HTTP and HTTPS
    if (protocol === 'HTTP' || protocol === 'HTTPS') {
      res.push(protocol);
    }

    return res;
  }, []);
}

RAML.prototype._mapTextSections = function(slTexts) {
  var results = [];
  for (var i in slTexts) {
    var text = slTexts[i];

    if (text.divider || _.isEmpty(text.name) || _.isEmpty(text.content)) {
      continue;
    }

    results.push({
      title: text.name,
      content: text.content
    });
  }
  return results;
};

// from ref=type1 to type=type1
RAML.prototype.convertRefAttFromObject = function(object) {
  for (var id in object) {
    if (object.hasOwnProperty(id)) {
      var val = object[id];
      if (id == 'ref') {
        object.type = val;
        delete object[id];
      } else if ((typeof val) === 'object') {
        object[id] = this.convertRefAttFromObject(val);
      }
    }
  }

  return object;
};

RAML.prototype._mapTraits = function(slTraits) {
  var traits = [];

  for (var i in slTraits) {
    var slTrait = slTraits[i],
        trait = {};

    try {
      var schema = JSON.parse(slTrait.request.queryString);
      if (!jsonHelper.isEmptySchema(schema)) {
        trait.queryParameters = this._mapNamedParams(schema);
      }
    } catch(e) {}

    try {
      var schema = JSON.parse(slTrait.request.headers);
      if (!jsonHelper.isEmptySchema(schema)) {
        trait.headers = this._mapNamedParams(schema);
      }
    } catch(e) {}

    try {
      if (slTrait.responses && slTrait.responses.length) {
        trait.responses = this._mapResponseBody(slTrait.responses);
      }
    } catch(e) {}

    var newTrait = {};
    newTrait[_.camelCase(slTrait.name)] = trait;
    traits.push(newTrait);
  }

  return traits;
};

RAML.prototype._mapEndpointTraits = function(slTraits, endpoint) {
  var is = [];

  for (var i in endpoint.traits) {
    var trait = _.find(slTraits, ['_id', endpoint.traits[i]]);
    if (!trait) {
      continue;
    }
    is.push(_.camelCase(trait.name));
  }

  return is;
};

function getDefaultMimeType(mimeType, defMimeType) {
  var mt = (mimeType && mimeType.length > 0) ? mimeType[0]:null;
  if (!mt) {
    if (_.isArray(defMimeType) && defMimeType.length) {
      mt = defMimeType[0];
    } else if (_.isString(defMimeType) && defMimeType !== '') {
      mt = defMimeType;
    }
  }
  return mt;
};

RAML.prototype._export = function () {
  var env = this.project.Environment;
  var ramlDef = new RAMLDefinition(this.project.Name, env);
  ramlDef.mediaType = this.mapMediaType(env.Consumes, env.Produces);

  ramlDef.documentation = [{
    title: this.project.Name,
    content: this.project.Description
  }];

  var docs = this._mapTextSections(this.project.Texts);
  if (docs.length) {
    ramlDef.documentation = ramlDef.documentation.concat(docs);
  }

  var slSecuritySchemes = this.project.Environment.SecuritySchemes;
  var securitySchemes = this._mapSecurityScheme(slSecuritySchemes);

  // if (Array.isArray(securitySchemes) && securitySchemes.length > 0) {
  if (!_.isEmpty(securitySchemes)) {
    ramlDef.securitySchemes = securitySchemes;
  }

  var endpoints = this.project.Endpoints;

  // Collect endpoints ids from environment resourcesOrder
  var orderedIds = env.resourcesOrder.docs.reduce(function(ids, group) {
    return ids.concat(_.map(_.filter(group.items, {type: 'endpoints'}), '_id'));
  }, []);

  // Sort endpoints similar to resourcesOrder items order
  endpoints.sort(function (a, b) {
    return orderedIds.indexOf(a._id) < orderedIds.indexOf(b._id) ? -1 : 1;
  });

  for(var i in endpoints) {

    var endpoint = endpoints[i];

    var method = {};
    if (endpoint.operationId || endpoint.Name) {
      method.displayName = endpoint.operationId || endpoint.Name;
    }
    if (endpoint.Description) {
      method.description = endpoint.Description;
    }

    var is = this._mapEndpointTraits(this.project.Traits, endpoint);
    if (is.length) {
      method.is = is;
    }

    if (endpoint.Method.toLowerCase() === 'post' ||
        endpoint.Method.toLowerCase() === 'put' ||
        endpoint.Method.toLowerCase() === 'patch') {
      var mimeType = getDefaultMimeType(endpoint.Consumes, ramlDef.mediaType);
      method.body = this._mapRequestBody(endpoint.Body, mimeType);
    }

    method.headers = this._mapNamedParams(endpoint.Headers);

    var mimeType = getDefaultMimeType(endpoint.Produces, ramlDef.mediaType);
    method.responses = this._mapResponseBody(endpoint.Responses, mimeType);

    method.queryParameters = this._mapURIParams(endpoint.QueryString);

    method.uriParameters = this._mapURIParams(endpoint.PathParams);

    if (endpoint.securedBy) {
      var rsecuredBy = [];
      if (endpoint.securedBy.oauth2) {
        rsecuredBy.push(slSecuritySchemes.oauth2.name || 'oauth2');
      }
      if (endpoint.securedBy.basic && slSecuritySchemes.basic.name) {
        rsecuredBy.push(slSecuritySchemes.basic.name);
      }
      if (rsecuredBy.length > 0) {
        method.securedBy = rsecuredBy;
      }
    }

    var uriParts = endpoint.Path.split('/');
    uriParts.splice(0, 1);
    ramlDef.addMethod(ramlDef, uriParts, endpoint.Method, method);
  }

  this.addSchema(ramlDef, this.mapSchema(this.project.Schemas));
  ramlDef.traits = this._mapTraits(this.project.Traits);

  // Clean empty field in definition
  for (var field in ramlDef) {
    if (ramlDef.hasOwnProperty(field) && !ramlDef[field]) {
      delete ramlDef[field];
    }
  }

  this.data = ramlDef;
};

RAML.prototype._getData = function(format) {
  switch (format) {
    case 'yaml':
      return '#%RAML ' + this.version() + '\n'+YAML.dump(JSON.parse(JSON.stringify(this.Data)), {lineWidth: -1});
    default:
      throw Error('RAML doesn not support '+format+' format');
  }
};

RAML.prototype.version = function() { throw new Error('version method not implemented'); };

RAML.prototype.mapMediaType = function(consumes, produces) { throw new Error('media type method not implemented'); };

RAML.prototype.mapAuthorizationGrants = function(flow) { throw new Error('mapAuthorizationGrants method not implemented');  };

RAML.prototype.mapRequestBodyJson = function(bodyData) { throw new Error('mapRequestBodyJson method not implemented'); };

RAML.prototype.mapRequestBodyForm = function(bodyData) { throw new Error('mapRequestBodyForm method not implemented'); };

RAML.prototype.mapResponseBody = function(bodyData) { throw new Error('mapResponseBody method not implemented'); };

RAML.prototype.addSchema = function(ramlDef, schema) { throw new Error('addSchema method not implemented'); };

RAML.prototype.mapSchema = function(schema) { throw new Error('mapSchema method not implemented'); };

module.exports = RAML;
<commit_msg>fixed RAML export protocols isues<commit_after>var _ = require('lodash'),
    Exporter = require('./exporter'),
    ramlHelper = require('../helpers/raml'),
    jsonHelper = require('../utils/json'),
    YAML = require('js-yaml');

function RAMLDefinition(title, env) {
  var protocols = mapProtocols(env.Protocols);

  this.title = title;
  //TODO anyway to know version?
  this.version = env.Version;
  this.baseUri = env.Host + env.BasePath;

  if (protocols.length) {
    this.protocols = protocols;
  }
}

RAMLDefinition.prototype.addMethod = function(resource, methodURIs, methodKey, method) {
  if (!methodURIs) {
    return;
  }

  if (methodURIs.length <= 0) {
    //reach the leaf of tree
    //TODO optional: check same method existence
    if(!resource.uriParameters) {
      resource.uriParameters = {};
    }
    for (var attrname in method.uriParameters) {
      //uri not available, so check with displayName, which is same
      var isURIParamExist = resource.displayName.split(attrname).length - 1;
      if (isURIParamExist) {
        resource.uriParameters[attrname] = method.uriParameters[attrname];
      }
    }
    delete method.uriParameters;
    resource[methodKey] = method;
  }
  else {
    var currentURI = '/' + methodURIs[0];
    if (!resource[currentURI]) {
      resource[currentURI] = {
        displayName: methodURIs[0],
        description: ''
      };
      //TODO uriParams?!?
    }
    methodURIs.splice(0, 1);
    this.addMethod(resource[currentURI], methodURIs, methodKey, method);
  }
};

function RAML() {
  this.metadata = null;
}

RAML.prototype = new Exporter();

RAML.prototype._mapSecurityScheme = function(slSecuritySchemes) {
  var ramlSecuritySchemes = {};

  if (slSecuritySchemes.hasOwnProperty('oauth2')) {
    var name = slSecuritySchemes.oauth2.name || 'oauth2';
    //missing describedBy, description

    ramlSecuritySchemes[name] = {
      type: 'OAuth 2.0',
      settings: {
        authorizationUri: slSecuritySchemes.oauth2.authorizationUrl,
        accessTokenUri: slSecuritySchemes.oauth2.tokenUrl,
        authorizationGrants: this.mapAuthorizationGrants(slSecuritySchemes.oauth2.flow)
      }
    };
  }

  if (slSecuritySchemes.hasOwnProperty('basic')) {
    var basicName = slSecuritySchemes.basic.name;
    if (basicName) {
      ramlSecuritySchemes[basicName] = {
        type: 'Basic Authentication',
        description: slSecuritySchemes.basic.description || ''
      };
    }
  }

  return ramlSecuritySchemes;
};

RAML.prototype._validateParam = function(params) {
  var acceptedTypes = ['string', 'number', 'integer', 'date', 'boolean', 'file'];
  for(var key in params) {
    var param = params[key];
    for (var prop in param) {
      switch (prop) {
        case 'type':
          var type = params[key].type;
          if (acceptedTypes.indexOf(type) < 0) {
            //not supported type, delete param
            delete params[key];
            continue;
          }
          break;
        case 'enum':
        case 'pattern':
        case 'minLength':
        case 'maxLength':
          if (params[key].type !== 'string') {
            delete params[key][prop];
          }
          break;
        case 'minimum':
        case 'maximum':
          var type = params[key].type.toLowerCase();
          if (type !== 'integer' && type !== 'number') {
            delete params[key][prop];
          }
          break;
        case 'required':
        case 'displayName':
        case 'description':
        case 'example':
        case 'repeat':
        case 'default':
          break;
        default:
          //not supported types
          if (params[key]) {
            delete params[key][prop];
          }
      }
    }
  }

  return params;
};

RAML.prototype._mapRequestBody = function(bodyData, mimeType){
  var body = {};
  if (bodyData.body) {
    if (mimeType === '') {
      return body;
    }

    switch(mimeType) {
      case 'application/json':
        body[mimeType] = this.mapRequestBodyJson(bodyData);
        break;
      case 'multipart/form-data':
      case 'application/x-www-form-urlencoded':
        var parsedBody = jsonHelper.parse(bodyData.body);
        body[mimeType] = this.mapRequestBodyForm(parsedBody);
        break;
      default:
        //unsuported format
        //TODO
    }
  }
  return body;
};

RAML.prototype._mapNamedParams = function(params){
  var newParams = {};
  for(var key in params.properties) {
    newParams[key] = ramlHelper.setParameterFields(params.properties[key], {});
    if(params.required && params.required.indexOf(key) > -1){
      newParams[key].required = true;
    }
    newParams[key] = jsonHelper.orderByKeys(newParams[key], ['type', 'description']);
  }
  return this._validateParam(newParams);
};

RAML.prototype._mapResponseBody = function(responseData, mimeType){
  var responses = {};

  for(var i in responseData) {
    var resBody = responseData[i];
    if(resBody.codes && _.isArray(resBody.codes) && resBody.codes.length>0) {
      var code = resBody.codes[0];
      if (code === 'default' || parseInt(code) == 'NaN') {
        continue;
      }

      responses[code] = {
        body: {}
      };

      if (resBody.description) {
        responses[code]['description'] = resBody.description;
      }

      var type = mimeType;
      if (type) {
        responses[code]['body'][type] = this.mapResponseBody(resBody);
      } else {
        responses[code] = {};
      }

      if (!jsonHelper.isEmptySchema(resBody.headers)) {
        responses[code]['body'][type].headers = this._mapNamedParams(resBody.headers);
      }
    }
  }
  return responses;
};

//TODO: Stoplight doesn't support seperate path params completely yet
RAML.prototype._mapURIParams = function(pathParamData) {
  var pathParams = {};
  if(!pathParamData.properties || Object.keys(pathParamData.properties).length == 0) {
    return pathParams;
  }

  for(var key in pathParamData.properties) {
    var prop = pathParamData.properties[key];

    pathParams[key] = ramlHelper.setParameterFields(prop, {});
    if(prop.description) {
      pathParams[key].displayName = prop.description;
    }

    pathParams[key].type = pathParams[key].type || 'string';
  }

  return this._validateParam(pathParams);
};

function mapProtocols(protocols) {
  if (!protocols || !protocols.length) {
    return [];
  }

  return protocols.reduce(function(res, p) {
    var protocol = p.toUpperCase();

    // RAML supports only HTTP and HTTPS
    if (protocol === 'HTTP' || protocol === 'HTTPS') {
      res.push(protocol);
    }

    return res;
  }, []);
}

RAML.prototype._mapTextSections = function(slTexts) {
  var results = [];
  for (var i in slTexts) {
    var text = slTexts[i];

    if (text.divider || _.isEmpty(text.name) || _.isEmpty(text.content)) {
      continue;
    }

    results.push({
      title: text.name,
      content: text.content
    });
  }
  return results;
};

// from ref=type1 to type=type1
RAML.prototype.convertRefAttFromObject = function(object) {
  for (var id in object) {
    if (object.hasOwnProperty(id)) {
      var val = object[id];
      if (id == 'ref') {
        object.type = val;
        delete object[id];
      } else if ((typeof val) === 'object') {
        object[id] = this.convertRefAttFromObject(val);
      }
    }
  }

  return object;
};

RAML.prototype._mapTraits = function(slTraits) {
  var traits = [];

  for (var i in slTraits) {
    var slTrait = slTraits[i],
        trait = {};

    try {
      var schema = JSON.parse(slTrait.request.queryString);
      if (!jsonHelper.isEmptySchema(schema)) {
        trait.queryParameters = this._mapNamedParams(schema);
      }
    } catch(e) {}

    try {
      var schema = JSON.parse(slTrait.request.headers);
      if (!jsonHelper.isEmptySchema(schema)) {
        trait.headers = this._mapNamedParams(schema);
      }
    } catch(e) {}

    try {
      if (slTrait.responses && slTrait.responses.length) {
        trait.responses = this._mapResponseBody(slTrait.responses);
      }
    } catch(e) {}

    var newTrait = {};
    newTrait[_.camelCase(slTrait.name)] = trait;
    traits.push(newTrait);
  }

  return traits;
};

RAML.prototype._mapEndpointTraits = function(slTraits, endpoint) {
  var is = [];

  for (var i in endpoint.traits) {
    var trait = _.find(slTraits, ['_id', endpoint.traits[i]]);
    if (!trait) {
      continue;
    }
    is.push(_.camelCase(trait.name));
  }

  return is;
};

function getDefaultMimeType(mimeType, defMimeType) {
  var mt = (mimeType && mimeType.length > 0) ? mimeType[0]:null;
  if (!mt) {
    if (_.isArray(defMimeType) && defMimeType.length) {
      mt = defMimeType[0];
    } else if (_.isString(defMimeType) && defMimeType !== '') {
      mt = defMimeType;
    }
  }
  return mt;
};

RAML.prototype._export = function () {
  var env = this.project.Environment;
  var ramlDef = new RAMLDefinition(this.project.Name, env);
  ramlDef.mediaType = this.mapMediaType(env.Consumes, env.Produces);

  ramlDef.documentation = [{
    title: this.project.Name,
    content: this.project.Description
  }];

  var docs = this._mapTextSections(this.project.Texts);
  if (docs.length) {
    ramlDef.documentation = ramlDef.documentation.concat(docs);
  }

  var slSecuritySchemes = this.project.Environment.SecuritySchemes;
  var securitySchemes = this._mapSecurityScheme(slSecuritySchemes);

  // if (Array.isArray(securitySchemes) && securitySchemes.length > 0) {
  if (!_.isEmpty(securitySchemes)) {
    ramlDef.securitySchemes = securitySchemes;
  }

  var endpoints = this.project.Endpoints;

  // Collect endpoints ids from environment resourcesOrder
  var orderedIds = env.resourcesOrder.docs.reduce(function(ids, group) {
    return ids.concat(_.map(_.filter(group.items, {type: 'endpoints'}), '_id'));
  }, []);

  // Sort endpoints similar to resourcesOrder items order
  endpoints.sort(function (a, b) {
    return orderedIds.indexOf(a._id) < orderedIds.indexOf(b._id) ? -1 : 1;
  });

  for(var i in endpoints) {

    var endpoint = endpoints[i];

    var method = {};
    if (endpoint.operationId || endpoint.Name) {
      method.displayName = endpoint.operationId || endpoint.Name;
    }
    if (endpoint.Description) {
      method.description = endpoint.Description;
    }

    var is = this._mapEndpointTraits(this.project.Traits, endpoint);
    if (is.length) {
      method.is = is;
    }

    if (endpoint.Method.toLowerCase() === 'post' ||
        endpoint.Method.toLowerCase() === 'put' ||
        endpoint.Method.toLowerCase() === 'patch') {
      var mimeType = getDefaultMimeType(endpoint.Consumes, ramlDef.mediaType);
      method.body = this._mapRequestBody(endpoint.Body, mimeType);
    }

    method.headers = this._mapNamedParams(endpoint.Headers);

    var mimeType = getDefaultMimeType(endpoint.Produces, ramlDef.mediaType);
    method.responses = this._mapResponseBody(endpoint.Responses, mimeType);

    method.queryParameters = this._mapURIParams(endpoint.QueryString);

    method.uriParameters = this._mapURIParams(endpoint.PathParams);

    if (endpoint.securedBy) {
      var rsecuredBy = [];
      if (endpoint.securedBy.oauth2) {
        rsecuredBy.push(slSecuritySchemes.oauth2.name || 'oauth2');
      }
      if (endpoint.securedBy.basic && slSecuritySchemes.basic.name) {
        rsecuredBy.push(slSecuritySchemes.basic.name);
      }
      if (rsecuredBy.length > 0) {
        method.securedBy = rsecuredBy;
      }
    }

    var uriParts = endpoint.Path.split('/');
    uriParts.splice(0, 1);
    ramlDef.addMethod(ramlDef, uriParts, endpoint.Method, method);
  }

  this.addSchema(ramlDef, this.mapSchema(this.project.Schemas));
  ramlDef.traits = this._mapTraits(this.project.Traits);

  // Clean empty field in definition
  for (var field in ramlDef) {
    if (ramlDef.hasOwnProperty(field) && !ramlDef[field]) {
      delete ramlDef[field];
    }
  }

  this.data = ramlDef;
};

RAML.prototype._getData = function(format) {
  switch (format) {
    case 'yaml':
      return '#%RAML ' + this.version() + '\n'+YAML.dump(JSON.parse(JSON.stringify(this.Data)), {lineWidth: -1});
    default:
      throw Error('RAML doesn not support '+format+' format');
  }
};

RAML.prototype.version = function() { throw new Error('version method not implemented'); };

RAML.prototype.mapMediaType = function(consumes, produces) { throw new Error('media type method not implemented'); };

RAML.prototype.mapAuthorizationGrants = function(flow) { throw new Error('mapAuthorizationGrants method not implemented');  };

RAML.prototype.mapRequestBodyJson = function(bodyData) { throw new Error('mapRequestBodyJson method not implemented'); };

RAML.prototype.mapRequestBodyForm = function(bodyData) { throw new Error('mapRequestBodyForm method not implemented'); };

RAML.prototype.mapResponseBody = function(bodyData) { throw new Error('mapResponseBody method not implemented'); };

RAML.prototype.addSchema = function(ramlDef, schema) { throw new Error('addSchema method not implemented'); };

RAML.prototype.mapSchema = function(schema) { throw new Error('mapSchema method not implemented'); };

module.exports = RAML;
<|endoftext|>


<commit_before>
// Express - Collection - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)

/**
 * Throw $break in order to stop iteration.
 */

$break = '__break__'

// --- Collection

Collection = Class({

  /**
   * Initialize collection with an array-like object.
   *
   * @param  {object} arr
   * @api private
   */

  init: function(arr) {
    this.arr = arr
  },

  /**
   * Return the value of _index_ or null.
   *
   * @param  {int} index
   * @return {mixed}
   * @api public
   */

  at: function(index) {
    if ('length' in this.arr)
      return this.arr[index]
    var result, i = 0
    this.each(function(val){
      if (i++ == index) {
        result = val
        throw $break
      }
    })
    return result
  },

  /**
   * Iterate collection using callback _fn_,
   * passing both the value and index.
   *
   * @param  {function} fn
   * @return {Collection}
   * @api public
   */

  each: function(fn) {
    try {
      if (this.arr.forEach)
        this.arr.forEach(fn)
      else
        for (var key in this.arr)
          if (this.arr.hasOwnProperty(key))
            fn(this.arr[key], key)
    }
    catch (e) {
      if (e != $break) throw e
    }
    return this
  },

  /**
   * Iterate with _memo_ using callback _fn_.
   * The _memo_ object is passed as the first
   * argument, and the return value of _fn_ becomes
   * the value of _memo_ providing a functional
   * approach to reducing a collection.
   *
   * @param  {mixed} memo
   * @param  {function} fn
   * @return {mixed}
   * @api public
   */

  reduce: function(memo, fn) {
    if (this.arr.reduce)
      return this.arr.reduce(fn, memo)
    this.each(function(val, key){
      memo = fn(memo, val, key)
    })
    return memo
  },

  /**
   * Map using callback _fn_, returning a
   * new collection of return values.
   *
   * @param  {function} fn
   * @return {Collection}
   * @api public
   */

  map: function(fn) {
    if (this.arr.map)
      return $(this.arr.map(fn))
    return $(this.reduce([], function(array, val, key){
      array.push(fn(val, key))
      return array
    }))
  },

  /**
   * Return collection of values when _fn_ evaluates
   * to true.
   *
   * @param  {function} fn
   * @return {Collection}
   * @api public
   */

  select: function(fn) {
    return $(this.reduce([], function(array, val, key){
      if (fn(val, key))
        array.push(val)
      return array
    }))
  },

  /**
   * Return collection of values when _fn_ evaluates
   * to false.
   *
   * @param  {function} fn
   * @return {Collection}
   * @api public
   */

  reject: function(fn) {
    return $(this.reduce([], function(array, val, key){
      if (!fn(val, key))
        array.push(val)
      return array
    }))
  },

  /**
   * Return the first _n_ value(s), defaults to 1.
   *
   * @param  {int} n
   * @return {mixed}
   * @api public
   */

  first: function(n) {
    return n ? this.slice(0, n) : this.at(0)
  },

  /**
   * Return a slice of values from _start_ to _end_.
   *
   * @param  {int} start
   * @param  {int} end
   * @return {Collection}
   * @api public
   */

  slice: function(start, end) {
    if (this.arr.slice)
      return $(this.arr.slice(start, end))
    var i = 0
    return $(this.reduce([], function(array, val){
      if (i++ >= start)
        if (i <= end)
          array.push(val)
        else
          throw $break
      return array
    }))
  },

  /**
   * Iterate until _fn_ evaluates to true, then
   * return the matching value.
   *
   * @param  {function} fn
   * @return {mixed}
   * @api public
   */

  find: function(fn) {
    var result
    this.each(function(val, key){
      if (fn(val, key)) {
        result = val
        throw $break
      }
    })
    return result
  },

  /**
   * Return true if _fn_ ever evaluates to true, otherwise
   * returns false.
   *
   * @param  {function} fn
   * @return {bool}
   * @api public
   */

  any: function(fn) {
    if (this.arr.some)
      return this.arr.some(fn)
    return !! this.find(fn)
  },

  /**
   * Returns true if _fn_ always evaluates to true, otherwise
   * returns false.
   *
   * @param  {function} fn
   * @return {bool}
   * @api public
   */

  all: function(fn) {
    if (this.arr.every)
      return this.arr.every(fn)
    return this.reduce(true, function(state, val, key){
      if (!state) throw $break
      return !! fn(val, key)
    })
  },

  /**
   * Select values matching _pattern_
   *
   * @param  {regexp} pattern
   * @return {Collection}
   * @api public
   */

  grep: function(pattern) {
    return this.select(function(val){
      return pattern.exec(val)
    })
  },

  /**
   * Return keys as a collection.
   *
   * @return {Collection}
   * @api public
   */

  keys: function() {
    return $(this.reduce([], function(array, val, key){
      array.push(key)
      return array
    }))
  },

  /**
   * Convert a collection to a true array.
   * Works recursively
   *
   * @return {array}
   * @api public
   */

  toArray: function() {
    return this.reduce([], function(array, val){
      if (val instanceof Collection)
        array.push(val.toArray())
      else
        array.push(val)
      return array
    })
  },

  /**
   * Return the lowest number in the collection.
   *
   * @return {number}
   * @api public
   */

  min: function() {
    return this.reduce(null, function(min, val){
      return min === null ? val :
          val < min ? val :
            min
    })
  },

  /**
   * Return the largest number in the collection.
   *
   * @return {number}
   * @api public
   */

  max: function() {
    return this.reduce(null, function(max, val){
      return max === null ? val :
        val > max ? val :
          max
    })
  },

  /**
   * Group collection into several collections grouped by _size_.
   *
   * @param  {int} size
   * @return {Collection}
   * @api public
   */

  chunk: function(size) {
    var len = this.arr.length,
        chunks = [], chunk = [], i = 0
    this.each(function(val, key){
      chunk.push(val)
      if (i++ > 0 && (i % size == 0 || i == len))
        chunks.push($(chunk)),
        chunk = []
    })
    return $(chunks)
  },

  /**
   * Return the length of this collection.
   *
   * @return {int}
   * @api public
   */

  length: function() {
    return this.reduce(0, function(len){
      return ++len
    })
  }
})

/**
 * Create a new collection from an array-like object.
 *
 * @param  {object} arr
 * @return {Collection}
 * @api public
 */

var $ = exports.$ = function(arr) {
  if (arr instanceof Collection) return arr
  return new Collection(arr)
}<commit_msg>Refactored Collection#length()<commit_after>
// Express - Collection - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)

/**
 * Throw $break in order to stop iteration.
 */

$break = '__break__'

// --- Collection

Collection = Class({

  /**
   * Initialize collection with an array-like object.
   *
   * @param  {object} arr
   * @api private
   */

  init: function(arr) {
    this.arr = arr
  },

  /**
   * Return the value of _index_ or null.
   *
   * @param  {int} index
   * @return {mixed}
   * @api public
   */

  at: function(index) {
    if ('length' in this.arr)
      return this.arr[index]
    var result, i = 0
    this.each(function(val){
      if (i++ == index) {
        result = val
        throw $break
      }
    })
    return result
  },

  /**
   * Iterate collection using callback _fn_,
   * passing both the value and index.
   *
   * @param  {function} fn
   * @return {Collection}
   * @api public
   */

  each: function(fn) {
    try {
      if (this.arr.forEach)
        this.arr.forEach(fn)
      else
        for (var key in this.arr)
          if (this.arr.hasOwnProperty(key))
            fn(this.arr[key], key)
    }
    catch (e) {
      if (e != $break) throw e
    }
    return this
  },

  /**
   * Iterate with _memo_ using callback _fn_.
   * The _memo_ object is passed as the first
   * argument, and the return value of _fn_ becomes
   * the value of _memo_ providing a functional
   * approach to reducing a collection.
   *
   * @param  {mixed} memo
   * @param  {function} fn
   * @return {mixed}
   * @api public
   */

  reduce: function(memo, fn) {
    if (this.arr.reduce)
      return this.arr.reduce(fn, memo)
    this.each(function(val, key){
      memo = fn(memo, val, key)
    })
    return memo
  },

  /**
   * Map using callback _fn_, returning a
   * new collection of return values.
   *
   * @param  {function} fn
   * @return {Collection}
   * @api public
   */

  map: function(fn) {
    if (this.arr.map)
      return $(this.arr.map(fn))
    return $(this.reduce([], function(array, val, key){
      array.push(fn(val, key))
      return array
    }))
  },

  /**
   * Return collection of values when _fn_ evaluates
   * to true.
   *
   * @param  {function} fn
   * @return {Collection}
   * @api public
   */

  select: function(fn) {
    return $(this.reduce([], function(array, val, key){
      if (fn(val, key))
        array.push(val)
      return array
    }))
  },

  /**
   * Return collection of values when _fn_ evaluates
   * to false.
   *
   * @param  {function} fn
   * @return {Collection}
   * @api public
   */

  reject: function(fn) {
    return $(this.reduce([], function(array, val, key){
      if (!fn(val, key))
        array.push(val)
      return array
    }))
  },

  /**
   * Return the first _n_ value(s), defaults to 1.
   *
   * @param  {int} n
   * @return {mixed}
   * @api public
   */

  first: function(n) {
    return n ? this.slice(0, n) : this.at(0)
  },

  /**
   * Return a slice of values from _start_ to _end_.
   *
   * @param  {int} start
   * @param  {int} end
   * @return {Collection}
   * @api public
   */

  slice: function(start, end) {
    if (this.arr.slice)
      return $(this.arr.slice(start, end))
    var i = 0
    return $(this.reduce([], function(array, val){
      if (i++ >= start)
        if (i <= end)
          array.push(val)
        else
          throw $break
      return array
    }))
  },

  /**
   * Iterate until _fn_ evaluates to true, then
   * return the matching value.
   *
   * @param  {function} fn
   * @return {mixed}
   * @api public
   */

  find: function(fn) {
    var result
    this.each(function(val, key){
      if (fn(val, key)) {
        result = val
        throw $break
      }
    })
    return result
  },

  /**
   * Return true if _fn_ ever evaluates to true, otherwise
   * returns false.
   *
   * @param  {function} fn
   * @return {bool}
   * @api public
   */

  any: function(fn) {
    if (this.arr.some)
      return this.arr.some(fn)
    return !! this.find(fn)
  },

  /**
   * Returns true if _fn_ always evaluates to true, otherwise
   * returns false.
   *
   * @param  {function} fn
   * @return {bool}
   * @api public
   */

  all: function(fn) {
    if (this.arr.every)
      return this.arr.every(fn)
    return this.reduce(true, function(state, val, key){
      if (!state) throw $break
      return !! fn(val, key)
    })
  },

  /**
   * Select values matching _pattern_
   *
   * @param  {regexp} pattern
   * @return {Collection}
   * @api public
   */

  grep: function(pattern) {
    return this.select(function(val){
      return pattern.exec(val)
    })
  },

  /**
   * Return keys as a collection.
   *
   * @return {Collection}
   * @api public
   */

  keys: function() {
    return $(this.reduce([], function(array, val, key){
      array.push(key)
      return array
    }))
  },

  /**
   * Convert a collection to a true array.
   * Works recursively
   *
   * @return {array}
   * @api public
   */

  toArray: function() {
    return this.reduce([], function(array, val){
      if (val instanceof Collection)
        array.push(val.toArray())
      else
        array.push(val)
      return array
    })
  },

  /**
   * Return the lowest number in the collection.
   *
   * @return {number}
   * @api public
   */

  min: function() {
    return this.reduce(null, function(min, val){
      return min === null ? val :
          val < min ? val :
            min
    })
  },

  /**
   * Return the largest number in the collection.
   *
   * @return {number}
   * @api public
   */

  max: function() {
    return this.reduce(null, function(max, val){
      return max === null ? val :
        val > max ? val :
          max
    })
  },

  /**
   * Group collection into several collections grouped by _size_.
   *
   * @param  {int} size
   * @return {Collection}
   * @api public
   */

  chunk: function(size) {
    var len = this.arr.length,
        chunks = [], chunk = [], i = 0
    this.each(function(val, key){
      chunk.push(val)
      if (i++ > 0 && (i % size == 0 || i == len))
        chunks.push($(chunk)),
        chunk = []
    })
    return $(chunks)
  },

  /**
   * Return the length of this collection.
   *
   * @return {int}
   * @api public
   */

  length: function() {
    if ('length' in this.arr)
      return this.arr.length
    return this.reduce(0, function(len){
      return ++len
    })
  }
})

/**
 * Create a new collection from an array-like object.
 *
 * @param  {object} arr
 * @return {Collection}
 * @api public
 */

var $ = exports.$ = function(arr) {
  if (arr instanceof Collection) return arr
  return new Collection(arr)
}<|endoftext|>


<commit_before>import { AbstractTheme } from '../theme'

export var bootstrap4Theme = AbstractTheme.extend({
  /* Theme config options that allows changing various aspects of the output */
  options: {
    'disable_theme_rules': false
  },
  /* Custom stylesheet rules. format: "selector" : "CSS rules" */
  rules: {
    'div[data-schemaid="root"]:after': 'position:relative;color:red;margin:10px 0;font-weight:600;display:block;width:100%;text-align:center;content:"This is an old JSON-Editor 1.x Theme and might not display elements correctly when used with the 2.x version"'
  },
  getSelectInput: function (options, multiple) {
    var el = this._super(options)
    el.classList.add('form-control')
    // el.style.width = 'auto';
    return el
  },
  setGridColumnSize: function (el, size, offset) {
    el.classList.add('col-md-' + size)
    if (offset) {
      el.classList.add('offset-md-' + offset)
    }
  },
  afterInputReady: function (input) {
    if (input.controlgroup) return
    input.controlgroup = this.closest(input, '.form-group')
    if (this.closest(input, '.compact')) {
      input.controlgroup.style.marginBottom = 0
    }

    // TODO: use bootstrap slider
  },
  getTextareaInput: function () {
    var el = document.createElement('textarea')
    el.classList.add('form-control')
    return el
  },
  getRangeInput: function (min, max, step) {
    // TODO: use better slider
    return this._super(min, max, step)
  },
  getFormInputField: function (type) {
    var el = this._super(type)
    if (type !== 'checkbox' && type !== 'radio') {
      el.classList.add('form-control')
    }
    return el
  },

  getFormControl: function (label, input, description) {
    var group = document.createElement('div')
    group.classList.add('form-group')

    if (label && (input.type === 'checkbox' || input.type === 'radio')) {
      var check = document.createElement('div')
      check.classList.add('form-check')

      input.classList.add('form-check-input')
      label.classList.add('form-check-label')

      // todo: nest input under label? not bootstrap default, can we set an unique ID here?
      input.id = input.name // no name yet available?
      label.for = input.id

      check.appendChild(input)
      check.appendChild(label)

      group.appendChild(check)
    } else {
      if (label) {
        group.appendChild(label)
      }

      group.appendChild(input)
    }

    if (description) {
      group.appendChild(description)
    }

    return group
  },

  /**
   * Multiple checkboxes in a row.
   *
   */
  getMultiCheckboxHolder: function (controls, label, description, infoText) {
    var el = document.createElement('div')
    el.classList.add('form-group')

    if (label) {
      label.style.display = 'block'
      el.appendChild(label)

      if (infoText) {
        label.appendChild(infoText)
      }
    }

    for (var i in controls) {
      if (!controls.hasOwnProperty(i)) {
        continue
      }

      // controls are already parsed by getFormControl() so they have an .form-group
      // wrapper we need to get rid of...
      var ctrl = controls[i].firstChild

      ctrl.classList.add('form-check-inline')
      el.appendChild(ctrl)
    }

    if (description) el.appendChild(description)

    return el
  },
  getIndentedPanel: function () {
    var el = document.createElement('div')
    el.classList.add('card', 'card-body', 'bg-light')
    return el
  },

  getFormInputDescription: function (text) {
    var el = document.createElement('small')
    el.classList.add('form-text')

    if (window.DOMPurify) {
      el.innerHTML = window.DOMPurify.sanitize(text)
    } else {
      el.textContent = this.cleanText(text)
    }

    return el
  },

  getHeaderButtonHolder: function () {
    var el = this.getButtonHolder()
    el.style.marginLeft = '10px'
    return el
  },
  getButtonHolder: function () {
    var el = document.createElement('div')
    el.classList.add('btn-group')
    return el
  },
  getButton: function (text, icon, title) {
    var el = this._super(text, icon, title)
    el.classList.add('btn', 'btn-secondary')
    return el
  },
  getTable: function () {
    var el = document.createElement('table')
    el.classList.add('table-bordered', 'table-sm')
    el.style.width = 'auto'
    el.style.maxWidth = 'none'
    return el
  },

  addInputError: function (input, text) {
    if (!input.controlgroup) return
    input.controlgroup.classList.add('has-danger')
    input.classList.add('is-invalid')
    if (!input.errmsg) {
      input.errmsg = document.createElement('p')
      input.errmsg.classList.add('form-text', 'invalid-feedback')
      input.controlgroup.appendChild(input.errmsg)
    } else {
      input.errmsg.style.display = ''
    }

    input.errmsg.textContent = text
  },
  removeInputError: function (input) {
    if (!input.errmsg) return
    input.errmsg.style.display = 'none'
    input.classList.remove('is-invalid')
    input.controlgroup.classList.remove('has-danger')
  },
  getTabHolder: function (propertyName) {
    var el = document.createElement('div')
    var pName = (typeof propertyName === 'undefined') ? '' : propertyName
    el.innerHTML = "

"
    el.classList.add('row')
    return el
  },
  addTab: function (holder, tab) {
    holder.children[0].children[0].appendChild(tab)
  },
  getTopTabHolder: function (propertyName) {
    var pName = (typeof propertyName === 'undefined') ? '' : propertyName
    var el = document.createElement('div')
    el.innerHTML = "

"
    return el
  },
  getTab: function (text, tabId) {
    var liel = document.createElement('li')
    liel.classList.add('nav-item')
    var ael = document.createElement('a')
    ael.classList.add('nav-link')
    ael.setAttribute('style', 'padding:10px;')
    ael.setAttribute('href', '#' + tabId)
    ael.setAttribute('data-toggle', 'tab')
    ael.appendChild(text)
    liel.appendChild(ael)
    return liel
  },
  getTopTab: function (text, tabId) {
    var el = document.createElement('li')
    el.classList.add('nav-item')
    var a = document.createElement('a')
    a.classList.add('nav-link')
    a.setAttribute('href', '#' + tabId)
    a.setAttribute('data-toggle', 'tab')
    a.appendChild(text)
    el.appendChild(a)
    return el
  },
  getTabContent: function () {
    var el = document.createElement('div')
    el.classList.add('tab-pane')
    el.setAttribute('role', 'tabpanel')
    return el
  },
  getTopTabContent: function () {
    var el = document.createElement('div')
    el.classList.add('tab-pane')
    el.setAttribute('role', 'tabpanel')
    return el
  },
  markTabActive: function (row) {
    row.tab.firstChild.classList.add('active')

    if (typeof row.rowPane !== 'undefined') {
      row.rowPane.classList.add('active')
    } else {
      row.container.classList.add('active')
    }
  },
  markTabInactive: function (row) {
    row.tab.firstChild.classList.remove('active')

    if (typeof row.rowPane !== 'undefined') {
      row.rowPane.classList.remove('active')
    } else {
      row.container.classList.remove('active')
    }
  },
  getProgressBar: function () {
    var min = 0
    var max = 100
    var start = 0

    var container = document.createElement('div')
    container.classList.add('progress')

    var bar = document.createElement('div')
    bar.classList.add('progress-bar')
    bar.setAttribute('role', 'progressbar')
    bar.setAttribute('aria-valuenow', start)
    bar.setAttribute('aria-valuemin', min)
    bar.setAttribute('aria-valuenax', max)
    bar.innerHTML = start + '%'
    container.appendChild(bar)

    return container
  },
  updateProgressBar: function (progressBar, progress) {
    if (!progressBar) return

    var bar = progressBar.firstChild
    var percentage = progress + '%'
    bar.setAttribute('aria-valuenow', progress)
    bar.style.width = percentage
    bar.innerHTML = percentage
  },
  updateProgressBarUnknown: function (progressBar) {
    if (!progressBar) return

    var bar = progressBar.firstChild
    progressBar.classList.add('progress', 'progress-striped', 'active')
    bar.removeAttribute('aria-valuenow')
    bar.style.width = '100%'
    bar.innerHTML = ''
  },
  getInputGroup: function (input, buttons) {
    if (!input) return

    var inputGroupContainer = document.createElement('div')
    inputGroupContainer.classList.add('input-group')
    inputGroupContainer.appendChild(input)

    var inputGroup = document.createElement('div')
    inputGroup.classList.add('input-group-prepend')
    inputGroupContainer.appendChild(inputGroup)

    for (var i = 0; i < buttons.length; i++) {
      inputGroup.appendChild(buttons[i])
    }

    return inputGroupContainer
  }
})
<commit_msg>twbs4 radios stacked / inline<commit_after>import { AbstractTheme } from '../theme'

export var bootstrap4Theme = AbstractTheme.extend({
  /* Theme config options that allows changing various aspects of the output */
  options: {
    'disable_theme_rules': false
  },
  /* Custom stylesheet rules. format: "selector" : "CSS rules" */
  rules: {
    'div[data-schemaid="root"]:after': 'position:relative;color:red;margin:10px 0;font-weight:600;display:block;width:100%;text-align:center;content:"This is an old JSON-Editor 1.x Theme and might not display elements correctly when used with the 2.x version"'
  },

  getSelectInput: function (options, multiple) {
    var el = this._super(options)
    el.classList.add('form-control')
    // el.style.width = 'auto';
    return el
  },

  setGridColumnSize: function (el, size, offset) {
    el.classList.add('col-md-' + size)

    if (offset) {
      el.classList.add('offset-md-' + offset)
    }
  },

  afterInputReady: function (input) {
    if (input.controlgroup) return

    input.controlgroup = this.closest(input, '.form-group')

    // TODO: use bootstrap slider
  },

  getTextareaInput: function () {
    var el = document.createElement('textarea')
    el.classList.add('form-control')
    return el
  },

  getRangeInput: function (min, max, step) {
    // TODO: use better slider
    return this._super(min, max, step)
  },

  getFormInputField: function (type) {
    var el = this._super(type)
    if (type !== 'checkbox' && type !== 'radio') {
      el.classList.add('form-control')
    }
    return el
  },

  getFormControl: function (label, input, description) {
    var group = document.createElement('div')
    group.classList.add('form-group')

    if (label && (input.type === 'checkbox' || input.type === 'radio')) {
      var check = document.createElement('div')
      check.classList.add('form-check')

      input.classList.add('form-check-input')
      label.classList.add('form-check-label')

      // todo: nest input under label? not bootstrap default, can we set an unique ID here?
      input.id = input.name // no name yet available?
      label.for = input.id

      check.appendChild(input)
      check.appendChild(label)

      group.appendChild(check)
    } else {
      if (label) {
        group.appendChild(label)
      }

      group.appendChild(input)
    }

    if (description) {
      group.appendChild(description)
    }

    return group
  },

  /**
   * Multiple checkboxes in a row.
   *
   */
  getMultiCheckboxHolder: function (controls, label, description, infoText) {
    var el = document.createElement('div')
    el.classList.add('form-group')

    if (label) {
      label.style.display = 'block'
      el.appendChild(label)

      if (infoText) {
        label.appendChild(infoText)
      }
    }

    for (var i in controls) {
      if (!controls.hasOwnProperty(i)) {
        continue
      }

      // controls are already parsed by getFormControl() so they have an .form-group
      // wrapper we need to get rid of...
      var ctrl = controls[i].firstChild

      ctrl.classList.add('form-check-inline')
      el.appendChild(ctrl)
    }

    if (description) el.appendChild(description)

    return el
  },

  /**
   * Single radio element
   */
  getFormRadio: function (attributes) {
    var el = this.getFormInputField('radio')

    for (var key in attributes) {
      el.setAttribute(key, attributes[key])
    }

    el.classList.add('form-check-input')

    return el
  },

  /**
   * Add the  for the single radio from getFormRadio()
   *
   */
  getFormRadioLabel: function (text, req) {
    var el = document.createElement('label')
    el.classList.add('form-check-label')
    el.appendChild(document.createTextNode(text))
    return el
  },

  /**
   * Stack the radios from getFormRadio()/getFormRadioLabel()
   *
   */
  getFormRadioControl: function (label, input, compact) {
    var el = document.createElement('div')
    el.classList.add('form-check')

    el.appendChild(input)
    el.appendChild(label)

    if (compact) {
      el.classList.add('form-check-inline')
    }

    return el
  },

  getIndentedPanel: function () {
    var el = document.createElement('div')
    el.classList.add('card', 'card-body', 'bg-light')
    return el
  },

  getFormInputDescription: function (text) {
    var el = document.createElement('small')
    el.classList.add('form-text')

    if (window.DOMPurify) {
      el.innerHTML = window.DOMPurify.sanitize(text)
    } else {
      el.textContent = this.cleanText(text)
    }

    return el
  },

  getHeaderButtonHolder: function () {
    var el = this.getButtonHolder()
    el.style.marginLeft = '10px'
    return el
  },
  getButtonHolder: function () {
    var el = document.createElement('div')
    el.classList.add('btn-group')
    return el
  },
  getButton: function (text, icon, title) {
    var el = this._super(text, icon, title)
    el.classList.add('btn', 'btn-secondary')
    return el
  },
  getTable: function () {
    var el = document.createElement('table')
    el.classList.add('table-bordered', 'table-sm')
    el.style.width = 'auto'
    el.style.maxWidth = 'none'
    return el
  },

  addInputError: function (input, text) {
    if (!input.controlgroup) return
    input.controlgroup.classList.add('has-danger')
    input.classList.add('is-invalid')
    if (!input.errmsg) {
      input.errmsg = document.createElement('p')
      input.errmsg.classList.add('form-text', 'invalid-feedback')
      input.controlgroup.appendChild(input.errmsg)
    } else {
      input.errmsg.style.display = ''
    }

    input.errmsg.textContent = text
  },
  removeInputError: function (input) {
    if (!input.errmsg) return
    input.errmsg.style.display = 'none'
    input.classList.remove('is-invalid')
    input.controlgroup.classList.remove('has-danger')
  },
  getTabHolder: function (propertyName) {
    var el = document.createElement('div')
    var pName = (typeof propertyName === 'undefined') ? '' : propertyName
    el.innerHTML = "

"
    el.classList.add('row')
    return el
  },
  addTab: function (holder, tab) {
    holder.children[0].children[0].appendChild(tab)
  },
  getTopTabHolder: function (propertyName) {
    var pName = (typeof propertyName === 'undefined') ? '' : propertyName
    var el = document.createElement('div')
    el.innerHTML = "

"
    return el
  },
  getTab: function (text, tabId) {
    var liel = document.createElement('li')
    liel.classList.add('nav-item')
    var ael = document.createElement('a')
    ael.classList.add('nav-link')
    ael.setAttribute('style', 'padding:10px;')
    ael.setAttribute('href', '#' + tabId)
    ael.setAttribute('data-toggle', 'tab')
    ael.appendChild(text)
    liel.appendChild(ael)
    return liel
  },
  getTopTab: function (text, tabId) {
    var el = document.createElement('li')
    el.classList.add('nav-item')
    var a = document.createElement('a')
    a.classList.add('nav-link')
    a.setAttribute('href', '#' + tabId)
    a.setAttribute('data-toggle', 'tab')
    a.appendChild(text)
    el.appendChild(a)
    return el
  },
  getTabContent: function () {
    var el = document.createElement('div')
    el.classList.add('tab-pane')
    el.setAttribute('role', 'tabpanel')
    return el
  },
  getTopTabContent: function () {
    var el = document.createElement('div')
    el.classList.add('tab-pane')
    el.setAttribute('role', 'tabpanel')
    return el
  },
  markTabActive: function (row) {
    row.tab.firstChild.classList.add('active')

    if (typeof row.rowPane !== 'undefined') {
      row.rowPane.classList.add('active')
    } else {
      row.container.classList.add('active')
    }
  },
  markTabInactive: function (row) {
    row.tab.firstChild.classList.remove('active')

    if (typeof row.rowPane !== 'undefined') {
      row.rowPane.classList.remove('active')
    } else {
      row.container.classList.remove('active')
    }
  },
  getProgressBar: function () {
    var min = 0
    var max = 100
    var start = 0

    var container = document.createElement('div')
    container.classList.add('progress')

    var bar = document.createElement('div')
    bar.classList.add('progress-bar')
    bar.setAttribute('role', 'progressbar')
    bar.setAttribute('aria-valuenow', start)
    bar.setAttribute('aria-valuemin', min)
    bar.setAttribute('aria-valuenax', max)
    bar.innerHTML = start + '%'
    container.appendChild(bar)

    return container
  },
  updateProgressBar: function (progressBar, progress) {
    if (!progressBar) return

    var bar = progressBar.firstChild
    var percentage = progress + '%'
    bar.setAttribute('aria-valuenow', progress)
    bar.style.width = percentage
    bar.innerHTML = percentage
  },
  updateProgressBarUnknown: function (progressBar) {
    if (!progressBar) return

    var bar = progressBar.firstChild
    progressBar.classList.add('progress', 'progress-striped', 'active')
    bar.removeAttribute('aria-valuenow')
    bar.style.width = '100%'
    bar.innerHTML = ''
  },
  getInputGroup: function (input, buttons) {
    if (!input) return

    var inputGroupContainer = document.createElement('div')
    inputGroupContainer.classList.add('input-group')
    inputGroupContainer.appendChild(input)

    var inputGroup = document.createElement('div')
    inputGroup.classList.add('input-group-prepend')
    inputGroupContainer.appendChild(inputGroup)

    for (var i = 0; i < buttons.length; i++) {
      inputGroup.appendChild(buttons[i])
    }

    return inputGroupContainer
  }
})
<|endoftext|>


<commit_before>function JuegoLaberinto(){
	this.nombre="JuegoLaberinto";
	this.laberinto=null;
	this.crearLaberinto=function(){
		this.laberinto=new Laberinto();
		var h1=new Habitacion();
		var h2=new Habitacion();
		var puerta=new Puerta(h1,h2);
		//h1.lados[0]=puerta;
		//h2.lados[2]=puerta;
		h1.norte=puerta;
		h2.sur=puerta;
		this.laberinto.agregarHabitacion(h1);
		this.laberinto.agregarHabitacion(h2);
		return this.laberinto
	}
}

function Laberinto(){
	this.nombre="Laberinto";
	this.habitaciones=[];
	this.agregarHabitacion=function(hab){
		hab.id=this.habitaciones.length;
		this.habitaciones.push(hab);
	}
	this.obtenerHabitacion=function(num){
		return this.habitaciones[num];
	}
}

function Pared(){
	this.nombre="Pared";
}

function Habitacion(){
	this.nombre="Habitacion";
	this.id=null;
	this.lados=[];
	this.norte=null;
	this.este=null;
	this.oeste=null;
	this.sur=null;
	this.agregarLado=function(em){
		this.lados.push(em);
	}
	//this.lados.push(new Pared());
	//this.lados.push(new Pared());
	//this.lados.push(new Pared());
	//this.lados.push(new Pared());
	this.norte=new Pared();
	this.este=new Pared();
	this.oeste=new Pared();
	this.sur=new Pared();
}

function Puerta(h1,h2){
	this.nombre="Puerta";
	this.h1=h1;
	this.h2=h2;
}

function Norte(){
	this.nombre="Norte";
}

function Este(){
	this.nombre="Este";
}
function Oeste(){
	this.nombre="Oeste";
}
function Sur(){
	this.nombre="Sur";
}<commit_msg>js nv<commit_after>function JuegoLaberinto(){
	this.nombre="JuegoLaberinto";
	this.laberinto=null;
	this.crearLaberinto=function(){
		this.laberinto=new Laberinto();
		var h1=new Habitacion();
		var h2=new Habitacion();
		var puerta=new Puerta(h1,h2);
		//h1.lados[0]=puerta;
		//h2.lados[2]=puerta;
		h1.norte=puerta;
		h2.sur=puerta;
		this.laberinto.agregarHabitacion(h1);
		this.laberinto.agregarHabitacion(h2);
		return this.laberinto
	}
}

function Laberinto(){
	this.nombre="Laberinto";
	this.habitaciones=[];
	this.agregarHabitacion=function(hab){
		hab.id=this.habitaciones.length;
		this.habitaciones.push(hab);
	}
	this.obtenerHabitacion=function(num){
		return this.habitaciones[num];
	}
}

function Pared(){
	this.nombre="Pared";
}

function Habitacion(){
	this.nombre="Habitacion";
	this.id=null;
	//this.lados=[];
	this.norte=null;
	this.este=null;
	this.oeste=null;
	this.sur=null;
	//this.agregarLado=function(em){
	//	this.lados.push(em);
	//}
	//this.lados.push(new Pared());
	//this.lados.push(new Pared());
	//this.lados.push(new Pared());
	//this.lados.push(new Pared());
	this.norte=new Pared();
	this.este=new Pared();
	this.oeste=new Pared();
	this.sur=new Pared();
}

function Puerta(h1,h2){
	this.nombre="Puerta";
	this.h1=h1;
	this.h2=h2;
}

function Norte(){
	this.nombre="Norte";
}

function Este(){
	this.nombre="Este";
}
function Oeste(){
	this.nombre="Oeste";
}
function Sur(){
	this.nombre="Sur";
}<|endoftext|>


<commit_before>'use strict';

var resolve   = require('path').resolve
  , lstat     = require('fs').lstat
  , deferred  = require('deferred')
  , watchPath = require('./watch-path')

  , isRoot, watch;

isRoot = function (path) {
	var def, gPath;

	gPath = resolve(path, '.git');
	def = deferred();
	lstat(gPath, function (err, stats) {
		def.resolve(err ? false : stats.isDirectory());
	});
	def.promise.path = gPath;
	return def.promise;
};

watch = function (path) {
	var promise = isRoot(path);
	watchPath(promise.path).on('change', function (event) {
		if (event.type === 'create') {
			promise.value = true;
		} else if (event.type == 'remove') {
			promise.value = false;
		} else {
			return;
		}
		promise.emit('change', promise.value, path);
	});
	return promise;
};

module.exports = exports = function (path) {
	var options, promise;
	path = resolve(String(path));
	options = arguments[1];
	return (options && options.watch) ? watch(path) : isRoot(path);
};
exports.isRoot = isRoot;
exports.watch = watch;
<commit_msg>Expose all needed paths on promise<commit_after>'use strict';

var resolve   = require('path').resolve
  , lstat     = require('fs').lstat
  , deferred  = require('deferred')
  , watchPath = require('./watch-path')

  , isRoot, watch;

isRoot = function (path) {
	var def, gPath;

	gPath = resolve(path, '.git');
	def = deferred();
	lstat(gPath, function (err, stats) {
		def.resolve(err ? false : stats.isDirectory());
	});
	def.promise.gitPath = gPath;
	def.promise.path = path;
	return def.promise;
};

watch = function (path) {
	var promise = isRoot(path);
	watchPath(promise.gitPath).on('change', function (event) {
		if (event.type === 'create') {
			promise.value = true;
		} else if (event.type == 'remove') {
			promise.value = false;
		} else {
			return;
		}
		promise.emit('change', promise.value, path);
	});
	return promise;
};

module.exports = exports = function (path) {
	var options, promise;
	path = resolve(String(path));
	options = arguments[1];
	return (options && options.watch) ? watch(path) : isRoot(path);
};
exports.isRoot = isRoot;
exports.watch = watch;
<|endoftext|>


<commit_before>(function($) {
	$.entwine('ss.zenvalidator', function($) {

		$('form.parsley').entwine({
			onmatch: function() {
					// Fix validation for optionset based class (attributes not set on child options)
					$(this).find('.optionset').each(function() {
						var attrs = $.makeArray(this.attributes);
						var parsley = {};
						for(var i=0; i < attrs.length; i++) {
							var att = attrs[i];
							if(att.name.indexOf('parsley-') !== -1) {
								parsley[att.name] = att.value;
							}
						}
						$(this).find('input').attr(parsley);
					});

        			$(this).parsley({
            				excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden], :hidden, .ignore-validation'
        			});
			}
		});

		$('.field').entwine({

			getFormField: function() {
				return this.find('[name='+this.getFieldName()+'], [name="'+this.getFieldName()+'[]"]');
			},

			getFieldName: function() {
				return this.attr('id');
			},

			getFieldValue: function() {
				return this.getFormField().val();
			},

			evaluateEqualTo: function(val) {
				return this.getFieldValue() === val;
			},

			evaluateNotEqualTo: function(val) {
				return this.getFieldValue() !== val;
			},

			evaluateLessThan: function(val) {
				num = parseFloat(val);
				return this.getFieldValue() < num;
			},

			evaluateGreaterThan: function(val) {
				num = parseFloat(val);
				return parseFloat(this.getFieldValue()) > num;
			},

			evaluateContains: function(val) {
				return this.getFieldValue().match(val) !== null;
			},

			evaluateEmpty: function() {
				return $.trim(this.getFieldValue()).length === 0;
			},

			evaluateNotEmpty: function() {
				return !this.evaluateEmpty();
			},

			evaluateChecked: function() {
				return this.getFormField().is(":checked");
			}

		});

		$('.field.validation-logic').entwine({
			onmatch: function () {
				masters = this.getMasters();
				for(m in masters) {
					this.closest('form').find('#'+masters[m]).addClass("validation-logic-master");
				}
			},

			getLogic: function() {
				return $.trim(this.getFormField().data('validation-logic-eval'));
			},

			parseLogic: function() {
				js = this.getLogic();
				result = eval(js);
				return result;
			},

			getMasters: function() {
				return this.getFormField().data('validation-logic-masters').split(",");
			}

		});

		$('.field.optionset').entwine({

			getFormField: function() {
				f = this._super().filter(":checked");
				return f;
			}

		});

		$('.field.optionset.checkboxset').entwine({

			evaluateHasCheckedOption: function(val) {
				this.find(':checkbox').filter(':checked').each(function() {
					return $(this).val() === val || $(this).getLabel() === val;
				})
			},

			evaluateHasCheckedAtLeast: function(num) {
				return this.find(':checked').length >= num;
			},

			evaluateHasCheckedLessThan: function(num) {
				return this.find(':checked').length <= num;
			}
		});

		$('.field input[type=checkbox]').entwine({
			getLabel: function() {
				return this.closest('form').find('label[for='+this.attr('id')+']');
			}
		});

		$('.field.validation-logic.validation-logic-validate').entwine({
			testLogic: function() {
				this.getFormField().toggleClass('ignore-validation', this.parseLogic());
			}
		});

		$('.field.validation-logic.validation-logic-exclude').entwine({
			testLogic: function() {
				this.getFormField().toggleClass('ignore-validation', !this.parseLogic());
			}
		});

		$('.field.validation-logic-master :text, .field.validation-logic-master select').entwine({
			onmatch: function() {
				this.closest(".field").notify();
			},

			onchange: function() {
				this.closest(".field").notify();
			}
		});

		$('.field.validation-logic-master :checkbox, .field.validation-logic-master :radio').entwine({
			onmatch: function() {
				this.closest(".field").notify();
			},

			onclick: function() {
				this.closest(".field").notify();
			}
		});

		$('.field.validation-logic-master').entwine({
			Listeners: null,

			notify: function() {
				$.each(this.getListeners(), function() {
					$(this).testLogic();
				});
			},

			getListeners: function() {
				if(l = this._super()) {
					return l;
				}
				var self = this;
				var listeners = [];
				this.closest("form").find('.validation-logic').each(function() {
					masters = $(this).getMasters();
					for(m in masters) {
						if(masters[m] == self.attr('id')) {
							listeners.push($(this));
							break;
						}
					}
				});
				this.setListeners(listeners);
				return this.getListeners();
			}
		});
	});

})(jQuery);
<commit_msg>fix error placement for optionsetfield<commit_after>(function($) {
	$.entwine('ss.zenvalidator', function($) {

		$('form.parsley').entwine({
			onmatch: function() {
					// Fix validation for optionset based class (attributes not set on child options)
					$(this).find('.optionset').each(function() {
						var attrs = $.makeArray(this.attributes);
						var parsley = {};
						for(var i=0; i < attrs.length; i++) {
							var att = attrs[i];
							if(att.name.indexOf('parsley-') !== -1) {
								parsley[att.name] = att.value;
							}
						}
						$(this).find('input').attr(parsley);
					});

        			$(this).parsley({
            				excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden], :hidden, .ignore-validation',
							errorsContainer: function (el) {
								return el.$element.closest(".field");
							}
        			});
			}
		});

		$('.field').entwine({

			getFormField: function() {
				return this.find('[name='+this.getFieldName()+'], [name="'+this.getFieldName()+'[]"]');
			},

			getFieldName: function() {
				return this.attr('id');
			},

			getFieldValue: function() {
				return this.getFormField().val();
			},

			evaluateEqualTo: function(val) {
				return this.getFieldValue() === val;
			},

			evaluateNotEqualTo: function(val) {
				return this.getFieldValue() !== val;
			},

			evaluateLessThan: function(val) {
				num = parseFloat(val);
				return this.getFieldValue() < num;
			},

			evaluateGreaterThan: function(val) {
				num = parseFloat(val);
				return parseFloat(this.getFieldValue()) > num;
			},

			evaluateContains: function(val) {
				return this.getFieldValue().match(val) !== null;
			},

			evaluateEmpty: function() {
				return $.trim(this.getFieldValue()).length === 0;
			},

			evaluateNotEmpty: function() {
				return !this.evaluateEmpty();
			},

			evaluateChecked: function() {
				return this.getFormField().is(":checked");
			}

		});

		$('.field.validation-logic').entwine({
			onmatch: function () {
				masters = this.getMasters();
				for(m in masters) {
					this.closest('form').find('#'+masters[m]).addClass("validation-logic-master");
				}
			},

			getLogic: function() {
				return $.trim(this.getFormField().data('validation-logic-eval'));
			},

			parseLogic: function() {
				js = this.getLogic();
				result = eval(js);
				return result;
			},

			getMasters: function() {
				return this.getFormField().data('validation-logic-masters').split(",");
			}

		});

		$('.field.optionset').entwine({

			getFormField: function() {
				f = this._super().filter(":checked");
				return f;
			}

		});

		$('.field.optionset.checkboxset').entwine({

			evaluateHasCheckedOption: function(val) {
				this.find(':checkbox').filter(':checked').each(function() {
					return $(this).val() === val || $(this).getLabel() === val;
				})
			},

			evaluateHasCheckedAtLeast: function(num) {
				return this.find(':checked').length >= num;
			},

			evaluateHasCheckedLessThan: function(num) {
				return this.find(':checked').length <= num;
			}
		});

		$('.field input[type=checkbox]').entwine({
			getLabel: function() {
				return this.closest('form').find('label[for='+this.attr('id')+']');
			}
		});

		$('.field.validation-logic.validation-logic-validate').entwine({
			testLogic: function() {
				this.getFormField().toggleClass('ignore-validation', this.parseLogic());
			}
		});

		$('.field.validation-logic.validation-logic-exclude').entwine({
			testLogic: function() {
				this.getFormField().toggleClass('ignore-validation', !this.parseLogic());
			}
		});

		$('.field.validation-logic-master :text, .field.validation-logic-master select').entwine({
			onmatch: function() {
				this.closest(".field").notify();
			},

			onchange: function() {
				this.closest(".field").notify();
			}
		});

		$('.field.validation-logic-master :checkbox, .field.validation-logic-master :radio').entwine({
			onmatch: function() {
				this.closest(".field").notify();
			},

			onclick: function() {
				this.closest(".field").notify();
			}
		});

		$('.field.validation-logic-master').entwine({
			Listeners: null,

			notify: function() {
				$.each(this.getListeners(), function() {
					$(this).testLogic();
				});
			},

			getListeners: function() {
				if(l = this._super()) {
					return l;
				}
				var self = this;
				var listeners = [];
				this.closest("form").find('.validation-logic').each(function() {
					masters = $(this).getMasters();
					for(m in masters) {
						if(masters[m] == self.attr('id')) {
							listeners.push($(this));
							break;
						}
					}
				});
				this.setListeners(listeners);
				return this.getListeners();
			}
		});
	});

})(jQuery);
<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
//  Copyright (C) 2008-2011  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// MenuBar
//============================================================================

var IPython = (function (IPython) {

    var MenuBar = function (selector) {
        this.selector = selector;
        if (this.selector !== undefined) {
            this.element = $(selector);
            this.style();
            this.bind_events();
        }
    };

    MenuBar.prototype.style = function () {
        this.element.addClass('border-box-sizing');
        $('ul#menus').menubar({
            select : function (event, ui) {
                // The selected cell loses focus when the menu is entered, so we
                // re-select it upon selection.
                var i = IPython.notebook.get_selected_index();
                IPython.notebook.select(i);
            }
        });
    };

    MenuBar.prototype.bind_events = function () {
        //  File
        this.element.find('#new_notebook').click(function () {
            window.open($('body').data('baseProjectUrl')+'new');
        });
        this.element.find('#open_notebook').click(function () {
            window.open($('body').data('baseProjectUrl'));
        });
        this.element.find('#rename_notebook').click(function () {
            IPython.save_widget.rename_notebook();
        });
        this.element.find('#copy_notebook').click(function () {
            var notebook_id = IPython.notebook.get_notebook_id();
            var url = $('body').data('baseProjectUrl') + notebook_id + '/copy';
            window.open(url,'_blank');
            return false;
        });
        this.element.find('#save_notebook').click(function () {
            IPython.notebook.save_notebook();
        });
        this.element.find('#download_ipynb').click(function () {
            var notebook_id = IPython.notebook.get_notebook_id();
            var url = $('body').data('baseProjectUrl') + 'notebooks/' +
                      notebook_id + '?format=json';
            window.location.assign(url);
        });
        this.element.find('#download_py').click(function () {
            var notebook_id = IPython.notebook.get_notebook_id();
            var url = $('body').data('baseProjectUrl') + 'notebooks/' +
                      notebook_id + '?format=py';
            window.location.assign(url);
        });
        this.element.find('button#print_notebook').click(function () {
            IPython.print_widget.print_notebook();
        });
        this.element.find('#kill_and_exit').click(function () {
            IPython.notebook.kernel.kill();
            setTimeout(function(){window.close();}, 200);
        });
        // Edit
        this.element.find('#cut_cell').click(function () {
            IPython.notebook.cut_cell();
        });
        this.element.find('#copy_cell').click(function () {
            IPython.notebook.copy_cell();
        });
        this.element.find('#delete_cell').click(function () {
            IPython.notebook.delete_cell();
        });
        this.element.find('#split_cell').click(function () {
            IPython.notebook.split_cell();
        });
        this.element.find('#merge_cell_above').click(function () {
            IPython.notebook.merge_cell_above();
        });
        this.element.find('#merge_cell_below').click(function () {
            IPython.notebook.merge_cell_below();
        });
        this.element.find('#move_cell_up').click(function () {
            IPython.notebook.move_cell_up();
        });
        this.element.find('#move_cell_down').click(function () {
            IPython.notebook.move_cell_down();
        });
        this.element.find('#select_previous').click(function () {
            IPython.notebook.select_prev();
        });
        this.element.find('#select_next').click(function () {
            IPython.notebook.select_next();
        });
        // View
        this.element.find('#toggle_header').click(function () {
            $('div#header').toggle();
            IPython.layout_manager.do_resize();
        });
        this.element.find('#toggle_toolbar').click(function () {
            IPython.toolbar.toggle();
        });
        // Insert
        this.element.find('#insert_cell_above').click(function () {
            IPython.notebook.insert_cell_above('code');
        });
        this.element.find('#insert_cell_below').click(function () {
            IPython.notebook.insert_cell_below('code');
        });
        // Cell
        this.element.find('#run_cell').click(function () {
            IPython.notebook.execute_selected_cell();
        });
        this.element.find('#run_cell_in_place').click(function () {
            IPython.notebook.execute_selected_cell({terminal:true});
        });
        this.element.find('#run_all_cells').click(function () {
            IPython.notebook.execute_all_cells();
        }).attr('title', 'Run all cells in the notebook');
        this.element.find('#run_all_cells_above').click(function () {
            IPython.notebook.execute_cells_above();
        }).attr('title', 'Run all cells above (but not including) this cell');
        this.element.find('#run_all_cells_below').click(function () {
            IPython.notebook.execute_cells_below();
        }).attr('title', 'Run this cell and all cells below it');
        this.element.find('#to_code').click(function () {
            IPython.notebook.to_code();
        });
        this.element.find('#to_markdown').click(function () {
            IPython.notebook.to_markdown();
        });
        this.element.find('#to_raw').click(function () {
            IPython.notebook.to_raw();
        });
        this.element.find('#to_heading1').click(function () {
            IPython.notebook.to_heading(undefined, 1);
        });
        this.element.find('#to_heading2').click(function () {
            IPython.notebook.to_heading(undefined, 2);
        });
        this.element.find('#to_heading3').click(function () {
            IPython.notebook.to_heading(undefined, 3);
        });
        this.element.find('#to_heading4').click(function () {
            IPython.notebook.to_heading(undefined, 4);
        });
        this.element.find('#to_heading5').click(function () {
            IPython.notebook.to_heading(undefined, 5);
        });
        this.element.find('#to_heading6').click(function () {
            IPython.notebook.to_heading(undefined, 6);
        });
        this.element.find('#toggle_output').click(function () {
            IPython.notebook.toggle_output();
        });
        this.element.find('#collapse_all_output').click(function () {
            IPython.notebook.collapse_all_output();
        });
        this.element.find('#scroll_all_output').click(function () {
            IPython.notebook.scroll_all_output();
        });
        this.element.find('#expand_all_output').click(function () {
            IPython.notebook.expand_all_output();
        });
        this.element.find('#clear_all_output').click(function () {
            IPython.notebook.clear_all_output();
        });
        // Kernel
        this.element.find('#int_kernel').click(function () {
            IPython.notebook.kernel.interrupt();
        });
        this.element.find('#restart_kernel').click(function () {
            IPython.notebook.restart_kernel();
        });
        // Help
        this.element.find('#keyboard_shortcuts').click(function () {
            IPython.quick_help.show_keyboard_shortcuts();
        });
    };

    IPython.MenuBar = MenuBar;

    return IPython;

}(IPython));
<commit_msg>make baseProjectUrl a method in Menubar<commit_after>//----------------------------------------------------------------------------
//  Copyright (C) 2008-2011  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// MenuBar
//============================================================================

var IPython = (function (IPython) {

    var MenuBar = function (selector) {
        this.selector = selector;
        if (this.selector !== undefined) {
            this.element = $(selector);
            this.style();
            this.bind_events();
        }
    };

    MenuBar.prototype.baseProjectUrl = function(){
        return $('body').data('baseProjectUrl');
    }

    MenuBar.prototype.style = function () {
        this.element.addClass('border-box-sizing');
        $('ul#menus').menubar({
            select : function (event, ui) {
                // The selected cell loses focus when the menu is entered, so we
                // re-select it upon selection.
                var i = IPython.notebook.get_selected_index();
                IPython.notebook.select(i);
            }
        });
    };

    MenuBar.prototype.bind_events = function () {
        //  File
        this.element.find('#new_notebook').click(function () {
            window.open(this.baseProjectUrl()+'new');
        });
        this.element.find('#open_notebook').click(function () {
            window.open(this.baseProjectUrl());
        });
        this.element.find('#rename_notebook').click(function () {
            IPython.save_widget.rename_notebook();
        });
        this.element.find('#copy_notebook').click(function () {
            var notebook_id = IPython.notebook.get_notebook_id();
            var url = this.baseProjectUrl() + notebook_id + '/copy';
            window.open(url,'_blank');
            return false;
        });
        this.element.find('#save_notebook').click(function () {
            IPython.notebook.save_notebook();
        });
        this.element.find('#download_ipynb').click(function () {
            var notebook_id = IPython.notebook.get_notebook_id();
            var url = this.baseProjectUrl() + 'notebooks/' +
                      notebook_id + '?format=json';
            window.location.assign(url);
        });
        this.element.find('#download_py').click(function () {
            var notebook_id = IPython.notebook.get_notebook_id();
            var url = this.baseProjectUrl() + 'notebooks/' +
                      notebook_id + '?format=py';
            window.location.assign(url);
        });
        this.element.find('button#print_notebook').click(function () {
            IPython.print_widget.print_notebook();
        });
        this.element.find('#kill_and_exit').click(function () {
            IPython.notebook.kernel.kill();
            setTimeout(function(){window.close();}, 200);
        });
        // Edit
        this.element.find('#cut_cell').click(function () {
            IPython.notebook.cut_cell();
        });
        this.element.find('#copy_cell').click(function () {
            IPython.notebook.copy_cell();
        });
        this.element.find('#delete_cell').click(function () {
            IPython.notebook.delete_cell();
        });
        this.element.find('#split_cell').click(function () {
            IPython.notebook.split_cell();
        });
        this.element.find('#merge_cell_above').click(function () {
            IPython.notebook.merge_cell_above();
        });
        this.element.find('#merge_cell_below').click(function () {
            IPython.notebook.merge_cell_below();
        });
        this.element.find('#move_cell_up').click(function () {
            IPython.notebook.move_cell_up();
        });
        this.element.find('#move_cell_down').click(function () {
            IPython.notebook.move_cell_down();
        });
        this.element.find('#select_previous').click(function () {
            IPython.notebook.select_prev();
        });
        this.element.find('#select_next').click(function () {
            IPython.notebook.select_next();
        });
        // View
        this.element.find('#toggle_header').click(function () {
            $('div#header').toggle();
            IPython.layout_manager.do_resize();
        });
        this.element.find('#toggle_toolbar').click(function () {
            IPython.toolbar.toggle();
        });
        // Insert
        this.element.find('#insert_cell_above').click(function () {
            IPython.notebook.insert_cell_above('code');
        });
        this.element.find('#insert_cell_below').click(function () {
            IPython.notebook.insert_cell_below('code');
        });
        // Cell
        this.element.find('#run_cell').click(function () {
            IPython.notebook.execute_selected_cell();
        });
        this.element.find('#run_cell_in_place').click(function () {
            IPython.notebook.execute_selected_cell({terminal:true});
        });
        this.element.find('#run_all_cells').click(function () {
            IPython.notebook.execute_all_cells();
        }).attr('title', 'Run all cells in the notebook');
        this.element.find('#run_all_cells_above').click(function () {
            IPython.notebook.execute_cells_above();
        }).attr('title', 'Run all cells above (but not including) this cell');
        this.element.find('#run_all_cells_below').click(function () {
            IPython.notebook.execute_cells_below();
        }).attr('title', 'Run this cell and all cells below it');
        this.element.find('#to_code').click(function () {
            IPython.notebook.to_code();
        });
        this.element.find('#to_markdown').click(function () {
            IPython.notebook.to_markdown();
        });
        this.element.find('#to_raw').click(function () {
            IPython.notebook.to_raw();
        });
        this.element.find('#to_heading1').click(function () {
            IPython.notebook.to_heading(undefined, 1);
        });
        this.element.find('#to_heading2').click(function () {
            IPython.notebook.to_heading(undefined, 2);
        });
        this.element.find('#to_heading3').click(function () {
            IPython.notebook.to_heading(undefined, 3);
        });
        this.element.find('#to_heading4').click(function () {
            IPython.notebook.to_heading(undefined, 4);
        });
        this.element.find('#to_heading5').click(function () {
            IPython.notebook.to_heading(undefined, 5);
        });
        this.element.find('#to_heading6').click(function () {
            IPython.notebook.to_heading(undefined, 6);
        });
        this.element.find('#toggle_output').click(function () {
            IPython.notebook.toggle_output();
        });
        this.element.find('#collapse_all_output').click(function () {
            IPython.notebook.collapse_all_output();
        });
        this.element.find('#scroll_all_output').click(function () {
            IPython.notebook.scroll_all_output();
        });
        this.element.find('#expand_all_output').click(function () {
            IPython.notebook.expand_all_output();
        });
        this.element.find('#clear_all_output').click(function () {
            IPython.notebook.clear_all_output();
        });
        // Kernel
        this.element.find('#int_kernel').click(function () {
            IPython.notebook.kernel.interrupt();
        });
        this.element.find('#restart_kernel').click(function () {
            IPython.notebook.restart_kernel();
        });
        // Help
        this.element.find('#keyboard_shortcuts').click(function () {
            IPython.quick_help.show_keyboard_shortcuts();
        });
    };

    IPython.MenuBar = MenuBar;

    return IPython;

}(IPython));
<|endoftext|>