Brunobkr/llama.cpp_AlgMor24_github
ΩFFFΣLLIa • llama.cpp • AlgMor24 ██████╗ ███████╗███████╗███████╗██╗ ██╗ ██╗ █████╗ ██╔═══██╗██╔════╝██╔════╝██╔════╝██║ ██║ ██║██╔══██╗ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║███████║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║██╔══██║ ╚██████╔╝██║ ██║ ███████╗███████╗███████╗██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ High-Performance LLM / VLM Inference & Autonomous Agentic Ecosystem… See the full description on the dataset page: https://huggingface.co/datasets/Brunobkr/llama.cpp_AlgMor24_github.
03.1k
1// parse a single path portion2var _a;3import { parseClass } from './brace-expressions.js';4import { unescape } from './unescape.js';5const types = new Set(['!', '?', '+', '*', '@']);6const isExtglobType = (c) => types.has(c);7const isExtglobAST = (c) => isExtglobType(c.type);8// Map of which extglob types can adopt the children of a nested extglob9//10// anything but ! can adopt a matching type:11// +(a|+(b|c)|d) => +(a|b|c|d)12// *(a|*(b|c)|d) => *(a|b|c|d)13// @(a|@(b|c)|d) => @(a|b|c|d)14// ?(a|?(b|c)|d) => ?(a|b|c|d)15//16// * can adopt anything, because 0 or repetition is allowed17// *(a|?(b|c)|d) => *(a|b|c|d)18// *(a|+(b|c)|d) => *(a|b|c|d)19// *(a|@(b|c)|d) => *(a|b|c|d)20//21// + can adopt @, because 1 or repetition is allowed22// +(a|@(b|c)|d) => +(a|b|c|d)23//24// + and @ CANNOT adopt *, because 0 would be allowed25// +(a|*(b|c)|d) => would match "", on *(b|c)26// @(a|*(b|c)|d) => would match "", on *(b|c)27//28// + and @ CANNOT adopt ?, because 0 would be allowed29// +(a|?(b|c)|d) => would match "", on ?(b|c)30// @(a|?(b|c)|d) => would match "", on ?(b|c)31//32// ? can adopt @, because 0 or 1 is allowed33// ?(a|@(b|c)|d) => ?(a|b|c|d)34//35// ? and @ CANNOT adopt * or +, because >1 would be allowed36// ?(a|*(b|c)|d) => would match bbb on *(b|c)37// @(a|*(b|c)|d) => would match bbb on *(b|c)38// ?(a|+(b|c)|d) => would match bbb on +(b|c)39// @(a|+(b|c)|d) => would match bbb on +(b|c)40//41// ! CANNOT adopt ! (nothing else can either)42// !(a|!(b|c)|d) => !(a|b|c|d) would fail to match on b (not not b|c)43//44// ! can adopt @45// !(a|@(b|c)|d) => !(a|b|c|d)46//47// ! CANNOT adopt *48// !(a|*(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed49//50// ! CANNOT adopt +51// !(a|+(b|c)|d) => !(a|b|c|d) would match on bbb, not allowed52//53// ! CANNOT adopt ?54// x!(a|?(b|c)|d) => x!(a|b|c|d) would fail to match "x"55const adoptionMap = new Map([56 ['!', ['@']],57 ['?', ['?', '@']],58 ['@', ['@']],59 ['*', ['*', '+', '?', '@']],60 ['+', ['+', '@']],61]);62// nested extglobs that can be adopted in, but with the addition of63// a blank '' element.64const adoptionWithSpaceMap = new Map([65 ['!', ['?']],66 ['@', ['?']],67 ['+', ['?', '*']],68]);69// union of the previous two maps70const adoptionAnyMap = new Map([71 ['!', ['?', '@']],72 ['?', ['?', '@']],73 ['@', ['?', '@']],74 ['*', ['*', '+', '?', '@']],75 ['+', ['+', '@', '?', '*']],76]);77// Extglobs that can take over their parent if they are the only child78// the key is parent, value maps child to resulting extglob parent type79// '@' is omitted because it's a special case. An `@` extglob with a single80// member can always be usurped by that subpattern.81const usurpMap = new Map([82 ['!', new Map([['!', '@']])],83 [84 '?',85 new Map([86 ['*', '*'],87 ['+', '*'],88 ]),89 ],90 [91 '@',92 new Map([93 ['!', '!'],94 ['?', '?'],95 ['@', '@'],96 ['*', '*'],97 ['+', '+'],98 ]),99 ],100 [101 '+',102 new Map([103 ['?', '*'],104 ['*', '*'],105 ]),106 ],107]);108// Patterns that get prepended to bind to the start of either the109// entire string, or just a single path portion, to prevent dots110// and/or traversal patterns, when needed.111// Exts don't need the ^ or / bit, because the root binds that already.112const startNoTraversal = '(?!(?:^|/)\\.\\.?(?:$|/))';113const startNoDot = '(?!\\.)';114// characters that indicate a start of pattern needs the "no dots" bit,115// because a dot *might* be matched. ( is not in the list, because in116// the case of a child extglob, it will handle the prevention itself.117const addPatternStart = new Set(['[', '.']);118// cases where traversal is A-OK, no dot prevention needed119const justDots = new Set(['..', '.']);120const reSpecials = new Set('().*{}+?[]^$\\!');121const regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');122// any single thing other than /123const qmark = '[^/]';124// * => any number of characters125const star = qmark + '*?';126// use + when we need to ensure that *something* matches, because the * is127// the only thing in the path portion.128const starNoEmpty = qmark + '+?';129// remove the \ chars that we added if we end up doing a nonmagic compare130// const deslash = (s: string) => s.replace(/\\(.)/g, '$1')131let ID = 0;132export class AST {133 type;134 #root;135 #hasMagic;136 #uflag = false;137 #parts = [];138 #parent;139 #parentIndex;140 #negs;141 #filledNegs = false;142 #options;143 #toString;144 // set to true if it's an extglob with no children145 // (which really means one child of '')146 #emptyExt = false;147 id = ++ID;148 get depth() {149 return (this.#parent?.depth ?? -1) + 1;150 }151 [Symbol.for('nodejs.util.inspect.custom')]() {152 return {153 '@@type': 'AST',154 id: this.id,155 type: this.type,156 root: this.#root.id,157 parent: this.#parent?.id,158 depth: this.depth,159 partsLength: this.#parts.length,160 parts: this.#parts,161 };162 }163 constructor(type, parent, options = {}) {164 this.type = type;165 // extglobs are inherently magical166 if (type)167 this.#hasMagic = true;168 this.#parent = parent;169 this.#root = this.#parent ? this.#parent.#root : this;170 this.#options = this.#root === this ? options : this.#root.#options;171 this.#negs = this.#root === this ? [] : this.#root.#negs;172 if (type === '!' && !this.#root.#filledNegs)173 this.#negs.push(this);174 this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0;175 }176 get hasMagic() {177 /* c8 ignore start */178 if (this.#hasMagic !== undefined)179 return this.#hasMagic;180 /* c8 ignore stop */181 for (const p of this.#parts) {182 if (typeof p === 'string')183 continue;184 if (p.type || p.hasMagic)185 return (this.#hasMagic = true);186 }187 // note: will be undefined until we generate the regexp src and find out188 return this.#hasMagic;189 }190 // reconstructs the pattern191 toString() {192 return (this.#toString !== undefined ? this.#toString193 : !this.type ?194 (this.#toString = this.#parts.map(p => String(p)).join(''))195 : (this.#toString =196 this.type +197 '(' +198 this.#parts.map(p => String(p)).join('|') +199 ')'));200 }201 #fillNegs() {202 /* c8 ignore start */203 if (this !== this.#root)204 throw new Error('should only call on root');205 if (this.#filledNegs)206 return this;207 /* c8 ignore stop */208 // call toString() once to fill this out209 this.toString();210 this.#filledNegs = true;211 let n;212 while ((n = this.#negs.pop())) {213 if (n.type !== '!')214 continue;215 // walk up the tree, appending everthing that comes AFTER parentIndex216 let p = n;217 let pp = p.#parent;218 while (pp) {219 for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) {220 for (const part of n.#parts) {221 /* c8 ignore start */222 if (typeof part === 'string') {223 throw new Error('string part in extglob AST??');224 }225 /* c8 ignore stop */226 part.copyIn(pp.#parts[i]);227 }228 }229 p = pp;230 pp = p.#parent;231 }232 }233 return this;234 }235 push(...parts) {236 for (const p of parts) {237 if (p === '')238 continue;239 /* c8 ignore start */240 if (typeof p !== 'string' &&241 !(p instanceof _a && p.#parent === this)) {242 throw new Error('invalid part: ' + p);243 }244 /* c8 ignore stop */245 this.#parts.push(p);246 }247 }248 toJSON() {249 const ret = this.type === null ?250 this.#parts251 .slice()252 .map(p => (typeof p === 'string' ? p : p.toJSON()))253 : [this.type, ...this.#parts.map(p => p.toJSON())];254 if (this.isStart() && !this.type)255 ret.unshift([]);256 if (this.isEnd() &&257 (this === this.#root ||258 (this.#root.#filledNegs && this.#parent?.type === '!'))) {259 ret.push({});260 }261 return ret;262 }263 isStart() {264 if (this.#root === this)265 return true;266 // if (this.type) return !!this.#parent?.isStart()267 if (!this.#parent?.isStart())268 return false;269 if (this.#parentIndex === 0)270 return true;271 // if everything AHEAD of this is a negation, then it's still the "start"272 const p = this.#parent;273 for (let i = 0; i < this.#parentIndex; i++) {274 const pp = p.#parts[i];275 if (!(pp instanceof _a && pp.type === '!')) {276 return false;277 }278 }279 return true;280 }281 isEnd() {282 if (this.#root === this)283 return true;284 if (this.#parent?.type === '!')285 return true;286 if (!this.#parent?.isEnd())287 return false;288 if (!this.type)289 return this.#parent?.isEnd();290 // if not root, it'll always have a parent291 /* c8 ignore start */292 const pl = this.#parent ? this.#parent.#parts.length : 0;293 /* c8 ignore stop */294 return this.#parentIndex === pl - 1;295 }296 copyIn(part) {297 if (typeof part === 'string')298 this.push(part);299 else300 this.push(part.clone(this));301 }302 clone(parent) {303 const c = new _a(this.type, parent);304 for (const p of this.#parts) {305 c.copyIn(p);306 }307 return c;308 }309 static #parseAST(str, ast, pos, opt, extDepth) {310 const maxDepth = opt.maxExtglobRecursion ?? 2;311 let escaping = false;312 let inBrace = false;313 let braceStart = -1;314 let braceNeg = false;315 if (ast.type === null) {316 // outside of a extglob, append until we find a start317 let i = pos;318 let acc = '';319 while (i < str.length) {320 const c = str.charAt(i++);321 // still accumulate escapes at this point, but we do ignore322 // starts that are escaped323 if (escaping || c === '\\') {324 escaping = !escaping;325 acc += c;326 continue;327 }328 if (inBrace) {329 if (i === braceStart + 1) {330 if (c === '^' || c === '!') {331 braceNeg = true;332 }333 }334 else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {335 inBrace = false;336 }337 acc += c;338 continue;339 }340 else if (c === '[') {341 inBrace = true;342 braceStart = i;343 braceNeg = false;344 acc += c;345 continue;346 }347 // we don't have to check for adoption here, because that's348 // done at the other recursion point.349 const doRecurse = !opt.noext &&350 isExtglobType(c) &&351 str.charAt(i) === '(' &&352 extDepth <= maxDepth;353 if (doRecurse) {354 ast.push(acc);355 acc = '';356 const ext = new _a(c, ast);357 i = _a.#parseAST(str, ext, i, opt, extDepth + 1);358 ast.push(ext);359 continue;360 }361 acc += c;362 }363 ast.push(acc);364 return i;365 }366 // some kind of extglob, pos is at the (367 // find the next | or )368 let i = pos + 1;369 let part = new _a(null, ast);370 const parts = [];371 let acc = '';372 while (i < str.length) {373 const c = str.charAt(i++);374 // still accumulate escapes at this point, but we do ignore375 // starts that are escaped376 if (escaping || c === '\\') {377 escaping = !escaping;378 acc += c;379 continue;380 }381 if (inBrace) {382 if (i === braceStart + 1) {383 if (c === '^' || c === '!') {384 braceNeg = true;385 }386 }387 else if (c === ']' && !(i === braceStart + 2 && braceNeg)) {388 inBrace = false;389 }390 acc += c;391 continue;392 }393 else if (c === '[') {394 inBrace = true;395 braceStart = i;396 braceNeg = false;397 acc += c;398 continue;399 }400 const doRecurse = !opt.noext &&401 isExtglobType(c) &&402 str.charAt(i) === '(' &&403 /* c8 ignore start - the maxDepth is sufficient here */404 (extDepth <= maxDepth || (ast && ast.#canAdoptType(c)));405 /* c8 ignore stop */406 if (doRecurse) {407 const depthAdd = ast && ast.#canAdoptType(c) ? 0 : 1;408 part.push(acc);409 acc = '';410 const ext = new _a(c, part);411 part.push(ext);412 i = _a.#parseAST(str, ext, i, opt, extDepth + depthAdd);413 continue;414 }415 if (c === '|') {416 part.push(acc);417 acc = '';418 parts.push(part);419 part = new _a(null, ast);420 continue;421 }422 if (c === ')') {423 if (acc === '' && ast.#parts.length === 0) {424 ast.#emptyExt = true;425 }426 part.push(acc);427 acc = '';428 ast.push(...parts, part);429 return i;430 }431 acc += c;432 }433 // unfinished extglob434 // if we got here, it was a malformed extglob! not an extglob, but435 // maybe something else in there.436 ast.type = null;437 ast.#hasMagic = undefined;438 ast.#parts = [str.substring(pos - 1)];439 return i;440 }441 #canAdoptWithSpace(child) {442 return this.#canAdopt(child, adoptionWithSpaceMap);443 }444 #canAdopt(child, map = adoptionMap) {445 if (!child ||446 typeof child !== 'object' ||447 child.type !== null ||448 child.#parts.length !== 1 ||449 this.type === null) {450 return false;451 }452 const gc = child.#parts[0];453 if (!gc || typeof gc !== 'object' || gc.type === null) {454 return false;455 }456 return this.#canAdoptType(gc.type, map);457 }458 #canAdoptType(c, map = adoptionAnyMap) {459 return !!map.get(this.type)?.includes(c);460 }461 #adoptWithSpace(child, index) {462 const gc = child.#parts[0];463 const blank = new _a(null, gc, this.options);464 blank.#parts.push('');465 gc.push(blank);466 this.#adopt(child, index);467 }468 #adopt(child, index) {469 const gc = child.#parts[0];470 this.#parts.splice(index, 1, ...gc.#parts);471 for (const p of gc.#parts) {472 if (typeof p === 'object')473 p.#parent = this;474 }475 this.#toString = undefined;476 }477 #canUsurpType(c) {478 const m = usurpMap.get(this.type);479 return !!m?.has(c);480 }481 #canUsurp(child) {482 if (!child ||483 typeof child !== 'object' ||484 child.type !== null ||485 child.#parts.length !== 1 ||486 this.type === null ||487 this.#parts.length !== 1) {488 return false;489 }490 const gc = child.#parts[0];491 if (!gc || typeof gc !== 'object' || gc.type === null) {492 return false;493 }494 return this.#canUsurpType(gc.type);495 }496 #usurp(child) {497 const m = usurpMap.get(this.type);498 const gc = child.#parts[0];499 const nt = m?.get(gc.type);500 /* c8 ignore start - impossible */501 if (!nt)502 return false;503 /* c8 ignore stop */504 this.#parts = gc.#parts;505 for (const p of this.#parts) {506 if (typeof p === 'object') {507 p.#parent = this;508 }509 }510 this.type = nt;511 this.#toString = undefined;512 this.#emptyExt = false;513 }514 static fromGlob(pattern, options = {}) {515 const ast = new _a(null, undefined, options);516 _a.#parseAST(pattern, ast, 0, options, 0);517 return ast;518 }519 // returns the regular expression if there's magic, or the unescaped520 // string if not.521 toMMPattern() {522 // should only be called on root523 /* c8 ignore start */524 if (this !== this.#root)525 return this.#root.toMMPattern();526 /* c8 ignore stop */527 const glob = this.toString();528 const [re, body, hasMagic, uflag] = this.toRegExpSource();529 // if we're in nocase mode, and not nocaseMagicOnly, then we do530 // still need a regular expression if we have to case-insensitively531 // match capital/lowercase characters.532 const anyMagic = hasMagic ||533 this.#hasMagic ||534 (this.#options.nocase &&535 !this.#options.nocaseMagicOnly &&536 glob.toUpperCase() !== glob.toLowerCase());537 if (!anyMagic) {538 return body;539 }540 const flags = (this.#options.nocase ? 'i' : '') + (uflag ? 'u' : '');541 return Object.assign(new RegExp(`^${re}$`, flags), {542 _src: re,543 _glob: glob,544 });545 }546 get options() {547 return this.#options;548 }549 // returns the string match, the regexp source, whether there's magic550 // in the regexp (so a regular expression is required) and whether or551 // not the uflag is needed for the regular expression (for posix classes)552 // TODO: instead of injecting the start/end at this point, just return553 // the BODY of the regexp, along with the start/end portions suitable554 // for binding the start/end in either a joined full-path makeRe context555 // (where we bind to (^|/), or a standalone matchPart context (where556 // we bind to ^, and not /). Otherwise slashes get duped!557 //558 // In part-matching mode, the start is:559 // - if not isStart: nothing560 // - if traversal possible, but not allowed: ^(?!\.\.?$)561 // - if dots allowed or not possible: ^562 // - if dots possible and not allowed: ^(?!\.)563 // end is:564 // - if not isEnd(): nothing565 // - else: $566 //567 // In full-path matching mode, we put the slash at the START of the568 // pattern, so start is:569 // - if first pattern: same as part-matching mode570 // - if not isStart(): nothing571 // - if traversal possible, but not allowed: /(?!\.\.?(?:$|/))572 // - if dots allowed or not possible: /573 // - if dots possible and not allowed: /(?!\.)574 // end is:575 // - if last pattern, same as part-matching mode576 // - else nothing577 //578 // Always put the (?:$|/) on negated tails, though, because that has to be579 // there to bind the end of the negated pattern portion, and it's easier to580 // just stick it in now rather than try to inject it later in the middle of581 // the pattern.582 //583 // We can just always return the same end, and leave it up to the caller584 // to know whether it's going to be used joined or in parts.585 // And, if the start is adjusted slightly, can do the same there:586 // - if not isStart: nothing587 // - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$)588 // - if dots allowed or not possible: (?:/|^)589 // - if dots possible and not allowed: (?:/|^)(?!\.)590 //591 // But it's better to have a simpler binding without a conditional, for592 // performance, so probably better to return both start options.593 //594 // Then the caller just ignores the end if it's not the first pattern,595 // and the start always gets applied.596 //597 // But that's always going to be $ if it's the ending pattern, or nothing,598 // so the caller can just attach $ at the end of the pattern when building.599 //600 // So the todo is:601 // - better detect what kind of start is needed602 // - return both flavors of starting pattern603 // - attach $ at the end of the pattern when creating the actual RegExp604 //605 // Ah, but wait, no, that all only applies to the root when the first pattern606 // is not an extglob. If the first pattern IS an extglob, then we need all607 // that dot prevention biz to live in the extglob portions, because eg608 // +(*|.x*) can match .xy but not .yx.609 //610 // So, return the two flavors if it's #root and the first child is not an611 // AST, otherwise leave it to the child AST to handle it, and there,612 // use the (?:^|/) style of start binding.613 //614 // Even simplified further:615 // - Since the start for a join is eg /(?!\.) and the start for a part616 // is ^(?!\.), we can just prepend (?!\.) to the pattern (either root617 // or start or whatever) and prepend ^ or / at the Regexp construction.618 toRegExpSource(allowDot) {619 const dot = allowDot ?? !!this.#options.dot;620 if (this.#root === this) {621 this.#flatten();622 this.#fillNegs();623 }624 if (!isExtglobAST(this)) {625 const noEmpty = this.isStart() &&626 this.isEnd() &&627 !this.#parts.some(s => typeof s !== 'string');628 const src = this.#parts629 .map(p => {630 const [re, _, hasMagic, uflag] = typeof p === 'string' ?631 _a.#parseGlob(p, this.#hasMagic, noEmpty)632 : p.toRegExpSource(allowDot);633 this.#hasMagic = this.#hasMagic || hasMagic;634 this.#uflag = this.#uflag || uflag;635 return re;636 })637 .join('');638 let start = '';639 if (this.isStart()) {640 if (typeof this.#parts[0] === 'string') {641 // this is the string that will match the start of the pattern,642 // so we need to protect against dots and such.643 // '.' and '..' cannot match unless the pattern is that exactly,644 // even if it starts with . or dot:true is set.645 const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]);646 if (!dotTravAllowed) {647 const aps = addPatternStart;648 // check if we have a possibility of matching . or ..,649 // and prevent that.650 const needNoTrav = 651 // dots are allowed, and the pattern starts with [ or .652 (dot && aps.has(src.charAt(0))) ||653 // the pattern starts with \., and then [ or .654 (src.startsWith('\\.') && aps.has(src.charAt(2))) ||655 // the pattern starts with \.\., and then [ or .656 (src.startsWith('\\.\\.') && aps.has(src.charAt(4)));657 // no need to prevent dots if it can't match a dot, or if a658 // sub-pattern will be preventing it anyway.659 const needNoDot = !dot && !allowDot && aps.has(src.charAt(0));660 start =661 needNoTrav ? startNoTraversal662 : needNoDot ? startNoDot663 : '';664 }665 }666 }667 // append the "end of path portion" pattern to negation tails668 let end = '';669 if (this.isEnd() &&670 this.#root.#filledNegs &&671 this.#parent?.type === '!') {672 end = '(?:$|\\/)';673 }674 const final = start + src + end;675 return [676 final,677 unescape(src),678 (this.#hasMagic = !!this.#hasMagic),679 this.#uflag,680 ];681 }682 // We need to calculate the body *twice* if it's a repeat pattern683 // at the start, once in nodot mode, then again in dot mode, so a684 // pattern like *(?) can match 'x.y'685 const repeated = this.type === '*' || this.type === '+';686 // some kind of extglob687 const start = this.type === '!' ? '(?:(?!(?:' : '(?:';688 let body = this.#partsToRegExp(dot);689 if (this.isStart() && this.isEnd() && !body && this.type !== '!') {690 // invalid extglob, has to at least be *something* present, if it's691 // the entire path portion.692 const s = this.toString();693 const me = this;694 me.#parts = [s];695 me.type = null;696 me.#hasMagic = undefined;697 return [s, unescape(this.toString()), false, false];698 }699 let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ?700 ''701 : this.#partsToRegExp(true);702 if (bodyDotAllowed === body) {703 bodyDotAllowed = '';704 }705 if (bodyDotAllowed) {706 body = `(?:${body})(?:${bodyDotAllowed})*?`;707 }708 // an empty !() is exactly equivalent to a starNoEmpty709 let final = '';710 if (this.type === '!' && this.#emptyExt) {711 final = (this.isStart() && !dot ? startNoDot : '') + starNoEmpty;712 }713 else {714 const close = this.type === '!' ?715 // !() must match something,but !(x) can match ''716 '))' +717 (this.isStart() && !dot && !allowDot ? startNoDot : '') +718 star +719 ')'720 : this.type === '@' ? ')'721 : this.type === '?' ? ')?'722 : this.type === '+' && bodyDotAllowed ? ')'723 : this.type === '*' && bodyDotAllowed ? `)?`724 : `)${this.type}`;725 final = start + body + close;726 }727 return [728 final,729 unescape(body),730 (this.#hasMagic = !!this.#hasMagic),731 this.#uflag,732 ];733 }734 #flatten() {735 if (!isExtglobAST(this)) {736 for (const p of this.#parts) {737 if (typeof p === 'object') {738 p.#flatten();739 }740 }741 }742 else {743 // do up to 10 passes to flatten as much as possible744 let iterations = 0;745 let done = false;746 do {747 done = true;748 for (let i = 0; i < this.#parts.length; i++) {749 const c = this.#parts[i];750 if (typeof c === 'object') {751 c.#flatten();752 if (this.#canAdopt(c)) {753 done = false;754 this.#adopt(c, i);755 }756 else if (this.#canAdoptWithSpace(c)) {757 done = false;758 this.#adoptWithSpace(c, i);759 }760 else if (this.#canUsurp(c)) {761 done = false;762 this.#usurp(c);763 }764 }765 }766 } while (!done && ++iterations < 10);767 }768 this.#toString = undefined;769 }770 #partsToRegExp(dot) {771 return this.#parts772 .map(p => {773 // extglob ASTs should only contain parent ASTs774 /* c8 ignore start */775 if (typeof p === 'string') {776 throw new Error('string type in extglob ast??');777 }778 /* c8 ignore stop */779 // can ignore hasMagic, because extglobs are already always magic780 const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot);781 this.#uflag = this.#uflag || uflag;782 return re;783 })784 .filter(p => !(this.isStart() && this.isEnd()) || !!p)785 .join('|');786 }787 static #parseGlob(glob, hasMagic, noEmpty = false) {788 let escaping = false;789 let re = '';790 let uflag = false;791 // multiple stars that aren't globstars coalesce into one *792 let inStar = false;793 for (let i = 0; i < glob.length; i++) {794 const c = glob.charAt(i);795 if (escaping) {796 escaping = false;797 re += (reSpecials.has(c) ? '\\' : '') + c;798 continue;799 }800 if (c === '*') {801 if (inStar)802 continue;803 inStar = true;804 re += noEmpty && /^[*]+$/.test(glob) ? starNoEmpty : star;805 hasMagic = true;806 continue;807 }808 else {809 inStar = false;810 }811 if (c === '\\') {812 if (i === glob.length - 1) {813 re += '\\\\';814 }815 else {816 escaping = true;817 }818 continue;819 }820 if (c === '[') {821 const [src, needUflag, consumed, magic] = parseClass(glob, i);822 if (consumed) {823 re += src;824 uflag = uflag || needUflag;825 i += consumed - 1;826 hasMagic = hasMagic || magic;827 continue;828 }829 }830 if (c === '?') {831 re += qmark;832 hasMagic = true;833 continue;834 }835 re += regExpEscape(c);836 }837 return [re, unescape(glob), !!hasMagic, uflag];838 }839}840_a = AST;841//# sourceMappingURL=ast.js.map