CoolFace
Apppublic

opusdev/vector-similarity-api

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes
index.js202 linesDownload Raw Back to brace-expansion
1var concatMap = require('concat-map');2var balanced = require('balanced-match');3 4module.exports = expandTop;5 6var escSlash = '\0SLASH'+Math.random()+'\0';7var escOpen = '\0OPEN'+Math.random()+'\0';8var escClose = '\0CLOSE'+Math.random()+'\0';9var escComma = '\0COMMA'+Math.random()+'\0';10var escPeriod = '\0PERIOD'+Math.random()+'\0';11 12function numeric(str) {13  return parseInt(str, 10) == str14    ? parseInt(str, 10)15    : str.charCodeAt(0);16}17 18function escapeBraces(str) {19  return str.split('\\\\').join(escSlash)20            .split('\\{').join(escOpen)21            .split('\\}').join(escClose)22            .split('\\,').join(escComma)23            .split('\\.').join(escPeriod);24}25 26function unescapeBraces(str) {27  return str.split(escSlash).join('\\')28            .split(escOpen).join('{')29            .split(escClose).join('}')30            .split(escComma).join(',')31            .split(escPeriod).join('.');32}33 34 35// Basically just str.split(","), but handling cases36// where we have nested braced sections, which should be37// treated as individual members, like {a,{b,c},d}38function parseCommaParts(str) {39  if (!str)40    return [''];41 42  var parts = [];43  var m = balanced('{', '}', str);44 45  if (!m)46    return str.split(',');47 48  var pre = m.pre;49  var body = m.body;50  var post = m.post;51  var p = pre.split(',');52 53  p[p.length-1] += '{' + body + '}';54  var postParts = parseCommaParts(post);55  if (post.length) {56    p[p.length-1] += postParts.shift();57    p.push.apply(p, postParts);58  }59 60  parts.push.apply(parts, p);61 62  return parts;63}64 65function expandTop(str) {66  if (!str)67    return [];68 69  // I don't know why Bash 4.3 does this, but it does.70  // Anything starting with {} will have the first two bytes preserved71  // but *only* at the top level, so {},a}b will not expand to anything,72  // but a{},b}c will be expanded to [a}c,abc].73  // One could argue that this is a bug in Bash, but since the goal of74  // this module is to match Bash's rules, we escape a leading {}75  if (str.substr(0, 2) === '{}') {76    str = '\\{\\}' + str.substr(2);77  }78 79  return expand(escapeBraces(str), true).map(unescapeBraces);80}81 82function identity(e) {83  return e;84}85 86function embrace(str) {87  return '{' + str + '}';88}89function isPadded(el) {90  return /^-?0\d/.test(el);91}92 93function lte(i, y) {94  return i <= y;95}96function gte(i, y) {97  return i >= y;98}99 100function expand(str, isTop) {101  var expansions = [];102 103  var m = balanced('{', '}', str);104  if (!m || /\$$/.test(m.pre)) return [str];105 106  var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);107  var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);108  var isSequence = isNumericSequence || isAlphaSequence;109  var isOptions = m.body.indexOf(',') >= 0;110  if (!isSequence && !isOptions) {111    // {a},b}112    if (m.post.match(/,(?!,).*\}/)) {113      str = m.pre + '{' + m.body + escClose + m.post;114      return expand(str);115    }116    return [str];117  }118 119  var n;120  if (isSequence) {121    n = m.body.split(/\.\./);122  } else {123    n = parseCommaParts(m.body);124    if (n.length === 1) {125      // x{{a,b}}y ==> x{a}y x{b}y126      n = expand(n[0], false).map(embrace);127      if (n.length === 1) {128        var post = m.post.length129          ? expand(m.post, false)130          : [''];131        return post.map(function(p) {132          return m.pre + n[0] + p;133        });134      }135    }136  }137 138  // at this point, n is the parts, and we know it's not a comma set139  // with a single entry.140 141  // no need to expand pre, since it is guaranteed to be free of brace-sets142  var pre = m.pre;143  var post = m.post.length144    ? expand(m.post, false)145    : [''];146 147  var N;148 149  if (isSequence) {150    var x = numeric(n[0]);151    var y = numeric(n[1]);152    var width = Math.max(n[0].length, n[1].length)153    var incr = n.length == 3154      ? Math.abs(numeric(n[2]))155      : 1;156    var test = lte;157    var reverse = y < x;158    if (reverse) {159      incr *= -1;160      test = gte;161    }162    var pad = n.some(isPadded);163 164    N = [];165 166    for (var i = x; test(i, y); i += incr) {167      var c;168      if (isAlphaSequence) {169        c = String.fromCharCode(i);170        if (c === '\\')171          c = '';172      } else {173        c = String(i);174        if (pad) {175          var need = width - c.length;176          if (need > 0) {177            var z = new Array(need + 1).join('0');178            if (i < 0)179              c = '-' + z + c.slice(1);180            else181              c = z + c;182          }183        }184      }185      N.push(c);186    }187  } else {188    N = concatMap(n, function(el) { return expand(el, false) });189  }190 191  for (var j = 0; j < N.length; j++) {192    for (var k = 0; k < post.length; k++) {193      var expansion = pre + N[j] + post[k];194      if (!isTop || isSequence || expansion)195        expansions.push(expansion);196    }197  }198 199  return expansions;200}201 202