@dyyz1993/pi-coding-agent 0.74.24 → 0.74.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +3 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/session-manager.d.ts +5 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +8 -0
- package/dist/core/session-manager.js.map +1 -1
- package/dist/extensions/agent-permissions/index.ts +235 -0
- package/dist/extensions/ask-tools/index.ts +115 -0
- package/dist/extensions/auto-memory/contract.d.ts +51 -0
- package/dist/extensions/auto-memory/contract.d.ts.map +1 -0
- package/dist/extensions/auto-memory/contract.js +2 -0
- package/dist/extensions/auto-memory/contract.js.map +1 -0
- package/dist/extensions/auto-memory/contract.ts +56 -0
- package/dist/extensions/auto-memory/index.ts +969 -0
- package/dist/extensions/auto-memory/prompts.ts +202 -0
- package/dist/extensions/auto-memory/skip-rules.ts +297 -0
- package/dist/extensions/auto-memory/utils.ts +208 -0
- package/dist/extensions/auto-session-title/index.ts +83 -0
- package/dist/extensions/bash-ext/contract.d.ts +79 -0
- package/dist/extensions/bash-ext/contract.d.ts.map +1 -0
- package/dist/extensions/bash-ext/contract.js +2 -0
- package/dist/extensions/bash-ext/contract.js.map +1 -0
- package/dist/extensions/bash-ext/contract.ts +69 -0
- package/dist/extensions/bash-ext/index.ts +858 -0
- package/dist/extensions/claude-hooks-compat/config-loader.ts +49 -0
- package/dist/extensions/claude-hooks-compat/handler-runner.ts +377 -0
- package/dist/extensions/claude-hooks-compat/if-parser.ts +53 -0
- package/dist/extensions/claude-hooks-compat/index.ts +178 -0
- package/dist/extensions/claude-hooks-compat/matcher.ts +17 -0
- package/dist/extensions/claude-hooks-compat/stdin-builder.ts +27 -0
- package/dist/extensions/claude-hooks-compat/types.ts +77 -0
- package/dist/extensions/compaction-manager/config.ts +47 -0
- package/dist/extensions/compaction-manager/context-fold.ts +63 -0
- package/dist/extensions/compaction-manager/index.ts +151 -0
- package/dist/extensions/compaction-manager/microcompact.ts +49 -0
- package/dist/extensions/compaction-manager/reactive.ts +9 -0
- package/dist/extensions/compaction-manager/session-memory.ts +48 -0
- package/dist/extensions/coordinator/INTEGRATION.md +376 -0
- package/dist/extensions/coordinator/handler.test.ts +277 -0
- package/dist/extensions/coordinator/handler.ts +189 -0
- package/dist/extensions/coordinator/index.ts +261 -0
- package/dist/extensions/coordinator/types.d.ts +100 -0
- package/dist/extensions/coordinator/types.d.ts.map +1 -0
- package/dist/extensions/coordinator/types.js +2 -0
- package/dist/extensions/coordinator/types.js.map +1 -0
- package/dist/extensions/coordinator/types.ts +72 -0
- package/dist/extensions/file-snapshot/index.ts +131 -0
- package/dist/extensions/file-time-guard/README.md +133 -0
- package/dist/extensions/file-time-guard/config.ts +13 -0
- package/dist/extensions/file-time-guard/index.ts +171 -0
- package/dist/extensions/hooks-engine/index.ts +117 -0
- package/dist/extensions/lsp/lsp/client/file-tracker.ts +70 -0
- package/dist/extensions/lsp/lsp/client/registry.ts +305 -0
- package/dist/extensions/lsp/lsp/client/runtime.ts +832 -0
- package/dist/extensions/lsp/lsp/config/resolver.ts +573 -0
- package/dist/extensions/lsp/lsp/contract.d.ts +101 -0
- package/dist/extensions/lsp/lsp/contract.d.ts.map +1 -0
- package/dist/extensions/lsp/lsp/contract.js +2 -0
- package/dist/extensions/lsp/lsp/contract.js.map +1 -0
- package/dist/extensions/lsp/lsp/contract.ts +103 -0
- package/dist/extensions/lsp/lsp/hooks/agent-end.ts +169 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts +10 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts.map +1 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js +30 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js.map +1 -0
- package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.ts +41 -0
- package/dist/extensions/lsp/lsp/hooks/writethrough.ts +342 -0
- package/dist/extensions/lsp/lsp/index.ts +310 -0
- package/dist/extensions/lsp/lsp/lsp.test.ts +684 -0
- package/dist/extensions/lsp/lsp/monitoring/server-metrics.ts +176 -0
- package/dist/extensions/lsp/lsp/tools/lsp-tool.ts +402 -0
- package/dist/extensions/lsp/lsp/utils/dependency-resolver.ts +147 -0
- package/dist/extensions/lsp/lsp/utils/diagnostics-wait.ts +41 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts +20 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts.map +1 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.js +64 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.js.map +1 -0
- package/dist/extensions/lsp/lsp/utils/lsp-helpers.ts +76 -0
- package/dist/extensions/message-bridge/GUIDE.md +210 -0
- package/dist/extensions/message-bridge/index.ts +222 -0
- package/dist/extensions/output-guard/index.ts +446 -0
- package/dist/extensions/preview/index.ts +278 -0
- package/dist/extensions/rules-engine/MATCH_HISTORY_RECONCILIATION.md +111 -0
- package/dist/extensions/rules-engine/RULES-ENGINE-GUIDE.md +470 -0
- package/dist/extensions/rules-engine/cache.js +232 -0
- package/dist/extensions/rules-engine/cache.ts +38 -0
- package/dist/extensions/rules-engine/config.js +63 -0
- package/dist/extensions/rules-engine/config.ts +70 -0
- package/dist/extensions/rules-engine/index.js +1530 -0
- package/dist/extensions/rules-engine/index.ts +552 -0
- package/dist/extensions/rules-engine/injector.js +68 -0
- package/dist/extensions/rules-engine/injector.ts +74 -0
- package/dist/extensions/rules-engine/loader.js +179 -0
- package/dist/extensions/rules-engine/loader.ts +205 -0
- package/dist/extensions/rules-engine/matcher.js +534 -0
- package/dist/extensions/rules-engine/matcher.ts +52 -0
- package/dist/extensions/rules-engine/types.d.ts +156 -0
- package/dist/extensions/rules-engine/types.d.ts.map +1 -0
- package/dist/extensions/rules-engine/types.js +2 -0
- package/dist/extensions/rules-engine/types.js.map +1 -0
- package/dist/extensions/rules-engine/types.ts +169 -0
- package/dist/extensions/session-supervisor/checker.ts +116 -0
- package/dist/extensions/session-supervisor/config.ts +45 -0
- package/dist/extensions/session-supervisor/index.ts +726 -0
- package/dist/extensions/session-supervisor/prompts.ts +132 -0
- package/dist/extensions/session-supervisor/scheduler.ts +69 -0
- package/dist/extensions/session-supervisor/types.ts +215 -0
- package/dist/extensions/subagent/README.md +172 -0
- package/dist/extensions/subagent/agents/explorer.md +25 -0
- package/dist/extensions/subagent/agents/guide.md +27 -0
- package/dist/extensions/subagent/agents/planner.md +37 -0
- package/dist/extensions/subagent/agents/reviewer.md +35 -0
- package/dist/extensions/subagent/agents/scout.md +50 -0
- package/dist/extensions/subagent/agents/verification.md +35 -0
- package/dist/extensions/subagent/agents/worker.md +24 -0
- package/dist/extensions/subagent/agents.ts +25 -0
- package/dist/extensions/subagent/index.ts +987 -0
- package/dist/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/dist/extensions/subagent/prompts/implement.md +10 -0
- package/dist/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/dist/extensions/subagent-ext/contract.d.ts +2 -0
- package/dist/extensions/subagent-ext/contract.d.ts.map +1 -0
- package/dist/extensions/subagent-ext/contract.js +2 -0
- package/dist/extensions/subagent-ext/contract.js.map +1 -0
- package/dist/extensions/subagent-ext/contract.ts +1 -0
- package/dist/extensions/subagent-ext/index.ts +347 -0
- package/dist/extensions/subagent-shared/contract.d.ts +25 -0
- package/dist/extensions/subagent-shared/contract.d.ts.map +1 -0
- package/dist/extensions/subagent-shared/contract.js +2 -0
- package/dist/extensions/subagent-shared/contract.js.map +1 -0
- package/dist/extensions/subagent-shared/contract.ts +28 -0
- package/dist/extensions/subagent-shared/index.ts +4 -0
- package/dist/extensions/subagent-shared/render.ts +166 -0
- package/dist/extensions/subagent-shared/types.ts +35 -0
- package/dist/extensions/subagent-shared/utils.ts +112 -0
- package/dist/extensions/subagent-v2/contract.d.ts +2 -0
- package/dist/extensions/subagent-v2/contract.d.ts.map +1 -0
- package/dist/extensions/subagent-v2/contract.js +2 -0
- package/dist/extensions/subagent-v2/contract.js.map +1 -0
- package/dist/extensions/subagent-v2/contract.ts +1 -0
- package/dist/extensions/subagent-v2/index.ts +599 -0
- package/dist/extensions/todo-ext/contract.d.ts +27 -0
- package/dist/extensions/todo-ext/contract.d.ts.map +1 -0
- package/dist/extensions/todo-ext/contract.js +2 -0
- package/dist/extensions/todo-ext/contract.js.map +1 -0
- package/dist/extensions/todo-ext/contract.ts +30 -0
- package/dist/extensions/todo-ext/index.ts +419 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +6 -5
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
19
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
20
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
21
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
22
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
23
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
24
|
+
mod
|
|
25
|
+
));
|
|
26
|
+
|
|
27
|
+
// node_modules/ignore/index.js
|
|
28
|
+
var require_ignore = __commonJS({
|
|
29
|
+
"node_modules/ignore/index.js"(exports, module) {
|
|
30
|
+
function makeArray(subject) {
|
|
31
|
+
return Array.isArray(subject) ? subject : [subject];
|
|
32
|
+
}
|
|
33
|
+
var UNDEFINED = void 0;
|
|
34
|
+
var EMPTY = "";
|
|
35
|
+
var SPACE = " ";
|
|
36
|
+
var ESCAPE = "\\";
|
|
37
|
+
var REGEX_TEST_BLANK_LINE = /^\s+$/;
|
|
38
|
+
var REGEX_INVALID_TRAILING_BACKSLASH = /(?:[^\\]|^)\\$/;
|
|
39
|
+
var REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/;
|
|
40
|
+
var REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/;
|
|
41
|
+
var REGEX_SPLITALL_CRLF = /\r?\n/g;
|
|
42
|
+
var REGEX_TEST_INVALID_PATH = /^\.{0,2}\/|^\.{1,2}$/;
|
|
43
|
+
var REGEX_TEST_TRAILING_SLASH = /\/$/;
|
|
44
|
+
var SLASH = "/";
|
|
45
|
+
var TMP_KEY_IGNORE = "node-ignore";
|
|
46
|
+
if (typeof Symbol !== "undefined") {
|
|
47
|
+
TMP_KEY_IGNORE = /* @__PURE__ */ Symbol.for("node-ignore");
|
|
48
|
+
}
|
|
49
|
+
var KEY_IGNORE = TMP_KEY_IGNORE;
|
|
50
|
+
var define = (object, key, value) => {
|
|
51
|
+
Object.defineProperty(object, key, { value });
|
|
52
|
+
return value;
|
|
53
|
+
};
|
|
54
|
+
var REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g;
|
|
55
|
+
var RETURN_FALSE = () => false;
|
|
56
|
+
var sanitizeRange = (range) => range.replace(
|
|
57
|
+
REGEX_REGEXP_RANGE,
|
|
58
|
+
(match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) ? match : EMPTY
|
|
59
|
+
);
|
|
60
|
+
var cleanRangeBackSlash = (slashes) => {
|
|
61
|
+
const { length } = slashes;
|
|
62
|
+
return slashes.slice(0, length - length % 2);
|
|
63
|
+
};
|
|
64
|
+
var REPLACERS = [
|
|
65
|
+
[
|
|
66
|
+
// Remove BOM
|
|
67
|
+
// TODO:
|
|
68
|
+
// Other similar zero-width characters?
|
|
69
|
+
/^\uFEFF/,
|
|
70
|
+
() => EMPTY
|
|
71
|
+
],
|
|
72
|
+
// > Trailing spaces are ignored unless they are quoted with backslash ("\")
|
|
73
|
+
[
|
|
74
|
+
// (a\ ) -> (a )
|
|
75
|
+
// (a ) -> (a)
|
|
76
|
+
// (a ) -> (a)
|
|
77
|
+
// (a \ ) -> (a )
|
|
78
|
+
/((?:\\\\)*?)(\\?\s+)$/,
|
|
79
|
+
(_, m1, m2) => m1 + (m2.indexOf("\\") === 0 ? SPACE : EMPTY)
|
|
80
|
+
],
|
|
81
|
+
// Replace (\ ) with ' '
|
|
82
|
+
// (\ ) -> ' '
|
|
83
|
+
// (\\ ) -> '\\ '
|
|
84
|
+
// (\\\ ) -> '\\ '
|
|
85
|
+
[
|
|
86
|
+
/(\\+?)\s/g,
|
|
87
|
+
(_, m1) => {
|
|
88
|
+
const { length } = m1;
|
|
89
|
+
return m1.slice(0, length - length % 2) + SPACE;
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
// Escape metacharacters
|
|
93
|
+
// which is written down by users but means special for regular expressions.
|
|
94
|
+
// > There are 12 characters with special meanings:
|
|
95
|
+
// > - the backslash \,
|
|
96
|
+
// > - the caret ^,
|
|
97
|
+
// > - the dollar sign $,
|
|
98
|
+
// > - the period or dot .,
|
|
99
|
+
// > - the vertical bar or pipe symbol |,
|
|
100
|
+
// > - the question mark ?,
|
|
101
|
+
// > - the asterisk or star *,
|
|
102
|
+
// > - the plus sign +,
|
|
103
|
+
// > - the opening parenthesis (,
|
|
104
|
+
// > - the closing parenthesis ),
|
|
105
|
+
// > - and the opening square bracket [,
|
|
106
|
+
// > - the opening curly brace {,
|
|
107
|
+
// > These special characters are often called "metacharacters".
|
|
108
|
+
[
|
|
109
|
+
/[\\$.|*+(){^]/g,
|
|
110
|
+
(match) => `\\${match}`
|
|
111
|
+
],
|
|
112
|
+
[
|
|
113
|
+
// > a question mark (?) matches a single character
|
|
114
|
+
/(?!\\)\?/g,
|
|
115
|
+
() => "[^/]"
|
|
116
|
+
],
|
|
117
|
+
// leading slash
|
|
118
|
+
[
|
|
119
|
+
// > A leading slash matches the beginning of the pathname.
|
|
120
|
+
// > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".
|
|
121
|
+
// A leading slash matches the beginning of the pathname
|
|
122
|
+
/^\//,
|
|
123
|
+
() => "^"
|
|
124
|
+
],
|
|
125
|
+
// replace special metacharacter slash after the leading slash
|
|
126
|
+
[
|
|
127
|
+
/\//g,
|
|
128
|
+
() => "\\/"
|
|
129
|
+
],
|
|
130
|
+
[
|
|
131
|
+
// > A leading "**" followed by a slash means match in all directories.
|
|
132
|
+
// > For example, "**/foo" matches file or directory "foo" anywhere,
|
|
133
|
+
// > the same as pattern "foo".
|
|
134
|
+
// > "**/foo/bar" matches file or directory "bar" anywhere that is directly
|
|
135
|
+
// > under directory "foo".
|
|
136
|
+
// Notice that the '*'s have been replaced as '\\*'
|
|
137
|
+
/^\^*\\\*\\\*\\\//,
|
|
138
|
+
// '**/foo' <-> 'foo'
|
|
139
|
+
() => "^(?:.*\\/)?"
|
|
140
|
+
],
|
|
141
|
+
// starting
|
|
142
|
+
[
|
|
143
|
+
// there will be no leading '/'
|
|
144
|
+
// (which has been replaced by section "leading slash")
|
|
145
|
+
// If starts with '**', adding a '^' to the regular expression also works
|
|
146
|
+
/^(?=[^^])/,
|
|
147
|
+
function startingReplacer() {
|
|
148
|
+
return !/\/(?!$)/.test(this) ? "(?:^|\\/)" : "^";
|
|
149
|
+
}
|
|
150
|
+
],
|
|
151
|
+
// two globstars
|
|
152
|
+
[
|
|
153
|
+
// Use lookahead assertions so that we could match more than one `'/**'`
|
|
154
|
+
/\\\/\\\*\\\*(?=\\\/|$)/g,
|
|
155
|
+
// Zero, one or several directories
|
|
156
|
+
// should not use '*', or it will be replaced by the next replacer
|
|
157
|
+
// Check if it is not the last `'/**'`
|
|
158
|
+
(_, index, str) => index + 6 < str.length ? "(?:\\/[^\\/]+)*" : "\\/.+"
|
|
159
|
+
],
|
|
160
|
+
// normal intermediate wildcards
|
|
161
|
+
[
|
|
162
|
+
// Never replace escaped '*'
|
|
163
|
+
// ignore rule '\*' will match the path '*'
|
|
164
|
+
// 'abc.*/' -> go
|
|
165
|
+
// 'abc.*' -> skip this rule,
|
|
166
|
+
// coz trailing single wildcard will be handed by [trailing wildcard]
|
|
167
|
+
/(^|[^\\]+)(\\\*)+(?=.+)/g,
|
|
168
|
+
// '*.js' matches '.js'
|
|
169
|
+
// '*.js' doesn't match 'abc'
|
|
170
|
+
(_, p1, p2) => {
|
|
171
|
+
const unescaped = p2.replace(/\\\*/g, "[^\\/]*");
|
|
172
|
+
return p1 + unescaped;
|
|
173
|
+
}
|
|
174
|
+
],
|
|
175
|
+
[
|
|
176
|
+
// unescape, revert step 3 except for back slash
|
|
177
|
+
// For example, if a user escape a '\\*',
|
|
178
|
+
// after step 3, the result will be '\\\\\\*'
|
|
179
|
+
/\\\\\\(?=[$.|*+(){^])/g,
|
|
180
|
+
() => ESCAPE
|
|
181
|
+
],
|
|
182
|
+
[
|
|
183
|
+
// '\\\\' -> '\\'
|
|
184
|
+
/\\\\/g,
|
|
185
|
+
() => ESCAPE
|
|
186
|
+
],
|
|
187
|
+
[
|
|
188
|
+
// > The range notation, e.g. [a-zA-Z],
|
|
189
|
+
// > can be used to match one of the characters in a range.
|
|
190
|
+
// `\` is escaped by step 3
|
|
191
|
+
/(\\)?\[([^\]/]*?)(\\*)($|\])/g,
|
|
192
|
+
(match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE ? `\\[${range}${cleanRangeBackSlash(endEscape)}${close}` : close === "]" ? endEscape.length % 2 === 0 ? `[${sanitizeRange(range)}${endEscape}]` : "[]" : "[]"
|
|
193
|
+
],
|
|
194
|
+
// ending
|
|
195
|
+
[
|
|
196
|
+
// 'js' will not match 'js.'
|
|
197
|
+
// 'ab' will not match 'abc'
|
|
198
|
+
/(?:[^*])$/,
|
|
199
|
+
// WTF!
|
|
200
|
+
// https://git-scm.com/docs/gitignore
|
|
201
|
+
// changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1)
|
|
202
|
+
// which re-fixes #24, #38
|
|
203
|
+
// > If there is a separator at the end of the pattern then the pattern
|
|
204
|
+
// > will only match directories, otherwise the pattern can match both
|
|
205
|
+
// > files and directories.
|
|
206
|
+
// 'js*' will not match 'a.js'
|
|
207
|
+
// 'js/' will not match 'a.js'
|
|
208
|
+
// 'js' will match 'a.js' and 'a.js/'
|
|
209
|
+
(match) => /\/$/.test(match) ? `${match}$` : `${match}(?=$|\\/$)`
|
|
210
|
+
]
|
|
211
|
+
];
|
|
212
|
+
var REGEX_REPLACE_TRAILING_WILDCARD = /(^|\\\/)?\\\*$/;
|
|
213
|
+
var MODE_IGNORE = "regex";
|
|
214
|
+
var MODE_CHECK_IGNORE = "checkRegex";
|
|
215
|
+
var UNDERSCORE = "_";
|
|
216
|
+
var TRAILING_WILD_CARD_REPLACERS = {
|
|
217
|
+
[MODE_IGNORE](_, p1) {
|
|
218
|
+
const prefix = p1 ? `${p1}[^/]+` : "[^/]*";
|
|
219
|
+
return `${prefix}(?=$|\\/$)`;
|
|
220
|
+
},
|
|
221
|
+
[MODE_CHECK_IGNORE](_, p1) {
|
|
222
|
+
const prefix = p1 ? `${p1}[^/]*` : "[^/]*";
|
|
223
|
+
return `${prefix}(?=$|\\/$)`;
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
var makeRegexPrefix = (pattern) => REPLACERS.reduce(
|
|
227
|
+
(prev, [matcher, replacer]) => prev.replace(matcher, replacer.bind(pattern)),
|
|
228
|
+
pattern
|
|
229
|
+
);
|
|
230
|
+
var isString = (subject) => typeof subject === "string";
|
|
231
|
+
var checkPattern = (pattern) => pattern && isString(pattern) && !REGEX_TEST_BLANK_LINE.test(pattern) && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern) && pattern.indexOf("#") !== 0;
|
|
232
|
+
var splitPattern = (pattern) => pattern.split(REGEX_SPLITALL_CRLF).filter(Boolean);
|
|
233
|
+
var IgnoreRule = class {
|
|
234
|
+
constructor(pattern, mark, body, ignoreCase, negative, prefix) {
|
|
235
|
+
this.pattern = pattern;
|
|
236
|
+
this.mark = mark;
|
|
237
|
+
this.negative = negative;
|
|
238
|
+
define(this, "body", body);
|
|
239
|
+
define(this, "ignoreCase", ignoreCase);
|
|
240
|
+
define(this, "regexPrefix", prefix);
|
|
241
|
+
}
|
|
242
|
+
get regex() {
|
|
243
|
+
const key = UNDERSCORE + MODE_IGNORE;
|
|
244
|
+
if (this[key]) {
|
|
245
|
+
return this[key];
|
|
246
|
+
}
|
|
247
|
+
return this._make(MODE_IGNORE, key);
|
|
248
|
+
}
|
|
249
|
+
get checkRegex() {
|
|
250
|
+
const key = UNDERSCORE + MODE_CHECK_IGNORE;
|
|
251
|
+
if (this[key]) {
|
|
252
|
+
return this[key];
|
|
253
|
+
}
|
|
254
|
+
return this._make(MODE_CHECK_IGNORE, key);
|
|
255
|
+
}
|
|
256
|
+
_make(mode, key) {
|
|
257
|
+
const str = this.regexPrefix.replace(
|
|
258
|
+
REGEX_REPLACE_TRAILING_WILDCARD,
|
|
259
|
+
// It does not need to bind pattern
|
|
260
|
+
TRAILING_WILD_CARD_REPLACERS[mode]
|
|
261
|
+
);
|
|
262
|
+
const regex = this.ignoreCase ? new RegExp(str, "i") : new RegExp(str);
|
|
263
|
+
return define(this, key, regex);
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
var createRule = ({
|
|
267
|
+
pattern,
|
|
268
|
+
mark
|
|
269
|
+
}, ignoreCase) => {
|
|
270
|
+
let negative = false;
|
|
271
|
+
let body = pattern;
|
|
272
|
+
if (body.indexOf("!") === 0) {
|
|
273
|
+
negative = true;
|
|
274
|
+
body = body.substr(1);
|
|
275
|
+
}
|
|
276
|
+
body = body.replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, "!").replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, "#");
|
|
277
|
+
const regexPrefix = makeRegexPrefix(body);
|
|
278
|
+
return new IgnoreRule(
|
|
279
|
+
pattern,
|
|
280
|
+
mark,
|
|
281
|
+
body,
|
|
282
|
+
ignoreCase,
|
|
283
|
+
negative,
|
|
284
|
+
regexPrefix
|
|
285
|
+
);
|
|
286
|
+
};
|
|
287
|
+
var RuleManager = class {
|
|
288
|
+
constructor(ignoreCase) {
|
|
289
|
+
this._ignoreCase = ignoreCase;
|
|
290
|
+
this._rules = [];
|
|
291
|
+
}
|
|
292
|
+
_add(pattern) {
|
|
293
|
+
if (pattern && pattern[KEY_IGNORE]) {
|
|
294
|
+
this._rules = this._rules.concat(pattern._rules._rules);
|
|
295
|
+
this._added = true;
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
if (isString(pattern)) {
|
|
299
|
+
pattern = {
|
|
300
|
+
pattern
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
if (checkPattern(pattern.pattern)) {
|
|
304
|
+
const rule = createRule(pattern, this._ignoreCase);
|
|
305
|
+
this._added = true;
|
|
306
|
+
this._rules.push(rule);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// @param {Array<string> | string | Ignore} pattern
|
|
310
|
+
add(pattern) {
|
|
311
|
+
this._added = false;
|
|
312
|
+
makeArray(
|
|
313
|
+
isString(pattern) ? splitPattern(pattern) : pattern
|
|
314
|
+
).forEach(this._add, this);
|
|
315
|
+
return this._added;
|
|
316
|
+
}
|
|
317
|
+
// Test one single path without recursively checking parent directories
|
|
318
|
+
//
|
|
319
|
+
// - checkUnignored `boolean` whether should check if the path is unignored,
|
|
320
|
+
// setting `checkUnignored` to `false` could reduce additional
|
|
321
|
+
// path matching.
|
|
322
|
+
// - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
|
|
323
|
+
// @returns {TestResult} true if a file is ignored
|
|
324
|
+
test(path, checkUnignored, mode) {
|
|
325
|
+
let ignored = false;
|
|
326
|
+
let unignored = false;
|
|
327
|
+
let matchedRule;
|
|
328
|
+
this._rules.forEach((rule) => {
|
|
329
|
+
const { negative } = rule;
|
|
330
|
+
if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
const matched = rule[mode].test(path);
|
|
334
|
+
if (!matched) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
ignored = !negative;
|
|
338
|
+
unignored = negative;
|
|
339
|
+
matchedRule = negative ? UNDEFINED : rule;
|
|
340
|
+
});
|
|
341
|
+
const ret = {
|
|
342
|
+
ignored,
|
|
343
|
+
unignored
|
|
344
|
+
};
|
|
345
|
+
if (matchedRule) {
|
|
346
|
+
ret.rule = matchedRule;
|
|
347
|
+
}
|
|
348
|
+
return ret;
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
var throwError = (message, Ctor) => {
|
|
352
|
+
throw new Ctor(message);
|
|
353
|
+
};
|
|
354
|
+
var checkPath = (path, originalPath, doThrow) => {
|
|
355
|
+
if (!isString(path)) {
|
|
356
|
+
return doThrow(
|
|
357
|
+
`path must be a string, but got \`${originalPath}\``,
|
|
358
|
+
TypeError
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
if (!path) {
|
|
362
|
+
return doThrow(`path must not be empty`, TypeError);
|
|
363
|
+
}
|
|
364
|
+
if (checkPath.isNotRelative(path)) {
|
|
365
|
+
const r = "`path.relative()`d";
|
|
366
|
+
return doThrow(
|
|
367
|
+
`path should be a ${r} string, but got "${originalPath}"`,
|
|
368
|
+
RangeError
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
return true;
|
|
372
|
+
};
|
|
373
|
+
var isNotRelative = (path) => REGEX_TEST_INVALID_PATH.test(path);
|
|
374
|
+
checkPath.isNotRelative = isNotRelative;
|
|
375
|
+
checkPath.convert = (p) => p;
|
|
376
|
+
var Ignore = class {
|
|
377
|
+
constructor({
|
|
378
|
+
ignorecase = true,
|
|
379
|
+
ignoreCase = ignorecase,
|
|
380
|
+
allowRelativePaths = false
|
|
381
|
+
} = {}) {
|
|
382
|
+
define(this, KEY_IGNORE, true);
|
|
383
|
+
this._rules = new RuleManager(ignoreCase);
|
|
384
|
+
this._strictPathCheck = !allowRelativePaths;
|
|
385
|
+
this._initCache();
|
|
386
|
+
}
|
|
387
|
+
_initCache() {
|
|
388
|
+
this._ignoreCache = /* @__PURE__ */ Object.create(null);
|
|
389
|
+
this._testCache = /* @__PURE__ */ Object.create(null);
|
|
390
|
+
}
|
|
391
|
+
add(pattern) {
|
|
392
|
+
if (this._rules.add(pattern)) {
|
|
393
|
+
this._initCache();
|
|
394
|
+
}
|
|
395
|
+
return this;
|
|
396
|
+
}
|
|
397
|
+
// legacy
|
|
398
|
+
addPattern(pattern) {
|
|
399
|
+
return this.add(pattern);
|
|
400
|
+
}
|
|
401
|
+
// @returns {TestResult}
|
|
402
|
+
_test(originalPath, cache, checkUnignored, slices) {
|
|
403
|
+
const path = originalPath && checkPath.convert(originalPath);
|
|
404
|
+
checkPath(
|
|
405
|
+
path,
|
|
406
|
+
originalPath,
|
|
407
|
+
this._strictPathCheck ? throwError : RETURN_FALSE
|
|
408
|
+
);
|
|
409
|
+
return this._t(path, cache, checkUnignored, slices);
|
|
410
|
+
}
|
|
411
|
+
checkIgnore(path) {
|
|
412
|
+
if (!REGEX_TEST_TRAILING_SLASH.test(path)) {
|
|
413
|
+
return this.test(path);
|
|
414
|
+
}
|
|
415
|
+
const slices = path.split(SLASH).filter(Boolean);
|
|
416
|
+
slices.pop();
|
|
417
|
+
if (slices.length) {
|
|
418
|
+
const parent = this._t(
|
|
419
|
+
slices.join(SLASH) + SLASH,
|
|
420
|
+
this._testCache,
|
|
421
|
+
true,
|
|
422
|
+
slices
|
|
423
|
+
);
|
|
424
|
+
if (parent.ignored) {
|
|
425
|
+
return parent;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return this._rules.test(path, false, MODE_CHECK_IGNORE);
|
|
429
|
+
}
|
|
430
|
+
_t(path, cache, checkUnignored, slices) {
|
|
431
|
+
if (path in cache) {
|
|
432
|
+
return cache[path];
|
|
433
|
+
}
|
|
434
|
+
if (!slices) {
|
|
435
|
+
slices = path.split(SLASH).filter(Boolean);
|
|
436
|
+
}
|
|
437
|
+
slices.pop();
|
|
438
|
+
if (!slices.length) {
|
|
439
|
+
return cache[path] = this._rules.test(path, checkUnignored, MODE_IGNORE);
|
|
440
|
+
}
|
|
441
|
+
const parent = this._t(
|
|
442
|
+
slices.join(SLASH) + SLASH,
|
|
443
|
+
cache,
|
|
444
|
+
checkUnignored,
|
|
445
|
+
slices
|
|
446
|
+
);
|
|
447
|
+
return cache[path] = parent.ignored ? parent : this._rules.test(path, checkUnignored, MODE_IGNORE);
|
|
448
|
+
}
|
|
449
|
+
ignores(path) {
|
|
450
|
+
return this._test(path, this._ignoreCache, false).ignored;
|
|
451
|
+
}
|
|
452
|
+
createFilter() {
|
|
453
|
+
return (path) => !this.ignores(path);
|
|
454
|
+
}
|
|
455
|
+
filter(paths) {
|
|
456
|
+
return makeArray(paths).filter(this.createFilter());
|
|
457
|
+
}
|
|
458
|
+
// @returns {TestResult}
|
|
459
|
+
test(path) {
|
|
460
|
+
return this._test(path, this._testCache, true);
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
var factory = (options) => new Ignore(options);
|
|
464
|
+
var isPathValid = (path) => checkPath(path && checkPath.convert(path), path, RETURN_FALSE);
|
|
465
|
+
var setupWindows = () => {
|
|
466
|
+
const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
|
|
467
|
+
checkPath.convert = makePosix;
|
|
468
|
+
const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
|
|
469
|
+
checkPath.isNotRelative = (path) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path) || isNotRelative(path);
|
|
470
|
+
};
|
|
471
|
+
if (
|
|
472
|
+
// Detect `process` so that it can run in browsers.
|
|
473
|
+
typeof process !== "undefined" && process.platform === "win32"
|
|
474
|
+
) {
|
|
475
|
+
setupWindows();
|
|
476
|
+
}
|
|
477
|
+
module.exports = factory;
|
|
478
|
+
factory.default = factory;
|
|
479
|
+
module.exports.isPathValid = isPathValid;
|
|
480
|
+
define(module.exports, /* @__PURE__ */ Symbol.for("setupWindows"), setupWindows);
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
// packages/coding-agent/extensions/rules-engine/matcher.ts
|
|
485
|
+
var import_ignore = __toESM(require_ignore(), 1);
|
|
486
|
+
function expandBraces(pattern) {
|
|
487
|
+
const braceIndex = pattern.indexOf("{");
|
|
488
|
+
if (braceIndex === -1) return [pattern];
|
|
489
|
+
const closeIndex = pattern.indexOf("}", braceIndex);
|
|
490
|
+
if (closeIndex === -1) return [pattern];
|
|
491
|
+
const prefix = pattern.slice(0, braceIndex);
|
|
492
|
+
const suffix = pattern.slice(closeIndex + 1);
|
|
493
|
+
const options = pattern.slice(braceIndex + 1, closeIndex).split(",");
|
|
494
|
+
const results = [];
|
|
495
|
+
for (const opt of options) {
|
|
496
|
+
results.push(...expandBraces(prefix + opt.trim() + suffix));
|
|
497
|
+
}
|
|
498
|
+
return results;
|
|
499
|
+
}
|
|
500
|
+
function expandPatterns(patterns) {
|
|
501
|
+
const expanded = [];
|
|
502
|
+
for (const p of patterns) {
|
|
503
|
+
expanded.push(...expandBraces(p));
|
|
504
|
+
}
|
|
505
|
+
return expanded;
|
|
506
|
+
}
|
|
507
|
+
function toRelative(filePath) {
|
|
508
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
509
|
+
return normalized.startsWith("/") ? normalized.slice(1) : normalized;
|
|
510
|
+
}
|
|
511
|
+
function matchGlob(pattern, target) {
|
|
512
|
+
if (!pattern || !target) return false;
|
|
513
|
+
const expanded = expandBraces(pattern);
|
|
514
|
+
const ig = (0, import_ignore.default)().add(expanded);
|
|
515
|
+
return ig.ignores(toRelative(target));
|
|
516
|
+
}
|
|
517
|
+
function matchesAnyGlob(globs, filePath) {
|
|
518
|
+
if (!filePath || globs.length === 0) return false;
|
|
519
|
+
const expanded = expandPatterns(globs);
|
|
520
|
+
const ig = (0, import_ignore.default)().add(expanded);
|
|
521
|
+
return ig.ignores(toRelative(filePath));
|
|
522
|
+
}
|
|
523
|
+
function createMatcher(globs) {
|
|
524
|
+
if (globs.length === 0) return () => false;
|
|
525
|
+
const expanded = expandPatterns(globs);
|
|
526
|
+
const ig = (0, import_ignore.default)().add(expanded);
|
|
527
|
+
return (filePath) => ig.ignores(toRelative(filePath));
|
|
528
|
+
}
|
|
529
|
+
export {
|
|
530
|
+
createMatcher,
|
|
531
|
+
matchGlob,
|
|
532
|
+
matchesAnyGlob
|
|
533
|
+
};
|
|
534
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2lnbm9yZS9pbmRleC5qcyIsICJtYXRjaGVyLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvLyBBIHNpbXBsZSBpbXBsZW1lbnRhdGlvbiBvZiBtYWtlLWFycmF5XG5mdW5jdGlvbiBtYWtlQXJyYXkgKHN1YmplY3QpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoc3ViamVjdClcbiAgICA/IHN1YmplY3RcbiAgICA6IFtzdWJqZWN0XVxufVxuXG5jb25zdCBVTkRFRklORUQgPSB1bmRlZmluZWRcbmNvbnN0IEVNUFRZID0gJydcbmNvbnN0IFNQQUNFID0gJyAnXG5jb25zdCBFU0NBUEUgPSAnXFxcXCdcbmNvbnN0IFJFR0VYX1RFU1RfQkxBTktfTElORSA9IC9eXFxzKyQvXG5jb25zdCBSRUdFWF9JTlZBTElEX1RSQUlMSU5HX0JBQ0tTTEFTSCA9IC8oPzpbXlxcXFxdfF4pXFxcXCQvXG5jb25zdCBSRUdFWF9SRVBMQUNFX0xFQURJTkdfRVhDQVBFRF9FWENMQU1BVElPTiA9IC9eXFxcXCEvXG5jb25zdCBSRUdFWF9SRVBMQUNFX0xFQURJTkdfRVhDQVBFRF9IQVNIID0gL15cXFxcIy9cbmNvbnN0IFJFR0VYX1NQTElUQUxMX0NSTEYgPSAvXFxyP1xcbi9nXG5cbi8vIEludmFsaWQ6XG4vLyAtIC9mb28sXG4vLyAtIC4vZm9vLFxuLy8gLSAuLi9mb28sXG4vLyAtIC5cbi8vIC0gLi5cbi8vIFZhbGlkOlxuLy8gLSAuZm9vXG5jb25zdCBSRUdFWF9URVNUX0lOVkFMSURfUEFUSCA9IC9eXFwuezAsMn1cXC98XlxcLnsxLDJ9JC9cblxuY29uc3QgUkVHRVhfVEVTVF9UUkFJTElOR19TTEFTSCA9IC9cXC8kL1xuXG5jb25zdCBTTEFTSCA9ICcvJ1xuXG4vLyBEbyBub3QgdXNlIHRlcm5hcnkgZXhwcmVzc2lvbiBoZXJlLCBzaW5jZSBcImlzdGFuYnVsIGlnbm9yZSBuZXh0XCIgaXMgYnVnZ3lcbmxldCBUTVBfS0VZX0lHTk9SRSA9ICdub2RlLWlnbm9yZSdcbi8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG5pZiAodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgVE1QX0tFWV9JR05PUkUgPSBTeW1ib2wuZm9yKCdub2RlLWlnbm9yZScpXG59XG5jb25zdCBLRVlfSUdOT1JFID0gVE1QX0tFWV9JR05PUkVcblxuY29uc3QgZGVmaW5lID0gKG9iamVjdCwga2V5LCB2YWx1ZSkgPT4ge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqZWN0LCBrZXksIHt2YWx1ZX0pXG4gIHJldHVybiB2YWx1ZVxufVxuXG5jb25zdCBSRUdFWF9SRUdFWFBfUkFOR0UgPSAvKFswLXpdKS0oWzAtel0pL2dcblxuY29uc3QgUkVUVVJOX0ZBTFNFID0gKCkgPT4gZmFsc2VcblxuLy8gU2FuaXRpemUgdGhlIHJhbmdlIG9mIGEgcmVndWxhciBleHByZXNzaW9uXG4vLyBUaGUgY2FzZXMgYXJlIGNvbXBsaWNhdGVkLCBzZWUgdGVzdCBjYXNlcyBmb3IgZGV0YWlsc1xuY29uc3Qgc2FuaXRpemVSYW5nZSA9IHJhbmdlID0+IHJhbmdlLnJlcGxhY2UoXG4gIFJFR0VYX1JFR0VYUF9SQU5HRSxcbiAgKG1hdGNoLCBmcm9tLCB0bykgPT4gZnJvbS5jaGFyQ29kZUF0KDApIDw9IHRvLmNoYXJDb2RlQXQoMClcbiAgICA/IG1hdGNoXG4gICAgLy8gSW52YWxpZCByYW5nZSAob3V0IG9mIG9yZGVyKSB3aGljaCBpcyBvayBmb3IgZ2l0aWdub3JlIHJ1bGVzIGJ1dFxuICAgIC8vICAgZmF0YWwgZm9yIEphdmFTY3JpcHQgcmVndWxhciBleHByZXNzaW9uLCBzbyBlbGltaW5hdGUgaXQuXG4gICAgOiBFTVBUWVxuKVxuXG4vLyBTZWUgZml4dHVyZXMgIzU5XG5jb25zdCBjbGVhblJhbmdlQmFja1NsYXNoID0gc2xhc2hlcyA9PiB7XG4gIGNvbnN0IHtsZW5ndGh9ID0gc2xhc2hlc1xuICByZXR1cm4gc2xhc2hlcy5zbGljZSgwLCBsZW5ndGggLSBsZW5ndGggJSAyKVxufVxuXG4vLyA+IElmIHRoZSBwYXR0ZXJuIGVuZHMgd2l0aCBhIHNsYXNoLFxuLy8gPiBpdCBpcyByZW1vdmVkIGZvciB0aGUgcHVycG9zZSBvZiB0aGUgZm9sbG93aW5nIGRlc2NyaXB0aW9uLFxuLy8gPiBidXQgaXQgd291bGQgb25seSBmaW5kIGEgbWF0Y2ggd2l0aCBhIGRpcmVjdG9yeS5cbi8vID4gSW4gb3RoZXIgd29yZHMsIGZvby8gd2lsbCBtYXRjaCBhIGRpcmVjdG9yeSBmb28gYW5kIHBhdGhzIHVuZGVybmVhdGggaXQsXG4vLyA+IGJ1dCB3aWxsIG5vdCBtYXRjaCBhIHJlZ3VsYXIgZmlsZSBvciBhIHN5bWJvbGljIGxpbmsgZm9vXG4vLyA+ICAodGhpcyBpcyBjb25zaXN0ZW50IHdpdGggdGhlIHdheSBob3cgcGF0aHNwZWMgd29ya3MgaW4gZ2VuZXJhbCBpbiBHaXQpLlxuLy8gJ2Bmb28vYCcgd2lsbCBub3QgbWF0Y2ggcmVndWxhciBmaWxlICdgZm9vYCcgb3Igc3ltYm9saWMgbGluayAnYGZvb2AnXG4vLyAtPiBpZ25vcmUtcnVsZXMgd2lsbCBub3QgZGVhbCB3aXRoIGl0LCBiZWNhdXNlIGl0IGNvc3RzIGV4dHJhIGBmcy5zdGF0YCBjYWxsXG4vLyAgICAgIHlvdSBjb3VsZCB1c2Ugb3B0aW9uIGBtYXJrOiB0cnVlYCB3aXRoIGBnbG9iYFxuXG4vLyAnYGZvby9gJyBzaG91bGQgbm90IGNvbnRpbnVlIHdpdGggdGhlICdgLi5gJ1xuY29uc3QgUkVQTEFDRVJTID0gW1xuXG4gIFtcbiAgICAvLyBSZW1vdmUgQk9NXG4gICAgLy8gVE9ETzpcbiAgICAvLyBPdGhlciBzaW1pbGFyIHplcm8td2lkdGggY2hhcmFjdGVycz9cbiAgICAvXlxcdUZFRkYvLFxuICAgICgpID0+IEVNUFRZXG4gIF0sXG5cbiAgLy8gPiBUcmFpbGluZyBzcGFjZXMgYXJlIGlnbm9yZWQgdW5sZXNzIHRoZXkgYXJlIHF1b3RlZCB3aXRoIGJhY2tzbGFzaCAoXCJcXFwiKVxuICBbXG4gICAgLy8gKGFcXCApIC0+IChhIClcbiAgICAvLyAoYSAgKSAtPiAoYSlcbiAgICAvLyAoYSApIC0+IChhKVxuICAgIC8vIChhIFxcICkgLT4gKGEgIClcbiAgICAvKCg/OlxcXFxcXFxcKSo/KShcXFxcP1xccyspJC8sXG4gICAgKF8sIG0xLCBtMikgPT4gbTEgKyAoXG4gICAgICBtMi5pbmRleE9mKCdcXFxcJykgPT09IDBcbiAgICAgICAgPyBTUEFDRVxuICAgICAgICA6IEVNUFRZXG4gICAgKVxuICBdLFxuXG4gIC8vIFJlcGxhY2UgKFxcICkgd2l0aCAnICdcbiAgLy8gKFxcICkgLT4gJyAnXG4gIC8vIChcXFxcICkgLT4gJ1xcXFwgJ1xuICAvLyAoXFxcXFxcICkgLT4gJ1xcXFwgJ1xuICBbXG4gICAgLyhcXFxcKz8pXFxzL2csXG4gICAgKF8sIG0xKSA9PiB7XG4gICAgICBjb25zdCB7bGVuZ3RofSA9IG0xXG4gICAgICByZXR1cm4gbTEuc2xpY2UoMCwgbGVuZ3RoIC0gbGVuZ3RoICUgMikgKyBTUEFDRVxuICAgIH1cbiAgXSxcblxuICAvLyBFc2NhcGUgbWV0YWNoYXJhY3RlcnNcbiAgLy8gd2hpY2ggaXMgd3JpdHRlbiBkb3duIGJ5IHVzZXJzIGJ1dCBtZWFucyBzcGVjaWFsIGZvciByZWd1bGFyIGV4cHJlc3Npb25zLlxuXG4gIC8vID4gVGhlcmUgYXJlIDEyIGNoYXJhY3RlcnMgd2l0aCBzcGVjaWFsIG1lYW5pbmdzOlxuICAvLyA+IC0gdGhlIGJhY2tzbGFzaCBcXCxcbiAgLy8gPiAtIHRoZSBjYXJldCBeLFxuICAvLyA+IC0gdGhlIGRvbGxhciBzaWduICQsXG4gIC8vID4gLSB0aGUgcGVyaW9kIG9yIGRvdCAuLFxuICAvLyA+IC0gdGhlIHZlcnRpY2FsIGJhciBvciBwaXBlIHN5bWJvbCB8LFxuICAvLyA+IC0gdGhlIHF1ZXN0aW9uIG1hcmsgPyxcbiAgLy8gPiAtIHRoZSBhc3RlcmlzayBvciBzdGFyICosXG4gIC8vID4gLSB0aGUgcGx1cyBzaWduICssXG4gIC8vID4gLSB0aGUgb3BlbmluZyBwYXJlbnRoZXNpcyAoLFxuICAvLyA+IC0gdGhlIGNsb3NpbmcgcGFyZW50aGVzaXMgKSxcbiAgLy8gPiAtIGFuZCB0aGUgb3BlbmluZyBzcXVhcmUgYnJhY2tldCBbLFxuICAvLyA+IC0gdGhlIG9wZW5pbmcgY3VybHkgYnJhY2UgeyxcbiAgLy8gPiBUaGVzZSBzcGVjaWFsIGNoYXJhY3RlcnMgYXJlIG9mdGVuIGNhbGxlZCBcIm1ldGFjaGFyYWN0ZXJzXCIuXG4gIFtcbiAgICAvW1xcXFwkLnwqKygpe15dL2csXG4gICAgbWF0Y2ggPT4gYFxcXFwke21hdGNofWBcbiAgXSxcblxuICBbXG4gICAgLy8gPiBhIHF1ZXN0aW9uIG1hcmsgKD8pIG1hdGNoZXMgYSBzaW5nbGUgY2hhcmFjdGVyXG4gICAgLyg/IVxcXFwpXFw/L2csXG4gICAgKCkgPT4gJ1teL10nXG4gIF0sXG5cbiAgLy8gbGVhZGluZyBzbGFzaFxuICBbXG5cbiAgICAvLyA+IEEgbGVhZGluZyBzbGFzaCBtYXRjaGVzIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHBhdGhuYW1lLlxuICAgIC8vID4gRm9yIGV4YW1wbGUsIFwiLyouY1wiIG1hdGNoZXMgXCJjYXQtZmlsZS5jXCIgYnV0IG5vdCBcIm1vemlsbGEtc2hhMS9zaGExLmNcIi5cbiAgICAvLyBBIGxlYWRpbmcgc2xhc2ggbWF0Y2hlcyB0aGUgYmVnaW5uaW5nIG9mIHRoZSBwYXRobmFtZVxuICAgIC9eXFwvLyxcbiAgICAoKSA9PiAnXidcbiAgXSxcblxuICAvLyByZXBsYWNlIHNwZWNpYWwgbWV0YWNoYXJhY3RlciBzbGFzaCBhZnRlciB0aGUgbGVhZGluZyBzbGFzaFxuICBbXG4gICAgL1xcLy9nLFxuICAgICgpID0+ICdcXFxcLydcbiAgXSxcblxuICBbXG4gICAgLy8gPiBBIGxlYWRpbmcgXCIqKlwiIGZvbGxvd2VkIGJ5IGEgc2xhc2ggbWVhbnMgbWF0Y2ggaW4gYWxsIGRpcmVjdG9yaWVzLlxuICAgIC8vID4gRm9yIGV4YW1wbGUsIFwiKiovZm9vXCIgbWF0Y2hlcyBmaWxlIG9yIGRpcmVjdG9yeSBcImZvb1wiIGFueXdoZXJlLFxuICAgIC8vID4gdGhlIHNhbWUgYXMgcGF0dGVybiBcImZvb1wiLlxuICAgIC8vID4gXCIqKi9mb28vYmFyXCIgbWF0Y2hlcyBmaWxlIG9yIGRpcmVjdG9yeSBcImJhclwiIGFueXdoZXJlIHRoYXQgaXMgZGlyZWN0bHlcbiAgICAvLyA+ICAgdW5kZXIgZGlyZWN0b3J5IFwiZm9vXCIuXG4gICAgLy8gTm90aWNlIHRoYXQgdGhlICcqJ3MgaGF2ZSBiZWVuIHJlcGxhY2VkIGFzICdcXFxcKidcbiAgICAvXlxcXipcXFxcXFwqXFxcXFxcKlxcXFxcXC8vLFxuXG4gICAgLy8gJyoqL2ZvbycgPC0+ICdmb28nXG4gICAgKCkgPT4gJ14oPzouKlxcXFwvKT8nXG4gIF0sXG5cbiAgLy8gc3RhcnRpbmdcbiAgW1xuICAgIC8vIHRoZXJlIHdpbGwgYmUgbm8gbGVhZGluZyAnLydcbiAgICAvLyAgICh3aGljaCBoYXMgYmVlbiByZXBsYWNlZCBieSBzZWN0aW9uIFwibGVhZGluZyBzbGFzaFwiKVxuICAgIC8vIElmIHN0YXJ0cyB3aXRoICcqKicsIGFkZGluZyBhICdeJyB0byB0aGUgcmVndWxhciBleHByZXNzaW9uIGFsc28gd29ya3NcbiAgICAvXig/PVteXl0pLyxcbiAgICBmdW5jdGlvbiBzdGFydGluZ1JlcGxhY2VyICgpIHtcbiAgICAgIC8vIElmIGhhcyBhIHNsYXNoIGAvYCBhdCB0aGUgYmVnaW5uaW5nIG9yIG1pZGRsZVxuICAgICAgcmV0dXJuICEvXFwvKD8hJCkvLnRlc3QodGhpcylcbiAgICAgICAgLy8gPiBQcmlvciB0byAyLjIyLjFcbiAgICAgICAgLy8gPiBJZiB0aGUgcGF0dGVybiBkb2VzIG5vdCBjb250YWluIGEgc2xhc2ggLyxcbiAgICAgICAgLy8gPiAgIEdpdCB0cmVhdHMgaXQgYXMgYSBzaGVsbCBnbG9iIHBhdHRlcm5cbiAgICAgICAgLy8gQWN0dWFsbHksIGlmIHRoZXJlIGlzIG9ubHkgYSB0cmFpbGluZyBzbGFzaCxcbiAgICAgICAgLy8gICBnaXQgYWxzbyB0cmVhdHMgaXQgYXMgYSBzaGVsbCBnbG9iIHBhdHRlcm5cblxuICAgICAgICAvLyBBZnRlciAyLjIyLjEgKGNvbXBhdGlibGUgYnV0IGNsZWFyZXIpXG4gICAgICAgIC8vID4gSWYgdGhlcmUgaXMgYSBzZXBhcmF0b3IgYXQgdGhlIGJlZ2lubmluZyBvciBtaWRkbGUgKG9yIGJvdGgpXG4gICAgICAgIC8vID4gb2YgdGhlIHBhdHRlcm4sIHRoZW4gdGhlIHBhdHRlcm4gaXMgcmVsYXRpdmUgdG8gdGhlIGRpcmVjdG9yeVxuICAgICAgICAvLyA+IGxldmVsIG9mIHRoZSBwYXJ0aWN1bGFyIC5naXRpZ25vcmUgZmlsZSBpdHNlbGYuXG4gICAgICAgIC8vID4gT3RoZXJ3aXNlIHRoZSBwYXR0ZXJuIG1heSBhbHNvIG1hdGNoIGF0IGFueSBsZXZlbCBiZWxvd1xuICAgICAgICAvLyA+IHRoZSAuZ2l0aWdub3JlIGxldmVsLlxuICAgICAgICA/ICcoPzpefFxcXFwvKSdcblxuICAgICAgICAvLyA+IE90aGVyd2lzZSwgR2l0IHRyZWF0cyB0aGUgcGF0dGVybiBhcyBhIHNoZWxsIGdsb2Igc3VpdGFibGUgZm9yXG4gICAgICAgIC8vID4gICBjb25zdW1wdGlvbiBieSBmbm1hdGNoKDMpXG4gICAgICAgIDogJ14nXG4gICAgfVxuICBdLFxuXG4gIC8vIHR3byBnbG9ic3RhcnNcbiAgW1xuICAgIC8vIFVzZSBsb29rYWhlYWQgYXNzZXJ0aW9ucyBzbyB0aGF0IHdlIGNvdWxkIG1hdGNoIG1vcmUgdGhhbiBvbmUgYCcvKionYFxuICAgIC9cXFxcXFwvXFxcXFxcKlxcXFxcXCooPz1cXFxcXFwvfCQpL2csXG5cbiAgICAvLyBaZXJvLCBvbmUgb3Igc2V2ZXJhbCBkaXJlY3Rvcmllc1xuICAgIC8vIHNob3VsZCBub3QgdXNlICcqJywgb3IgaXQgd2lsbCBiZSByZXBsYWNlZCBieSB0aGUgbmV4dCByZXBsYWNlclxuXG4gICAgLy8gQ2hlY2sgaWYgaXQgaXMgbm90IHRoZSBsYXN0IGAnLyoqJ2BcbiAgICAoXywgaW5kZXgsIHN0cikgPT4gaW5kZXggKyA2IDwgc3RyLmxlbmd0aFxuXG4gICAgICAvLyBjYXNlOiAvKiovXG4gICAgICAvLyA+IEEgc2xhc2ggZm9sbG93ZWQgYnkgdHdvIGNvbnNlY3V0aXZlIGFzdGVyaXNrcyB0aGVuIGEgc2xhc2ggbWF0Y2hlc1xuICAgICAgLy8gPiAgIHplcm8gb3IgbW9yZSBkaXJlY3Rvcmllcy5cbiAgICAgIC8vID4gRm9yIGV4YW1wbGUsIFwiYS8qKi9iXCIgbWF0Y2hlcyBcImEvYlwiLCBcImEveC9iXCIsIFwiYS94L3kvYlwiIGFuZCBzbyBvbi5cbiAgICAgIC8vICcvKiovJ1xuICAgICAgPyAnKD86XFxcXC9bXlxcXFwvXSspKidcblxuICAgICAgLy8gY2FzZTogLyoqXG4gICAgICAvLyA+IEEgdHJhaWxpbmcgYFwiLyoqXCJgIG1hdGNoZXMgZXZlcnl0aGluZyBpbnNpZGUuXG5cbiAgICAgIC8vICMyMTogZXZlcnl0aGluZyBpbnNpZGUgYnV0IGl0IHNob3VsZCBub3QgaW5jbHVkZSB0aGUgY3VycmVudCBmb2xkZXJcbiAgICAgIDogJ1xcXFwvLisnXG4gIF0sXG5cbiAgLy8gbm9ybWFsIGludGVybWVkaWF0ZSB3aWxkY2FyZHNcbiAgW1xuICAgIC8vIE5ldmVyIHJlcGxhY2UgZXNjYXBlZCAnKidcbiAgICAvLyBpZ25vcmUgcnVsZSAnXFwqJyB3aWxsIG1hdGNoIHRoZSBwYXRoICcqJ1xuXG4gICAgLy8gJ2FiYy4qLycgLT4gZ29cbiAgICAvLyAnYWJjLionICAtPiBza2lwIHRoaXMgcnVsZSxcbiAgICAvLyAgICBjb3ogdHJhaWxpbmcgc2luZ2xlIHdpbGRjYXJkIHdpbGwgYmUgaGFuZGVkIGJ5IFt0cmFpbGluZyB3aWxkY2FyZF1cbiAgICAvKF58W15cXFxcXSspKFxcXFxcXCopKyg/PS4rKS9nLFxuXG4gICAgLy8gJyouanMnIG1hdGNoZXMgJy5qcydcbiAgICAvLyAnKi5qcycgZG9lc24ndCBtYXRjaCAnYWJjJ1xuICAgIChfLCBwMSwgcDIpID0+IHtcbiAgICAgIC8vIDEuXG4gICAgICAvLyA+IEFuIGFzdGVyaXNrIFwiKlwiIG1hdGNoZXMgYW55dGhpbmcgZXhjZXB0IGEgc2xhc2guXG4gICAgICAvLyAyLlxuICAgICAgLy8gPiBPdGhlciBjb25zZWN1dGl2ZSBhc3Rlcmlza3MgYXJlIGNvbnNpZGVyZWQgcmVndWxhciBhc3Rlcmlza3NcbiAgICAgIC8vID4gYW5kIHdpbGwgbWF0Y2ggYWNjb3JkaW5nIHRvIHRoZSBwcmV2aW91cyBydWxlcy5cbiAgICAgIGNvbnN0IHVuZXNjYXBlZCA9IHAyLnJlcGxhY2UoL1xcXFxcXCovZywgJ1teXFxcXC9dKicpXG4gICAgICByZXR1cm4gcDEgKyB1bmVzY2FwZWRcbiAgICB9XG4gIF0sXG5cbiAgW1xuICAgIC8vIHVuZXNjYXBlLCByZXZlcnQgc3RlcCAzIGV4Y2VwdCBmb3IgYmFjayBzbGFzaFxuICAgIC8vIEZvciBleGFtcGxlLCBpZiBhIHVzZXIgZXNjYXBlIGEgJ1xcXFwqJyxcbiAgICAvLyBhZnRlciBzdGVwIDMsIHRoZSByZXN1bHQgd2lsbCBiZSAnXFxcXFxcXFxcXFxcKidcbiAgICAvXFxcXFxcXFxcXFxcKD89WyQufCorKCl7Xl0pL2csXG4gICAgKCkgPT4gRVNDQVBFXG4gIF0sXG5cbiAgW1xuICAgIC8vICdcXFxcXFxcXCcgLT4gJ1xcXFwnXG4gICAgL1xcXFxcXFxcL2csXG4gICAgKCkgPT4gRVNDQVBFXG4gIF0sXG5cbiAgW1xuICAgIC8vID4gVGhlIHJhbmdlIG5vdGF0aW9uLCBlLmcuIFthLXpBLVpdLFxuICAgIC8vID4gY2FuIGJlIHVzZWQgdG8gbWF0Y2ggb25lIG9mIHRoZSBjaGFyYWN0ZXJzIGluIGEgcmFuZ2UuXG5cbiAgICAvLyBgXFxgIGlzIGVzY2FwZWQgYnkgc3RlcCAzXG4gICAgLyhcXFxcKT9cXFsoW15cXF0vXSo/KShcXFxcKikoJHxcXF0pL2csXG4gICAgKG1hdGNoLCBsZWFkRXNjYXBlLCByYW5nZSwgZW5kRXNjYXBlLCBjbG9zZSkgPT4gbGVhZEVzY2FwZSA9PT0gRVNDQVBFXG4gICAgICAvLyAnXFxcXFtiYXJdJyAtPiAnXFxcXFxcXFxbYmFyXFxcXF0nXG4gICAgICA/IGBcXFxcWyR7cmFuZ2V9JHtjbGVhblJhbmdlQmFja1NsYXNoKGVuZEVzY2FwZSl9JHtjbG9zZX1gXG4gICAgICA6IGNsb3NlID09PSAnXSdcbiAgICAgICAgPyBlbmRFc2NhcGUubGVuZ3RoICUgMiA9PT0gMFxuICAgICAgICAgIC8vIEEgbm9ybWFsIGNhc2UsIGFuZCBpdCBpcyBhIHJhbmdlIG5vdGF0aW9uXG4gICAgICAgICAgLy8gJ1tiYXJdJ1xuICAgICAgICAgIC8vICdbYmFyXFxcXFxcXFxdJ1xuICAgICAgICAgID8gYFske3Nhbml0aXplUmFuZ2UocmFuZ2UpfSR7ZW5kRXNjYXBlfV1gXG4gICAgICAgICAgLy8gSW52YWxpZCByYW5nZSBub3RhdG9uXG4gICAgICAgICAgLy8gJ1tiYXJcXFxcXScgLT4gJ1tiYXJcXFxcXFxcXF0nXG4gICAgICAgICAgOiAnW10nXG4gICAgICAgIDogJ1tdJ1xuICBdLFxuXG4gIC8vIGVuZGluZ1xuICBbXG4gICAgLy8gJ2pzJyB3aWxsIG5vdCBtYXRjaCAnanMuJ1xuICAgIC8vICdhYicgd2lsbCBub3QgbWF0Y2ggJ2FiYydcbiAgICAvKD86W14qXSkkLyxcblxuICAgIC8vIFdURiFcbiAgICAvLyBodHRwczovL2dpdC1zY20uY29tL2RvY3MvZ2l0aWdub3JlXG4gICAgLy8gY2hhbmdlcyBpbiBbMi4yMi4xXShodHRwczovL2dpdC1zY20uY29tL2RvY3MvZ2l0aWdub3JlLzIuMjIuMSlcbiAgICAvLyB3aGljaCByZS1maXhlcyAjMjQsICMzOFxuXG4gICAgLy8gPiBJZiB0aGVyZSBpcyBhIHNlcGFyYXRvciBhdCB0aGUgZW5kIG9mIHRoZSBwYXR0ZXJuIHRoZW4gdGhlIHBhdHRlcm5cbiAgICAvLyA+IHdpbGwgb25seSBtYXRjaCBkaXJlY3Rvcmllcywgb3RoZXJ3aXNlIHRoZSBwYXR0ZXJuIGNhbiBtYXRjaCBib3RoXG4gICAgLy8gPiBmaWxlcyBhbmQgZGlyZWN0b3JpZXMuXG5cbiAgICAvLyAnanMqJyB3aWxsIG5vdCBtYXRjaCAnYS5qcydcbiAgICAvLyAnanMvJyB3aWxsIG5vdCBtYXRjaCAnYS5qcydcbiAgICAvLyAnanMnIHdpbGwgbWF0Y2ggJ2EuanMnIGFuZCAnYS5qcy8nXG4gICAgbWF0Y2ggPT4gL1xcLyQvLnRlc3QobWF0Y2gpXG4gICAgICAvLyBmb28vIHdpbGwgbm90IG1hdGNoICdmb28nXG4gICAgICA/IGAke21hdGNofSRgXG4gICAgICAvLyBmb28gbWF0Y2hlcyAnZm9vJyBhbmQgJ2Zvby8nXG4gICAgICA6IGAke21hdGNofSg/PSR8XFxcXC8kKWBcbiAgXVxuXVxuXG5jb25zdCBSRUdFWF9SRVBMQUNFX1RSQUlMSU5HX1dJTERDQVJEID0gLyhefFxcXFxcXC8pP1xcXFxcXCokL1xuY29uc3QgTU9ERV9JR05PUkUgPSAncmVnZXgnXG5jb25zdCBNT0RFX0NIRUNLX0lHTk9SRSA9ICdjaGVja1JlZ2V4J1xuY29uc3QgVU5ERVJTQ09SRSA9ICdfJ1xuXG5jb25zdCBUUkFJTElOR19XSUxEX0NBUkRfUkVQTEFDRVJTID0ge1xuICBbTU9ERV9JR05PUkVdIChfLCBwMSkge1xuICAgIGNvbnN0IHByZWZpeCA9IHAxXG4gICAgICAvLyAnXFxeJzpcbiAgICAgIC8vICcvKicgZG9lcyBub3QgbWF0Y2ggRU1QVFlcbiAgICAgIC8vICcvKicgZG9lcyBub3QgbWF0Y2ggZXZlcnl0aGluZ1xuXG4gICAgICAvLyAnXFxcXFxcLyc6XG4gICAgICAvLyAnYWJjLyonIGRvZXMgbm90IG1hdGNoICdhYmMvJ1xuICAgICAgPyBgJHtwMX1bXi9dK2BcblxuICAgICAgLy8gJ2EqJyBtYXRjaGVzICdhJ1xuICAgICAgLy8gJ2EqJyBtYXRjaGVzICdhYSdcbiAgICAgIDogJ1teL10qJ1xuXG4gICAgcmV0dXJuIGAke3ByZWZpeH0oPz0kfFxcXFwvJClgXG4gIH0sXG5cbiAgW01PREVfQ0hFQ0tfSUdOT1JFXSAoXywgcDEpIHtcbiAgICAvLyBXaGVuIGRvaW5nIGBnaXQgY2hlY2staWdub3JlYFxuICAgIGNvbnN0IHByZWZpeCA9IHAxXG4gICAgICAvLyAnXFxcXFxcLyc6XG4gICAgICAvLyAnYWJjLyonIERPRVMgbWF0Y2ggJ2FiYy8nICFcbiAgICAgID8gYCR7cDF9W14vXSpgXG5cbiAgICAgIC8vICdhKicgbWF0Y2hlcyAnYSdcbiAgICAgIC8vICdhKicgbWF0Y2hlcyAnYWEnXG4gICAgICA6ICdbXi9dKidcblxuICAgIHJldHVybiBgJHtwcmVmaXh9KD89JHxcXFxcLyQpYFxuICB9XG59XG5cbi8vIEBwYXJhbSB7cGF0dGVybn1cbmNvbnN0IG1ha2VSZWdleFByZWZpeCA9IHBhdHRlcm4gPT4gUkVQTEFDRVJTLnJlZHVjZShcbiAgKHByZXYsIFttYXRjaGVyLCByZXBsYWNlcl0pID0+XG4gICAgcHJldi5yZXBsYWNlKG1hdGNoZXIsIHJlcGxhY2VyLmJpbmQocGF0dGVybikpLFxuICBwYXR0ZXJuXG4pXG5cbmNvbnN0IGlzU3RyaW5nID0gc3ViamVjdCA9PiB0eXBlb2Ygc3ViamVjdCA9PT0gJ3N0cmluZydcblxuLy8gPiBBIGJsYW5rIGxpbmUgbWF0Y2hlcyBubyBmaWxlcywgc28gaXQgY2FuIHNlcnZlIGFzIGEgc2VwYXJhdG9yIGZvciByZWFkYWJpbGl0eS5cbmNvbnN0IGNoZWNrUGF0dGVybiA9IHBhdHRlcm4gPT4gcGF0dGVyblxuICAmJiBpc1N0cmluZyhwYXR0ZXJuKVxuICAmJiAhUkVHRVhfVEVTVF9CTEFOS19MSU5FLnRlc3QocGF0dGVybilcbiAgJiYgIVJFR0VYX0lOVkFMSURfVFJBSUxJTkdfQkFDS1NMQVNILnRlc3QocGF0dGVybilcblxuICAvLyA+IEEgbGluZSBzdGFydGluZyB3aXRoICMgc2VydmVzIGFzIGEgY29tbWVudC5cbiAgJiYgcGF0dGVybi5pbmRleE9mKCcjJykgIT09IDBcblxuY29uc3Qgc3BsaXRQYXR0ZXJuID0gcGF0dGVybiA9PiBwYXR0ZXJuXG4uc3BsaXQoUkVHRVhfU1BMSVRBTExfQ1JMRilcbi5maWx0ZXIoQm9vbGVhbilcblxuY2xhc3MgSWdub3JlUnVsZSB7XG4gIGNvbnN0cnVjdG9yIChcbiAgICBwYXR0ZXJuLFxuICAgIG1hcmssXG4gICAgYm9keSxcbiAgICBpZ25vcmVDYXNlLFxuICAgIG5lZ2F0aXZlLFxuICAgIHByZWZpeFxuICApIHtcbiAgICB0aGlzLnBhdHRlcm4gPSBwYXR0ZXJuXG4gICAgdGhpcy5tYXJrID0gbWFya1xuICAgIHRoaXMubmVnYXRpdmUgPSBuZWdhdGl2ZVxuXG4gICAgZGVmaW5lKHRoaXMsICdib2R5JywgYm9keSlcbiAgICBkZWZpbmUodGhpcywgJ2lnbm9yZUNhc2UnLCBpZ25vcmVDYXNlKVxuICAgIGRlZmluZSh0aGlzLCAncmVnZXhQcmVmaXgnLCBwcmVmaXgpXG4gIH1cblxuICBnZXQgcmVnZXggKCkge1xuICAgIGNvbnN0IGtleSA9IFVOREVSU0NPUkUgKyBNT0RFX0lHTk9SRVxuXG4gICAgaWYgKHRoaXNba2V5XSkge1xuICAgICAgcmV0dXJuIHRoaXNba2V5XVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9tYWtlKE1PREVfSUdOT1JFLCBrZXkpXG4gIH1cblxuICBnZXQgY2hlY2tSZWdleCAoKSB7XG4gICAgY29uc3Qga2V5ID0gVU5ERVJTQ09SRSArIE1PREVfQ0hFQ0tfSUdOT1JFXG5cbiAgICBpZiAodGhpc1trZXldKSB7XG4gICAgICByZXR1cm4gdGhpc1trZXldXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX21ha2UoTU9ERV9DSEVDS19JR05PUkUsIGtleSlcbiAgfVxuXG4gIF9tYWtlIChtb2RlLCBrZXkpIHtcbiAgICBjb25zdCBzdHIgPSB0aGlzLnJlZ2V4UHJlZml4LnJlcGxhY2UoXG4gICAgICBSRUdFWF9SRVBMQUNFX1RSQUlMSU5HX1dJTERDQVJELFxuXG4gICAgICAvLyBJdCBkb2VzIG5vdCBuZWVkIHRvIGJpbmQgcGF0dGVyblxuICAgICAgVFJBSUxJTkdfV0lMRF9DQVJEX1JFUExBQ0VSU1ttb2RlXVxuICAgIClcblxuICAgIGNvbnN0IHJlZ2V4ID0gdGhpcy5pZ25vcmVDYXNlXG4gICAgICA/IG5ldyBSZWdFeHAoc3RyLCAnaScpXG4gICAgICA6IG5ldyBSZWdFeHAoc3RyKVxuXG4gICAgcmV0dXJuIGRlZmluZSh0aGlzLCBrZXksIHJlZ2V4KVxuICB9XG59XG5cbmNvbnN0IGNyZWF0ZVJ1bGUgPSAoe1xuICBwYXR0ZXJuLFxuICBtYXJrXG59LCBpZ25vcmVDYXNlKSA9PiB7XG4gIGxldCBuZWdhdGl2ZSA9IGZhbHNlXG4gIGxldCBib2R5ID0gcGF0dGVyblxuXG4gIC8vID4gQW4gb3B0aW9uYWwgcHJlZml4IFwiIVwiIHdoaWNoIG5lZ2F0ZXMgdGhlIHBhdHRlcm47XG4gIGlmIChib2R5LmluZGV4T2YoJyEnKSA9PT0gMCkge1xuICAgIG5lZ2F0aXZlID0gdHJ1ZVxuICAgIGJvZHkgPSBib2R5LnN1YnN0cigxKVxuICB9XG5cbiAgYm9keSA9IGJvZHlcbiAgLy8gPiBQdXQgYSBiYWNrc2xhc2ggKFwiXFxcIikgaW4gZnJvbnQgb2YgdGhlIGZpcnN0IFwiIVwiIGZvciBwYXR0ZXJucyB0aGF0XG4gIC8vID4gICBiZWdpbiB3aXRoIGEgbGl0ZXJhbCBcIiFcIiwgZm9yIGV4YW1wbGUsIGBcIlxcIWltcG9ydGFudCEudHh0XCJgLlxuICAucmVwbGFjZShSRUdFWF9SRVBMQUNFX0xFQURJTkdfRVhDQVBFRF9FWENMQU1BVElPTiwgJyEnKVxuICAvLyA+IFB1dCBhIGJhY2tzbGFzaCAoXCJcXFwiKSBpbiBmcm9udCBvZiB0aGUgZmlyc3QgaGFzaCBmb3IgcGF0dGVybnMgdGhhdFxuICAvLyA+ICAgYmVnaW4gd2l0aCBhIGhhc2guXG4gIC5yZXBsYWNlKFJFR0VYX1JFUExBQ0VfTEVBRElOR19FWENBUEVEX0hBU0gsICcjJylcblxuICBjb25zdCByZWdleFByZWZpeCA9IG1ha2VSZWdleFByZWZpeChib2R5KVxuXG4gIHJldHVybiBuZXcgSWdub3JlUnVsZShcbiAgICBwYXR0ZXJuLFxuICAgIG1hcmssXG4gICAgYm9keSxcbiAgICBpZ25vcmVDYXNlLFxuICAgIG5lZ2F0aXZlLFxuICAgIHJlZ2V4UHJlZml4XG4gIClcbn1cblxuY2xhc3MgUnVsZU1hbmFnZXIge1xuICBjb25zdHJ1Y3RvciAoaWdub3JlQ2FzZSkge1xuICAgIHRoaXMuX2lnbm9yZUNhc2UgPSBpZ25vcmVDYXNlXG4gICAgdGhpcy5fcnVsZXMgPSBbXVxuICB9XG5cbiAgX2FkZCAocGF0dGVybikge1xuICAgIC8vICMzMlxuICAgIGlmIChwYXR0ZXJuICYmIHBhdHRlcm5bS0VZX0lHTk9SRV0pIHtcbiAgICAgIHRoaXMuX3J1bGVzID0gdGhpcy5fcnVsZXMuY29uY2F0KHBhdHRlcm4uX3J1bGVzLl9ydWxlcylcbiAgICAgIHRoaXMuX2FkZGVkID0gdHJ1ZVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKGlzU3RyaW5nKHBhdHRlcm4pKSB7XG4gICAgICBwYXR0ZXJuID0ge1xuICAgICAgICBwYXR0ZXJuXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNoZWNrUGF0dGVybihwYXR0ZXJuLnBhdHRlcm4pKSB7XG4gICAgICBjb25zdCBydWxlID0gY3JlYXRlUnVsZShwYXR0ZXJuLCB0aGlzLl9pZ25vcmVDYXNlKVxuICAgICAgdGhpcy5fYWRkZWQgPSB0cnVlXG4gICAgICB0aGlzLl9ydWxlcy5wdXNoKHJ1bGUpXG4gICAgfVxuICB9XG5cbiAgLy8gQHBhcmFtIHtBcnJheTxzdHJpbmc+IHwgc3RyaW5nIHwgSWdub3JlfSBwYXR0ZXJuXG4gIGFkZCAocGF0dGVybikge1xuICAgIHRoaXMuX2FkZGVkID0gZmFsc2VcblxuICAgIG1ha2VBcnJheShcbiAgICAgIGlzU3RyaW5nKHBhdHRlcm4pXG4gICAgICAgID8gc3BsaXRQYXR0ZXJuKHBhdHRlcm4pXG4gICAgICAgIDogcGF0dGVyblxuICAgICkuZm9yRWFjaCh0aGlzLl9hZGQsIHRoaXMpXG5cbiAgICByZXR1cm4gdGhpcy5fYWRkZWRcbiAgfVxuXG4gIC8vIFRlc3Qgb25lIHNpbmdsZSBwYXRoIHdpdGhvdXQgcmVjdXJzaXZlbHkgY2hlY2tpbmcgcGFyZW50IGRpcmVjdG9yaWVzXG4gIC8vXG4gIC8vIC0gY2hlY2tVbmlnbm9yZWQgYGJvb2xlYW5gIHdoZXRoZXIgc2hvdWxkIGNoZWNrIGlmIHRoZSBwYXRoIGlzIHVuaWdub3JlZCxcbiAgLy8gICBzZXR0aW5nIGBjaGVja1VuaWdub3JlZGAgdG8gYGZhbHNlYCBjb3VsZCByZWR1Y2UgYWRkaXRpb25hbFxuICAvLyAgIHBhdGggbWF0Y2hpbmcuXG4gIC8vIC0gY2hlY2sgYHN0cmluZ2AgZWl0aGVyIGBNT0RFX0lHTk9SRWAgb3IgYE1PREVfQ0hFQ0tfSUdOT1JFYFxuXG4gIC8vIEByZXR1cm5zIHtUZXN0UmVzdWx0fSB0cnVlIGlmIGEgZmlsZSBpcyBpZ25vcmVkXG4gIHRlc3QgKHBhdGgsIGNoZWNrVW5pZ25vcmVkLCBtb2RlKSB7XG4gICAgbGV0IGlnbm9yZWQgPSBmYWxzZVxuICAgIGxldCB1bmlnbm9yZWQgPSBmYWxzZVxuICAgIGxldCBtYXRjaGVkUnVsZVxuXG4gICAgdGhpcy5fcnVsZXMuZm9yRWFjaChydWxlID0+IHtcbiAgICAgIGNvbnN0IHtuZWdhdGl2ZX0gPSBydWxlXG5cbiAgICAgIC8vICAgICAgICAgIHwgICAgICAgICAgIGlnbm9yZWQgOiB1bmlnbm9yZWRcbiAgICAgIC8vIC0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAvLyBuZWdhdGl2ZSB8ICAgMDowICAgfCAgIDA6MSAgIHwgICAxOjAgICB8ICAgMToxXG4gICAgICAvLyAtLS0tLS0tLSB8IC0tLS0tLS0gfCAtLS0tLS0tIHwgLS0tLS0tLSB8IC0tLS0tLS0tXG4gICAgICAvLyAgICAgMCAgICB8ICBURVNUICAgfCAgVEVTVCAgIHwgIFNLSVAgICB8ICAgIFhcbiAgICAgIC8vICAgICAxICAgIHwgIFRFU1RJRiB8ICBTS0lQICAgfCAgVEVTVCAgIHwgICAgWFxuXG4gICAgICAvLyAtIFNLSVA6IGFsd2F5cyBza2lwXG4gICAgICAvLyAtIFRFU1Q6IGFsd2F5cyB0ZXN0XG4gICAgICAvLyAtIFRFU1RJRjogb25seSB0ZXN0IGlmIGNoZWNrVW5pZ25vcmVkXG4gICAgICAvLyAtIFg6IHRoYXQgbmV2ZXIgaGFwcGVuXG4gICAgICBpZiAoXG4gICAgICAgIHVuaWdub3JlZCA9PT0gbmVnYXRpdmUgJiYgaWdub3JlZCAhPT0gdW5pZ25vcmVkXG4gICAgICAgIHx8IG5lZ2F0aXZlICYmICFpZ25vcmVkICYmICF1bmlnbm9yZWQgJiYgIWNoZWNrVW5pZ25vcmVkXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1hdGNoZWQgPSBydWxlW21vZGVdLnRlc3QocGF0aClcblxuICAgICAgaWYgKCFtYXRjaGVkKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZ25vcmVkID0gIW5lZ2F0aXZlXG4gICAgICB1bmlnbm9yZWQgPSBuZWdhdGl2ZVxuXG4gICAgICBtYXRjaGVkUnVsZSA9IG5lZ2F0aXZlXG4gICAgICAgID8gVU5ERUZJTkVEXG4gICAgICAgIDogcnVsZVxuICAgIH0pXG5cbiAgICBjb25zdCByZXQgPSB7XG4gICAgICBpZ25vcmVkLFxuICAgICAgdW5pZ25vcmVkXG4gICAgfVxuXG4gICAgaWYgKG1hdGNoZWRSdWxlKSB7XG4gICAgICByZXQucnVsZSA9IG1hdGNoZWRSdWxlXG4gICAgfVxuXG4gICAgcmV0dXJuIHJldFxuICB9XG59XG5cbmNvbnN0IHRocm93RXJyb3IgPSAobWVzc2FnZSwgQ3RvcikgPT4ge1xuICB0aHJvdyBuZXcgQ3RvcihtZXNzYWdlKVxufVxuXG5jb25zdCBjaGVja1BhdGggPSAocGF0aCwgb3JpZ2luYWxQYXRoLCBkb1Rocm93KSA9PiB7XG4gIGlmICghaXNTdHJpbmcocGF0aCkpIHtcbiAgICByZXR1cm4gZG9UaHJvdyhcbiAgICAgIGBwYXRoIG11c3QgYmUgYSBzdHJpbmcsIGJ1dCBnb3QgXFxgJHtvcmlnaW5hbFBhdGh9XFxgYCxcbiAgICAgIFR5cGVFcnJvclxuICAgIClcbiAgfVxuXG4gIC8vIFdlIGRvbid0IGtub3cgaWYgd2Ugc2hvdWxkIGlnbm9yZSBFTVBUWSwgc28gdGhyb3dcbiAgaWYgKCFwYXRoKSB7XG4gICAgcmV0dXJuIGRvVGhyb3coYHBhdGggbXVzdCBub3QgYmUgZW1wdHlgLCBUeXBlRXJyb3IpXG4gIH1cblxuICAvLyBDaGVjayBpZiBpdCBpcyBhIHJlbGF0aXZlIHBhdGhcbiAgaWYgKGNoZWNrUGF0aC5pc05vdFJlbGF0aXZlKHBhdGgpKSB7XG4gICAgY29uc3QgciA9ICdgcGF0aC5yZWxhdGl2ZSgpYGQnXG4gICAgcmV0dXJuIGRvVGhyb3coXG4gICAgICBgcGF0aCBzaG91bGQgYmUgYSAke3J9IHN0cmluZywgYnV0IGdvdCBcIiR7b3JpZ2luYWxQYXRofVwiYCxcbiAgICAgIFJhbmdlRXJyb3JcbiAgICApXG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuXG5jb25zdCBpc05vdFJlbGF0aXZlID0gcGF0aCA9PiBSRUdFWF9URVNUX0lOVkFMSURfUEFUSC50ZXN0KHBhdGgpXG5cbmNoZWNrUGF0aC5pc05vdFJlbGF0aXZlID0gaXNOb3RSZWxhdGl2ZVxuXG4vLyBPbiB3aW5kb3dzLCB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uIHdpbGwgYmUgcmVwbGFjZWRcbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5jaGVja1BhdGguY29udmVydCA9IHAgPT4gcFxuXG5cbmNsYXNzIElnbm9yZSB7XG4gIGNvbnN0cnVjdG9yICh7XG4gICAgaWdub3JlY2FzZSA9IHRydWUsXG4gICAgaWdub3JlQ2FzZSA9IGlnbm9yZWNhc2UsXG4gICAgYWxsb3dSZWxhdGl2ZVBhdGhzID0gZmFsc2VcbiAgfSA9IHt9KSB7XG4gICAgZGVmaW5lKHRoaXMsIEtFWV9JR05PUkUsIHRydWUpXG5cbiAgICB0aGlzLl9ydWxlcyA9IG5ldyBSdWxlTWFuYWdlcihpZ25vcmVDYXNlKVxuICAgIHRoaXMuX3N0cmljdFBhdGhDaGVjayA9ICFhbGxvd1JlbGF0aXZlUGF0aHNcbiAgICB0aGlzLl9pbml0Q2FjaGUoKVxuICB9XG5cbiAgX2luaXRDYWNoZSAoKSB7XG4gICAgLy8gQSBjYWNoZSBmb3IgdGhlIHJlc3VsdCBvZiBgLmlnbm9yZXMoKWBcbiAgICB0aGlzLl9pZ25vcmVDYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbClcblxuICAgIC8vIEEgY2FjaGUgZm9yIHRoZSByZXN1bHQgb2YgYC50ZXN0KClgXG4gICAgdGhpcy5fdGVzdENhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuICB9XG5cbiAgYWRkIChwYXR0ZXJuKSB7XG4gICAgaWYgKHRoaXMuX3J1bGVzLmFkZChwYXR0ZXJuKSkge1xuICAgICAgLy8gU29tZSBydWxlcyBoYXZlIGp1c3QgYWRkZWQgdG8gdGhlIGlnbm9yZSxcbiAgICAgIC8vICAgbWFraW5nIHRoZSBiZWhhdmlvciBjaGFuZ2VkLFxuICAgICAgLy8gICBzbyB3ZSBuZWVkIHRvIHJlLWluaXRpYWxpemUgdGhlIHJlc3VsdCBjYWNoZVxuICAgICAgdGhpcy5faW5pdENhY2hlKClcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgLy8gbGVnYWN5XG4gIGFkZFBhdHRlcm4gKHBhdHRlcm4pIHtcbiAgICByZXR1cm4gdGhpcy5hZGQocGF0dGVybilcbiAgfVxuXG4gIC8vIEByZXR1cm5zIHtUZXN0UmVzdWx0fVxuICBfdGVzdCAob3JpZ2luYWxQYXRoLCBjYWNoZSwgY2hlY2tVbmlnbm9yZWQsIHNsaWNlcykge1xuICAgIGNvbnN0IHBhdGggPSBvcmlnaW5hbFBhdGhcbiAgICAgIC8vIFN1cHBvcnRzIG51bGxhYmxlIHBhdGhcbiAgICAgICYmIGNoZWNrUGF0aC5jb252ZXJ0KG9yaWdpbmFsUGF0aClcblxuICAgIGNoZWNrUGF0aChcbiAgICAgIHBhdGgsXG4gICAgICBvcmlnaW5hbFBhdGgsXG4gICAgICB0aGlzLl9zdHJpY3RQYXRoQ2hlY2tcbiAgICAgICAgPyB0aHJvd0Vycm9yXG4gICAgICAgIDogUkVUVVJOX0ZBTFNFXG4gICAgKVxuXG4gICAgcmV0dXJuIHRoaXMuX3QocGF0aCwgY2FjaGUsIGNoZWNrVW5pZ25vcmVkLCBzbGljZXMpXG4gIH1cblxuICBjaGVja0lnbm9yZSAocGF0aCkge1xuICAgIC8vIElmIHRoZSBwYXRoIGRvZXN0IG5vdCBlbmQgd2l0aCBhIHNsYXNoLCBgLmlnbm9yZXMoKWAgaXMgbXVjaCBlcXVpdmFsZW50XG4gICAgLy8gICB0byBgZ2l0IGNoZWNrLWlnbm9yZWBcbiAgICBpZiAoIVJFR0VYX1RFU1RfVFJBSUxJTkdfU0xBU0gudGVzdChwYXRoKSkge1xuICAgICAgcmV0dXJuIHRoaXMudGVzdChwYXRoKVxuICAgIH1cblxuICAgIGNvbnN0IHNsaWNlcyA9IHBhdGguc3BsaXQoU0xBU0gpLmZpbHRlcihCb29sZWFuKVxuICAgIHNsaWNlcy5wb3AoKVxuXG4gICAgaWYgKHNsaWNlcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHBhcmVudCA9IHRoaXMuX3QoXG4gICAgICAgIHNsaWNlcy5qb2luKFNMQVNIKSArIFNMQVNILFxuICAgICAgICB0aGlzLl90ZXN0Q2FjaGUsXG4gICAgICAgIHRydWUsXG4gICAgICAgIHNsaWNlc1xuICAgICAgKVxuXG4gICAgICBpZiAocGFyZW50Lmlnbm9yZWQpIHtcbiAgICAgICAgcmV0dXJuIHBhcmVudFxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9ydWxlcy50ZXN0KHBhdGgsIGZhbHNlLCBNT0RFX0NIRUNLX0lHTk9SRSlcbiAgfVxuXG4gIF90IChcbiAgICAvLyBUaGUgcGF0aCB0byBiZSB0ZXN0ZWRcbiAgICBwYXRoLFxuXG4gICAgLy8gVGhlIGNhY2hlIGZvciB0aGUgcmVzdWx0IG9mIGEgY2VydGFpbiBjaGVja2luZ1xuICAgIGNhY2hlLFxuXG4gICAgLy8gV2hldGhlciBzaG91bGQgY2hlY2sgaWYgdGhlIHBhdGggaXMgdW5pZ25vcmVkXG4gICAgY2hlY2tVbmlnbm9yZWQsXG5cbiAgICAvLyBUaGUgcGF0aCBzbGljZXNcbiAgICBzbGljZXNcbiAgKSB7XG4gICAgaWYgKHBhdGggaW4gY2FjaGUpIHtcbiAgICAgIHJldHVybiBjYWNoZVtwYXRoXVxuICAgIH1cblxuICAgIGlmICghc2xpY2VzKSB7XG4gICAgICAvLyBwYXRoL3RvL2EuanNcbiAgICAgIC8vIFsncGF0aCcsICd0bycsICdhLmpzJ11cbiAgICAgIHNsaWNlcyA9IHBhdGguc3BsaXQoU0xBU0gpLmZpbHRlcihCb29sZWFuKVxuICAgIH1cblxuICAgIHNsaWNlcy5wb3AoKVxuXG4gICAgLy8gSWYgdGhlIHBhdGggaGFzIG5vIHBhcmVudCBkaXJlY3RvcnksIGp1c3QgdGVzdCBpdFxuICAgIGlmICghc2xpY2VzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGNhY2hlW3BhdGhdID0gdGhpcy5fcnVsZXMudGVzdChwYXRoLCBjaGVja1VuaWdub3JlZCwgTU9ERV9JR05PUkUpXG4gICAgfVxuXG4gICAgY29uc3QgcGFyZW50ID0gdGhpcy5fdChcbiAgICAgIHNsaWNlcy5qb2luKFNMQVNIKSArIFNMQVNILFxuICAgICAgY2FjaGUsXG4gICAgICBjaGVja1VuaWdub3JlZCxcbiAgICAgIHNsaWNlc1xuICAgIClcblxuICAgIC8vIElmIHRoZSBwYXRoIGNvbnRhaW5zIGEgcGFyZW50IGRpcmVjdG9yeSwgY2hlY2sgdGhlIHBhcmVudCBmaXJzdFxuICAgIHJldHVybiBjYWNoZVtwYXRoXSA9IHBhcmVudC5pZ25vcmVkXG4gICAgICAvLyA+IEl0IGlzIG5vdCBwb3NzaWJsZSB0byByZS1pbmNsdWRlIGEgZmlsZSBpZiBhIHBhcmVudCBkaXJlY3Rvcnkgb2ZcbiAgICAgIC8vID4gICB0aGF0IGZpbGUgaXMgZXhjbHVkZWQuXG4gICAgICA/IHBhcmVudFxuICAgICAgOiB0aGlzLl9ydWxlcy50ZXN0KHBhdGgsIGNoZWNrVW5pZ25vcmVkLCBNT0RFX0lHTk9SRSlcbiAgfVxuXG4gIGlnbm9yZXMgKHBhdGgpIHtcbiAgICByZXR1cm4gdGhpcy5fdGVzdChwYXRoLCB0aGlzLl9pZ25vcmVDYWNoZSwgZmFsc2UpLmlnbm9yZWRcbiAgfVxuXG4gIGNyZWF0ZUZpbHRlciAoKSB7XG4gICAgcmV0dXJuIHBhdGggPT4gIXRoaXMuaWdub3JlcyhwYXRoKVxuICB9XG5cbiAgZmlsdGVyIChwYXRocykge1xuICAgIHJldHVybiBtYWtlQXJyYXkocGF0aHMpLmZpbHRlcih0aGlzLmNyZWF0ZUZpbHRlcigpKVxuICB9XG5cbiAgLy8gQHJldHVybnMge1Rlc3RSZXN1bHR9XG4gIHRlc3QgKHBhdGgpIHtcbiAgICByZXR1cm4gdGhpcy5fdGVzdChwYXRoLCB0aGlzLl90ZXN0Q2FjaGUsIHRydWUpXG4gIH1cbn1cblxuY29uc3QgZmFjdG9yeSA9IG9wdGlvbnMgPT4gbmV3IElnbm9yZShvcHRpb25zKVxuXG5jb25zdCBpc1BhdGhWYWxpZCA9IHBhdGggPT5cbiAgY2hlY2tQYXRoKHBhdGggJiYgY2hlY2tQYXRoLmNvbnZlcnQocGF0aCksIHBhdGgsIFJFVFVSTl9GQUxTRSlcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmNvbnN0IHNldHVwV2luZG93cyA9ICgpID0+IHtcbiAgLyogZXNsaW50IG5vLWNvbnRyb2wtcmVnZXg6IFwib2ZmXCIgKi9cbiAgY29uc3QgbWFrZVBvc2l4ID0gc3RyID0+IC9eXFxcXFxcXFxcXD9cXFxcLy50ZXN0KHN0cilcbiAgfHwgL1tcIjw+fFxcdTAwMDAtXFx1MDAxRl0rL3UudGVzdChzdHIpXG4gICAgPyBzdHJcbiAgICA6IHN0ci5yZXBsYWNlKC9cXFxcL2csICcvJylcblxuICBjaGVja1BhdGguY29udmVydCA9IG1ha2VQb3NpeFxuXG4gIC8vICdDOlxcXFxmb28nICAgICA8LSAnQzpcXFxcZm9vJyBoYXMgYmVlbiBjb252ZXJ0ZWQgdG8gJ0M6LydcbiAgLy8gJ2Q6XFxcXGZvbydcbiAgY29uc3QgUkVHRVhfVEVTVF9XSU5ET1dTX1BBVEhfQUJTT0xVVEUgPSAvXlthLXpdOlxcLy9pXG4gIGNoZWNrUGF0aC5pc05vdFJlbGF0aXZlID0gcGF0aCA9PlxuICAgIFJFR0VYX1RFU1RfV0lORE9XU19QQVRIX0FCU09MVVRFLnRlc3QocGF0aClcbiAgICB8fCBpc05vdFJlbGF0aXZlKHBhdGgpXG59XG5cblxuLy8gV2luZG93c1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5pZiAoXG4gIC8vIERldGVjdCBgcHJvY2Vzc2Agc28gdGhhdCBpdCBjYW4gcnVuIGluIGJyb3dzZXJzLlxuICB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCdcbiAgJiYgcHJvY2Vzcy5wbGF0Zm9ybSA9PT0gJ3dpbjMyJ1xuKSB7XG4gIHNldHVwV2luZG93cygpXG59XG5cbi8vIENPTU1PTkpTX0VYUE9SVFMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzID0gZmFjdG9yeVxuXG4vLyBBbHRob3VnaCBpdCBpcyBhbiBhbnRpLXBhdHRlcm4sXG4vLyAgIGl0IGlzIHN0aWxsIHdpZGVseSBtaXN1c2VkIGJ5IGEgbG90IG9mIGxpYnJhcmllcyBpbiBnaXRodWJcbi8vIFJlZjogaHR0cHM6Ly9naXRodWIuY29tL3NlYXJjaD9xPWlnbm9yZS5kZWZhdWx0JTI4JTI5JnR5cGU9Y29kZVxuZmFjdG9yeS5kZWZhdWx0ID0gZmFjdG9yeVxuXG5tb2R1bGUuZXhwb3J0cy5pc1BhdGhWYWxpZCA9IGlzUGF0aFZhbGlkXG5cbi8vIEZvciB0ZXN0aW5nIHB1cnBvc2VzXG5kZWZpbmUobW9kdWxlLmV4cG9ydHMsIFN5bWJvbC5mb3IoJ3NldHVwV2luZG93cycpLCBzZXR1cFdpbmRvd3MpXG4iLCAiaW1wb3J0IGlnbm9yZSBmcm9tIFwiaWdub3JlXCI7XG5cbmZ1bmN0aW9uIGV4cGFuZEJyYWNlcyhwYXR0ZXJuOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG5cdGNvbnN0IGJyYWNlSW5kZXggPSBwYXR0ZXJuLmluZGV4T2YoXCJ7XCIpO1xuXHRpZiAoYnJhY2VJbmRleCA9PT0gLTEpIHJldHVybiBbcGF0dGVybl07XG5cdGNvbnN0IGNsb3NlSW5kZXggPSBwYXR0ZXJuLmluZGV4T2YoXCJ9XCIsIGJyYWNlSW5kZXgpO1xuXHRpZiAoY2xvc2VJbmRleCA9PT0gLTEpIHJldHVybiBbcGF0dGVybl07XG5cblx0Y29uc3QgcHJlZml4ID0gcGF0dGVybi5zbGljZSgwLCBicmFjZUluZGV4KTtcblx0Y29uc3Qgc3VmZml4ID0gcGF0dGVybi5zbGljZShjbG9zZUluZGV4ICsgMSk7XG5cdGNvbnN0IG9wdGlvbnMgPSBwYXR0ZXJuLnNsaWNlKGJyYWNlSW5kZXggKyAxLCBjbG9zZUluZGV4KS5zcGxpdChcIixcIik7XG5cblx0Y29uc3QgcmVzdWx0czogc3RyaW5nW10gPSBbXTtcblx0Zm9yIChjb25zdCBvcHQgb2Ygb3B0aW9ucykge1xuXHRcdHJlc3VsdHMucHVzaCguLi5leHBhbmRCcmFjZXMocHJlZml4ICsgb3B0LnRyaW0oKSArIHN1ZmZpeCkpO1xuXHR9XG5cdHJldHVybiByZXN1bHRzO1xufVxuXG5mdW5jdGlvbiBleHBhbmRQYXR0ZXJucyhwYXR0ZXJuczogc3RyaW5nW10pOiBzdHJpbmdbXSB7XG5cdGNvbnN0IGV4cGFuZGVkOiBzdHJpbmdbXSA9IFtdO1xuXHRmb3IgKGNvbnN0IHAgb2YgcGF0dGVybnMpIHtcblx0XHRleHBhbmRlZC5wdXNoKC4uLmV4cGFuZEJyYWNlcyhwKSk7XG5cdH1cblx0cmV0dXJuIGV4cGFuZGVkO1xufVxuXG5mdW5jdGlvbiB0b1JlbGF0aXZlKGZpbGVQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuXHRjb25zdCBub3JtYWxpemVkID0gZmlsZVBhdGgucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XG5cdHJldHVybiBub3JtYWxpemVkLnN0YXJ0c1dpdGgoXCIvXCIpID8gbm9ybWFsaXplZC5zbGljZSgxKSA6IG5vcm1hbGl6ZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXRjaEdsb2IocGF0dGVybjogc3RyaW5nLCB0YXJnZXQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuXHRpZiAoIXBhdHRlcm4gfHwgIXRhcmdldCkgcmV0dXJuIGZhbHNlO1xuXHRjb25zdCBleHBhbmRlZCA9IGV4cGFuZEJyYWNlcyhwYXR0ZXJuKTtcblx0Y29uc3QgaWcgPSBpZ25vcmUoKS5hZGQoZXhwYW5kZWQpO1xuXHRyZXR1cm4gaWcuaWdub3Jlcyh0b1JlbGF0aXZlKHRhcmdldCkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2hlc0FueUdsb2IoZ2xvYnM6IHN0cmluZ1tdLCBmaWxlUGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG5cdGlmICghZmlsZVBhdGggfHwgZ2xvYnMubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7XG5cdGNvbnN0IGV4cGFuZGVkID0gZXhwYW5kUGF0dGVybnMoZ2xvYnMpO1xuXHRjb25zdCBpZyA9IGlnbm9yZSgpLmFkZChleHBhbmRlZCk7XG5cdHJldHVybiBpZy5pZ25vcmVzKHRvUmVsYXRpdmUoZmlsZVBhdGgpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1hdGNoZXIoZ2xvYnM6IHN0cmluZ1tdKTogKGZpbGVQYXRoOiBzdHJpbmcpID0+IGJvb2xlYW4ge1xuXHRpZiAoZ2xvYnMubGVuZ3RoID09PSAwKSByZXR1cm4gKCkgPT4gZmFsc2U7XG5cdGNvbnN0IGV4cGFuZGVkID0gZXhwYW5kUGF0dGVybnMoZ2xvYnMpO1xuXHRjb25zdCBpZyA9IGlnbm9yZSgpLmFkZChleHBhbmRlZCk7XG5cdHJldHVybiAoZmlsZVBhdGg6IHN0cmluZykgPT4gaWcuaWdub3Jlcyh0b1JlbGF0aXZlKGZpbGVQYXRoKSk7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQ0EsYUFBUyxVQUFXLFNBQVM7QUFDM0IsYUFBTyxNQUFNLFFBQVEs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
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import ignore from "ignore";
|
|
2
|
+
|
|
3
|
+
function expandBraces(pattern: string): string[] {
|
|
4
|
+
const braceIndex = pattern.indexOf("{");
|
|
5
|
+
if (braceIndex === -1) return [pattern];
|
|
6
|
+
const closeIndex = pattern.indexOf("}", braceIndex);
|
|
7
|
+
if (closeIndex === -1) return [pattern];
|
|
8
|
+
|
|
9
|
+
const prefix = pattern.slice(0, braceIndex);
|
|
10
|
+
const suffix = pattern.slice(closeIndex + 1);
|
|
11
|
+
const options = pattern.slice(braceIndex + 1, closeIndex).split(",");
|
|
12
|
+
|
|
13
|
+
const results: string[] = [];
|
|
14
|
+
for (const opt of options) {
|
|
15
|
+
results.push(...expandBraces(prefix + opt.trim() + suffix));
|
|
16
|
+
}
|
|
17
|
+
return results;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function expandPatterns(patterns: string[]): string[] {
|
|
21
|
+
const expanded: string[] = [];
|
|
22
|
+
for (const p of patterns) {
|
|
23
|
+
expanded.push(...expandBraces(p));
|
|
24
|
+
}
|
|
25
|
+
return expanded;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function toRelative(filePath: string): string {
|
|
29
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
30
|
+
return normalized.startsWith("/") ? normalized.slice(1) : normalized;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function matchGlob(pattern: string, target: string): boolean {
|
|
34
|
+
if (!pattern || !target) return false;
|
|
35
|
+
const expanded = expandBraces(pattern);
|
|
36
|
+
const ig = ignore().add(expanded);
|
|
37
|
+
return ig.ignores(toRelative(target));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function matchesAnyGlob(globs: string[], filePath: string): boolean {
|
|
41
|
+
if (!filePath || globs.length === 0) return false;
|
|
42
|
+
const expanded = expandPatterns(globs);
|
|
43
|
+
const ig = ignore().add(expanded);
|
|
44
|
+
return ig.ignores(toRelative(filePath));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function createMatcher(globs: string[]): (filePath: string) => boolean {
|
|
48
|
+
if (globs.length === 0) return () => false;
|
|
49
|
+
const expanded = expandPatterns(globs);
|
|
50
|
+
const ig = ignore().add(expanded);
|
|
51
|
+
return (filePath: string) => ig.ignores(toRelative(filePath));
|
|
52
|
+
}
|