@dyyz1993/pi-coding-agent 0.74.23 → 0.74.25

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.
Files changed (142) hide show
  1. package/dist/extensions/agent-permissions/index.ts +235 -0
  2. package/dist/extensions/ask-tools/index.ts +115 -0
  3. package/dist/extensions/auto-memory/contract.d.ts +51 -0
  4. package/dist/extensions/auto-memory/contract.d.ts.map +1 -0
  5. package/dist/extensions/auto-memory/contract.js +2 -0
  6. package/dist/extensions/auto-memory/contract.js.map +1 -0
  7. package/dist/extensions/auto-memory/contract.ts +56 -0
  8. package/dist/extensions/auto-memory/index.ts +969 -0
  9. package/dist/extensions/auto-memory/prompts.ts +202 -0
  10. package/dist/extensions/auto-memory/skip-rules.ts +297 -0
  11. package/dist/extensions/auto-memory/utils.ts +208 -0
  12. package/dist/extensions/auto-session-title/index.ts +83 -0
  13. package/dist/extensions/bash-ext/contract.d.ts +79 -0
  14. package/dist/extensions/bash-ext/contract.d.ts.map +1 -0
  15. package/dist/extensions/bash-ext/contract.js +2 -0
  16. package/dist/extensions/bash-ext/contract.js.map +1 -0
  17. package/dist/extensions/bash-ext/contract.ts +69 -0
  18. package/dist/extensions/bash-ext/index.ts +858 -0
  19. package/dist/extensions/claude-hooks-compat/config-loader.ts +49 -0
  20. package/dist/extensions/claude-hooks-compat/handler-runner.ts +377 -0
  21. package/dist/extensions/claude-hooks-compat/if-parser.ts +53 -0
  22. package/dist/extensions/claude-hooks-compat/index.ts +178 -0
  23. package/dist/extensions/claude-hooks-compat/matcher.ts +17 -0
  24. package/dist/extensions/claude-hooks-compat/stdin-builder.ts +27 -0
  25. package/dist/extensions/claude-hooks-compat/types.ts +77 -0
  26. package/dist/extensions/compaction-manager/config.ts +47 -0
  27. package/dist/extensions/compaction-manager/context-fold.ts +63 -0
  28. package/dist/extensions/compaction-manager/index.ts +151 -0
  29. package/dist/extensions/compaction-manager/microcompact.ts +49 -0
  30. package/dist/extensions/compaction-manager/reactive.ts +9 -0
  31. package/dist/extensions/compaction-manager/session-memory.ts +48 -0
  32. package/dist/extensions/coordinator/INTEGRATION.md +376 -0
  33. package/dist/extensions/coordinator/handler.test.ts +277 -0
  34. package/dist/extensions/coordinator/handler.ts +189 -0
  35. package/dist/extensions/coordinator/index.ts +261 -0
  36. package/dist/extensions/coordinator/types.d.ts +100 -0
  37. package/dist/extensions/coordinator/types.d.ts.map +1 -0
  38. package/dist/extensions/coordinator/types.js +2 -0
  39. package/dist/extensions/coordinator/types.js.map +1 -0
  40. package/dist/extensions/coordinator/types.ts +72 -0
  41. package/dist/extensions/file-snapshot/index.ts +131 -0
  42. package/dist/extensions/file-time-guard/README.md +133 -0
  43. package/dist/extensions/file-time-guard/config.ts +13 -0
  44. package/dist/extensions/file-time-guard/index.ts +171 -0
  45. package/dist/extensions/hooks-engine/index.ts +117 -0
  46. package/dist/extensions/lsp/lsp/client/file-tracker.ts +70 -0
  47. package/dist/extensions/lsp/lsp/client/registry.ts +305 -0
  48. package/dist/extensions/lsp/lsp/client/runtime.ts +832 -0
  49. package/dist/extensions/lsp/lsp/config/resolver.ts +573 -0
  50. package/dist/extensions/lsp/lsp/contract.d.ts +101 -0
  51. package/dist/extensions/lsp/lsp/contract.d.ts.map +1 -0
  52. package/dist/extensions/lsp/lsp/contract.js +2 -0
  53. package/dist/extensions/lsp/lsp/contract.js.map +1 -0
  54. package/dist/extensions/lsp/lsp/contract.ts +103 -0
  55. package/dist/extensions/lsp/lsp/hooks/agent-end.ts +169 -0
  56. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts +10 -0
  57. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.d.ts.map +1 -0
  58. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js +30 -0
  59. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.js.map +1 -0
  60. package/dist/extensions/lsp/lsp/hooks/diagnostics-mode.ts +41 -0
  61. package/dist/extensions/lsp/lsp/hooks/writethrough.ts +342 -0
  62. package/dist/extensions/lsp/lsp/index.ts +307 -0
  63. package/dist/extensions/lsp/lsp/lsp.test.ts +684 -0
  64. package/dist/extensions/lsp/lsp/monitoring/server-metrics.ts +176 -0
  65. package/dist/extensions/lsp/lsp/tools/lsp-tool.ts +402 -0
  66. package/dist/extensions/lsp/lsp/utils/dependency-resolver.ts +147 -0
  67. package/dist/extensions/lsp/lsp/utils/diagnostics-wait.ts +41 -0
  68. package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts +20 -0
  69. package/dist/extensions/lsp/lsp/utils/lsp-helpers.d.ts.map +1 -0
  70. package/dist/extensions/lsp/lsp/utils/lsp-helpers.js +64 -0
  71. package/dist/extensions/lsp/lsp/utils/lsp-helpers.js.map +1 -0
  72. package/dist/extensions/lsp/lsp/utils/lsp-helpers.ts +76 -0
  73. package/dist/extensions/message-bridge/GUIDE.md +210 -0
  74. package/dist/extensions/message-bridge/index.ts +222 -0
  75. package/dist/extensions/output-guard/index.ts +384 -0
  76. package/dist/extensions/preview/index.ts +278 -0
  77. package/dist/extensions/rules-engine/MATCH_HISTORY_RECONCILIATION.md +111 -0
  78. package/dist/extensions/rules-engine/RULES-ENGINE-GUIDE.md +470 -0
  79. package/dist/extensions/rules-engine/cache.js +232 -0
  80. package/dist/extensions/rules-engine/cache.ts +38 -0
  81. package/dist/extensions/rules-engine/config.js +63 -0
  82. package/dist/extensions/rules-engine/config.ts +70 -0
  83. package/dist/extensions/rules-engine/index.js +1530 -0
  84. package/dist/extensions/rules-engine/index.ts +552 -0
  85. package/dist/extensions/rules-engine/injector.js +68 -0
  86. package/dist/extensions/rules-engine/injector.ts +74 -0
  87. package/dist/extensions/rules-engine/loader.js +179 -0
  88. package/dist/extensions/rules-engine/loader.ts +205 -0
  89. package/dist/extensions/rules-engine/matcher.js +534 -0
  90. package/dist/extensions/rules-engine/matcher.ts +52 -0
  91. package/dist/extensions/rules-engine/types.d.ts +156 -0
  92. package/dist/extensions/rules-engine/types.d.ts.map +1 -0
  93. package/dist/extensions/rules-engine/types.js +2 -0
  94. package/dist/extensions/rules-engine/types.js.map +1 -0
  95. package/dist/extensions/rules-engine/types.ts +169 -0
  96. package/dist/extensions/session-supervisor/checker.ts +116 -0
  97. package/dist/extensions/session-supervisor/config.ts +45 -0
  98. package/dist/extensions/session-supervisor/index.ts +726 -0
  99. package/dist/extensions/session-supervisor/prompts.ts +132 -0
  100. package/dist/extensions/session-supervisor/scheduler.ts +69 -0
  101. package/dist/extensions/session-supervisor/types.ts +215 -0
  102. package/dist/extensions/subagent/README.md +172 -0
  103. package/dist/extensions/subagent/agents/explorer.md +25 -0
  104. package/dist/extensions/subagent/agents/guide.md +27 -0
  105. package/dist/extensions/subagent/agents/planner.md +37 -0
  106. package/dist/extensions/subagent/agents/reviewer.md +35 -0
  107. package/dist/extensions/subagent/agents/scout.md +50 -0
  108. package/dist/extensions/subagent/agents/verification.md +35 -0
  109. package/dist/extensions/subagent/agents/worker.md +24 -0
  110. package/dist/extensions/subagent/agents.ts +25 -0
  111. package/dist/extensions/subagent/index.ts +987 -0
  112. package/dist/extensions/subagent/prompts/implement-and-review.md +10 -0
  113. package/dist/extensions/subagent/prompts/implement.md +10 -0
  114. package/dist/extensions/subagent/prompts/scout-and-plan.md +9 -0
  115. package/dist/extensions/subagent-ext/contract.d.ts +2 -0
  116. package/dist/extensions/subagent-ext/contract.d.ts.map +1 -0
  117. package/dist/extensions/subagent-ext/contract.js +2 -0
  118. package/dist/extensions/subagent-ext/contract.js.map +1 -0
  119. package/dist/extensions/subagent-ext/contract.ts +1 -0
  120. package/dist/extensions/subagent-ext/index.ts +347 -0
  121. package/dist/extensions/subagent-shared/contract.d.ts +25 -0
  122. package/dist/extensions/subagent-shared/contract.d.ts.map +1 -0
  123. package/dist/extensions/subagent-shared/contract.js +2 -0
  124. package/dist/extensions/subagent-shared/contract.js.map +1 -0
  125. package/dist/extensions/subagent-shared/contract.ts +28 -0
  126. package/dist/extensions/subagent-shared/index.ts +4 -0
  127. package/dist/extensions/subagent-shared/render.ts +166 -0
  128. package/dist/extensions/subagent-shared/types.ts +35 -0
  129. package/dist/extensions/subagent-shared/utils.ts +112 -0
  130. package/dist/extensions/subagent-v2/contract.d.ts +2 -0
  131. package/dist/extensions/subagent-v2/contract.d.ts.map +1 -0
  132. package/dist/extensions/subagent-v2/contract.js +2 -0
  133. package/dist/extensions/subagent-v2/contract.js.map +1 -0
  134. package/dist/extensions/subagent-v2/contract.ts +1 -0
  135. package/dist/extensions/subagent-v2/index.ts +599 -0
  136. package/dist/extensions/todo-ext/contract.d.ts +27 -0
  137. package/dist/extensions/todo-ext/contract.d.ts.map +1 -0
  138. package/dist/extensions/todo-ext/contract.js +2 -0
  139. package/dist/extensions/todo-ext/contract.js.map +1 -0
  140. package/dist/extensions/todo-ext/contract.ts +30 -0
  141. package/dist/extensions/todo-ext/index.ts +419 -0
  142. package/package.json +3 -2
@@ -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
+ }