diff --git a/.github/scripts/merge_manager.js b/.github/scripts/merge_manager.js
index f55d6e4d3..c2b39de6a 100644
--- a/.github/scripts/merge_manager.js
+++ b/.github/scripts/merge_manager.js
@@ -1,5 +1,5 @@
const { Buffer } = require('node:buffer');
-const { minimatch } = require('./minimatch-lite.js');
+const { minimatch } = require('minimatch');
const { ensureRateLimitWrapped } = require('./github-rate-limited-wrapper.js');
async function fetchAllowlist(github, owner, repo, path, ref) {
diff --git a/.github/scripts/minimatch-lite.js b/.github/scripts/minimatch-lite.js
deleted file mode 100644
index 345b37fe9..000000000
--- a/.github/scripts/minimatch-lite.js
+++ /dev/null
@@ -1,176 +0,0 @@
-'use strict';
-
-function escapeRegExp(value) {
- return value.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&');
-}
-
-function expandBraces(pattern) {
- const start = pattern.indexOf('{');
- if (start === -1) {
- return [pattern];
- }
- let depth = 0;
- let end = -1;
- for (let i = start; i < pattern.length; i += 1) {
- const char = pattern[i];
- if (char === '\\') {
- i += 1;
- continue;
- }
- if (char === '{') {
- depth += 1;
- } else if (char === '}') {
- depth -= 1;
- if (depth === 0) {
- end = i;
- break;
- }
- }
- }
- if (end === -1) {
- return [pattern];
- }
- const prefix = pattern.slice(0, start);
- const suffix = pattern.slice(end + 1);
- const body = pattern.slice(start + 1, end);
- const parts = [];
- let current = '';
- let nested = 0;
- for (let i = 0; i < body.length; i += 1) {
- const char = body[i];
- if (char === '\\') {
- current += char;
- if (i + 1 < body.length) {
- current += body[i + 1];
- i += 1;
- }
- continue;
- }
- if (char === '{') {
- nested += 1;
- } else if (char === '}') {
- nested -= 1;
- }
- if (char === ',' && nested === 0) {
- parts.push(current);
- current = '';
- continue;
- }
- current += char;
- }
- parts.push(current);
- const expanded = [];
- for (const part of parts) {
- for (const next of expandBraces(`${prefix}${part}${suffix}`)) {
- expanded.push(next);
- }
- }
- return expanded;
-}
-
-function globToRegExp(pattern) {
- let regex = '^';
- for (let i = 0; i < pattern.length; i += 1) {
- const char = pattern[i];
- if (char === '\\') {
- const next = pattern[i + 1];
- if (next !== undefined) {
- regex += escapeRegExp(next);
- i += 1;
- } else {
- regex += '\\\\';
- }
- continue;
- }
- if (char === '*') {
- const next = pattern[i + 1];
- if (next === '*') {
- const nextChar = pattern[i + 2];
- if (nextChar === '/') {
- regex += '(?:.*/)?';
- i += 2;
- } else {
- regex += '.*';
- i += 1;
- }
- } else {
- regex += '[^/]*';
- }
- continue;
- }
- if (char === '?') {
- regex += '[^/]';
- continue;
- }
- if (char === '[') {
- let j = i + 1;
- let content = '';
- let closed = false;
- if (pattern[j] === '!' || pattern[j] === '^') {
- content += '^';
- j += 1;
- }
- for (; j < pattern.length; j += 1) {
- const inner = pattern[j];
- if (inner === '\\') {
- if (j + 1 < pattern.length) {
- content += `\\${pattern[j + 1]}`;
- j += 1;
- continue;
- }
- }
- if (inner === ']') {
- closed = true;
- break;
- }
- content += inner;
- }
- if (closed) {
- regex += `[${content}]`;
- i = j;
- } else {
- regex += '\\[';
- }
- continue;
- }
- regex += escapeRegExp(char);
- }
- regex += '$';
- return new RegExp(regex);
-}
-
-function minimatch(pathname, pattern, options = {}) {
- if (typeof pathname !== 'string' || typeof pattern !== 'string') {
- return false;
- }
-
- const opts = options || {};
-
- if (!opts.nocomment && pattern.startsWith('#')) {
- return false;
- }
-
- if (!opts.nonegate && pattern.startsWith('!')) {
- const next = pattern.slice(1);
- return !minimatch(pathname, next, { ...opts, nonegate: true });
- }
-
- let target = pathname;
- let pat = pattern;
-
- if (opts.nocase) {
- target = target.toLowerCase();
- pat = pat.toLowerCase();
- }
-
- const patterns = expandBraces(pat);
- for (const expanded of patterns) {
- const regex = globToRegExp(expanded);
- if (regex.test(target)) {
- return true;
- }
- }
- return false;
-}
-
-module.exports = { minimatch };
diff --git a/.github/scripts/pr-context-graphql.js b/.github/scripts/pr-context-graphql.js
index 6eb3ffa1e..fafcc2d4c 100644
--- a/.github/scripts/pr-context-graphql.js
+++ b/.github/scripts/pr-context-graphql.js
@@ -1,7 +1,7 @@
'use strict';
const { ensureRateLimitWrapped } = require('./github-rate-limited-wrapper.js');
-const { minimatch } = require('./minimatch-lite.js');
+const { minimatch } = require('minimatch');
/**
* GraphQL-based PR Context Fetcher
diff --git a/.github/sync-manifest.yml b/.github/sync-manifest.yml
index ad794f0c0..6aad21089 100644
--- a/.github/sync-manifest.yml
+++ b/.github/sync-manifest.yml
@@ -248,6 +248,12 @@ scripts:
- source: .github/scripts/node_modules/minimatch/
description: "Vendored minimatch dependency for .github scripts"
+ - source: .github/scripts/node_modules/brace-expansion/
+ description: "Vendored brace-expansion dependency (transitive dep of minimatch)"
+
+ - source: .github/scripts/node_modules/balanced-match/
+ description: "Vendored balanced-match dependency (transitive dep of brace-expansion)"
+
# JavaScript scripts for issue/PR handling
- source: .github/scripts/issue_pr_locator.js
description: "Locates PRs associated with issues"
diff --git a/templates/consumer-repo/.github/scripts/merge_manager.js b/templates/consumer-repo/.github/scripts/merge_manager.js
index f55d6e4d3..c2b39de6a 100644
--- a/templates/consumer-repo/.github/scripts/merge_manager.js
+++ b/templates/consumer-repo/.github/scripts/merge_manager.js
@@ -1,5 +1,5 @@
const { Buffer } = require('node:buffer');
-const { minimatch } = require('./minimatch-lite.js');
+const { minimatch } = require('minimatch');
const { ensureRateLimitWrapped } = require('./github-rate-limited-wrapper.js');
async function fetchAllowlist(github, owner, repo, path, ref) {
diff --git a/templates/consumer-repo/.github/scripts/node_modules/balanced-match/.github/FUNDING.yml b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/.github/FUNDING.yml
new file mode 100644
index 000000000..cea8b16e9
--- /dev/null
+++ b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+tidelift: "npm/balanced-match"
+patreon: juliangruber
diff --git a/templates/consumer-repo/.github/scripts/node_modules/balanced-match/LICENSE.md b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/LICENSE.md
new file mode 100644
index 000000000..2cdc8e414
--- /dev/null
+++ b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/LICENSE.md
@@ -0,0 +1,21 @@
+(MIT)
+
+Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/templates/consumer-repo/.github/scripts/node_modules/balanced-match/README.md b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/README.md
new file mode 100644
index 000000000..d2a48b6b4
--- /dev/null
+++ b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/README.md
@@ -0,0 +1,97 @@
+# balanced-match
+
+Match balanced string pairs, like `{` and `}` or `` and ``. Supports regular expressions as well!
+
+[](http://travis-ci.org/juliangruber/balanced-match)
+[](https://www.npmjs.org/package/balanced-match)
+
+[](https://ci.testling.com/juliangruber/balanced-match)
+
+## Example
+
+Get the first matching pair of braces:
+
+```js
+var balanced = require('balanced-match');
+
+console.log(balanced('{', '}', 'pre{in{nested}}post'));
+console.log(balanced('{', '}', 'pre{first}between{second}post'));
+console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post'));
+```
+
+The matches are:
+
+```bash
+$ node example.js
+{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' }
+{ start: 3,
+ end: 9,
+ pre: 'pre',
+ body: 'first',
+ post: 'between{second}post' }
+{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' }
+```
+
+## API
+
+### var m = balanced(a, b, str)
+
+For the first non-nested matching pair of `a` and `b` in `str`, return an
+object with those keys:
+
+* **start** the index of the first match of `a`
+* **end** the index of the matching `b`
+* **pre** the preamble, `a` and `b` not included
+* **body** the match, `a` and `b` not included
+* **post** the postscript, `a` and `b` not included
+
+If there's no match, `undefined` will be returned.
+
+If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`.
+
+### var r = balanced.range(a, b, str)
+
+For the first non-nested matching pair of `a` and `b` in `str`, return an
+array with indexes: `[ , ]`.
+
+If there's no match, `undefined` will be returned.
+
+If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`.
+
+## Installation
+
+With [npm](https://npmjs.org) do:
+
+```bash
+npm install balanced-match
+```
+
+## Security contact information
+
+To report a security vulnerability, please use the
+[Tidelift security contact](https://tidelift.com/security).
+Tidelift will coordinate the fix and disclosure.
+
+## License
+
+(MIT)
+
+Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/templates/consumer-repo/.github/scripts/node_modules/balanced-match/index.js b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/index.js
new file mode 100644
index 000000000..c67a64608
--- /dev/null
+++ b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/index.js
@@ -0,0 +1,62 @@
+'use strict';
+module.exports = balanced;
+function balanced(a, b, str) {
+ if (a instanceof RegExp) a = maybeMatch(a, str);
+ if (b instanceof RegExp) b = maybeMatch(b, str);
+
+ var r = range(a, b, str);
+
+ return r && {
+ start: r[0],
+ end: r[1],
+ pre: str.slice(0, r[0]),
+ body: str.slice(r[0] + a.length, r[1]),
+ post: str.slice(r[1] + b.length)
+ };
+}
+
+function maybeMatch(reg, str) {
+ var m = str.match(reg);
+ return m ? m[0] : null;
+}
+
+balanced.range = range;
+function range(a, b, str) {
+ var begs, beg, left, right, result;
+ var ai = str.indexOf(a);
+ var bi = str.indexOf(b, ai + 1);
+ var i = ai;
+
+ if (ai >= 0 && bi > 0) {
+ if(a===b) {
+ return [ai, bi];
+ }
+ begs = [];
+ left = str.length;
+
+ while (i >= 0 && !result) {
+ if (i == ai) {
+ begs.push(i);
+ ai = str.indexOf(a, i + 1);
+ } else if (begs.length == 1) {
+ result = [ begs.pop(), bi ];
+ } else {
+ beg = begs.pop();
+ if (beg < left) {
+ left = beg;
+ right = bi;
+ }
+
+ bi = str.indexOf(b, i + 1);
+ }
+
+ i = ai < bi && ai >= 0 ? ai : bi;
+ }
+
+ if (begs.length) {
+ result = [ left, right ];
+ }
+ }
+
+ return result;
+}
diff --git a/templates/consumer-repo/.github/scripts/node_modules/balanced-match/package.json b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/package.json
new file mode 100644
index 000000000..ce6073e04
--- /dev/null
+++ b/templates/consumer-repo/.github/scripts/node_modules/balanced-match/package.json
@@ -0,0 +1,48 @@
+{
+ "name": "balanced-match",
+ "description": "Match balanced character pairs, like \"{\" and \"}\"",
+ "version": "1.0.2",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/juliangruber/balanced-match.git"
+ },
+ "homepage": "https://github.com/juliangruber/balanced-match",
+ "main": "index.js",
+ "scripts": {
+ "test": "tape test/test.js",
+ "bench": "matcha test/bench.js"
+ },
+ "devDependencies": {
+ "matcha": "^0.7.0",
+ "tape": "^4.6.0"
+ },
+ "keywords": [
+ "match",
+ "regexp",
+ "test",
+ "balanced",
+ "parse"
+ ],
+ "author": {
+ "name": "Julian Gruber",
+ "email": "mail@juliangruber.com",
+ "url": "http://juliangruber.com"
+ },
+ "license": "MIT",
+ "testling": {
+ "files": "test/*.js",
+ "browsers": [
+ "ie/8..latest",
+ "firefox/20..latest",
+ "firefox/nightly",
+ "chrome/25..latest",
+ "chrome/canary",
+ "opera/12..latest",
+ "opera/next",
+ "safari/5.1..latest",
+ "ipad/6.0..latest",
+ "iphone/6.0..latest",
+ "android-browser/4.2..latest"
+ ]
+ }
+}
diff --git a/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/.github/FUNDING.yml b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/.github/FUNDING.yml
new file mode 100644
index 000000000..79d1eafce
--- /dev/null
+++ b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+tidelift: "npm/brace-expansion"
+patreon: juliangruber
diff --git a/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/LICENSE b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/LICENSE
new file mode 100644
index 000000000..de3226673
--- /dev/null
+++ b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2013 Julian Gruber
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/README.md b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/README.md
new file mode 100644
index 000000000..e55c583dd
--- /dev/null
+++ b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/README.md
@@ -0,0 +1,135 @@
+# brace-expansion
+
+[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html),
+as known from sh/bash, in JavaScript.
+
+[](http://travis-ci.org/juliangruber/brace-expansion)
+[](https://www.npmjs.org/package/brace-expansion)
+[](https://greenkeeper.io/)
+
+[](https://ci.testling.com/juliangruber/brace-expansion)
+
+## Example
+
+```js
+var expand = require('brace-expansion');
+
+expand('file-{a,b,c}.jpg')
+// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg']
+
+expand('-v{,,}')
+// => ['-v', '-v', '-v']
+
+expand('file{0..2}.jpg')
+// => ['file0.jpg', 'file1.jpg', 'file2.jpg']
+
+expand('file-{a..c}.jpg')
+// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg']
+
+expand('file{2..0}.jpg')
+// => ['file2.jpg', 'file1.jpg', 'file0.jpg']
+
+expand('file{0..4..2}.jpg')
+// => ['file0.jpg', 'file2.jpg', 'file4.jpg']
+
+expand('file-{a..e..2}.jpg')
+// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg']
+
+expand('file{00..10..5}.jpg')
+// => ['file00.jpg', 'file05.jpg', 'file10.jpg']
+
+expand('{{A..C},{a..c}}')
+// => ['A', 'B', 'C', 'a', 'b', 'c']
+
+expand('ppp{,config,oe{,conf}}')
+// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf']
+```
+
+## API
+
+```js
+var expand = require('brace-expansion');
+```
+
+### var expanded = expand(str)
+
+Return an array of all possible and valid expansions of `str`. If none are
+found, `[str]` is returned.
+
+Valid expansions are:
+
+```js
+/^(.*,)+(.+)?$/
+// {a,b,...}
+```
+
+A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`.
+
+```js
+/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
+// {x..y[..incr]}
+```
+
+A numeric sequence from `x` to `y` inclusive, with optional increment.
+If `x` or `y` start with a leading `0`, all the numbers will be padded
+to have equal length. Negative numbers and backwards iteration work too.
+
+```js
+/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
+// {x..y[..incr]}
+```
+
+An alphabetic sequence from `x` to `y` inclusive, with optional increment.
+`x` and `y` must be exactly one character, and if given, `incr` must be a
+number.
+
+For compatibility reasons, the string `${` is not eligible for brace expansion.
+
+## Installation
+
+With [npm](https://npmjs.org) do:
+
+```bash
+npm install brace-expansion
+```
+
+## Contributors
+
+- [Julian Gruber](https://github.com/juliangruber)
+- [Isaac Z. Schlueter](https://github.com/isaacs)
+
+## Sponsors
+
+This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)!
+
+Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)!
+
+## Security contact information
+
+To report a security vulnerability, please use the
+[Tidelift security contact](https://tidelift.com/security).
+Tidelift will coordinate the fix and disclosure.
+
+## License
+
+(MIT)
+
+Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/index.js b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/index.js
new file mode 100644
index 000000000..a27f81ce0
--- /dev/null
+++ b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/index.js
@@ -0,0 +1,203 @@
+var balanced = require('balanced-match');
+
+module.exports = expandTop;
+
+var escSlash = '\0SLASH'+Math.random()+'\0';
+var escOpen = '\0OPEN'+Math.random()+'\0';
+var escClose = '\0CLOSE'+Math.random()+'\0';
+var escComma = '\0COMMA'+Math.random()+'\0';
+var escPeriod = '\0PERIOD'+Math.random()+'\0';
+
+function numeric(str) {
+ return parseInt(str, 10) == str
+ ? parseInt(str, 10)
+ : str.charCodeAt(0);
+}
+
+function escapeBraces(str) {
+ return str.split('\\\\').join(escSlash)
+ .split('\\{').join(escOpen)
+ .split('\\}').join(escClose)
+ .split('\\,').join(escComma)
+ .split('\\.').join(escPeriod);
+}
+
+function unescapeBraces(str) {
+ return str.split(escSlash).join('\\')
+ .split(escOpen).join('{')
+ .split(escClose).join('}')
+ .split(escComma).join(',')
+ .split(escPeriod).join('.');
+}
+
+
+// Basically just str.split(","), but handling cases
+// where we have nested braced sections, which should be
+// treated as individual members, like {a,{b,c},d}
+function parseCommaParts(str) {
+ if (!str)
+ return [''];
+
+ var parts = [];
+ var m = balanced('{', '}', str);
+
+ if (!m)
+ return str.split(',');
+
+ var pre = m.pre;
+ var body = m.body;
+ var post = m.post;
+ var p = pre.split(',');
+
+ p[p.length-1] += '{' + body + '}';
+ var postParts = parseCommaParts(post);
+ if (post.length) {
+ p[p.length-1] += postParts.shift();
+ p.push.apply(p, postParts);
+ }
+
+ parts.push.apply(parts, p);
+
+ return parts;
+}
+
+function expandTop(str) {
+ if (!str)
+ return [];
+
+ // I don't know why Bash 4.3 does this, but it does.
+ // Anything starting with {} will have the first two bytes preserved
+ // but *only* at the top level, so {},a}b will not expand to anything,
+ // but a{},b}c will be expanded to [a}c,abc].
+ // One could argue that this is a bug in Bash, but since the goal of
+ // this module is to match Bash's rules, we escape a leading {}
+ if (str.substr(0, 2) === '{}') {
+ str = '\\{\\}' + str.substr(2);
+ }
+
+ return expand(escapeBraces(str), true).map(unescapeBraces);
+}
+
+function embrace(str) {
+ return '{' + str + '}';
+}
+function isPadded(el) {
+ return /^-?0\d/.test(el);
+}
+
+function lte(i, y) {
+ return i <= y;
+}
+function gte(i, y) {
+ return i >= y;
+}
+
+function expand(str, isTop) {
+ var expansions = [];
+
+ var m = balanced('{', '}', str);
+ if (!m) return [str];
+
+ // no need to expand pre, since it is guaranteed to be free of brace-sets
+ var pre = m.pre;
+ var post = m.post.length
+ ? expand(m.post, false)
+ : [''];
+
+ if (/\$$/.test(m.pre)) {
+ for (var k = 0; k < post.length; k++) {
+ var expansion = pre+ '{' + m.body + '}' + post[k];
+ expansions.push(expansion);
+ }
+ } else {
+ var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
+ var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
+ var isSequence = isNumericSequence || isAlphaSequence;
+ var isOptions = m.body.indexOf(',') >= 0;
+ if (!isSequence && !isOptions) {
+ // {a},b}
+ if (m.post.match(/,(?!,).*\}/)) {
+ str = m.pre + '{' + m.body + escClose + m.post;
+ return expand(str);
+ }
+ return [str];
+ }
+
+ var n;
+ if (isSequence) {
+ n = m.body.split(/\.\./);
+ } else {
+ n = parseCommaParts(m.body);
+ if (n.length === 1) {
+ // x{{a,b}}y ==> x{a}y x{b}y
+ n = expand(n[0], false).map(embrace);
+ if (n.length === 1) {
+ return post.map(function(p) {
+ return m.pre + n[0] + p;
+ });
+ }
+ }
+ }
+
+ // at this point, n is the parts, and we know it's not a comma set
+ // with a single entry.
+ var N;
+
+ if (isSequence) {
+ var x = numeric(n[0]);
+ var y = numeric(n[1]);
+ var width = Math.max(n[0].length, n[1].length)
+ var incr = n.length == 3
+ ? Math.abs(numeric(n[2]))
+ : 1;
+ var test = lte;
+ var reverse = y < x;
+ if (reverse) {
+ incr *= -1;
+ test = gte;
+ }
+ var pad = n.some(isPadded);
+
+ N = [];
+
+ for (var i = x; test(i, y); i += incr) {
+ var c;
+ if (isAlphaSequence) {
+ c = String.fromCharCode(i);
+ if (c === '\\')
+ c = '';
+ } else {
+ c = String(i);
+ if (pad) {
+ var need = width - c.length;
+ if (need > 0) {
+ var z = new Array(need + 1).join('0');
+ if (i < 0)
+ c = '-' + z + c.slice(1);
+ else
+ c = z + c;
+ }
+ }
+ }
+ N.push(c);
+ }
+ } else {
+ N = [];
+
+ for (var j = 0; j < n.length; j++) {
+ N.push.apply(N, expand(n[j], false));
+ }
+ }
+
+ for (var j = 0; j < N.length; j++) {
+ for (var k = 0; k < post.length; k++) {
+ var expansion = pre + N[j] + post[k];
+ if (!isTop || isSequence || expansion)
+ expansions.push(expansion);
+ }
+ }
+ }
+
+ return expansions;
+}
+
diff --git a/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/package.json b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/package.json
new file mode 100644
index 000000000..c7eee3451
--- /dev/null
+++ b/templates/consumer-repo/.github/scripts/node_modules/brace-expansion/package.json
@@ -0,0 +1,49 @@
+{
+ "name": "brace-expansion",
+ "description": "Brace expansion as known from sh/bash",
+ "version": "2.0.2",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/juliangruber/brace-expansion.git"
+ },
+ "homepage": "https://github.com/juliangruber/brace-expansion",
+ "main": "index.js",
+ "scripts": {
+ "test": "tape test/*.js",
+ "gentest": "bash test/generate.sh",
+ "bench": "matcha test/perf/bench.js"
+ },
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ },
+ "devDependencies": {
+ "@c4312/matcha": "^1.3.1",
+ "tape": "^4.6.0"
+ },
+ "keywords": [],
+ "author": {
+ "name": "Julian Gruber",
+ "email": "mail@juliangruber.com",
+ "url": "http://juliangruber.com"
+ },
+ "license": "MIT",
+ "testling": {
+ "files": "test/*.js",
+ "browsers": [
+ "ie/8..latest",
+ "firefox/20..latest",
+ "firefox/nightly",
+ "chrome/25..latest",
+ "chrome/canary",
+ "opera/12..latest",
+ "opera/next",
+ "safari/5.1..latest",
+ "ipad/6.0..latest",
+ "iphone/6.0..latest",
+ "android-browser/4.2..latest"
+ ]
+ },
+ "publishConfig": {
+ "tag": "2.x"
+ }
+}
diff --git a/templates/consumer-repo/.github/scripts/pr-context-graphql.js b/templates/consumer-repo/.github/scripts/pr-context-graphql.js
index 6eb3ffa1e..fafcc2d4c 100644
--- a/templates/consumer-repo/.github/scripts/pr-context-graphql.js
+++ b/templates/consumer-repo/.github/scripts/pr-context-graphql.js
@@ -1,7 +1,7 @@
'use strict';
const { ensureRateLimitWrapped } = require('./github-rate-limited-wrapper.js');
-const { minimatch } = require('./minimatch-lite.js');
+const { minimatch } = require('minimatch');
/**
* GraphQL-based PR Context Fetcher