<commit_before>// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.
exports.path = {};
exports.path.getFileNameWithoutExtension = getFileNameWithoutExtension;
exports.path.getDirectoryName = getDirectoryName;

exports.getHtmlId = getHtmlId;

exports.getViewSourceHref = getViewSourceHref;
exports.getImproveTheDocHref = getImproveTheDocHref;
exports.processSeeAlso = processSeeAlso;

exports.isAbsolutePath = isAbsolutePath;
exports.isRelativePath = isRelativePath;

function getFileNameWithoutExtension(path) {
    if (!path || path[path.length - 1] === '/' || path[path.length - 1] === '\\') return '';
    var fileName = path.split('\\').pop().split('/').pop();
    return fileName.slice(0, fileName.lastIndexOf('.'));
}

function getDirectoryName(path) {
    if (!path) return '';
    var index = path.lastIndexOf('/');
    return path.slice(0, index + 1);
}

function getHtmlId(input) {
    if (!input) return '';
    return input.replace(/\W/g, '_');
}

// Note: the parameter `gitContribute` won't be used in this function
function getViewSourceHref(item, gitContribute, gitUrlPattern) {
    if (!item || !item.source || !item.source.remote) return '';
    return getRemoteUrl(item.source.remote, item.source.startLine - '0' + 1, null, gitUrlPattern);
}

function getImproveTheDocHref(item, gitContribute, gitUrlPattern) {
    if (!item) return '';
    if (!item.documentation || !item.documentation.remote) {
        return getNewFileUrl(item, gitContribute, gitUrlPattern);
    } else {
        return getRemoteUrl(item.documentation.remote, item.documentation.startLine + 1, gitContribute, gitUrlPattern);
    }
}

function processSeeAlso(item) {
    if (item.seealso) {
        for (var key in item.seealso) {
            addIsCref(item.seealso[key]);
        }
    }
    item.seealso = item.seealso || null;
}

function isAbsolutePath(path) {
    return /^(\w+:)?\/\//g.test(path);
}

function isRelativePath(path) {
    if (!path) return false;
    return !exports.isAbsolutePath(path);
}

var gitUrlPatternItems = {
    'github': {
        // HTTPS form: https://github.com/{org}/{repo}.git
        // SSH form: git@github.com:{org}/{repo}.git
        // generate URL: https://github.com/{org}/{repo}/blob/{branch}/{path}
        'testRegex': /^(https?:\/\/)?(\S+\@)?(\S+\.)?github\.com(\/|:).*/i,
        'generateUrl': function (gitInfo) {
            var url = normalizeGitUrlToHttps(gitInfo.repo);
            url = getRepoWithoutGitExtension(url);
            url += '/blob' + '/' + gitInfo.branch + '/' + gitInfo.path;
            if (gitInfo.startLine && gitInfo.startLine > 0) {
                url += '/#L' + gitInfo.startLine;
            }
            return url;
        },
        'generateNewFileUrl': function (gitInfo, uid) {
            var url = normalizeGitUrlToHttps(gitInfo.repo);
            url = getRepoWithoutGitExtension(url);
            url += '/new';
            url += '/' + gitInfo.branch;
            url += '/' + getOverrideFolder(gitInfo.apiSpecFolder);
            url += '/new?filename=' + getHtmlId(uid) + '.md';
            url += '&value=' + encodeURIComponent(getOverrideTemplate(uid));
            return url;
        }
    },
    'vso': {
        // HTTPS form: https://{user}.visualstudio.com/{org}/_git/{repo}
        // SSH form: ssh://{user}@{user}.visualstudio.com:22/{org}/_git/{repo}
        // generated URL under branch: https://{user}.visualstudio.com/{org}/_git/{repo}?path={path}&version=GB{branch}
        // generated URL under detached HEAD: https://{user}.visualstudio.com/{org}/_git/{repo}?path={path}&version=GC{commit}
        'testRegex': /^(https?:\/\/)?(ssh:\/\/\S+\@)?(\S+\.)?visualstudio\.com(\/|:).*/i,
        'generateUrl': function (gitInfo) {
            var url = normalizeGitUrlToHttps(gitInfo.repo);
            var branchPrefix = /[0-9a-fA-F]{40}/.test(gitInfo.branch) ? 'GC' : 'GB';
            url += '?path=' + gitInfo.path + '&version=' + branchPrefix + gitInfo.branch;
            if (gitInfo.startLine && gitInfo.startLine > 0) {
                url += '&line=' + gitInfo.startLine;
            }
            return url;
        },
        'generateNewFileUrl': function (gitInfo, uid) {
            return '';
        }
    }
}

function getRepoWithoutGitExtension(repo) {
    if (repo.substr(-4) === '.git') {
        repo = repo.substr(0, repo.length - 4);
    }
    return repo;
}

function normalizeGitUrlToHttps(repo) {
    var pos = repo.indexOf('@');
    if (pos == -1) return repo;
    return 'https://' + repo.substr(pos + 1).replace(/:[0-9]+/g, '').replace(/:/g, '/');
}

function getNewFileUrl(item, gitContribute, gitUrlPattern) {
    // do not support VSO for now
    if (!item.source) {
        return '';
    }

    var gitInfo = getGitInfo(gitContribute, item.source.remote);
    if (!gitInfo.repo || !gitInfo.branch || !gitInfo.path) {
        return '';
    }

    var patternName = getPatternName(gitInfo.repo, gitUrlPattern);
    if (!patternName) return patternName;
    return gitUrlPatternItems[patternName].generateNewFileUrl(gitInfo, item.uid);
}

function getRemoteUrl(remote, startLine, gitContribute, gitUrlPattern) {
    var gitInfo = getGitInfo(gitContribute, remote);
    if (!gitInfo.repo || !gitInfo.branch || !gitInfo.path) {
        return '';
    }

    var patternName = getPatternName(gitInfo.repo, gitUrlPattern);
    if (!patternName) return '';

    gitInfo.startLine = startLine;
    return gitUrlPatternItems[patternName].generateUrl(gitInfo);
}

function getGitInfo(gitContribute, gitRemote) {
    // apiSpecFolder defines the folder contains overwrite files for MRef, the default value is apiSpec
    var defaultApiSpecFolder = 'apiSpec';

    var result = {};
    if (gitContribute && gitContribute.apiSpecFolder) {
        result.apiSpecFolder = gitContribute.apiSpecFolder;
    } else {
        result.apiSpecFolder = defaultApiSpecFolder;
    }
    mergeKey(gitContribute, gitRemote, result, 'repo');
    mergeKey(gitContribute, gitRemote, result, 'branch');
    mergeKey(gitContribute, gitRemote, result, 'path');

    return result;

    function mergeKey(source, sourceFallback, dest, key) {
        if (source && source.hasOwnProperty(key)) {
            dest[key] = source[key];
        } else if (sourceFallback && sourceFallback.hasOwnProperty(key)) {
            dest[key] = sourceFallback[key];
        }
    }
}

function getPatternName(repo, gitUrlPattern) {
    if (gitUrlPattern && gitUrlPattern.toLowerCase() in gitUrlPatternItems) {
        return gitUrlPattern.toLowerCase();
    } else {
        for (var p in gitUrlPatternItems) {
            if (gitUrlPatternItems[p].testRegex.test(repo)) {
                return p;
            }
        }
    }
    return '';
}

function getOverrideFolder(path) {
    if (!path) return "";
    path = path.replace(/\\/g, '/');
    if (path.charAt(path.length - 1) == '/') path = path.substring(0, path.length - 1);
    return path;
}

function getOverrideTemplate(uid) {
    if (!uid) return "";
    var content = "";
    content += "---\n";
    content += "uid: " + uid + "\n";
    content += "summary: '*You can override summary for the API here using *MARKDOWN* syntax'\n";
    content += "---\n";
    content += "\n";
    content += "*Please type below more information about this API:*\n";
    content += "\n";
    return content;
}

function addIsCref(seealso) {
    if (!seealso.linkType || seealso.linkType.toLowerCase() == "cref") {
        seealso.isCref = true;
    }
}
<commit_msg>Add support for "View Source" with Bitbucket repos (#4317)<commit_after>// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.
exports.path = {};
exports.path.getFileNameWithoutExtension = getFileNameWithoutExtension;
exports.path.getDirectoryName = getDirectoryName;

exports.getHtmlId = getHtmlId;

exports.getViewSourceHref = getViewSourceHref;
exports.getImproveTheDocHref = getImproveTheDocHref;
exports.processSeeAlso = processSeeAlso;

exports.isAbsolutePath = isAbsolutePath;
exports.isRelativePath = isRelativePath;

function getFileNameWithoutExtension(path) {
    if (!path || path[path.length - 1] === '/' || path[path.length - 1] === '\\') return '';
    var fileName = path.split('\\').pop().split('/').pop();
    return fileName.slice(0, fileName.lastIndexOf('.'));
}

function getDirectoryName(path) {
    if (!path) return '';
    var index = path.lastIndexOf('/');
    return path.slice(0, index + 1);
}

function getHtmlId(input) {
    if (!input) return '';
    return input.replace(/\W/g, '_');
}

// Note: the parameter `gitContribute` won't be used in this function
function getViewSourceHref(item, gitContribute, gitUrlPattern) {
    if (!item || !item.source || !item.source.remote) return '';
    return getRemoteUrl(item.source.remote, item.source.startLine - '0' + 1, null, gitUrlPattern);
}

function getImproveTheDocHref(item, gitContribute, gitUrlPattern) {
    if (!item) return '';
    if (!item.documentation || !item.documentation.remote) {
        return getNewFileUrl(item, gitContribute, gitUrlPattern);
    } else {
        return getRemoteUrl(item.documentation.remote, item.documentation.startLine + 1, gitContribute, gitUrlPattern);
    }
}

function processSeeAlso(item) {
    if (item.seealso) {
        for (var key in item.seealso) {
            addIsCref(item.seealso[key]);
        }
    }
    item.seealso = item.seealso || null;
}

function isAbsolutePath(path) {
    return /^(\w+:)?\/\//g.test(path);
}

function isRelativePath(path) {
    if (!path) return false;
    return !exports.isAbsolutePath(path);
}

var gitUrlPatternItems = {
    'github': {
        // HTTPS form: https://github.com/{org}/{repo}.git
        // SSH form: git@github.com:{org}/{repo}.git
        // generate URL: https://github.com/{org}/{repo}/blob/{branch}/{path}
        'testRegex': /^(https?:\/\/)?(\S+\@)?(\S+\.)?github\.com(\/|:).*/i,
        'generateUrl': function (gitInfo) {
            var url = normalizeGitUrlToHttps(gitInfo.repo);
            url = getRepoWithoutGitExtension(url);
            url += '/blob' + '/' + gitInfo.branch + '/' + gitInfo.path;
            if (gitInfo.startLine && gitInfo.startLine > 0) {
                url += '/#L' + gitInfo.startLine;
            }
            return url;
        },
        'generateNewFileUrl': function (gitInfo, uid) {
            var url = normalizeGitUrlToHttps(gitInfo.repo);
            url = getRepoWithoutGitExtension(url);
            url += '/new';
            url += '/' + gitInfo.branch;
            url += '/' + getOverrideFolder(gitInfo.apiSpecFolder);
            url += '/new?filename=' + getHtmlId(uid) + '.md';
            url += '&value=' + encodeURIComponent(getOverrideTemplate(uid));
            return url;
        }
    },
    'vso': {
        // HTTPS form: https://{user}.visualstudio.com/{org}/_git/{repo}
        // SSH form: ssh://{user}@{user}.visualstudio.com:22/{org}/_git/{repo}
        // generated URL under branch: https://{user}.visualstudio.com/{org}/_git/{repo}?path={path}&version=GB{branch}
        // generated URL under detached HEAD: https://{user}.visualstudio.com/{org}/_git/{repo}?path={path}&version=GC{commit}
        'testRegex': /^(https?:\/\/)?(ssh:\/\/\S+\@)?(\S+\.)?visualstudio\.com(\/|:).*/i,
        'generateUrl': function (gitInfo) {
            var url = normalizeGitUrlToHttps(gitInfo.repo);
            var branchPrefix = /[0-9a-fA-F]{40}/.test(gitInfo.branch) ? 'GC' : 'GB';
            url += '?path=' + gitInfo.path + '&version=' + branchPrefix + gitInfo.branch;
            if (gitInfo.startLine && gitInfo.startLine > 0) {
                url += '&line=' + gitInfo.startLine;
            }
            return url;
        },
        'generateNewFileUrl': function (gitInfo, uid) {
            return '';
        }
    },
    'bitbucket': {
        // HTTPS form: https://{user}@bitbucket.org/{org}/{repo}.git
        // SSH form: git@bitbucket.org:{org}/{repo}.git
        // generate URL: https://bitbucket.org/{org}/{repo}/src/{branch}/{path}
        'testRegex': /^(https?:\/\/)?(\S+\@)?(\S+\.)?bitbucket\.org(\/|:).*/i,
        'generateUrl': function (gitInfo) {
            var url = normalizeGitUrlToHttps(gitInfo.repo);
            url = getRepoWithoutGitExtension(url);
            url += '/src' + '/' + gitInfo.branch + '/' + gitInfo.path;
            if (gitInfo.startLine && gitInfo.startLine > 0) {
                url += '#lines-' + gitInfo.startLine;
            }
            return url;
        },
        'generateNewFileUrl': function (gitInfo, uid) {
            return '';
        }
    }
}

function getRepoWithoutGitExtension(repo) {
    if (repo.substr(-4) === '.git') {
        repo = repo.substr(0, repo.length - 4);
    }
    return repo;
}

function normalizeGitUrlToHttps(repo) {
    var pos = repo.indexOf('@');
    if (pos == -1) return repo;
    return 'https://' + repo.substr(pos + 1).replace(/:[0-9]+/g, '').replace(/:/g, '/');
}

function getNewFileUrl(item, gitContribute, gitUrlPattern) {
    // do not support VSO for now
    if (!item.source) {
        return '';
    }

    var gitInfo = getGitInfo(gitContribute, item.source.remote);
    if (!gitInfo.repo || !gitInfo.branch || !gitInfo.path) {
        return '';
    }

    var patternName = getPatternName(gitInfo.repo, gitUrlPattern);
    if (!patternName) return patternName;
    return gitUrlPatternItems[patternName].generateNewFileUrl(gitInfo, item.uid);
}

function getRemoteUrl(remote, startLine, gitContribute, gitUrlPattern) {
    var gitInfo = getGitInfo(gitContribute, remote);
    if (!gitInfo.repo || !gitInfo.branch || !gitInfo.path) {
        return '';
    }

    var patternName = getPatternName(gitInfo.repo, gitUrlPattern);
    if (!patternName) return '';

    gitInfo.startLine = startLine;
    return gitUrlPatternItems[patternName].generateUrl(gitInfo);
}

function getGitInfo(gitContribute, gitRemote) {
    // apiSpecFolder defines the folder contains overwrite files for MRef, the default value is apiSpec
    var defaultApiSpecFolder = 'apiSpec';

    var result = {};
    if (gitContribute && gitContribute.apiSpecFolder) {
        result.apiSpecFolder = gitContribute.apiSpecFolder;
    } else {
        result.apiSpecFolder = defaultApiSpecFolder;
    }
    mergeKey(gitContribute, gitRemote, result, 'repo');
    mergeKey(gitContribute, gitRemote, result, 'branch');
    mergeKey(gitContribute, gitRemote, result, 'path');

    return result;

    function mergeKey(source, sourceFallback, dest, key) {
        if (source && source.hasOwnProperty(key)) {
            dest[key] = source[key];
        } else if (sourceFallback && sourceFallback.hasOwnProperty(key)) {
            dest[key] = sourceFallback[key];
        }
    }
}

function getPatternName(repo, gitUrlPattern) {
    if (gitUrlPattern && gitUrlPattern.toLowerCase() in gitUrlPatternItems) {
        return gitUrlPattern.toLowerCase();
    } else {
        for (var p in gitUrlPatternItems) {
            if (gitUrlPatternItems[p].testRegex.test(repo)) {
                return p;
            }
        }
    }
    return '';
}

function getOverrideFolder(path) {
    if (!path) return "";
    path = path.replace(/\\/g, '/');
    if (path.charAt(path.length - 1) == '/') path = path.substring(0, path.length - 1);
    return path;
}

function getOverrideTemplate(uid) {
    if (!uid) return "";
    var content = "";
    content += "---\n";
    content += "uid: " + uid + "\n";
    content += "summary: '*You can override summary for the API here using *MARKDOWN* syntax'\n";
    content += "---\n";
    content += "\n";
    content += "*Please type below more information about this API:*\n";
    content += "\n";
    return content;
}

function addIsCref(seealso) {
    if (!seealso.linkType || seealso.linkType.toLowerCase() == "cref") {
        seealso.isCref = true;
    }
}
<|endoftext|>


<commit_before>angular.module("Prometheus.services").factory('VariableInterpolator', ["$rootScope", function($rootScope) {
  // Verify that the string is using interpolation.
  var hasInterpolation = /{{.+}}/g;
  // Match single interpolated values.
  var singleInterpolation = /{{\s?(\w+)\s?}}/g;
  // Match piped interpolated values.
  var pipedInterpolation = /{{\s?\w+\s?(\|\s?\w+(:('|\")?([\sa-zA-Z0-9(\[?=:!^\])]+)?('|\")?){0,}\s?){1,}}}/g;
  function knownFilters() {
    return ["regex", "toPercent", "toPercentile", "hostname"];
  }

  return function(str, varValues) {
    var vars = str.match(hasInterpolation);
    if (!vars) {
      return str;
    }
    vars = vars[0];

    // Deal with filtered variables.
    var pipedVars = vars.match(pipedInterpolation);
    var pipeObj = {};
    if (pipedVars) {
      var scope = $rootScope.$new(true);
      pipedVars.forEach(function(v) { pipeObj[v] = null; });
      pipedVars.forEach(function(match) {
        var rep = match.replace(/\s+/g, '').replace(/{|}/g, '').split("|");

        // Set on scope so we can $eval.
        scope[rep[0]] = varValues[rep[0]]
        // Check to see if rep[1] is in the list of known filters.
        if (knownFilters().indexOf(rep[1].split(":")[0]) > -1) {
          var result;
          try {
            result = scope.$eval(rep.join("|"));
          } catch (e) {
            // Result will get displayed as undefined.
          }
          pipeObj[match] = result;
        }
      });
      scope.$destroy();
    }

    // Replace the filtered variables.
    for (var i in pipeObj) {
      // Need to escape the | in the piped statement.
      escapedSeq = i.replace(/\|/g, "\\|")
      str = str.replace(new RegExp(escapedSeq, "g"), pipeObj[i]);
    }

    // Replace the single variables.
    var singleMatches = vars.match(singleInterpolation);
    if ((singleMatches || []).length) {
      for (var i = 0; i < singleMatches.length; i++) {
        str = str.replace(singleMatches[i], varValues[singleMatches[i].replace(/{|}|\s/g, '')]);
      }
    }
    return str;
  };
}]);

<commit_msg>Remove global variable and fix regex support<commit_after>angular.module("Prometheus.services").factory('VariableInterpolator', ["$rootScope", function($rootScope) {
  // Verify that the string is using interpolation.
  var hasInterpolation = /{{.+}}/g;
  // Match single interpolated values.
  var singleInterpolation = /{{\s?(\w+)\s?}}/g;
  // Match piped interpolated values.
  var pipedInterpolation = /{{\s?\w+\s?(\|\s?\w+(:('|\")?([\sa-zA-Z0-9(\[?=:!^\])]+)?('|\")?){0,}\s?){1,}}}/g;
  function knownFilters() {
    return ["regex", "toPercent", "toPercentile", "hostname"];
  }

  return function(str, varValues) {
    var vars = str.match(hasInterpolation);
    if (!vars) {
      return str;
    }
    vars = vars[0];

    // Deal with filtered variables.
    var pipedVars = vars.match(pipedInterpolation);
    var pipeObj = {};
    if (pipedVars) {
      var scope = $rootScope.$new(true);
      pipedVars.forEach(function(v) { pipeObj[v] = null; });
      pipedVars.forEach(function(match) {
        var rep = match.replace(/\s+/g, '').replace(/{|}/g, '').split("|");

        // Set on scope so we can $eval.
        scope[rep[0]] = varValues[rep[0]]
        // Check to see if rep[1] is in the list of known filters.
        if (knownFilters().indexOf(rep[1].split(":")[0]) > -1) {
          var result;
          try {
            result = scope.$eval(rep.join("|"));
          } catch (e) {
            // Result will get displayed as undefined.
          }
          pipeObj[match] = result;
        }
      });
      scope.$destroy();
    }

    // Replace the filtered variables.
    for (var i in pipeObj) {
      // Need to escape any special matchers.
      var escapedSeq = i.replace(/([.*+?^=!:$()|\[\]\/\\])/g, "\\$1");
      str = str.replace(new RegExp(escapedSeq, "g"), pipeObj[i]);
    }

    // Replace the single variables.
    var singleMatches = vars.match(singleInterpolation);
    if ((singleMatches || []).length) {
      for (var i = 0; i < singleMatches.length; i++) {
        str = str.replace(singleMatches[i], varValues[singleMatches[i].replace(/{|}|\s/g, '')]);
      }
    }
    return str;
  };
}]);

<|endoftext|>


<commit_before>var ffi = require('./ffi')
  , EventEmitter = require('events').EventEmitter
  , POINTER_SIZE = ffi.Bindings.POINTER_SIZE

/**
 * Represents a foreign function in another library. Manages all of the aspects
 * of function execution, including marshalling the data parameters for the
 * function into native types and also unmarshalling the return from function
 * execution.
 */

function ForeignFunction (ptr, returnType, types, async) {
  var numArgs = types.length
    , result = new ffi.Pointer(ffi.sizeOf(returnType))
    , argsList = new ffi.Pointer(numArgs * POINTER_SIZE)
    , cif = new ffi.CIF(returnType, types)
    , self = this

  // XXX: Remove
  this._cif = cif

  // allocate a storage area for each argument,
  // then write the pointer to the argument list
  var argputf = types.map(function (type, i) {
    var argPtr = argsList.seek(i * POINTER_SIZE)

    if (ffi.isStructType(type)) {
      return function (val) {
        argPtr.putPointer(val.ref())
      }
    }

    var valPtr = new ffi.Pointer(ffi.sizeOf(type))
    argPtr.putPointer(valPtr)

    if (type == 'string') {
      return function (val) {
        var ptr = ffi.Pointer.NULL
        if (typeof val !== 'undefined' && val !== null) {
          var len = Buffer.byteLength(val, 'utf8')
          ptr = new ffi.Pointer(len+1)
          ptr.putCString(val)
        }
        valPtr.putPointer(ptr)
      }
    } else if (type == 'pointer') {
      // Bypass the struct check for non-struct types
      return function (val) {
        valPtr._putPointer(val)
      }
    } else {
      // Generic type putter function
      var putCall = 'put' + ffi.TYPE_TO_POINTER_METHOD_MAP[type]
      return function (val) {
        valPtr[putCall](val)
      }
    }
  })

  var drefVal = ffi.derefValuePtrFunc(returnType)
    , caller = new ffi.Bindings.ForeignCaller(
        cif.getPointer()
      , ptr
      , argsList
      , result
      , async
    )

  this._proxy = function () {
    self // XXX: if this isn't in here, callbacks segfault. what.. the.. f?
    var alen = arguments.length

    if (alen !== numArgs) {
      throw new Error('Function arguments did not meet specification')
    }

    // write arguments to storage areas
    for (var i = 0; i < alen; i++) {
      argputf[i](arguments[i])
    }

    var r = caller.exec()

    if (async) {
      var emitter = new EventEmitter()
      r.on('success', function () {
        emitter.emit('success', drefVal(result))
      })
      return emitter
    }

    return drefVal(result)
  }
}
module.exports = ForeignFunction

/**
 * Returns a JavaScript Function proxy for this foreign function.
 */

ForeignFunction.prototype.getFunction = function getFunction () {
  return this._proxy
}

/**
 * Creates a new ForeignFunction instance and returns the JS proxy function.
 */

ForeignFunction.build = function build (ptr, returnType, types, async) {
  var ff = new ForeignFunction(ptr, returnType, types, async)
  return ff.getFunction()
}
<commit_msg>Make ForeignFunction() return it's function directly.<commit_after>var ffi = require('./ffi')
  , EventEmitter = require('events').EventEmitter
  , POINTER_SIZE = ffi.Bindings.POINTER_SIZE

/**
 * Represents a foreign function in another library. Manages all of the aspects
 * of function execution, including marshalling the data parameters for the
 * function into native types and also unmarshalling the return from function
 * execution.
 */

function ForeignFunction (ptr, returnType, types, async) {
  var self = this
    , numArgs = types.length
    , drefVal = ffi.derefValuePtrFunc(returnType)
    , result = new ffi.Pointer(ffi.sizeOf(returnType))
    , argsList = new ffi.Pointer(numArgs * POINTER_SIZE)
    , cif = new ffi.CIF(returnType, types)
    , caller = new ffi.Bindings.ForeignCaller(
        cif.getPointer()
      , ptr
      , argsList
      , result
      , async
    )

  // XXX: Can't remove or shit segsaults... WTF....
  this._ = cif

  // allocate a storage area for each argument,
  // then write the pointer to the argument list
  var argputf = types.map(function (type, i) {
    var argPtr = argsList.seek(i * POINTER_SIZE)

    if (ffi.isStructType(type)) {
      return function (val) {
        argPtr.putPointer(val.ref())
      }
    }

    var valPtr = new ffi.Pointer(ffi.sizeOf(type))
    argPtr.putPointer(valPtr)

    if (type == 'string') {
      return function (val) {
        var ptr = ffi.Pointer.NULL
        if (typeof val !== 'undefined' && val !== null) {
          var len = Buffer.byteLength(val, 'utf8')
          ptr = new ffi.Pointer(len+1)
          ptr.putCString(val)
        }
        valPtr.putPointer(ptr)
      }
    } else if (type == 'pointer') {
      // Bypass the struct check for non-struct types
      return function (val) {
        valPtr._putPointer(val)
      }
    } else {
      // Generic type putter function
      var putCall = 'put' + ffi.TYPE_TO_POINTER_METHOD_MAP[type]
      return function (val) {
        valPtr[putCall](val)
      }
    }
  })

  var proxy = function () {
    self // XXX: if this isn't in here, callbacks segfault. what.. the.. f?

    if (arguments.length !== numArgs) {
      throw new Error('Function arguments did not meet specification')
    }

    // write arguments to storage areas
    for (var i=0; i<numArgs; i++) {
      argputf[i](arguments[i])
    }

    var r = caller.exec()

    if (async) {
      var emitter = new EventEmitter()
      r.on('success', function () {
        emitter.emit('success', drefVal(result))
      })
      return emitter
    }

    return drefVal(result)
  }

  // Backwards compat
  proxy.getFunction = function () { return this }

  return proxy
}
module.exports = ForeignFunction

/**
 * Creates a new ForeignFunction instance and returns the JS proxy function.
 */

ForeignFunction.build = function build (ptr, returnType, types, async) {
  var ff = new ForeignFunction(ptr, returnType, types, async)
  return ff.getFunction()
}
<|endoftext|>


<commit_before>var Surface = require('../gamejs').Surface;
var matrix = require('./utils/matrix');
var math = require('./utils/math');
var vectors = require('./utils/vectors');

/**
 * @fileoverview Rotate and scale Surfaces.
 */

/**
 * Returns a new surface which holds the original surface rotate by angle degrees.
 * @param {Surface} surface
 * @param {angel} angle Clockwise angle by which to rotate
 * @returns {Surface} new, rotated surface
 */
exports.rotate = function (surface, angle) {
   var origSize = surface.getSize();
   var radians = (angle * Math.PI / 180);
   var newSize = origSize;
   // find new bounding box
   if (angle % 360 !== 0) {
      var rect = surface.getRect();
      var points = [
         [-rect.width/2, rect.height/2],
         [rect.width/2, rect.height/2],
         [-rect.width/2, -rect.height/2],
         [rect.width/2, -rect.height/2]
      ];
      var rotPoints = points.map(function(p) {
         return vectors.rotate(p, radians);
      });
      var xs = rotPoints.map(function(p) { return p[0]; });
      var ys = rotPoints.map(function(p) { return p[1]; });
      var left = Math.min.apply(Math, xs);
      var right = Math.max.apply(Math, xs);
      var bottom = Math.min.apply(Math, ys);
      var top = Math.max.apply(Math, ys);
      newSize = [right-left, top-bottom];
   }
   var newSurface = new Surface(newSize);
   var oldMatrix = surface._matrix;
   surface._matrix = matrix.translate(surface._matrix, origSize[0]/2, origSize[1]/2);
   surface._matrix = matrix.rotate(surface._matrix, radians);
   surface._matrix = matrix.translate(surface._matrix, -origSize[0]/2, -origSize[1]/2);
   var offset = [(newSize[0] - origSize[0]) / 2, (newSize[1] - origSize[1]) / 2];
   newSurface.blit(surface, offset);
   surface._matrix = oldMatrix;
   return newSurface;
};

/**
 * Returns a new surface holding the scaled surface.
 * @param {Surface} surface
 * @param {Array} dimensions new [width, height] of surface after scaling
 * @returns {Surface} new, scaled surface
 */
exports.scale = function(surface, dims) {
   var width = dims[0];
   var height = dims[1];
   var oldDims = surface.getSize();
   var ws = width / oldDims[0];
   var hs = height / oldDims[1];
   var newSurface = new Surface([width, height]);
   var originalMatrix = surface._matrix.slice(0);
   surface._matrix = matrix.scale(surface._matrix, [ws, hs]);
   newSurface.blit(surface);
   surface._matrix = originalMatrix;
   return newSurface;
};

/**
 * Flip a Surface either vertically, horizontally or both. This returns
 * a new Surface (i.e: nondestructive).
 * @param {gamejs.Surface} surface
 * @param {Boolean} flipHorizontal
 * @param {Boolean} flipVertical
 * @returns {Surface} new, flipped surface
 */
exports.flip = function(surface, flipHorizontal, flipVertical) {
   var dims = surface.getSize();
   var newSurface = new Surface(dims);
   var scaleX = 1;
   var scaleY = 1;
   var xPos = 0;
   var yPos = 0;
   if (flipHorizontal === true) {
      scaleX = -1;
      xPos = -dims[0];
   }
   if (flipVertical === true) {
      scaleY = -1;
      yPos = -dims[1];
   }
   newSurface.context.save();
   newSurface.context.scale(scaleX, scaleY);
   newSurface.context.drawImage(surface.canvas, xPos, yPos);
   newSurface.context.restore();
   return newSurface;
};
<commit_msg>warn when scaling <= 0<commit_after>var Surface = require('../gamejs').Surface;
var matrix = require('./utils/matrix');
var math = require('./utils/math');
var vectors = require('./utils/vectors');

/**
 * @fileoverview Rotate and scale Surfaces.
 */

/**
 * Returns a new surface which holds the original surface rotate by angle degrees.
 * @param {Surface} surface
 * @param {angel} angle Clockwise angle by which to rotate
 * @returns {Surface} new, rotated surface
 */
exports.rotate = function (surface, angle) {
   var origSize = surface.getSize();
   var radians = (angle * Math.PI / 180);
   var newSize = origSize;
   // find new bounding box
   if (angle % 360 !== 0) {
      var rect = surface.getRect();
      var points = [
         [-rect.width/2, rect.height/2],
         [rect.width/2, rect.height/2],
         [-rect.width/2, -rect.height/2],
         [rect.width/2, -rect.height/2]
      ];
      var rotPoints = points.map(function(p) {
         return vectors.rotate(p, radians);
      });
      var xs = rotPoints.map(function(p) { return p[0]; });
      var ys = rotPoints.map(function(p) { return p[1]; });
      var left = Math.min.apply(Math, xs);
      var right = Math.max.apply(Math, xs);
      var bottom = Math.min.apply(Math, ys);
      var top = Math.max.apply(Math, ys);
      newSize = [right-left, top-bottom];
   }
   var newSurface = new Surface(newSize);
   var oldMatrix = surface._matrix;
   surface._matrix = matrix.translate(surface._matrix, origSize[0]/2, origSize[1]/2);
   surface._matrix = matrix.rotate(surface._matrix, radians);
   surface._matrix = matrix.translate(surface._matrix, -origSize[0]/2, -origSize[1]/2);
   var offset = [(newSize[0] - origSize[0]) / 2, (newSize[1] - origSize[1]) / 2];
   newSurface.blit(surface, offset);
   surface._matrix = oldMatrix;
   return newSurface;
};

/**
 * Returns a new surface holding the scaled surface.
 * @param {Surface} surface
 * @param {Array} dimensions new [width, height] of surface after scaling
 * @returns {Surface} new, scaled surface
 */
exports.scale = function(surface, dims) {
   var width = dims[0];
   var height = dims[1];
   if (width <= 0 || height <= 0) {
      throw new Error('[gamejs.transform.scale] Invalid arguments for height and width', [width, height]);
   }
   var oldDims = surface.getSize();
   var ws = width / oldDims[0];
   var hs = height / oldDims[1];
   var newSurface = new Surface([width, height]);
   var originalMatrix = surface._matrix.slice(0);
   surface._matrix = matrix.scale(surface._matrix, [ws, hs]);
   newSurface.blit(surface);
   surface._matrix = originalMatrix;
   return newSurface;
};

/**
 * Flip a Surface either vertically, horizontally or both. This returns
 * a new Surface (i.e: nondestructive).
 * @param {gamejs.Surface} surface
 * @param {Boolean} flipHorizontal
 * @param {Boolean} flipVertical
 * @returns {Surface} new, flipped surface
 */
exports.flip = function(surface, flipHorizontal, flipVertical) {
   var dims = surface.getSize();
   var newSurface = new Surface(dims);
   var scaleX = 1;
   var scaleY = 1;
   var xPos = 0;
   var yPos = 0;
   if (flipHorizontal === true) {
      scaleX = -1;
      xPos = -dims[0];
   }
   if (flipVertical === true) {
      scaleY = -1;
      yPos = -dims[1];
   }
   newSurface.context.save();
   newSurface.context.scale(scaleX, scaleY);
   newSurface.context.drawImage(surface.canvas, xPos, yPos);
   newSurface.context.restore();
   return newSurface;
};
<|endoftext|>


<commit_before>import axios from '../../lib/utils/axios_utils';
import statusCodes from '../../lib/utils/http_status';
import { backOff } from '../../lib/utils/common_utils';

const MAX_REQUESTS = 3;

function backOffRequest(makeRequestCallback) {
  let requestCounter = 0;
  return backOff((next, stop) => {
    makeRequestCallback().then((resp) => {
      if (resp.status === statusCodes.NO_CONTENT) {
        requestCounter += 1;
        if (requestCounter < MAX_REQUESTS) {
          next();
        } else {
          stop(new Error('Failed to connect to the prometheus server'));
        }
      } else {
        stop(resp);
      }
    }).catch(stop);
  });
}

export default class MonitoringService {
  constructor({ metricsEndpoint, deploymentEndpoint }) {
    this.metricsEndpoint = metricsEndpoint;
    this.deploymentEndpoint = deploymentEndpoint;
  }

  getGraphsData() {
    return backOffRequest(() => axios.get(this.metricsEndpoint))
      .then(resp => resp.data)
      .then((response) => {
        if (!response || !response.data) {
          throw new Error('Unexpected metrics data response from prometheus endpoint');
        }
        return response.data;
      });
  }

  getDeploymentData() {
    return backOffRequest(() => axios.get(this.deploymentEndpoint))
      .then(resp => resp.data)
      .then((response) => {
        if (!response || !response.deployments) {
          throw new Error('Unexpected deployment data response from prometheus endpoint');
        }
        return response.deployments;
      });
  }
}
<commit_msg>make deployments endpoint optional<commit_after>import axios from '../../lib/utils/axios_utils';
import statusCodes from '../../lib/utils/http_status';
import { backOff } from '../../lib/utils/common_utils';

const MAX_REQUESTS = 3;

function backOffRequest(makeRequestCallback) {
  let requestCounter = 0;
  return backOff((next, stop) => {
    makeRequestCallback().then((resp) => {
      if (resp.status === statusCodes.NO_CONTENT) {
        requestCounter += 1;
        if (requestCounter < MAX_REQUESTS) {
          next();
        } else {
          stop(new Error('Failed to connect to the prometheus server'));
        }
      } else {
        stop(resp);
      }
    }).catch(stop);
  });
}

export default class MonitoringService {
  constructor({ metricsEndpoint, deploymentEndpoint }) {
    this.metricsEndpoint = metricsEndpoint;
    this.deploymentEndpoint = deploymentEndpoint;
  }

  getGraphsData() {
    return backOffRequest(() => axios.get(this.metricsEndpoint))
      .then(resp => resp.data)
      .then((response) => {
        if (!response || !response.data) {
          throw new Error('Unexpected metrics data response from prometheus endpoint');
        }
        return response.data;
      });
  }

  getDeploymentData() {
    if (!this.deploymentEndpoint) {
      return Promise.resolve([]);
    }
    return backOffRequest(() => axios.get(this.deploymentEndpoint))
      .then(resp => resp.data)
      .then((response) => {
        if (!response || !response.deployments) {
          throw new Error('Unexpected deployment data response from prometheus endpoint');
        }
        return response.deployments;
      });
  }
}
<|endoftext|>


<commit_before>var enhancedEditor = {
    init: function(wmd) {
        var urls = ['https://cdn.rawgit.com/dwieeb/jquery-textrange/1.x/jquery-textrange.js',
            'https://cdn.rawgit.com/jeresig/jquery.hotkeys/master/jquery.hotkeys.js',
            'https://rawgit.com/ajaxorg/ace-builds/master/src-noconflict/ace.js',
            'https://rawgit.com/ajaxorg/ace-builds/master/src-noconflict/ext-language_tools.js',
            'https://rawgit.com/ajaxorg/ace-builds/master/src-noconflict/theme-github.js',
            'https://rawgit.com/ajaxorg/ace-builds/master/src-noconflict/mode-javascript.js',
            'https://rawgit.com/ajaxorg/ace-builds/master/src-noconflict/snippets/javascript.js'];

        for (var i = 0; i < urls.length; i++) {
            $('head').append('');
        }
        $('head').append("<link rel='stylesheet' type='text/css' href='https://rawgit.com/soxscripted/sox/experimental/enhancedEditor/sox.enhancedEdtitor.css' />");

        $('[id^="enhancedEditor"]').remove();
        var s = '#'+wmd; //s is the selector we pass onto each function so the action is applied to the correct textarea (and not, for example the 'add answer' textarea *and* the 'edit' textarea!)
        enhancedEditor.startInsertLink(s);
        enhancedEditor.startInsertImages(s);
        enhancedEditor.betterTabKey(s);
        enhancedEditor.keyboardShortcuts(s);

        $(s).before(" Insert code (Ace editor) | Find & Replace | KBD-ify | Auto correct");

        $('#startAce').click(function(e) {
            enhancedEditor.startAceEditor(s);
            e.preventDefault();
            e.stopPropagation();
        });
        $('#surroundKbd').click(function(e) {
            enhancedEditor.addKbd($(this).parent().attr('id').split('|')[1]);
            e.preventDefault();
            e.stopPropagation();
        });
        $('#findReplace').click(function(e) {
            enhancedEditor.findReplace($(this).parent().attr('id').split('|')[1]);
            e.preventDefault();
            e.stopPropagation();
        });
        $('#autoCorrect').click(function(e) {
            enhancedEditor.autoCorrect($(this).parent().attr('id').split('|')[1]);
            e.preventDefault();
            e.stopPropagation();
        });
        $(document).on('click', '.enhancedEditor-closeDialog', function() {
            $(this).parent().hide();
        });

        $(document).click(function(event) {
            //doesn't work with #enhancedEditor-aceEditor for some reason... so skip it
            if(!$(event.target).closest('#enhancedEditor-insertLinkDialog, #enhancedEditor-insertImageDialog').length) {
                $('#enhancedEditor-insertLinkDialog, #enhancedEditor-insertImageDialog').hide()
            }
        });
    },

    startAceEditor: function(s) {
        var aceDiv = "
 \
              <select class='enhancedEditor-aceLanguages'></select>\
              <button class='enhancedEditor-addCode'>Add code</button>\
              x\

Ace Editor
\

\

";

        var languages = {
            'CoffeeScript': 'coffee',
            'CSS': 'css',
            'HTML': 'html',
            'JavaScript': 'javascript',
            'JSON': 'json',
            'PHP': 'php',
            'XML': 'xml',
            'AppleScript': 'applescript',
            'Cobol': 'cobol',
            'C#': 'csharp',
            'Python': 'python',
            'Ruby': 'ruby'
        };

        $('body').append(aceDiv);

        $.each(languages, function (lang, file) {
            $('select.enhancedEditor-aceLanguages').append("<option value='"+file+"'>"+lang+"</option>");
        });

        $('select.enhancedEditor-aceLanguages option[value="javascript"]').prop('selected', true);
        setTimeout(function() {
            editor = ace.edit("editor");
            editor.setTheme("ace/theme/github");
            editor.getSession().setMode("ace/mode/javascript");
            editor.setOptions({
                enableBasicAutocompletion: true,
                enableSnippets: true,
                enableLiveAutocompletion: true
            });
        }, 2000);

        $('select.enhancedEditor-aceLanguages').on('change', function() {
            editor = ace.edit("editor");
            editor.getSession().setMode("ace/mode/"+$(this).val());
        });

        $(document).on('click', '.enhancedEditor-addCode', function() {
            editor = ace.edit("editor");
            code = editor.getSession().getValue();
            var codeToAdd = '',
                gap = "    ",
                lines = code.split("\n"),
                pos = $(s).textrange('get', 'position'),
                oldVal = $(s).val();

            for(i = 0; i < lines.length; i++) {
                codeToAdd += gap + lines[i] + '\n';
            }

            //http://stackoverflow.com/a/15977052/3541881:
            $(s).val(oldVal.substring(0, pos) + codeToAdd + oldVal.substring(pos));

            enhancedEditor.refreshPreview();
        });
    },

    startInsertLink: function(s) {
        var linkDiv = "
 \
              x\

Insert link
\

\

Enter URL:\
                      <input class='ownURL' type='url' value='http://' />\
                      <input class='go' id='ownGo' type='button' value='insert' />\

\

\

\

\

\

\
                              <input class='go' id='suggestGo' type='button' value='insert' />\

\

\

\

\

\

Results from DuckDuckGo\

\

\

\

";
        $('body').append(linkDiv);

        setTimeout(function() {
            $('#wmd-link-button > span').click(function(e) {
                $('#DDG-header').html('');
                $('#DDG-text').html('');
                $('#DDG-credit a').attr('href', 'http://google.com');
                $('#enhancedEditor-insertLinkDialog').show(500);
                setTimeout(function () {
                    query = $(s).textrange();

                    $.getJSON("http://api.duckduckgo.com/?q=" + query.text + "&format=json&t=stackExchangeEditorPro&callback=?", function (json) {
                        $('#DDG-header').append("" + json.Heading + "");
                        $('#DDG-text').append(json.Abstract);
                        $('.DDG-credit a').attr('href', json.AbstractURL);
                    });

                    $('#ownGo').click(function() {
                        enhancedEditor.addLink(query, $(this).prev().val(), s);
                    });
                    $('#suggestGo').click(function() {
                        enhancedEditor.addLink(query, $('#DDG-header a').attr('href'), s);
                    });
                }, 1000);
                e.stopPropagation();
                e.preventDefault();
                return false;
            });
        }, 3000);
    },

    startInsertImages: function(s) {
        var imagesDiv = "
 \
              x\

Insert image
\

\

Select file:\
                      <input class='ownImage' type='file' />\
                      <input class='go' id='ownGoImage' type='button' value='insert' />\
                      <input type='checkbox' id='enhancedEditor-imageAsLink'>Insert smaller image with link to bigger?\

\

\

\

Enter URL:\
                      <input class='URLImage' type='url' value='http://' />\
                      <input class='go' id='goImage' type='button' value='insert' />\
                      <input type='checkbox' id='enhancedEditor-imageAsLink'>Insert smaller image with link to bigger?\

\

\

";
        $('body').append(imagesDiv);

        setTimeout(function() {
            $('#wmd-image-button > span').click(function(e) {
                $('#enhancedEditor-insertImageDialog').show(500);
                setTimeout(function () {
                    query = $(s).textrange();

                    $('#ownGoImage').click(function() {
                        $check = $(this).next();
                        enhancedEditor.uploadToImgur('file', $(this).prev(), function(url) {
                            enhancedEditor.addImageLink(query, url, $check, s);
                        });
                    });
                    $('#goImage').click(function() {
                        $check = $(this).next();
                        enhancedEditor.uploadToImgur('url', $(this).prev(), function(url) {
                            enhancedEditor.addImageLink(query, url, $check, s);
                        });
                    });
                }, 1000);
                e.stopPropagation();
                e.preventDefault();
                return false;
            });
        }, 3000);
    },

    betterTabKey: function(s) {
        $(s).on('keydown', function(e) {
            if(e.keyCode == 9) {
                pos = $(s).textrange('get', 'position');
                oldVal = $(s).val();

                //http://stackoverflow.com/a/15977052/3541881:
                $(s).val(oldVal.substring(0, pos) + '\t' + oldVal.substring(pos));

                return false;
                e.preventDefault();
            }
        });
    },

    findReplace: function(s) {
        $(s).prev().after("
<input id='find' type='text' placeholder='Find'><input id='modifier' type='text' placeholder='Modifier'><input id='replace' type='text' placeholder='Replace with'><input id='replaceGo' type='button' value='Go'>
");
        $(document).on('click', '.findReplace #replaceGo', function() {
            regex = new RegExp($('.findReplace #find').val(), $('.findReplace #modifier').val());
            oldval = $(s).val();
            newval = oldval.replace(regex, $('.findReplace #replace').val());
            $(s).val(newval);
            enhancedEditor.refreshPreview();
        });
    },

    autoCorrect: function(s) {
        var oldVal = $(s).val();
        var newVal = oldVal.replace(/\bi\b/g, "I") //capitalise 'I'
        .replace(/\.\.\.*/gi, "...") //truncate elipses
        .replace(/(?!\.\.\.*)([,.!?;:])(\S)/g, "$1 $2") //add space after punctuation
        .replace(/\s(\?|!)/g, "$1") //remove space before !/?
        .replace(/\bwud\b/gi, "would") //wud->would
        .replace(/\bcant\b/gi, "can't") //cant->can't
        .replace(/\bcud\b/gi, "could") //cud->could
        .replace(/\bwont\b/gi, "won't") //wont->won't
        .replace(/\bshud\b/gi, "should") //shud->should
        .replace(/\b(plz|pls)\b/gi, "please") //plz/pls->please
        .replace(/\bim\b/gi, "I'm") //im->I'm
        .replace(/\bu\b/gi, "you") //u->you
        .replace(/\bure?\b/gi, "your") //ur(e)->your
        .replace(/(^.)/gm,  function (txt) { //Capitalise new line first character
            return txt.toUpperCase();
        })
        .replace(/.+?[\.\?\!](\s|$)/g,  function (txt) { //Fix capitalisation. http://stackoverflow.com/a/20442069/3541881
            return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
        });
        $(s).val(newVal);

        enhancedEditor.refreshPreview();
    },

    addLink: function(query, url, s) {
        $(s).textrange('replace', '['+query.text+']('+url+')');
        $('#enhancedEditor-insertLinkDialog').hide();
        enhancedEditor.refreshPreview();
    },

    addKbd: function(s) {
        origText = $(s).textrange();
        $(s).textrange('replace', ''+origText.text+'');
        enhancedEditor.refreshPreview();
    },

    keyboardShortcuts: function(s) {
        $(s).bind('keydown', 'alt+k', function() { //kbd
            enhancedEditor.addKbd();
        });
        $(s).bind('keydown', 'alt+a', function() { //ace editor
            $('#enhancedEditor-aceEditor').show(500);
        });
        $(s).bind('keydown', 'alt+f', function() { //find replace
            $('#findReplace').trigger('click');
        });

        //Replace default SE bindings
        $(document).keydown(function(e) {
            if(e.which == 71 && e.ctrlKey) { //alt+g (images)
                $('#enhancedEditor-insertImageDialog').show(500);
                e.stopPropagation();
                e.preventDefault();
                return false;
            }
            if(e.which == 76 && e.ctrlKey) { //alt+l (links)
                $('#enhancedEditor-insertLinkDialog').show(500);
                e.stopPropagation();
                e.preventDefault();
                return false;
            }
        });
    },

    uploadToImgur: function(type, $fileData, callback) {
        var formData = new FormData(),
            data = '';
        if (type=='file') {
            formData.append("image", $fileData[0].files[0]);
        } else {
            data = $fileData.val();
        }

        $.ajax({
            url: "https://api.imgur.com/3/image",
            type: "POST",
            headers: {
                'Authorization': 'Client-ID 1ebf24e58286774'
            },
            data: (type=='file' ? formData : data),
            success: function(response) {
                callback(response.data.link);
            },
            processData: false,
            contentType: false
        });

    },

    addImageLink: function(query, url, $check, s) {
        if($check.find('input').is(':checked')) {
            urlsplit = url.split('/')[3].split('.');
            urlToUse = 'http://i.imgur.com/'+urlsplit[0]+'m.'+urlsplit[1];
            $(s).textrange('replace', '[!['+query.text+']('+urlToUse+')]('+url+')\n\nclick image for larger variant');
        } else {
            $(s).textrange('replace', '!['+query.text+']('+url+')');
        }
        $('#enhancedEditor-insertImageDialog').hide();
        enhancedEditor.refreshPreview();
    },

    refreshPreview: function() {
        StackExchange.MarkdownEditor.refreshAllPreviews();
    }
};

setTimeout(function() {
    $.each($('textarea[id^="wmd-input"].processed'), function() {
        enhancedEditor.init($(this).attr('id'));
    });

    $('.edit-post').click(function() {
        $that = $(this);
        setTimeout(function() {
            enhancedEditor.init($that.parents('table').find('.inline-editor textarea.processed').attr('id'));
        }, 2000);
    });
}, 2000);
<commit_msg>Update sox.enhancedEditor.js<commit_after>var enhancedEditor = {
    startFeature: function() {
        setTimeout(function() {
            $.each($('textarea[id^="wmd-input"].processed'), function() {
                enhancedEditor.init($(this).attr('id'));
            });

            $('.edit-post').click(function() {
                $that = $(this);
                setTimeout(function() {
                    enhancedEditor.init($that.parents('table').find('.inline-editor textarea.processed').attr('id'));
                }, 2000);
            });
        }, 2000);
    },

    init: function(wmd) {
        var urls = ['https://cdn.rawgit.com/dwieeb/jquery-textrange/1.x/jquery-textrange.js',
            'https://cdn.rawgit.com/jeresig/jquery.hotkeys/master/jquery.hotkeys.js',
            'https://rawgit.com/ajaxorg/ace-builds/master/src-noconflict/ace.js',
            'https://rawgit.com/ajaxorg/ace-builds/master/src-noconflict/ext-language_tools.js',
            'https://rawgit.com/ajaxorg/ace-builds/master/src-noconflict/theme-github.js',
            'https://rawgit.com/ajaxorg/ace-builds/master/src-noconflict/mode-javascript.js',
            'https://rawgit.com/ajaxorg/ace-builds/master/src-noconflict/snippets/javascript.js'];

        for (var i = 0; i < urls.length; i++) {
            $('head').append('');
        }
        $('head').append("<link rel='stylesheet' type='text/css' href='https://rawgit.com/soxscripted/sox/experimental/enhancedEditor/sox.enhancedEdtitor.css' />");

        $('[id^="enhancedEditor"]').remove();
        var s = '#'+wmd; //s is the selector we pass onto each function so the action is applied to the correct textarea (and not, for example the 'add answer' textarea *and* the 'edit' textarea!)
        enhancedEditor.startInsertLink(s);
        enhancedEditor.startInsertImages(s);
        enhancedEditor.betterTabKey(s);
        enhancedEditor.keyboardShortcuts(s);

        $(s).before(" Insert code (Ace editor) | Find & Replace | KBD-ify | Auto correct");

        $('#startAce').click(function(e) {
            enhancedEditor.startAceEditor(s);
            e.preventDefault();
            e.stopPropagation();
        });
        $('#surroundKbd').click(function(e) {
            enhancedEditor.addKbd($(this).parent().attr('id').split('|')[1]);
            e.preventDefault();
            e.stopPropagation();
        });
        $('#findReplace').click(function(e) {
            enhancedEditor.findReplace($(this).parent().attr('id').split('|')[1]);
            e.preventDefault();
            e.stopPropagation();
        });
        $('#autoCorrect').click(function(e) {
            enhancedEditor.autoCorrect($(this).parent().attr('id').split('|')[1]);
            e.preventDefault();
            e.stopPropagation();
        });
        $(document).on('click', '.enhancedEditor-closeDialog', function() {
            $(this).parent().hide();
        });

        $(document).click(function(event) {
            //doesn't work with #enhancedEditor-aceEditor for some reason... so skip it
            if(!$(event.target).closest('#enhancedEditor-insertLinkDialog, #enhancedEditor-insertImageDialog').length) {
                $('#enhancedEditor-insertLinkDialog, #enhancedEditor-insertImageDialog').hide()
            }
        });
    },

    startAceEditor: function(s) {
        var aceDiv = "
 \
              <select class='enhancedEditor-aceLanguages'></select>\
              <button class='enhancedEditor-addCode'>Add code</button>\
              x\

Ace Editor
\

\

";

        var languages = {
            'CoffeeScript': 'coffee',
            'CSS': 'css',
            'HTML': 'html',
            'JavaScript': 'javascript',
            'JSON': 'json',
            'PHP': 'php',
            'XML': 'xml',
            'AppleScript': 'applescript',
            'Cobol': 'cobol',
            'C#': 'csharp',
            'Python': 'python',
            'Ruby': 'ruby'
        };

        $('body').append(aceDiv);

        $.each(languages, function (lang, file) {
            $('select.enhancedEditor-aceLanguages').append("<option value='"+file+"'>"+lang+"</option>");
        });

        $('select.enhancedEditor-aceLanguages option[value="javascript"]').prop('selected', true);
        setTimeout(function() {
            editor = ace.edit("editor");
            editor.setTheme("ace/theme/github");
            editor.getSession().setMode("ace/mode/javascript");
            editor.setOptions({
                enableBasicAutocompletion: true,
                enableSnippets: true,
                enableLiveAutocompletion: true
            });
        }, 2000);

        $('select.enhancedEditor-aceLanguages').on('change', function() {
            editor = ace.edit("editor");
            editor.getSession().setMode("ace/mode/"+$(this).val());
        });

        $(document).on('click', '.enhancedEditor-addCode', function() {
            editor = ace.edit("editor");
            code = editor.getSession().getValue();
            var codeToAdd = '',
                gap = "    ",
                lines = code.split("\n"),
                pos = $(s).textrange('get', 'position'),
                oldVal = $(s).val();

            for(i = 0; i < lines.length; i++) {
                codeToAdd += gap + lines[i] + '\n';
            }

            //http://stackoverflow.com/a/15977052/3541881:
            $(s).val(oldVal.substring(0, pos) + codeToAdd + oldVal.substring(pos));

            enhancedEditor.refreshPreview();
        });
    },

    startInsertLink: function(s) {
        var linkDiv = "
 \
              x\

Insert link
\

\

Enter URL:\
                      <input class='ownURL' type='url' value='http://' />\
                      <input class='go' id='ownGo' type='button' value='insert' />\

\

\

\

\

\

\
                              <input class='go' id='suggestGo' type='button' value='insert' />\

\

\

\

\

\

Results from DuckDuckGo\

\

\

\

";
        $('body').append(linkDiv);

        setTimeout(function() {
            $('#wmd-link-button > span').click(function(e) {
                $('#DDG-header').html('');
                $('#DDG-text').html('');
                $('#DDG-credit a').attr('href', 'http://google.com');
                $('#enhancedEditor-insertLinkDialog').show(500);
                setTimeout(function () {
                    query = $(s).textrange();

                    $.getJSON("http://api.duckduckgo.com/?q=" + query.text + "&format=json&t=stackExchangeEditorPro&callback=?", function (json) {
                        $('#DDG-header').append("" + json.Heading + "");
                        $('#DDG-text').append(json.Abstract);
                        $('.DDG-credit a').attr('href', json.AbstractURL);
                    });

                    $('#ownGo').click(function() {
                        enhancedEditor.addLink(query, $(this).prev().val(), s);
                    });
                    $('#suggestGo').click(function() {
                        enhancedEditor.addLink(query, $('#DDG-header a').attr('href'), s);
                    });
                }, 1000);
                e.stopPropagation();
                e.preventDefault();
                return false;
            });
        }, 3000);
    },

    startInsertImages: function(s) {
        var imagesDiv = "
 \
              x\

Insert image
\

\

Select file:\
                      <input class='ownImage' type='file' />\
                      <input class='go' id='ownGoImage' type='button' value='insert' />\
                      <input type='checkbox' id='enhancedEditor-imageAsLink'>Insert smaller image with link to bigger?\

\

\

\

Enter URL:\
                      <input class='URLImage' type='url' value='http://' />\
                      <input class='go' id='goImage' type='button' value='insert' />\
                      <input type='checkbox' id='enhancedEditor-imageAsLink'>Insert smaller image with link to bigger?\

\

\

";
        $('body').append(imagesDiv);

        setTimeout(function() {
            $('#wmd-image-button > span').click(function(e) {
                $('#enhancedEditor-insertImageDialog').show(500);
                setTimeout(function () {
                    query = $(s).textrange();

                    $('#ownGoImage').click(function() {
                        $check = $(this).next();
                        enhancedEditor.uploadToImgur('file', $(this).prev(), function(url) {
                            enhancedEditor.addImageLink(query, url, $check, s);
                        });
                    });
                    $('#goImage').click(function() {
                        $check = $(this).next();
                        enhancedEditor.uploadToImgur('url', $(this).prev(), function(url) {
                            enhancedEditor.addImageLink(query, url, $check, s);
                        });
                    });
                }, 1000);
                e.stopPropagation();
                e.preventDefault();
                return false;
            });
        }, 3000);
    },

    betterTabKey: function(s) {
        $(s).on('keydown', function(e) {
            if(e.keyCode == 9) {
                pos = $(s).textrange('get', 'position');
                oldVal = $(s).val();

                //http://stackoverflow.com/a/15977052/3541881:
                $(s).val(oldVal.substring(0, pos) + '\t' + oldVal.substring(pos));

                return false;
                e.preventDefault();
            }
        });
    },

    findReplace: function(s) {
        $(s).prev().after("
<input id='find' type='text' placeholder='Find'><input id='modifier' type='text' placeholder='Modifier'><input id='replace' type='text' placeholder='Replace with'><input id='replaceGo' type='button' value='Go'>
");
        $(document).on('click', '.findReplace #replaceGo', function() {
            regex = new RegExp($('.findReplace #find').val(), $('.findReplace #modifier').val());
            oldval = $(s).val();
            newval = oldval.replace(regex, $('.findReplace #replace').val());
            $(s).val(newval);
            enhancedEditor.refreshPreview();
        });
    },

    autoCorrect: function(s) {
        var oldVal = $(s).val();
        var newVal = oldVal.replace(/\bi\b/g, "I") //capitalise 'I'
        .replace(/\.\.\.*/gi, "...") //truncate elipses
        .replace(/(?!\.\.\.*)([,.!?;:])(\S)/g, "$1 $2") //add space after punctuation
        .replace(/\s(\?|!)/g, "$1") //remove space before !/?
        .replace(/\bwud\b/gi, "would") //wud->would
        .replace(/\bcant\b/gi, "can't") //cant->can't
        .replace(/\bcud\b/gi, "could") //cud->could
        .replace(/\bwont\b/gi, "won't") //wont->won't
        .replace(/\bshud\b/gi, "should") //shud->should
        .replace(/\b(plz|pls)\b/gi, "please") //plz/pls->please
        .replace(/\bim\b/gi, "I'm") //im->I'm
        .replace(/\bu\b/gi, "you") //u->you
        .replace(/\bure?\b/gi, "your") //ur(e)->your
        .replace(/(^.)/gm,  function (txt) { //Capitalise new line first character
            return txt.toUpperCase();
        })
        .replace(/.+?[\.\?\!](\s|$)/g,  function (txt) { //Fix capitalisation. http://stackoverflow.com/a/20442069/3541881
            return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
        });
        $(s).val(newVal);

        enhancedEditor.refreshPreview();
    },

    addLink: function(query, url, s) {
        $(s).textrange('replace', '['+query.text+']('+url+')');
        $('#enhancedEditor-insertLinkDialog').hide();
        enhancedEditor.refreshPreview();
    },

    addKbd: function(s) {
        origText = $(s).textrange();
        $(s).textrange('replace', ''+origText.text+'');
        enhancedEditor.refreshPreview();
    },

    keyboardShortcuts: function(s) {
        $(s).bind('keydown', 'alt+k', function() { //kbd
            enhancedEditor.addKbd();
        });
        $(s).bind('keydown', 'alt+a', function() { //ace editor
            $('#enhancedEditor-aceEditor').show(500);
        });
        $(s).bind('keydown', 'alt+f', function() { //find replace
            $('#findReplace').trigger('click');
        });

        //Replace default SE bindings
        $(document).keydown(function(e) {
            if(e.which == 71 && e.ctrlKey) { //alt+g (images)
                $('#enhancedEditor-insertImageDialog').show(500);
                e.stopPropagation();
                e.preventDefault();
                return false;
            }
            if(e.which == 76 && e.ctrlKey) { //alt+l (links)
                $('#enhancedEditor-insertLinkDialog').show(500);
                e.stopPropagation();
                e.preventDefault();
                return false;
            }
        });
    },

    uploadToImgur: function(type, $fileData, callback) {
        var formData = new FormData(),
            data = '';
        if (type=='file') {
            formData.append("image", $fileData[0].files[0]);
        } else {
            data = $fileData.val();
        }

        $.ajax({
            url: "https://api.imgur.com/3/image",
            type: "POST",
            headers: {
                'Authorization': 'Client-ID 1ebf24e58286774'
            },
            data: (type=='file' ? formData : data),
            success: function(response) {
                callback(response.data.link);
            },
            processData: false,
            contentType: false
        });

    },

    addImageLink: function(query, url, $check, s) {
        if($check.find('input').is(':checked')) {
            urlsplit = url.split('/')[3].split('.');
            urlToUse = 'http://i.imgur.com/'+urlsplit[0]+'m.'+urlsplit[1];
            $(s).textrange('replace', '[!['+query.text+']('+urlToUse+')]('+url+')\n\nclick image for larger variant');
        } else {
            $(s).textrange('replace', '!['+query.text+']('+url+')');
        }
        $('#enhancedEditor-insertImageDialog').hide();
        enhancedEditor.refreshPreview();
    },

    refreshPreview: function() {
        StackExchange.MarkdownEditor.refreshAllPreviews();
    }
};

setTimeout(function() {
    $.each($('textarea[id^="wmd-input"].processed'), function() {
        enhancedEditor.init($(this).attr('id'));
    });

    $('.edit-post').click(function() {
        $that = $(this);
        setTimeout(function() {
            enhancedEditor.init($that.parents('table').find('.inline-editor textarea.processed').attr('id'));
        }, 2000);
    });
}, 2000);
<|endoftext|>


<commit_before>/** @jsx React.DOM */
'use strict';
var React = require('react');
var url = require('url');
var globals = require('./globals');
var dbxref = require('./dbxref');
var image = require('./image');

var Attachment = image.Attachment;
var DbxrefList = dbxref.DbxrefList;

var StatusLabel = module.exports.StatusLabel = React.createClass({
    render: function() {
        var status = this.props.status;
        var title = this.props.title;
        if (typeof status === 'string') {
            // Display simple string and optional title in badge
            return (

                        {title ? {title + ': '} : null}
                        {status}

            );
        } else if (typeof status === 'object') {
            // Display a list of badges from array of objects with status and optional title
            return (

                    {status.map(function (status) {
                        return(

                                {status.title ? {status.title + ': '} : null}
                                {status.status}

                        );
                    })}

            );
        } else {
            return null;
        }
    }
});

var Approval = module.exports.Approval = React.createClass({
    render: function() {
        var context = this.props.context;

        return (

{context.accession}

Source (vendor)

{context.source.title}

Product ID

{context.product_id}

Lot ID

{context.lot_id}

                        {context.lot_id_alias.length ?

Lot ID aliases

{context.lot_id_alias.join(', ')}

                        : null}

Host

{context.host_organism.name}

                        {context.clonality ?

Clonality

{context.clonality}

                        : null}

                        {context.purifications.length ?

Purification

{context.purifications.join(', ')}

                        : null}

                        {context.isotype ?

Isotype

{context.isotype}

                        : null}

                        {context.antigen_description ?

Antigen description

{context.antigen_description}

                        : null}

                        {context.antigen_sequence ?

Antigen sequence

{context.antigen_sequence}

                        : null}

                        {context.aliases && context.aliases.length ?

Aliases

{context.aliases.join(", ")}

                        : null}

                        {context.dbxrefs && context.dbxrefs.length ?

External resources

<DbxrefList values={context.dbxrefs} />

                        : null}

        );
    }
});

globals.content_views.register(Approval, 'antibody_lot');

var Characterization = module.exports.Characterization = React.createClass({
    render: function() {
        var context = this.props.context;
        var figure = <Attachment context={this.props.context} className="characterization" />;

        var attachmentHref, download;
        if (context.attachment) {
            attachmentHref = url.resolve(context['@id'], context.attachment.href);
            download = (

                    {context.attachment.download}

            );
        } else {
            download = (
                Document not available
            );
        }

        return (

                            {figure}

                                {context.status}

Method

{context.characterization_method}

Target species

{context.target.organism.scientific_name}

                            {context.caption ?
Caption
 : null}
                            {context.caption ?
{context.caption}
 : null}

Submitted by

{context.submitted_by.title}

Lab

{context.lab.title}

Grant

{context.award.name}

                            {/*

Approver

{context.validated_by}

                            */}

Image

<StatusLabel status={context.status} />

 Download

{download}

        );
    }
});

globals.panel_views.register(Characterization, 'antibody_characterization');
<commit_msg>Complete antibody lot heading to include targets, organism name.<commit_after>/** @jsx React.DOM */
'use strict';
var React = require('react');
var url = require('url');
var _ = require('underscore');
var globals = require('./globals');
var dbxref = require('./dbxref');
var image = require('./image');

var Attachment = image.Attachment;
var DbxrefList = dbxref.DbxrefList;

var StatusLabel = module.exports.StatusLabel = React.createClass({
    render: function() {
        var status = this.props.status;
        var title = this.props.title;
        if (typeof status === 'string') {
            // Display simple string and optional title in badge
            return (

                        {title ? {title + ': '} : null}
                        {status}

            );
        } else if (typeof status === 'object') {
            // Display a list of badges from array of objects with status and optional title
            return (

                    {status.map(function (status) {
                        return(

                                {status.title ? {status.title + ': '} : null}
                                {status.status}

                        );
                    })}

            );
        } else {
            return null;
        }
    }
});

var Lot = module.exports.Approval = React.createClass({
    render: function() {
        var context = this.props.context;

        // Make an array of targets with no falsy entries and no repeats
        var targets = context.characterizations ? context.characterizations.map(function(characterization) {
            return characterization.target; // Might be undefined or empty
        }) : [];
        targets = _.uniq(_.compact(targets), function(target) {return target['@id']; });

        // Make string of alternate accessions
        var altacc = context.alternate_accessions ? context.alternate_accessions.join(', ') : undefined;

        return (

{context.accession}

                        {altacc ?
Replaces {altacc}
 : null}

                            Antibody against
                            {targets.map(function(target, i) {
                                return {i !== 0 ? ', ' : ''}{target.label}{' ('}{target.organism.scientific_name}{')'};
                            })}

Source (vendor)

{context.source.title}

Product ID

{context.product_id}

Lot ID

{context.lot_id}

                        {targets.length ?

Targets

{targets.map(function(target, i) {
                                    return {i !== 0 ? ', ' : ''}{target.label}{' ('}{target.organism.scientific_name}{')'};
                                })}

                        : null}

                        {context.lot_id_alias.length ?

Lot ID aliases

{context.lot_id_alias.join(', ')}

                        : null}

Host

{context.host_organism.name}

                        {context.clonality ?

Clonality

{context.clonality}

                        : null}

                        {context.purifications.length ?

Purification

{context.purifications.join(', ')}

                        : null}

                        {context.isotype ?

Isotype

{context.isotype}

                        : null}

                        {context.antigen_description ?

Antigen description

{context.antigen_description}

                        : null}

                        {context.antigen_sequence ?

Antigen sequence

{context.antigen_sequence}

                        : null}

                        {context.aliases && context.aliases.length ?

Aliases

{context.aliases.join(", ")}

                        : null}

                        {context.dbxrefs && context.dbxrefs.length ?

External resources

<DbxrefList values={context.dbxrefs} />

                        : null}

        );
    }
});

globals.content_views.register(Lot, 'antibody_lot');

var Characterization = module.exports.Characterization = React.createClass({
    render: function() {
        var context = this.props.context;
        var figure = <Attachment context={this.props.context} className="characterization" />;

        var attachmentHref, download;
        if (context.attachment) {
            attachmentHref = url.resolve(context['@id'], context.attachment.href);
            download = (

                    {context.attachment.download}

            );
        } else {
            download = (
                Document not available
            );
        }

        return (

                            {figure}

                                {context.status}

Method

{context.characterization_method}

Target species

{context.target.organism.scientific_name}

                            {context.caption ?
Caption
 : null}
                            {context.caption ?
{context.caption}
 : null}

Submitted by

{context.submitted_by.title}

Lab

{context.lab.title}

Grant

{context.award.name}

                            {/*

Approver

{context.validated_by}

                            */}

Image

<StatusLabel status={context.status} />

 Download

{download}

        );
    }
});

globals.panel_views.register(Characterization, 'antibody_characterization');
<|endoftext|>


<commit_before>var GEOM = require("./geom");
var FEATURE = require("./feature");
var LAYER = require("./layer");
var UTIL = require("./util");

var bound = false;
var cache = {};

exports.bind = function() {
    bound = true;
}
exports.unbind = function() {
    bound = false;
    delete require("geoscript/shell").cache.frame;
}

exports.drawIfBound = function() {
    if (bound) {
        draw.apply(null, arguments);
    }
}

var drawGeometries = function(geometries, options) {
    options = UTIL.applyIf(options, {
        size: [500, 500],
        fill: true,
        strokeWidth: 1,
        buffer: 50
    });

    var width = options.size[0];
    var height = options.size[1];

    var len = geometries.length;
    var _geometries = new Array(len);
    for (var i=0; i<len; ++i) {
        _geometries[i] = geometries[i]._geometry;
    }
    var _collection = GEOM.Geometry._factory.createGeometryCollection(_geometries);

    var envelope = _collection.getEnvelopeInternal();
    var shapeWidth = envelope.getWidth();
    var shapeHeight = envelope.getHeight();

    var transform = new java.awt.geom.AffineTransform();

    // scale to size of canvas (inverting the y axis)
    var scale = (shapeWidth || shapeHeight) ? Math.min(width / shapeWidth, height / shapeHeight) : 1;
    transform.scale(scale, -scale);

    // center the shape using scaled offsets
    transform.translate(
        (options.buffer / scale) - envelope.getMinX() + (((width / scale) - shapeWidth) / 2),
        (-options.buffer / scale) - envelope.getMaxY() - (((height / scale) - shapeHeight) / 2)
    );

    var LiteShape = Packages.org.geotools.geometry.jts.LiteShape;

    var panel = new JavaAdapter(javax.swing.JPanel, {
        paintComponent: function(gc) {
            var v6 = (java.lang.System.getProperty("java.version").indexOf("1.6") === 0);
            if (!v6) {
                gc.setRenderingHint(
                    java.awt.RenderingHints.KEY_ANTIALIASING,
                    java.awt.RenderingHints.VALUE_ANTIALIAS_ON
                );
            }
            gc.setStroke(java.awt.BasicStroke(options.strokeWidth));
            var opaque = gc.getComposite();

            for (var i=0; i<len; ++i) {
                var shp = new LiteShape(_geometries[i], transform, false);
                if (options.fill) {
                    gc.setColor(java.awt.Color.WHITE);
                    if (!v6) {
                        gc.setComposite(
                            java.awt.AlphaComposite.getInstance(
                                java.awt.AlphaComposite.SRC_OVER, 0.5
                            )
                        );
                    }
                    gc.fill(shp);
                }
                gc.setColor(java.awt.Color.BLACK);
                if (!v6) {
                    gc.setComposite(opaque);
                }
                gc.draw(shp);
            }
        }
    });
    panel.setPreferredSize(new java.awt.Dimension(
        java.lang.Integer(width + 2 * options.buffer),
        java.lang.Integer(height + 2 * options.buffer)
    ));

    var frame;
    if (bound) {
        frame = cache.frame;
    }
    if (!frame) {
        frame = new javax.swing.JFrame();
    }
    frame.setTitle(options.title);
    frame.setContentPane(panel);
    frame.pack();
    frame.setVisible(true);
    frame.repaint();
    if (bound) {
        cache.frame = frame;
    }
};

var draw = function(obj, options) {
    options = options || {};
    var geometries;
    if (obj instanceof Array) {
        var first = obj[0];
        if (first instanceof GEOM.Geometry) {
            geometries = obj;
        } else if (first instanceof FEATURE.Feature) {
            var len = obj.length;
            geometries = new Array(len);
            for (var i=0; i<len; ++i) {
                geometries[i] = obj[i].geometry;
            }
        }
    } else if (obj instanceof GEOM.Geometry) {
        geometries = [obj];
    } else if (obj instanceof FEATURE.Feature) {
        geometries = [obj.geometry];
    } else if (obj instanceof LAYER.Layer) {
        geometries = new Array(obj.count);
        obj.features.forEach(function(feature, i) {
            geometries[i] = feature.geometry;
        });
    }
    if (!options.title) {
        options.title = obj.toString(false);
    }
    drawGeometries(geometries, options);
};

exports.draw = draw;
<commit_msg>Don't fill lines.<commit_after>var GEOM = require("./geom");
var FEATURE = require("./feature");
var LAYER = require("./layer");
var UTIL = require("./util");

var bound = false;
var cache = {};

exports.bind = function() {
    bound = true;
}
exports.unbind = function() {
    bound = false;
    delete require("geoscript/shell").cache.frame;
}

exports.drawIfBound = function() {
    if (bound) {
        draw.apply(null, arguments);
    }
}

var drawGeometries = function(geometries, options) {
    options = UTIL.applyIf(options, {
        size: [350, 350],
        fill: true,
        strokeWidth: 1,
        buffer: 50
    });

    var width = options.size[0];
    var height = options.size[1];

    var len = geometries.length;
    var _geometries = new Array(len);
    for (var i=0; i<len; ++i) {
        _geometries[i] = geometries[i]._geometry;
    }
    var _collection = GEOM.Geometry._factory.createGeometryCollection(_geometries);

    var envelope = _collection.getEnvelopeInternal();
    var shapeWidth = envelope.getWidth();
    var shapeHeight = envelope.getHeight();

    var transform = new java.awt.geom.AffineTransform();

    // scale to size of canvas (inverting the y axis)
    var scale = (shapeWidth || shapeHeight) ? Math.min(width / shapeWidth, height / shapeHeight) : 1;
    transform.scale(scale, -scale);

    // center the shape using scaled offsets
    transform.translate(
        (options.buffer / scale) - envelope.getMinX() + (((width / scale) - shapeWidth) / 2),
        (-options.buffer / scale) - envelope.getMaxY() - (((height / scale) - shapeHeight) / 2)
    );

    var LiteShape = Packages.org.geotools.geometry.jts.LiteShape;

    var panel = new JavaAdapter(javax.swing.JPanel, {
        paintComponent: function(gc) {
            var v6 = (java.lang.System.getProperty("java.version").indexOf("1.6") === 0);
            if (!v6) {
                gc.setRenderingHint(
                    java.awt.RenderingHints.KEY_ANTIALIASING,
                    java.awt.RenderingHints.VALUE_ANTIALIAS_ON
                );
            }
            gc.setStroke(java.awt.BasicStroke(options.strokeWidth));
            var opaque = gc.getComposite();
            var _geometry;
            for (var i=0; i<len; ++i) {
                _geometry = _geometries[i];
                var shp = new LiteShape(_geometry, transform, false);
                if (options.fill && _geometry.getDimension() > 1) {
                    gc.setColor(java.awt.Color.WHITE);
                    if (!v6) {
                        gc.setComposite(
                            java.awt.AlphaComposite.getInstance(
                                java.awt.AlphaComposite.SRC_OVER, 0.5
                            )
                        );
                    }
                    gc.fill(shp);
                }
                gc.setColor(java.awt.Color.BLACK);
                if (!v6) {
                    gc.setComposite(opaque);
                }
                gc.draw(shp);
            }
        }
    });
    panel.setPreferredSize(new java.awt.Dimension(
        java.lang.Integer(width + 2 * options.buffer),
        java.lang.Integer(height + 2 * options.buffer)
    ));

    var frame;
    if (bound) {
        frame = cache.frame;
    }
    if (!frame) {
        frame = new javax.swing.JFrame();
    }
    frame.setTitle(options.title);
    frame.setContentPane(panel);
    frame.pack();
    frame.repaint();
    frame.setVisible(true);
    if (bound) {
        cache.frame = frame;
    }
};

var draw = function(obj, options) {
    options = options || {};
    var geometries;
    if (obj instanceof Array) {
        var first = obj[0];
        if (first instanceof GEOM.Geometry) {
            geometries = obj;
        } else if (first instanceof FEATURE.Feature) {
            var len = obj.length;
            geometries = new Array(len);
            for (var i=0; i<len; ++i) {
                geometries[i] = obj[i].geometry;
            }
        }
    } else if (obj instanceof GEOM.Geometry) {
        geometries = [obj];
    } else if (obj instanceof FEATURE.Feature) {
        geometries = [obj.geometry];
    } else if (obj instanceof LAYER.Layer) {
        geometries = new Array(obj.count);
        obj.features.forEach(function(feature, i) {
            geometries[i] = feature.geometry;
        });
    }
    if (!options.title) {
        options.title = obj.toString(false);
    }
    drawGeometries(geometries, options);
};

exports.draw = draw;
<|endoftext|>


<commit_before>/*
 * client.js: Client object responsible for managing Producers attached to a TCP or UDP client.
 *
 * (C) 2012, Nodejitsu Inc.
 *
 */

var dgram = require('dgram'),
    net = require('net'),
    util = require('util'),
    backoff = require('backoff'),
    EventEmitter = require('events').EventEmitter;

//
// ### function Server (options)
// #### @options {Object} Options for this server
// ####   @options.type      {udp|tcp} Networking protocol of this server.
// ####   @options.producers {Array}   Set of producers to get data from.
// ####   @options.host      {string}  Host to send producer data to.
// ####   @options.port      {Number}  Port to send producer data to.
// Constructor function for the Client object responsible for managing
// Producers attached to a TCP or UDP client.
//
var Client = module.exports = function Client(options) {
  EventEmitter.call(this);

  if (!options || !options.type
      || !~['tcp', 'udp', 'unix'].indexOf(options.type)) {
    throw new Error('Cannot create client without type: udp, tcp, unix');
  }

  var self = this;

  this.type      = options.type;
  this.host      = options.host;
  this.port      = options.port;
  this.path      = options.path;
  this.reconnect = options.reconnect;
  this.producers = {};
  this.handlers  = {
    data: {},
    end:  {}
  };

  if (Array.isArray(options.producers)) {
    options.producers.forEach(function (producer) {
      self.add(producer);
    });
  }
};

//
// Inherit from EventEmitter
//
util.inherits(Client, EventEmitter);

//
// ### function add (producer)
// #### @producer {Producer} Producer to add to this server
// Adds the specified `producer` to this client. All data
// from the producer will be sent over the underlying
// network connection.
//
Client.prototype.add = function (producer) {
  var self = this,
      id = producer.id;

  this.producers[producer.id] = producer;

  producer.on('end', this.handlers.end[producer.id] = function () {
    self.remove(producer, id);
  });

  producer.on('data', this.handlers.data[producer.id] = function (data) {
    //
    // Ignore data until we have a socket
    //
    if (self.socket) {
      self.write(data);
    }
  });
};

//
// ### function remove (reactor)
// #### @producer {producer} Producer to remove from this client.
// Removes the specified `producer` from this client. All data
// from the producer will no longer be sent over the underlying
// network connection.
//
Client.prototype.remove = function (producer, id) {
  id = id || producer.id;

  producer.removeListener('data', this.handlers.data[id]);
  producer.removeListener('end',  this.handlers.end[id]);
  delete this.producers[id];
  delete this.handlers.data[id];
  delete this.handlers.end[id];
};

//
// ### function write (data)
// #### @data {Object} Data to write.
// Writes the specified `data` to the underlying network
// connection associated with this client.
//
Client.prototype.write = function (data) {
  var message = !Array.isArray(data)
    ? JSON.stringify(data) + 'g!\n!t'
    : data.map(function (d) {
      return JSON.stringify(d) + 'g!\n!t';
    }).join();

  if (this.type === 'tcp' || this.type === 'unix') {
    this.socket.write(message);
  }
  else if (this.type === 'udp') {
    message = new Buffer(message);
    this.socket.send(message, 0, message.length, this.port, this.host);
  }
};

//
// ### function connect (callback)
// #### @port {Number} **Optional** Port number to connect on.
// #### @host {String} **Optional** Host to connect to.
// #### @callback {function} **Optional** Continuation to respond to.
// Opens the underlying network connection for this client.
//
Client.prototype.connect = function (port, host, callback) {
  var self = this,
      connectBackoff, backoffType;

  if (this.reconnect) {
    if (typeof this.reconnect === 'object') {
      backoffType = this.reconnect.type || 'exponential';
      connectBackoff = backoff[backoffType](this.reconnect);
      connectBackoff.failAfter(this.reconnect.maxTries || 10);
    }
    else {
      connectBackoff = backoff.exponential();
      connectBackoff.failAfter(10);
    }

    connectBackoff.on('fail', function (err) {
      self.emit('error', err);
    });

    connectBackoff.on('ready', function () {
      connect();
    });
  }

  //
  // Do some fancy arguments parsing to support everything
  // being optional.
  //
  if (!callback && typeof host === 'function') {
    callback = host;
    host = null;
  }

  Array.prototype.slice.call(arguments).forEach(function (arg) {
    switch (typeof arg) {
      case 'number':   port = arg; break;
      case 'string':   host = arg; break;
      case 'function': callback = arg; break;
    }
  });

  function error (arg) {
    var err = new Error(arg + ' required to connect');
    return callback
      ? callback(err)
      : self.emit('error', err) ;
  }

  function onError(err) {
    return connectBackoff ? connectBackoff.backoff(err) : self.emit('error', err);
  }

  function connect() {
    if (self.type === 'tcp') {
      self.socket = net.connect({ port: self.port, host: self.host }, callback);
    }
    else if (self.type === 'udp') {
      self.socket = dgram.createSocket('udp4');
      if (callback) {
        process.nextTick(callback);
      }
    }
    else if (self.type === 'unix') {
      self.socket = net.connect({ path: self.path }, callback);
    }

    self.socket.on('error', onError);
    self.socket.on('connect', function () {
      if (connectBackoff) {
        connectBackoff.reset();
      }
      return self.emit('connect');
    });
  }

  // Split cases due to unix using `this.path`
  if (this.type === 'tcp' || this.type === 'udp') {
    this.port = port || this.port;
    this.host = host || this.host || '0.0.0.0';

    if (!this.host || !this.port) {
      error('host and port are');
    }
  }
  else if (this.type === 'unix') {
    this.path = host || this.path;

    if (!this.path) {
      error('path is');
    }
  }

  connect();
};

//
// ### function close ()
// Closes the underlying network connection for this client.
//
Client.prototype.close = function () {
  if (this.type === 'tcp' || this.type === 'unix') {
    this.socket.destroy();
  }
  else if (this.type === 'udp') {
    this.socket.close();
  }

  var self = this;

  Object.keys(this.producers).forEach(function (id) {
    self.remove(self.producers[id]);
  });

  return this.emit('close');
};
<commit_msg>[fix] don't return the 'connect' emit in case there is a callback and ensure the socket is closed before emitting close on the client<commit_after>/*
 * client.js: Client object responsible for managing Producers attached to a TCP or UDP client.
 *
 * (C) 2012, Nodejitsu Inc.
 *
 */

var dgram = require('dgram'),
    net = require('net'),
    util = require('util'),
    backoff = require('backoff'),
    EventEmitter = require('events').EventEmitter;

//
// ### function Server (options)
// #### @options {Object} Options for this server
// ####   @options.type      {udp|tcp} Networking protocol of this server.
// ####   @options.producers {Array}   Set of producers to get data from.
// ####   @options.host      {string}  Host to send producer data to.
// ####   @options.port      {Number}  Port to send producer data to.
// Constructor function for the Client object responsible for managing
// Producers attached to a TCP or UDP client.
//
var Client = module.exports = function Client(options) {
  EventEmitter.call(this);

  if (!options || !options.type
      || !~['tcp', 'udp', 'unix'].indexOf(options.type)) {
    throw new Error('Cannot create client without type: udp, tcp, unix');
  }

  var self = this;

  this.type      = options.type;
  this.host      = options.host;
  this.port      = options.port;
  this.path      = options.path;
  this.reconnect = options.reconnect;
  this.producers = {};
  this.handlers  = {
    data: {},
    end:  {}
  };

  if (Array.isArray(options.producers)) {
    options.producers.forEach(function (producer) {
      self.add(producer);
    });
  }
};

//
// Inherit from EventEmitter
//
util.inherits(Client, EventEmitter);

//
// ### function add (producer)
// #### @producer {Producer} Producer to add to this server
// Adds the specified `producer` to this client. All data
// from the producer will be sent over the underlying
// network connection.
//
Client.prototype.add = function (producer) {
  var self = this,
      id = producer.id;

  this.producers[producer.id] = producer;

  producer.on('end', this.handlers.end[producer.id] = function () {
    self.remove(producer, id);
  });

  producer.on('data', this.handlers.data[producer.id] = function (data) {
    //
    // Ignore data until we have a socket
    //
    if (self.socket) {
      self.write(data);
    }
  });
};

//
// ### function remove (reactor)
// #### @producer {producer} Producer to remove from this client.
// Removes the specified `producer` from this client. All data
// from the producer will no longer be sent over the underlying
// network connection.
//
Client.prototype.remove = function (producer, id) {
  id = id || producer.id;

  producer.removeListener('data', this.handlers.data[id]);
  producer.removeListener('end',  this.handlers.end[id]);
  delete this.producers[id];
  delete this.handlers.data[id];
  delete this.handlers.end[id];
};

//
// ### function write (data)
// #### @data {Object} Data to write.
// Writes the specified `data` to the underlying network
// connection associated with this client.
//
Client.prototype.write = function (data) {
  var message = !Array.isArray(data)
    ? JSON.stringify(data) + 'g!\n!t'
    : data.map(function (d) {
      return JSON.stringify(d) + 'g!\n!t';
    }).join();

  if (this.type === 'tcp' || this.type === 'unix') {
    this.socket.write(message);
  }
  else if (this.type === 'udp') {
    message = new Buffer(message);
    this.socket.send(message, 0, message.length, this.port, this.host);
  }
};

//
// ### function connect (callback)
// #### @port {Number} **Optional** Port number to connect on.
// #### @host {String} **Optional** Host to connect to.
// #### @callback {function} **Optional** Continuation to respond to.
// Opens the underlying network connection for this client.
//
Client.prototype.connect = function (port, host, callback) {
  var self = this,
      connectBackoff, backoffType;

  if (this.reconnect) {
    if (typeof this.reconnect === 'object') {
      backoffType = this.reconnect.type || 'exponential';
      connectBackoff = backoff[backoffType](this.reconnect);
      connectBackoff.failAfter(this.reconnect.maxTries || 10);
    }
    else {
      connectBackoff = backoff.exponential();
      connectBackoff.failAfter(10);
    }

    connectBackoff.on('fail', function (err) {
      self.emit('error', err);
    });

    connectBackoff.on('ready', function () {
      connect();
    });
  }

  //
  // Do some fancy arguments parsing to support everything
  // being optional.
  //
  if (!callback && typeof host === 'function') {
    callback = host;
    host = null;
  }

  Array.prototype.slice.call(arguments).forEach(function (arg) {
    switch (typeof arg) {
      case 'number':   port = arg; break;
      case 'string':   host = arg; break;
      case 'function': callback = arg; break;
    }
  });

  function error (arg) {
    var err = new Error(arg + ' required to connect');
    return callback
      ? callback(err)
      : self.emit('error', err) ;
  }

  function onError(err) {
    return connectBackoff ? connectBackoff.backoff(err) : self.emit('error', err);
  }

  function connect() {
    if (self.type === 'tcp') {
      self.socket = net.connect({ port: self.port, host: self.host }, callback);
    }
    else if (self.type === 'udp') {
      self.socket = dgram.createSocket('udp4');
      if (callback) {
        process.nextTick(callback);
      }
    }
    else if (self.type === 'unix') {
      self.socket = net.connect({ path: self.path }, callback);
    }

    self.socket.on('error', onError);
    self.socket.on('connect', function () {
      if (connectBackoff) {
        connectBackoff.reset();
      }
      self.emit('connect');
    });
  }

  // Split cases due to unix using `this.path`
  if (this.type === 'tcp' || this.type === 'udp') {
    this.port = port || this.port;
    this.host = host || this.host || '0.0.0.0';

    if (!this.host || !this.port) {
      error('host and port are');
    }
  }
  else if (this.type === 'unix') {
    this.path = host || this.path;

    if (!this.path) {
      error('path is');
    }
  }

  connect();
};

//
// ### function close ()
// Closes the underlying network connection for this client.
//
Client.prototype.close = function () {
  var self = this;

  if (this.type === 'tcp' || this.type === 'unix') {
    this.socket.destroy();
  }
  else if (this.type === 'udp') {
    this.socket.close();
  }

  var self = this;

  Object.keys(this.producers).forEach(function (id) {
    self.remove(self.producers[id]);
  });

  this.socket.on('close', function () {
    self.emit('close');
  });
};
<|endoftext|>