obsidian-dev-utils 76.1.0 → 77.0.0

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 (61) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/dev/main.js +268 -50
  3. package/dist/lib/cjs/library.cjs +1 -1
  4. package/dist/lib/cjs/obsidian/attachment-path.cjs +2 -2
  5. package/dist/lib/cjs/obsidian/attachment-path.d.cts +11 -4
  6. package/dist/lib/cjs/obsidian/case-insensitive-file-index.cjs +238 -0
  7. package/dist/lib/cjs/obsidian/case-insensitive-file-index.d.cts +92 -0
  8. package/dist/lib/cjs/obsidian/components/case-insensitive-file-index-component.cjs +173 -0
  9. package/dist/lib/cjs/obsidian/components/case-insensitive-file-index-component.d.cts +29 -0
  10. package/dist/lib/cjs/obsidian/components/embed-extensions-component.cjs +167 -0
  11. package/dist/lib/cjs/obsidian/components/embed-extensions-component.d.cts +38 -0
  12. package/dist/lib/cjs/obsidian/components/index.cjs +7 -1
  13. package/dist/lib/cjs/obsidian/components/index.d.cts +2 -0
  14. package/dist/lib/cjs/obsidian/components/rename-delete-handler-component.cjs +17 -15
  15. package/dist/lib/cjs/obsidian/file-change.cjs +2 -2
  16. package/dist/lib/cjs/obsidian/file-manager.cjs +4 -4
  17. package/dist/lib/cjs/obsidian/file-system.cjs +20 -19
  18. package/dist/lib/cjs/obsidian/file-system.d.cts +6 -12
  19. package/dist/lib/cjs/obsidian/index.cjs +7 -1
  20. package/dist/lib/cjs/obsidian/index.d.cts +2 -0
  21. package/dist/lib/cjs/obsidian/link.cjs +8 -9
  22. package/dist/lib/cjs/obsidian/vault.cjs +3 -3
  23. package/dist/lib/cjs/obsidian/view-registrar.cjs +156 -0
  24. package/dist/lib/cjs/obsidian/view-registrar.d.cts +39 -0
  25. package/dist/lib/cjs/script-utils/linters/index.cjs +6 -3
  26. package/dist/lib/cjs/script-utils/linters/index.d.cts +1 -0
  27. package/dist/lib/cjs/script-utils/linters/over-exposure.cjs +453 -0
  28. package/dist/lib/cjs/script-utils/linters/over-exposure.d.cts +204 -0
  29. package/dist/lib/esm/library.mjs +1 -1
  30. package/dist/lib/esm/obsidian/attachment-path.d.mts +11 -4
  31. package/dist/lib/esm/obsidian/attachment-path.mjs +2 -2
  32. package/dist/lib/esm/obsidian/case-insensitive-file-index.d.mts +92 -0
  33. package/dist/lib/esm/obsidian/case-insensitive-file-index.mjs +127 -0
  34. package/dist/lib/esm/obsidian/components/case-insensitive-file-index-component.d.mts +29 -0
  35. package/dist/lib/esm/obsidian/components/case-insensitive-file-index-component.mjs +69 -0
  36. package/dist/lib/esm/obsidian/components/embed-extensions-component.d.mts +38 -0
  37. package/dist/lib/esm/obsidian/components/embed-extensions-component.mjs +59 -0
  38. package/dist/lib/esm/obsidian/components/index.d.mts +2 -0
  39. package/dist/lib/esm/obsidian/components/index.mjs +5 -1
  40. package/dist/lib/esm/obsidian/components/rename-delete-handler-component.mjs +17 -15
  41. package/dist/lib/esm/obsidian/file-change.mjs +2 -2
  42. package/dist/lib/esm/obsidian/file-manager.mjs +4 -4
  43. package/dist/lib/esm/obsidian/file-system.d.mts +6 -12
  44. package/dist/lib/esm/obsidian/file-system.mjs +20 -19
  45. package/dist/lib/esm/obsidian/index.d.mts +2 -0
  46. package/dist/lib/esm/obsidian/index.mjs +5 -1
  47. package/dist/lib/esm/obsidian/link.mjs +8 -9
  48. package/dist/lib/esm/obsidian/vault.mjs +3 -3
  49. package/dist/lib/esm/obsidian/view-registrar.d.mts +39 -0
  50. package/dist/lib/esm/obsidian/view-registrar.mjs +48 -0
  51. package/dist/lib/esm/script-utils/linters/index.d.mts +1 -0
  52. package/dist/lib/esm/script-utils/linters/index.mjs +4 -2
  53. package/dist/lib/esm/script-utils/linters/over-exposure.d.mts +204 -0
  54. package/dist/lib/esm/script-utils/linters/over-exposure.mjs +365 -0
  55. package/dist/scripts/linters/over-exposure/find-overexposed.ts +12 -0
  56. package/obsidian/Components/case-insensitive-file-index-component/package.json +6 -0
  57. package/obsidian/Components/embed-extensions-component/package.json +6 -0
  58. package/obsidian/case-insensitive-file-index/package.json +6 -0
  59. package/obsidian/view-registrar/package.json +6 -0
  60. package/package.json +15 -15
  61. package/script-utils/linters/over-exposure/package.json +6 -0
@@ -0,0 +1,365 @@
1
+ /*
2
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
3
+ if you want to view the source, please visit the github repository of this plugin
4
+ */
5
+
6
+ (function initEsm() {
7
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
8
+ if (globalThis.process) {
9
+ return;
10
+ }
11
+
12
+ const browserProcess = {
13
+ browser: true,
14
+ cwd() {
15
+ return '/';
16
+ },
17
+ env: {},
18
+ platform: 'android'
19
+ };
20
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
21
+ globalThis.process = browserProcess;
22
+ })();
23
+
24
+ import {
25
+ canHaveModifiers,
26
+ createDocumentRegistry,
27
+ createLanguageService,
28
+ getDefaultLibFilePath,
29
+ getModifiers,
30
+ isClassDeclaration,
31
+ isClassLike,
32
+ isEnumDeclaration,
33
+ isFunctionDeclaration,
34
+ isGetAccessorDeclaration,
35
+ isIdentifier,
36
+ isInterfaceDeclaration,
37
+ isMethodDeclaration,
38
+ isPropertyDeclaration,
39
+ isSetAccessorDeclaration,
40
+ isSourceFile,
41
+ isTypeAliasDeclaration,
42
+ isVariableStatement,
43
+ ScriptSnapshot,
44
+ SyntaxKind,
45
+ sys
46
+ } from "typescript";
47
+ import { assertNonNullable } from "../../type-guards.mjs";
48
+ import {
49
+ parseTsConfig,
50
+ toCanonical
51
+ } from "../check-project-types.mjs";
52
+ const LIFECYCLE_ALLOWLIST = /* @__PURE__ */ new Set([
53
+ "display",
54
+ "hide",
55
+ "onExternalSettingsChange",
56
+ "onLayoutReady",
57
+ "onload",
58
+ "onloadImpl",
59
+ "onLoadSettings",
60
+ "onSaveSettings",
61
+ "onunload",
62
+ "onunloadImpl"
63
+ ]);
64
+ const MEMBER_EXPOSURE_ORDER = ["private", "protected", "public"];
65
+ const SCOPE_DESCRIPTION = {
66
+ "file-local": "within its own file",
67
+ "private": "inside its own class",
68
+ "protected": "inside its class + subclasses"
69
+ };
70
+ function analyzeOverExposure(params) {
71
+ const { languageService, onProgress, srcFolder } = params;
72
+ const program = languageService.getProgram();
73
+ if (!program) {
74
+ return [];
75
+ }
76
+ const context = {
77
+ checker: program.getTypeChecker(),
78
+ findings: [],
79
+ languageService,
80
+ program
81
+ };
82
+ const sourceFilesToAnalyze = program.getSourceFiles().filter((sourceFile) => {
83
+ const filePath = toCanonical(sourceFile.fileName);
84
+ return isOwnSourceFile(filePath, srcFolder) && !isTestFile(filePath);
85
+ });
86
+ for (const [analyzedFileCount, sourceFile] of sourceFilesToAnalyze.entries()) {
87
+ onProgress?.({
88
+ analyzedFileCount,
89
+ currentFilePath: toCanonical(sourceFile.fileName),
90
+ totalFileCount: sourceFilesToAnalyze.length
91
+ });
92
+ visit(sourceFile);
93
+ }
94
+ return context.findings;
95
+ function visit(node) {
96
+ analyzeMember(node, context);
97
+ analyzeExport(node, context);
98
+ node.forEachChild(visit);
99
+ }
100
+ }
101
+ function createLanguageServiceHost(params) {
102
+ const { compilerOptions, fileNames, fileSystem } = params;
103
+ return {
104
+ directoryExists: (directory) => fileSystem.directoryExists(directory),
105
+ fileExists: (file) => fileSystem.fileExists(file),
106
+ getCompilationSettings: () => compilerOptions,
107
+ getCurrentDirectory: () => fileSystem.getCurrentDirectory(),
108
+ getDefaultLibFileName: (libOptions) => getDefaultLibFilePath(libOptions),
109
+ getDirectories: (directory) => fileSystem.getDirectories(directory),
110
+ getScriptFileNames: () => [...fileNames],
111
+ getScriptSnapshot: (fileName) => {
112
+ const text = fileSystem.readFile(fileName);
113
+ return text === void 0 ? void 0 : ScriptSnapshot.fromString(text);
114
+ },
115
+ getScriptVersion: () => "0",
116
+ readDirectory: (path, extensions, exclude, include, depth) => fileSystem.readDirectory(path, extensions, exclude, include, depth),
117
+ readFile: (file) => fileSystem.readFile(file)
118
+ };
119
+ }
120
+ function createProjectLanguageService(params) {
121
+ const { fileNames, options } = parseTsConfig(params.tsConfigPath);
122
+ return createLanguageService(createLanguageServiceHost({ compilerOptions: options, fileNames, fileSystem: sys }), createDocumentRegistry());
123
+ }
124
+ function findOverExposure(params) {
125
+ const projectFolder = toCanonical(params.projectFolder);
126
+ const languageService = createProjectLanguageService({ tsConfigPath: `${projectFolder}/tsconfig.json` });
127
+ return analyzeOverExposure({
128
+ languageService,
129
+ srcFolder: `${projectFolder}/src`,
130
+ ...params.onProgress ? { onProgress: params.onProgress } : {}
131
+ });
132
+ }
133
+ function formatOverExposureFindings(findings) {
134
+ if (findings.length === 0) {
135
+ return "No over-exposed declarations found.\n";
136
+ }
137
+ const byFile = /* @__PURE__ */ new Map();
138
+ for (const finding of findings) {
139
+ const list = byFile.get(finding.filePath) ?? [];
140
+ list.push(finding);
141
+ byFile.set(finding.filePath, list);
142
+ }
143
+ const lines = [];
144
+ for (const [filePath, list] of byFile) {
145
+ for (const finding of [...list].sort((a, b) => a.line - b.line)) {
146
+ const location = `${filePath}:${String(finding.line)}:${String(finding.column)}`;
147
+ const change = `${finding.currentExposure} ${finding.name} -> ${finding.suggestedExposure}`;
148
+ lines.push(`${location} ${change} -- ${describeReason(finding)}`);
149
+ }
150
+ }
151
+ lines.push("", `${String(findings.length)} finding(s).`);
152
+ return `${lines.join("\n")}
153
+ `;
154
+ }
155
+ function analyzeExport(node, context) {
156
+ const sourceFile = node.getSourceFile();
157
+ if (node.parent !== sourceFile || !getModifierKinds(node).has(SyntaxKind.ExportKeyword)) {
158
+ return;
159
+ }
160
+ const declFilePath = toCanonical(sourceFile.fileName);
161
+ for (const nameNode of getExportedNameNodes(node)) {
162
+ const references = collectReferences(context.languageService.findReferences(sourceFile.fileName, nameNode.getStart())).filter((reference) => !isDeclarationItself(reference, nameNode));
163
+ const otherFileReferences = references.filter((reference) => toCanonical(reference.fileName) !== declFilePath);
164
+ if (otherFileReferences.length === 0) {
165
+ context.findings.push(buildFinding(node, nameNode, "export", "file-local", { hasNoReferences: references.length === 0, isForcedByTestOnly: false }));
166
+ continue;
167
+ }
168
+ const nonTestReferences = otherFileReferences.filter((reference) => !isTestFile(toCanonical(reference.fileName)));
169
+ if (nonTestReferences.length === 0) {
170
+ context.findings.push(buildFinding(node, nameNode, "export", "file-local", { hasNoReferences: false, isForcedByTestOnly: true }));
171
+ }
172
+ }
173
+ }
174
+ function analyzeMember(node, context) {
175
+ const nameNode = getMemberNameNode(node);
176
+ if (!nameNode) {
177
+ return;
178
+ }
179
+ const declaringClass = getEnclosingClass(node);
180
+ if (!declaringClass) {
181
+ return;
182
+ }
183
+ const modifierKinds = getModifierKinds(node);
184
+ if (modifierKinds.has(SyntaxKind.StaticKeyword) || modifierKinds.has(SyntaxKind.OverrideKeyword) || LIFECYCLE_ALLOWLIST.has(nameNode.getText())) {
185
+ return;
186
+ }
187
+ const currentExposure = getCurrentMemberExposure(modifierKinds);
188
+ if (currentExposure === "private") {
189
+ return;
190
+ }
191
+ const sourceFile = node.getSourceFile();
192
+ const references = collectReferences(context.languageService.findReferences(sourceFile.fileName, nameNode.getStart())).filter((reference) => !isDeclarationItself(reference, nameNode));
193
+ const nonTestReferences = references.filter((reference) => !isTestFile(toCanonical(reference.fileName)));
194
+ const neededForSrc = computeNeededExposure(nonTestReferences, declaringClass, context);
195
+ const neededWithTests = computeNeededExposure(references, declaringClass, context);
196
+ if (neededForSrc === "public") {
197
+ return;
198
+ }
199
+ if (rankExposure(neededForSrc) >= rankExposure(currentExposure)) {
200
+ return;
201
+ }
202
+ context.findings.push(buildFinding(node, nameNode, currentExposure, neededForSrc, {
203
+ hasNoReferences: references.length === 0,
204
+ isForcedByTestOnly: rankExposure(neededWithTests) > rankExposure(neededForSrc)
205
+ }));
206
+ }
207
+ function buildFinding(node, nameNode, currentExposure, suggestedExposure, flags) {
208
+ const sourceFile = node.getSourceFile();
209
+ const { character, line } = sourceFile.getLineAndCharacterOfPosition(nameNode.getStart());
210
+ return {
211
+ column: character + 1,
212
+ currentExposure,
213
+ filePath: toCanonical(sourceFile.fileName),
214
+ hasNoReferences: flags.hasNoReferences,
215
+ isForcedByTestOnly: flags.isForcedByTestOnly,
216
+ isMember: currentExposure !== "export",
217
+ line: line + 1,
218
+ name: nameNode.getText(),
219
+ suggestedExposure
220
+ };
221
+ }
222
+ function collectReferences(referencedSymbols) {
223
+ const references = [];
224
+ for (const referencedSymbol of referencedSymbols ?? []) {
225
+ for (const reference of referencedSymbol.references) {
226
+ references.push({ fileName: reference.fileName, start: reference.textSpan.start });
227
+ }
228
+ }
229
+ return references;
230
+ }
231
+ function computeNeededExposure(references, declaringClass, context) {
232
+ if (references.length === 0) {
233
+ return "private";
234
+ }
235
+ let needed = "private";
236
+ for (const reference of references) {
237
+ const referenceClass = getClassAtPosition(context.program, reference.fileName, reference.start);
238
+ if (referenceClass === declaringClass) {
239
+ continue;
240
+ }
241
+ if (referenceClass && isDerivedFrom(referenceClass, declaringClass, context.checker)) {
242
+ needed = "protected";
243
+ continue;
244
+ }
245
+ return "public";
246
+ }
247
+ return needed;
248
+ }
249
+ function describeReason(finding) {
250
+ const base = `referenced only ${SCOPE_DESCRIPTION[finding.suggestedExposure]}`;
251
+ if (finding.isForcedByTestOnly) {
252
+ return `${base} (exposed only for tests)`;
253
+ }
254
+ if (finding.hasNoReferences) {
255
+ return `${base} (no references at all)`;
256
+ }
257
+ return base;
258
+ }
259
+ function findNodeAtPosition(node, position) {
260
+ if (position < node.getStart() || position >= node.getEnd()) {
261
+ return void 0;
262
+ }
263
+ let result = node;
264
+ node.forEachChild((child) => {
265
+ const found = findNodeAtPosition(child, position);
266
+ if (found) {
267
+ result = found;
268
+ }
269
+ });
270
+ return result;
271
+ }
272
+ function getClassAtPosition(program, fileName, position) {
273
+ const sourceFile = program.getSourceFile(fileName);
274
+ assertNonNullable(sourceFile, `Source file not found in program: ${fileName}`);
275
+ const node = findNodeAtPosition(sourceFile, position);
276
+ assertNonNullable(node, `No node found at position ${String(position)} in ${fileName}`);
277
+ return getEnclosingClass(node);
278
+ }
279
+ function getCurrentMemberExposure(modifierKinds) {
280
+ if (modifierKinds.has(SyntaxKind.PrivateKeyword)) {
281
+ return "private";
282
+ }
283
+ if (modifierKinds.has(SyntaxKind.ProtectedKeyword)) {
284
+ return "protected";
285
+ }
286
+ return "public";
287
+ }
288
+ function getEnclosingClass(node) {
289
+ let current = node;
290
+ while (!isSourceFile(current)) {
291
+ if (isClassLike(current)) {
292
+ return current;
293
+ }
294
+ current = current.parent;
295
+ }
296
+ return void 0;
297
+ }
298
+ function getExportedNameNodes(node) {
299
+ if (isFunctionDeclaration(node) || isClassDeclaration(node) || isInterfaceDeclaration(node) || isTypeAliasDeclaration(node) || isEnumDeclaration(node)) {
300
+ return node.name ? [node.name] : [];
301
+ }
302
+ if (isVariableStatement(node)) {
303
+ return node.declarationList.declarations.map((declaration) => declaration.name).filter(isIdentifier);
304
+ }
305
+ return [];
306
+ }
307
+ function getMemberNameNode(node) {
308
+ if (isMethodDeclaration(node) || isPropertyDeclaration(node) || isGetAccessorDeclaration(node) || isSetAccessorDeclaration(node)) {
309
+ return node.name;
310
+ }
311
+ return void 0;
312
+ }
313
+ function getModifierKinds(node) {
314
+ const kinds = /* @__PURE__ */ new Set();
315
+ if (canHaveModifiers(node)) {
316
+ for (const modifier of getModifiers(node) ?? []) {
317
+ kinds.add(modifier.kind);
318
+ }
319
+ }
320
+ return kinds;
321
+ }
322
+ function isDeclarationItself(reference, nameNode) {
323
+ return toCanonical(reference.fileName) === toCanonical(nameNode.getSourceFile().fileName) && reference.start === nameNode.getStart();
324
+ }
325
+ function isDerivedFrom(derived, base, checker) {
326
+ const baseSymbol = base.name ? checker.getSymbolAtLocation(base.name) : void 0;
327
+ if (!baseSymbol) {
328
+ return false;
329
+ }
330
+ for (const clause of derived.heritageClauses ?? []) {
331
+ if (clause.token !== SyntaxKind.ExtendsKeyword) {
332
+ continue;
333
+ }
334
+ for (const typeExpression of clause.types) {
335
+ const symbol = checker.getTypeAtLocation(typeExpression.expression).getSymbol();
336
+ if (symbol === baseSymbol) {
337
+ return true;
338
+ }
339
+ for (const declaration of symbol?.declarations ?? []) {
340
+ if (isClassLike(declaration) && isDerivedFrom(declaration, base, checker)) {
341
+ return true;
342
+ }
343
+ }
344
+ }
345
+ }
346
+ return false;
347
+ }
348
+ function isOwnSourceFile(filePath, srcFolder) {
349
+ return filePath.startsWith(`${srcFolder}/`) && filePath.endsWith(".ts") && !filePath.endsWith(".d.ts");
350
+ }
351
+ function isTestFile(filePath) {
352
+ return filePath.includes(".test.") || filePath.includes(".integration.");
353
+ }
354
+ function rankExposure(exposure) {
355
+ return MEMBER_EXPOSURE_ORDER.indexOf(exposure);
356
+ }
357
+ export {
358
+ LIFECYCLE_ALLOWLIST,
359
+ analyzeOverExposure,
360
+ createLanguageServiceHost,
361
+ createProjectLanguageService,
362
+ findOverExposure,
363
+ formatOverExposureFindings
364
+ };
365
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vc3JjL3NjcmlwdC11dGlscy9saW50ZXJzL292ZXItZXhwb3N1cmUudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBPdmVyLWV4cG9zdXJlIGFuYWx5emVyLlxuICpcbiAqIEZpbmRzIGRlY2xhcmF0aW9ucyBleHBvc2VkIG1vcmUgYnJvYWRseSB0aGFuIHRoZWlyIHJlZmVyZW5jZXMgcmVxdWlyZSwgc28gdGhlIGV4cG9zdXJlIGNhbiBiZVxuICogdGlnaHRlbmVkOlxuICpcbiAqIC0gYGV4cG9ydGBlZCBzeW1ib2xzIHJlZmVyZW5jZWQgb25seSB3aXRoaW4gdGhlaXIgb3duIGZpbGUgXHUyMDE0IHRoZSBgZXhwb3J0YCBjYW4gYmUgZHJvcHBlZC5cbiAqIC0gYHB1YmxpY2AgY2xhc3MgbWVtYmVycyByZWZlcmVuY2VkIG9ubHkgaW5zaWRlIHRoZWlyIG93biBjbGFzcyBcdTIwMTQgdGhleSBjYW4gYmUgYHByaXZhdGVgLlxuICogLSBgcHVibGljYCBjbGFzcyBtZW1iZXJzIHJlZmVyZW5jZWQgb25seSBpbnNpZGUgdGhlaXIgb3duIGNsYXNzIGFuZCBpdHMgc3ViY2xhc3NlcyBcdTIwMTQgdGhleSBjYW4gYmVcbiAqICAgYHByb3RlY3RlZGAuXG4gKiAtIGBwcm90ZWN0ZWRgIGNsYXNzIG1lbWJlcnMgcmVmZXJlbmNlZCBvbmx5IGluc2lkZSB0aGVpciBvd24gY2xhc3MgXHUyMDE0IHRoZXkgY2FuIGJlIGBwcml2YXRlYC5cbiAqXG4gKiBUaGUgYW5hbHlzaXMgaXMgd2hvbGUtcHJvZ3JhbSBhbmQgdHlwZS1hd2FyZTogaXQgdXNlcyB0aGUgVHlwZVNjcmlwdCBsYW5ndWFnZSBzZXJ2aWNlJ3NcbiAqIGZpbmQtYWxsLXJlZmVyZW5jZXMgdG8gbG9jYXRlIGV2ZXJ5IHVzZSBvZiBlYWNoIGRlY2xhcmF0aW9uLCB0aGVuIGNsYXNzaWZpZXMgdGhlIHRpZ2h0ZXN0XG4gKiBleHBvc3VyZSB0aGF0IHN0aWxsIGNvdmVycyBhbGwgcmVmZXJlbmNlcy4gTWVtYmVycyBpbnZva2VkIGJ5IHRoZSBmcmFtZXdvcmsgdmlhIHJlZ2lzdHJhdGlvblxuICogcmF0aGVyIHRoYW4gYnkgdmlzaWJsZSByZWZlcmVuY2VzIChPYnNpZGlhbiBsaWZlY3ljbGUgaG9va3MsIHNldHRpbmdzLXRhYiBgZGlzcGxheWAsIGV0Yy4pIGFyZVxuICogZXhjbHVkZWQgdmlhIHtAbGluayBMSUZFQ1lDTEVfQUxMT1dMSVNUfSwgYXMgYXJlIGBvdmVycmlkZWAgYW5kIGBzdGF0aWNgIG1lbWJlcnMgd2hvc2UgZXhwb3N1cmUgaXNcbiAqIGNvbnN0cmFpbmVkIGJ5IGEgYmFzZSBkZWNsYXJhdGlvbi5cbiAqXG4gKiBBIG1lbWJlciByZWZlcmVuY2VkIG9ubHkgZnJvbSB0ZXN0IGZpbGVzIGlzIHJlcG9ydGVkIHdpdGgge0BsaW5rIE92ZXJFeHBvc3VyZUZpbmRpbmcuaXNGb3JjZWRCeVRlc3RPbmx5fVxuICogc2V0LCBzdXJmYWNpbmcgbWVtYmVycyB3aWRlbmVkIHB1cmVseSBmb3IgdGVzdGFiaWxpdHkgXHUyMDE0IHRoZSBjYW5vbmljYWwgY2FzZSBmb3IgZXh0cmFjdGluZyBsb2dpY1xuICogaW50byBhbiBpbmRlcGVuZGVudGx5IHRlc3RhYmxlIGNvbXBvbmVudCBpbnN0ZWFkLlxuICovXG5cbmltcG9ydCB0eXBlIHtcbiAgQ2xhc3NMaWtlRGVjbGFyYXRpb24sXG4gIENvbXBpbGVyT3B0aW9ucyxcbiAgSVNjcmlwdFNuYXBzaG90LFxuICBMYW5ndWFnZVNlcnZpY2UsXG4gIExhbmd1YWdlU2VydmljZUhvc3QsXG4gIE5vZGUsXG4gIFByb2dyYW0sXG4gIFJlZmVyZW5jZWRTeW1ib2wsXG4gIFR5cGVDaGVja2VyXG59IGZyb20gJ3R5cGVzY3JpcHQnO1xuXG5pbXBvcnQge1xuICBjYW5IYXZlTW9kaWZpZXJzLFxuICBjcmVhdGVEb2N1bWVudFJlZ2lzdHJ5LFxuICBjcmVhdGVMYW5ndWFnZVNlcnZpY2UsXG4gIGdldERlZmF1bHRMaWJGaWxlUGF0aCxcbiAgZ2V0TW9kaWZpZXJzLFxuICBpc0NsYXNzRGVjbGFyYXRpb24sXG4gIGlzQ2xhc3NMaWtlLFxuICBpc0VudW1EZWNsYXJhdGlvbixcbiAgaXNGdW5jdGlvbkRlY2xhcmF0aW9uLFxuICBpc0dldEFjY2Vzc29yRGVjbGFyYXRpb24sXG4gIGlzSWRlbnRpZmllcixcbiAgaXNJbnRlcmZhY2VEZWNsYXJhdGlvbixcbiAgaXNNZXRob2REZWNsYXJhdGlvbixcbiAgaXNQcm9wZXJ0eURlY2xhcmF0aW9uLFxuICBpc1NldEFjY2Vzc29yRGVjbGFyYXRpb24sXG4gIGlzU291cmNlRmlsZSxcbiAgaXNUeXBlQWxpYXNEZWNsYXJhdGlvbixcbiAgaXNWYXJpYWJsZVN0YXRlbWVudCxcbiAgU2NyaXB0U25hcHNob3QsXG4gIFN5bnRheEtpbmQsXG4gIHN5c1xufSBmcm9tICd0eXBlc2NyaXB0JztcblxuaW1wb3J0IHsgYXNzZXJ0Tm9uTnVsbGFibGUgfSBmcm9tICcuLi8uLi90eXBlLWd1YXJkcy50cyc7XG5pbXBvcnQge1xuICBwYXJzZVRzQ29uZmlnLFxuICB0b0Nhbm9uaWNhbFxufSBmcm9tICcuLi9jaGVjay1wcm9qZWN0LXR5cGVzLnRzJztcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgYW5hbHl6ZU92ZXJFeHBvc3VyZX0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQW5hbHl6ZU92ZXJFeHBvc3VyZVBhcmFtcyB7XG4gIC8qKiBUaGUgbGFuZ3VhZ2Ugc2VydmljZSB0byBxdWVyeSBmb3IgcmVmZXJlbmNlcyBhbmQgdHlwZXMuICovXG4gIHJlYWRvbmx5IGxhbmd1YWdlU2VydmljZTogTGFuZ3VhZ2VTZXJ2aWNlO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBjYWxsYmFjayBpbnZva2VkIG9uY2UgcGVyIGFuYWx5emVkIHNvdXJjZSBmaWxlLCBiZWZvcmUgdGhhdCBmaWxlIGlzIHByb2Nlc3NlZC4gVGhlXG4gICAqIHdob2xlLXByb2dyYW0gcmVmZXJlbmNlIGFuYWx5c2lzIGlzIHNsb3csIHNvIHRoaXMgbGV0cyBjYWxsZXJzIHJlcG9ydCBsaXZlIHByb2dyZXNzIGluc3RlYWQgb2ZcbiAgICogYXBwZWFyaW5nIHRvIGhhbmcuXG4gICAqL1xuICBvblByb2dyZXNzPyh0aGlzOiB2b2lkLCBwcm9ncmVzczogT3ZlckV4cG9zdXJlUHJvZ3Jlc3MpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBBYnNvbHV0ZSAoY2Fub25pY2FsKSBwYXRoIG9mIHRoZSBwcm9qZWN0J3MgYHNyY2AgZm9sZGVyLiBPbmx5IGRlY2xhcmF0aW9ucyBpbiBub24tdGVzdCBmaWxlc1xuICAgKiB1bmRlciB0aGlzIGZvbGRlciBhcmUgYW5hbHl6ZWQ7IGRlY2xhcmF0aW9ucyBlbHNld2hlcmUgKHRlc3QgZmlsZXMsIGRlcGVuZGVuY2llcykgYXJlIGlnbm9yZWRcbiAgICogYnV0IHN0aWxsIGNvdW50ZWQgYXMgcmVmZXJlbmNlIHNpdGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgc3JjRm9sZGVyOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGNyZWF0ZUxhbmd1YWdlU2VydmljZUhvc3R9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZUxhbmd1YWdlU2VydmljZUhvc3RQYXJhbXMge1xuICAvKiogVGhlIGNvbXBpbGVyIG9wdGlvbnMuICovXG4gIHJlYWRvbmx5IGNvbXBpbGVyT3B0aW9uczogQ29tcGlsZXJPcHRpb25zO1xuXG4gIC8qKiBUaGUgZmlsZXMgdG8gaW5jbHVkZSBpbiB0aGUgcHJvZ3JhbS4gKi9cbiAgcmVhZG9ubHkgZmlsZU5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcblxuICAvKiogVGhlIGZpbGUtc3lzdGVtIG9wZXJhdGlvbnMgdXNlZCB0byByZWFkIHNvdXJjZXMuICovXG4gIHJlYWRvbmx5IGZpbGVTeXN0ZW06IE92ZXJFeHBvc3VyZUZpbGVTeXN0ZW07XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGNyZWF0ZVByb2plY3RMYW5ndWFnZVNlcnZpY2V9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZVByb2plY3RMYW5ndWFnZVNlcnZpY2VQYXJhbXMge1xuICAvKiogQWJzb2x1dGUgcGF0aCB0byB0aGUgcHJvamVjdCdzIGB0c2NvbmZpZy5qc29uYC4gKi9cbiAgcmVhZG9ubHkgdHNDb25maWdQYXRoOiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIGV4cG9zdXJlIGxldmVsIGEgZGVjbGFyYXRpb24gY3VycmVudGx5IGhhcy5cbiAqL1xuZXhwb3J0IHR5cGUgQ3VycmVudEV4cG9zdXJlID0gJ2V4cG9ydCcgfCAncHJvdGVjdGVkJyB8ICdwdWJsaWMnO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBmaW5kT3ZlckV4cG9zdXJlfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBGaW5kT3ZlckV4cG9zdXJlUGFyYW1zIHtcbiAgLyoqXG4gICAqIE9wdGlvbmFsIGNhbGxiYWNrIGludm9rZWQgb25jZSBwZXIgYW5hbHl6ZWQgc291cmNlIGZpbGUsIGZvciBsaXZlIHByb2dyZXNzIHJlcG9ydGluZy4gRm9yd2FyZGVkXG4gICAqIHRvIHtAbGluayBhbmFseXplT3ZlckV4cG9zdXJlfS5cbiAgICovXG4gIG9uUHJvZ3Jlc3M/KHRoaXM6IHZvaWQsIHByb2dyZXNzOiBPdmVyRXhwb3N1cmVQcm9ncmVzcyk6IHZvaWQ7XG5cbiAgLyoqIEFic29sdXRlIHBhdGggdG8gdGhlIHByb2plY3Qgcm9vdCAodGhlIGZvbGRlciBjb250YWluaW5nIGB0c2NvbmZpZy5qc29uYCBhbmQgYHNyY2ApLiAqL1xuICByZWFkb25seSBwcm9qZWN0Rm9sZGVyOiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIHN1YnNldCBvZiBmaWxlLXN5c3RlbSBvcGVyYXRpb25zIHRoZSBsYW5ndWFnZS1zZXJ2aWNlIGhvc3QgbmVlZHMuIEluamVjdGluZyB0aGlzIChyYXRoZXIgdGhhblxuICogYWx3YXlzIHVzaW5nIGB0eXBlc2NyaXB0YCdzIGBzeXNgKSBsZXRzIHRlc3RzIGRyaXZlIHRoZSBhbmFseXplciBhZ2FpbnN0IGluLW1lbW9yeSBzb3VyY2VzIHdpdGggbm9cbiAqIHJlYWwgZmlsZS1zeXN0ZW0gYWNjZXNzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE92ZXJFeHBvc3VyZUZpbGVTeXN0ZW0ge1xuICAvKipcbiAgICogQHBhcmFtIHBhdGggLSBEaXJlY3RvcnkgcGF0aC5cbiAgICogQHJldHVybnMgYHRydWVgIHdoZW4gdGhlIGRpcmVjdG9yeSBleGlzdHMuXG4gICAqL1xuICBkaXJlY3RvcnlFeGlzdHModGhpczogdm9pZCwgcGF0aDogc3RyaW5nKTogYm9vbGVhbjtcblxuICAvKipcbiAgICogQHBhcmFtIHBhdGggLSBGaWxlIHBhdGguXG4gICAqIEByZXR1cm5zIGB0cnVlYCB3aGVuIHRoZSBmaWxlIGV4aXN0cy5cbiAgICovXG4gIGZpbGVFeGlzdHModGhpczogdm9pZCwgcGF0aDogc3RyaW5nKTogYm9vbGVhbjtcblxuICAvKipcbiAgICogQHJldHVybnMgVGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuXG4gICAqL1xuICBnZXRDdXJyZW50RGlyZWN0b3J5KHRoaXM6IHZvaWQpOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBwYXRoIC0gRGlyZWN0b3J5IHBhdGguXG4gICAqIEByZXR1cm5zIFRoZSBpbW1lZGlhdGUgc3ViZGlyZWN0b3J5IG5hbWVzLlxuICAgKi9cbiAgZ2V0RGlyZWN0b3JpZXModGhpczogdm9pZCwgcGF0aDogc3RyaW5nKTogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBwYXRoIC0gUm9vdCBkaXJlY3RvcnkuXG4gICAqIEBwYXJhbSBleHRlbnNpb25zIC0gRXh0ZW5zaW9ucyB0byBpbmNsdWRlLlxuICAgKiBAcGFyYW0gZXhjbHVkZSAtIFBhdHRlcm5zIHRvIGV4Y2x1ZGUuXG4gICAqIEBwYXJhbSBpbmNsdWRlIC0gUGF0dGVybnMgdG8gaW5jbHVkZS5cbiAgICogQHBhcmFtIGRlcHRoIC0gTWF4aW11bSByZWN1cnNpb24gZGVwdGguXG4gICAqIEByZXR1cm5zIFRoZSBtYXRjaGluZyBmaWxlIHBhdGhzLlxuICAgKi9cbiAgcmVhZERpcmVjdG9yeSh0aGlzOiB2b2lkLCBwYXRoOiBzdHJpbmcsIGV4dGVuc2lvbnM/OiByZWFkb25seSBzdHJpbmdbXSwgZXhjbHVkZT86IHJlYWRvbmx5IHN0cmluZ1tdLCBpbmNsdWRlPzogcmVhZG9ubHkgc3RyaW5nW10sIGRlcHRoPzogbnVtYmVyKTogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBwYXRoIC0gRmlsZSBwYXRoLlxuICAgKiBAcmV0dXJucyBUaGUgZmlsZSBjb250ZW50cywgb3IgYHVuZGVmaW5lZGAgd2hlbiBhYnNlbnQuXG4gICAqL1xuICByZWFkRmlsZSh0aGlzOiB2b2lkLCBwYXRoOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQSBzaW5nbGUgb3Zlci1leHBvc2VkIGRlY2xhcmF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE92ZXJFeHBvc3VyZUZpbmRpbmcge1xuICAvKiogMS1iYXNlZCBjb2x1bW4gb2YgdGhlIGRlY2xhcmF0aW9uJ3MgbmFtZS4gKi9cbiAgcmVhZG9ubHkgY29sdW1uOiBudW1iZXI7XG5cbiAgLyoqIFRoZSBjdXJyZW50IGV4cG9zdXJlIGxldmVsLiAqL1xuICByZWFkb25seSBjdXJyZW50RXhwb3N1cmU6IEN1cnJlbnRFeHBvc3VyZTtcblxuICAvKiogQWJzb2x1dGUgcGF0aCBvZiB0aGUgZmlsZSBkZWNsYXJpbmcgdGhlIHN5bWJvbC4gKi9cbiAgcmVhZG9ubHkgZmlsZVBhdGg6IHN0cmluZztcblxuICAvKiogYHRydWVgIHdoZW4gdGhlIGRlY2xhcmF0aW9uIGhhcyBubyByZWZlcmVuY2VzIGF0IGFsbCAoYmVzaWRlcyBpdHNlbGYpLiAqL1xuICByZWFkb25seSBoYXNOb1JlZmVyZW5jZXM6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIGB0cnVlYCB3aGVuIHRoZSBkZWNsYXJhdGlvbiB3b3VsZCBxdWFsaWZ5IGZvciBhIHRpZ2h0ZXIgZXhwb3N1cmUgaWYgbm90IGZvciByZWZlcmVuY2VzIGNvbWluZ1xuICAgKiBleGNsdXNpdmVseSBmcm9tIHRlc3QgZmlsZXMgXHUyMDE0IGkuZS4gaXQgaXMgZXhwb3NlZCBwdXJlbHkgZm9yIHRlc3RhYmlsaXR5LlxuICAgKi9cbiAgcmVhZG9ubHkgaXNGb3JjZWRCeVRlc3RPbmx5OiBib29sZWFuO1xuXG4gIC8qKiBgdHJ1ZWAgZm9yIGEgY2xhc3MgbWVtYmVyLCBgZmFsc2VgIGZvciBhIHRvcC1sZXZlbCBleHBvcnQuICovXG4gIHJlYWRvbmx5IGlzTWVtYmVyOiBib29sZWFuO1xuXG4gIC8qKiAxLWJhc2VkIGxpbmUgb2YgdGhlIGRlY2xhcmF0aW9uJ3MgbmFtZS4gKi9cbiAgcmVhZG9ubHkgbGluZTogbnVtYmVyO1xuXG4gIC8qKiBUaGUgZGVjbGFyZWQgbmFtZS4gKi9cbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuXG4gIC8qKiBUaGUgZXhwb3N1cmUgdGhlIGRlY2xhcmF0aW9uIGNvdWxkIGJlIHRpZ2h0ZW5lZCB0by4gKi9cbiAgcmVhZG9ubHkgc3VnZ2VzdGVkRXhwb3N1cmU6IFN1Z2dlc3RlZEV4cG9zdXJlO1xufVxuXG4vKipcbiAqIFByb2dyZXNzIHJlcG9ydGVkIHdoaWxlIGFuYWx5emluZyBhIHByb2plY3QsIG9uZSBldmVudCBwZXIgYW5hbHl6ZWQgc291cmNlIGZpbGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3ZlckV4cG9zdXJlUHJvZ3Jlc3Mge1xuICAvKiogTnVtYmVyIG9mIHNvdXJjZSBmaWxlcyBmdWxseSBhbmFseXplZCBiZWZvcmUgdGhlIGN1cnJlbnQgb25lICgwLWJhc2VkKS4gKi9cbiAgcmVhZG9ubHkgYW5hbHl6ZWRGaWxlQ291bnQ6IG51bWJlcjtcblxuICAvKiogQWJzb2x1dGUgKGNhbm9uaWNhbCkgcGF0aCBvZiB0aGUgc291cmNlIGZpbGUgYWJvdXQgdG8gYmUgYW5hbHl6ZWQuICovXG4gIHJlYWRvbmx5IGN1cnJlbnRGaWxlUGF0aDogc3RyaW5nO1xuXG4gIC8qKiBUb3RhbCBudW1iZXIgb2Ygc291cmNlIGZpbGVzIHRoYXQgd2lsbCBiZSBhbmFseXplZC4gKi9cbiAgcmVhZG9ubHkgdG90YWxGaWxlQ291bnQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBUaGUgKHRpZ2h0ZXIpIGV4cG9zdXJlIGxldmVsIGEgZGVjbGFyYXRpb24gY291bGQgYmUgcmVkdWNlZCB0by5cbiAqL1xuZXhwb3J0IHR5cGUgU3VnZ2VzdGVkRXhwb3N1cmUgPSAnZmlsZS1sb2NhbCcgfCAncHJpdmF0ZScgfCAncHJvdGVjdGVkJztcblxuLyoqXG4gKiBMaWZlY3ljbGUgYW5kIGZyYW1ld29yayBtZW1iZXJzIGludm9rZWQgYnkgT2JzaWRpYW4gb3IgYSBiYXNlIGNsYXNzIHZpYSByZWdpc3RyYXRpb24gcmF0aGVyIHRoYW5cbiAqIGJ5IHJlZmVyZW5jZXMgdGhlIGxhbmd1YWdlIHNlcnZpY2UgY2FuIHNlZS4gVGlnaHRlbmluZyB0aGVzZSB3b3VsZCBicmVhayB0aGUgZnJhbWV3b3JrIGNvbnRyYWN0LFxuICogc28gdGhleSBhcmUgbmV2ZXIgcmVwb3J0ZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBMSUZFQ1lDTEVfQUxMT1dMSVNUOiBSZWFkb25seVNldDxzdHJpbmc+ID0gbmV3IFNldDxzdHJpbmc+KFtcbiAgJ2Rpc3BsYXknLFxuICAnaGlkZScsXG4gICdvbkV4dGVybmFsU2V0dGluZ3NDaGFuZ2UnLFxuICAnb25MYXlvdXRSZWFkeScsXG4gICdvbmxvYWQnLFxuICAnb25sb2FkSW1wbCcsXG4gICdvbkxvYWRTZXR0aW5ncycsXG4gICdvblNhdmVTZXR0aW5ncycsXG4gICdvbnVubG9hZCcsXG4gICdvbnVubG9hZEltcGwnXG5dKTtcblxuaW50ZXJmYWNlIEFuYWx5c2lzQ29udGV4dCB7XG4gIHJlYWRvbmx5IGNoZWNrZXI6IFR5cGVDaGVja2VyO1xuICByZWFkb25seSBmaW5kaW5nczogT3ZlckV4cG9zdXJlRmluZGluZ1tdO1xuICByZWFkb25seSBsYW5ndWFnZVNlcnZpY2U6IExhbmd1YWdlU2VydmljZTtcbiAgcmVhZG9ubHkgcHJvZ3JhbTogUHJvZ3JhbTtcbn1cblxuaW50ZXJmYWNlIEZpbmRpbmdGbGFncyB7XG4gIHJlYWRvbmx5IGhhc05vUmVmZXJlbmNlczogYm9vbGVhbjtcbiAgcmVhZG9ubHkgaXNGb3JjZWRCeVRlc3RPbmx5OiBib29sZWFuO1xufVxuXG50eXBlIE1lbWJlckV4cG9zdXJlID0gJ3ByaXZhdGUnIHwgJ3Byb3RlY3RlZCcgfCAncHVibGljJztcblxuaW50ZXJmYWNlIFJlZmVyZW5jZUxvY2F0aW9uIHtcbiAgcmVhZG9ubHkgZmlsZU5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgc3RhcnQ6IG51bWJlcjtcbn1cblxuY29uc3QgTUVNQkVSX0VYUE9TVVJFX09SREVSOiByZWFkb25seSBNZW1iZXJFeHBvc3VyZVtdID0gWydwcml2YXRlJywgJ3Byb3RlY3RlZCcsICdwdWJsaWMnXTtcbmNvbnN0IFNDT1BFX0RFU0NSSVBUSU9OOiBSZWNvcmQ8U3VnZ2VzdGVkRXhwb3N1cmUsIHN0cmluZz4gPSB7XG4gICdmaWxlLWxvY2FsJzogJ3dpdGhpbiBpdHMgb3duIGZpbGUnLFxuICAncHJpdmF0ZSc6ICdpbnNpZGUgaXRzIG93biBjbGFzcycsXG4gICdwcm90ZWN0ZWQnOiAnaW5zaWRlIGl0cyBjbGFzcyArIHN1YmNsYXNzZXMnXG59O1xuXG4vKipcbiAqIEFuYWx5emVzIGEgcHJvamVjdCAoYWxyZWFkeSBsb2FkZWQgaW50byBhIGxhbmd1YWdlIHNlcnZpY2UpIGZvciBvdmVyLWV4cG9zZWQgZGVjbGFyYXRpb25zLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUge0BsaW5rIEFuYWx5emVPdmVyRXhwb3N1cmVQYXJhbXN9LlxuICogQHJldHVybnMgVGhlIG92ZXItZXhwb3NlZCBkZWNsYXJhdGlvbnMsIGluIGRpc2NvdmVyeSBvcmRlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFuYWx5emVPdmVyRXhwb3N1cmUocGFyYW1zOiBBbmFseXplT3ZlckV4cG9zdXJlUGFyYW1zKTogT3ZlckV4cG9zdXJlRmluZGluZ1tdIHtcbiAgY29uc3QgeyBsYW5ndWFnZVNlcnZpY2UsIG9uUHJvZ3Jlc3MsIHNyY0ZvbGRlciB9ID0gcGFyYW1zO1xuICBjb25zdCBwcm9ncmFtID0gbGFuZ3VhZ2VTZXJ2aWNlLmdldFByb2dyYW0oKTtcbiAgaWYgKCFwcm9ncmFtKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgY29uc3QgY29udGV4dDogQW5hbHlzaXNDb250ZXh0ID0ge1xuICAgIGNoZWNrZXI6IHByb2dyYW0uZ2V0VHlwZUNoZWNrZXIoKSxcbiAgICBmaW5kaW5nczogW10sXG4gICAgbGFuZ3VhZ2VTZXJ2aWNlLFxuICAgIHByb2dyYW1cbiAgfTtcblxuICBjb25zdCBzb3VyY2VGaWxlc1RvQW5hbHl6ZSA9IHByb2dyYW0uZ2V0U291cmNlRmlsZXMoKS5maWx0ZXIoKHNvdXJjZUZpbGUpID0+IHtcbiAgICBjb25zdCBmaWxlUGF0aCA9IHRvQ2Fub25pY2FsKHNvdXJjZUZpbGUuZmlsZU5hbWUpO1xuICAgIHJldHVybiBpc093blNvdXJjZUZpbGUoZmlsZVBhdGgsIHNyY0ZvbGRlcikgJiYgIWlzVGVzdEZpbGUoZmlsZVBhdGgpO1xuICB9KTtcblxuICBmb3IgKGNvbnN0IFthbmFseXplZEZpbGVDb3VudCwgc291cmNlRmlsZV0gb2Ygc291cmNlRmlsZXNUb0FuYWx5emUuZW50cmllcygpKSB7XG4gICAgb25Qcm9ncmVzcz8uKHtcbiAgICAgIGFuYWx5emVkRmlsZUNvdW50LFxuICAgICAgY3VycmVudEZpbGVQYXRoOiB0b0Nhbm9uaWNhbChzb3VyY2VGaWxlLmZpbGVOYW1lKSxcbiAgICAgIHRvdGFsRmlsZUNvdW50OiBzb3VyY2VGaWxlc1RvQW5hbHl6ZS5sZW5ndGhcbiAgICB9KTtcbiAgICB2aXNpdChzb3VyY2VGaWxlKTtcbiAgfVxuICByZXR1cm4gY29udGV4dC5maW5kaW5ncztcblxuICBmdW5jdGlvbiB2aXNpdChub2RlOiBOb2RlKTogdm9pZCB7XG4gICAgYW5hbHl6ZU1lbWJlcihub2RlLCBjb250ZXh0KTtcbiAgICBhbmFseXplRXhwb3J0KG5vZGUsIGNvbnRleHQpO1xuICAgIG5vZGUuZm9yRWFjaENoaWxkKHZpc2l0KTtcbiAgfVxufVxuXG4vKipcbiAqIEJ1aWxkcyBhIHtAbGluayBMYW5ndWFnZVNlcnZpY2VIb3N0fSBiYWNrZWQgYnkgYW4gZXhwbGljaXQgZmlsZSBsaXN0IGFuZCBmaWxlIHN5c3RlbS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHtAbGluayBDcmVhdGVMYW5ndWFnZVNlcnZpY2VIb3N0UGFyYW1zfS5cbiAqIEByZXR1cm5zIFRoZSBsYW5ndWFnZS1zZXJ2aWNlIGhvc3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVMYW5ndWFnZVNlcnZpY2VIb3N0KHBhcmFtczogQ3JlYXRlTGFuZ3VhZ2VTZXJ2aWNlSG9zdFBhcmFtcyk6IExhbmd1YWdlU2VydmljZUhvc3Qge1xuICBjb25zdCB7IGNvbXBpbGVyT3B0aW9ucywgZmlsZU5hbWVzLCBmaWxlU3lzdGVtIH0gPSBwYXJhbXM7XG4gIHJldHVybiB7XG4gICAgZGlyZWN0b3J5RXhpc3RzOiAoZGlyZWN0b3J5KSA9PiBmaWxlU3lzdGVtLmRpcmVjdG9yeUV4aXN0cyhkaXJlY3RvcnkpLFxuICAgIGZpbGVFeGlzdHM6IChmaWxlKSA9PiBmaWxlU3lzdGVtLmZpbGVFeGlzdHMoZmlsZSksXG4gICAgZ2V0Q29tcGlsYXRpb25TZXR0aW5nczogKCkgPT4gY29tcGlsZXJPcHRpb25zLFxuICAgIGdldEN1cnJlbnREaXJlY3Rvcnk6ICgpID0+IGZpbGVTeXN0ZW0uZ2V0Q3VycmVudERpcmVjdG9yeSgpLFxuICAgIGdldERlZmF1bHRMaWJGaWxlTmFtZTogKGxpYk9wdGlvbnMpID0+IGdldERlZmF1bHRMaWJGaWxlUGF0aChsaWJPcHRpb25zKSxcbiAgICBnZXREaXJlY3RvcmllczogKGRpcmVjdG9yeSkgPT4gZmlsZVN5c3RlbS5nZXREaXJlY3RvcmllcyhkaXJlY3RvcnkpLFxuICAgIGdldFNjcmlwdEZpbGVOYW1lczogKCkgPT4gWy4uLmZpbGVOYW1lc10sXG4gICAgZ2V0U2NyaXB0U25hcHNob3Q6IChmaWxlTmFtZSk6IElTY3JpcHRTbmFwc2hvdCB8IHVuZGVmaW5lZCA9PiB7XG4gICAgICBjb25zdCB0ZXh0ID0gZmlsZVN5c3RlbS5yZWFkRmlsZShmaWxlTmFtZSk7XG4gICAgICByZXR1cm4gdGV4dCA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogU2NyaXB0U25hcHNob3QuZnJvbVN0cmluZyh0ZXh0KTtcbiAgICB9LFxuICAgIGdldFNjcmlwdFZlcnNpb246ICgpID0+ICcwJyxcbiAgICByZWFkRGlyZWN0b3J5OiAocGF0aCwgZXh0ZW5zaW9ucywgZXhjbHVkZSwgaW5jbHVkZSwgZGVwdGgpID0+IGZpbGVTeXN0ZW0ucmVhZERpcmVjdG9yeShwYXRoLCBleHRlbnNpb25zLCBleGNsdWRlLCBpbmNsdWRlLCBkZXB0aCksXG4gICAgcmVhZEZpbGU6IChmaWxlKSA9PiBmaWxlU3lzdGVtLnJlYWRGaWxlKGZpbGUpXG4gIH07XG59XG5cbi8qKlxuICogQnVpbGRzIGEgbGFuZ3VhZ2Ugc2VydmljZSBvdmVyIGV2ZXJ5IGZpbGUgaW4gYSBwcm9qZWN0J3MgYHRzY29uZmlnLmpzb25gLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUge0BsaW5rIENyZWF0ZVByb2plY3RMYW5ndWFnZVNlcnZpY2VQYXJhbXN9LlxuICogQHJldHVybnMgQSBsYW5ndWFnZSBzZXJ2aWNlIHJlYWR5IGZvciB7QGxpbmsgYW5hbHl6ZU92ZXJFeHBvc3VyZX0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQcm9qZWN0TGFuZ3VhZ2VTZXJ2aWNlKHBhcmFtczogQ3JlYXRlUHJvamVjdExhbmd1YWdlU2VydmljZVBhcmFtcyk6IExhbmd1YWdlU2VydmljZSB7XG4gIGNvbnN0IHsgZmlsZU5hbWVzLCBvcHRpb25zIH0gPSBwYXJzZVRzQ29uZmlnKHBhcmFtcy50c0NvbmZpZ1BhdGgpO1xuICByZXR1cm4gY3JlYXRlTGFuZ3VhZ2VTZXJ2aWNlKGNyZWF0ZUxhbmd1YWdlU2VydmljZUhvc3QoeyBjb21waWxlck9wdGlvbnM6IG9wdGlvbnMsIGZpbGVOYW1lcywgZmlsZVN5c3RlbTogc3lzIH0pLCBjcmVhdGVEb2N1bWVudFJlZ2lzdHJ5KCkpO1xufVxuXG4vKipcbiAqIEZpbmRzIG92ZXItZXhwb3NlZCBkZWNsYXJhdGlvbnMgaW4gYSBwcm9qZWN0IG9uIGRpc2suXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSB7QGxpbmsgRmluZE92ZXJFeHBvc3VyZVBhcmFtc30uXG4gKiBAcmV0dXJucyBUaGUgb3Zlci1leHBvc2VkIGRlY2xhcmF0aW9ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRPdmVyRXhwb3N1cmUocGFyYW1zOiBGaW5kT3ZlckV4cG9zdXJlUGFyYW1zKTogT3ZlckV4cG9zdXJlRmluZGluZ1tdIHtcbiAgY29uc3QgcHJvamVjdEZvbGRlciA9IHRvQ2Fub25pY2FsKHBhcmFtcy5wcm9qZWN0Rm9sZGVyKTtcbiAgY29uc3QgbGFuZ3VhZ2VTZXJ2aWNlID0gY3JlYXRlUHJvamVjdExhbmd1YWdlU2VydmljZSh7IHRzQ29uZmlnUGF0aDogYCR7cHJvamVjdEZvbGRlcn0vdHNjb25maWcuanNvbmAgfSk7XG4gIHJldHVybiBhbmFseXplT3ZlckV4cG9zdXJlKHtcbiAgICBsYW5ndWFnZVNlcnZpY2UsXG4gICAgc3JjRm9sZGVyOiBgJHtwcm9qZWN0Rm9sZGVyfS9zcmNgLFxuICAgIC4uLnBhcmFtcy5vblByb2dyZXNzID8geyBvblByb2dyZXNzOiBwYXJhbXMub25Qcm9ncmVzcyB9IDoge31cbiAgfSk7XG59XG5cbi8qKlxuICogRm9ybWF0cyBvdmVyLWV4cG9zdXJlIGZpbmRpbmdzIGFzIGEgaHVtYW4tcmVhZGFibGUgcmVwb3J0LiBGaW5kaW5ncyBhcmUgZ3JvdXBlZCBieSBmaWxlIGFuZCBlYWNoXG4gKiBsaW5lIGJlZ2lucyB3aXRoIGEgYHBhdGg6bGluZTpjb2x1bW5gIGxvY2F0aW9uIHNvIHRlcm1pbmFscyAoZS5nLiBWUyBDb2RlKSByZW5kZXIgaXQgYXMgYVxuICogY2xpY2thYmxlIGxpbmsgdGhhdCBqdW1wcyB0byB0aGUgZGVjbGFyYXRpb24uXG4gKlxuICogQHBhcmFtIGZpbmRpbmdzIC0gVGhlIGZpbmRpbmdzIHRvIGZvcm1hdC5cbiAqIEByZXR1cm5zIFRoZSByZXBvcnQgdGV4dC4gRW1wdHktZmluZGluZyBpbnB1dCB5aWVsZHMgYSBzaW5nbGUgXCJubyBmaW5kaW5nc1wiIGxpbmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRPdmVyRXhwb3N1cmVGaW5kaW5ncyhmaW5kaW5nczogcmVhZG9ubHkgT3ZlckV4cG9zdXJlRmluZGluZ1tdKTogc3RyaW5nIHtcbiAgaWYgKGZpbmRpbmdzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiAnTm8gb3Zlci1leHBvc2VkIGRlY2xhcmF0aW9ucyBmb3VuZC5cXG4nO1xuICB9XG5cbiAgY29uc3QgYnlGaWxlID0gbmV3IE1hcDxzdHJpbmcsIE92ZXJFeHBvc3VyZUZpbmRpbmdbXT4oKTtcbiAgZm9yIChjb25zdCBmaW5kaW5nIG9mIGZpbmRpbmdzKSB7XG4gICAgY29uc3QgbGlzdCA9IGJ5RmlsZS5nZXQoZmluZGluZy5maWxlUGF0aCkgPz8gW107XG4gICAgbGlzdC5wdXNoKGZpbmRpbmcpO1xuICAgIGJ5RmlsZS5zZXQoZmluZGluZy5maWxlUGF0aCwgbGlzdCk7XG4gIH1cblxuICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXTtcbiAgZm9yIChjb25zdCBbZmlsZVBhdGgsIGxpc3RdIG9mIGJ5RmlsZSkge1xuICAgIGZvciAoY29uc3QgZmluZGluZyBvZiBbLi4ubGlzdF0uc29ydCgoYSwgYikgPT4gYS5saW5lIC0gYi5saW5lKSkge1xuICAgICAgY29uc3QgbG9jYXRpb24gPSBgJHtmaWxlUGF0aH06JHtTdHJpbmcoZmluZGluZy5saW5lKX06JHtTdHJpbmcoZmluZGluZy5jb2x1bW4pfWA7XG4gICAgICBjb25zdCBjaGFuZ2UgPSBgJHtmaW5kaW5nLmN1cnJlbnRFeHBvc3VyZX0gJHtmaW5kaW5nLm5hbWV9IC0+ICR7ZmluZGluZy5zdWdnZXN0ZWRFeHBvc3VyZX1gO1xuICAgICAgbGluZXMucHVzaChgJHtsb2NhdGlvbn0gJHtjaGFuZ2V9IC0tICR7ZGVzY3JpYmVSZWFzb24oZmluZGluZyl9YCk7XG4gICAgfVxuICB9XG4gIGxpbmVzLnB1c2goJycsIGAke1N0cmluZyhmaW5kaW5ncy5sZW5ndGgpfSBmaW5kaW5nKHMpLmApO1xuICByZXR1cm4gYCR7bGluZXMuam9pbignXFxuJyl9XFxuYDtcbn1cblxuZnVuY3Rpb24gYW5hbHl6ZUV4cG9ydChub2RlOiBOb2RlLCBjb250ZXh0OiBBbmFseXNpc0NvbnRleHQpOiB2b2lkIHtcbiAgY29uc3Qgc291cmNlRmlsZSA9IG5vZGUuZ2V0U291cmNlRmlsZSgpO1xuICBpZiAobm9kZS5wYXJlbnQgIT09IHNvdXJjZUZpbGUgfHwgIWdldE1vZGlmaWVyS2luZHMobm9kZSkuaGFzKFN5bnRheEtpbmQuRXhwb3J0S2V5d29yZCkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBkZWNsRmlsZVBhdGggPSB0b0Nhbm9uaWNhbChzb3VyY2VGaWxlLmZpbGVOYW1lKTtcbiAgZm9yIChjb25zdCBuYW1lTm9kZSBvZiBnZXRFeHBvcnRlZE5hbWVOb2Rlcyhub2RlKSkge1xuICAgIGNvbnN0IHJlZmVyZW5jZXMgPSBjb2xsZWN0UmVmZXJlbmNlcyhjb250ZXh0Lmxhbmd1YWdlU2VydmljZS5maW5kUmVmZXJlbmNlcyhzb3VyY2VGaWxlLmZpbGVOYW1lLCBuYW1lTm9kZS5nZXRTdGFydCgpKSlcbiAgICAgIC5maWx0ZXIoKHJlZmVyZW5jZSkgPT4gIWlzRGVjbGFyYXRpb25JdHNlbGYocmVmZXJlbmNlLCBuYW1lTm9kZSkpO1xuICAgIGNvbnN0IG90aGVyRmlsZVJlZmVyZW5jZXMgPSByZWZlcmVuY2VzLmZpbHRlcigocmVmZXJlbmNlKSA9PiB0b0Nhbm9uaWNhbChyZWZlcmVuY2UuZmlsZU5hbWUpICE9PSBkZWNsRmlsZVBhdGgpO1xuXG4gICAgaWYgKG90aGVyRmlsZVJlZmVyZW5jZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb250ZXh0LmZpbmRpbmdzLnB1c2goYnVpbGRGaW5kaW5nKG5vZGUsIG5hbWVOb2RlLCAnZXhwb3J0JywgJ2ZpbGUtbG9jYWwnLCB7IGhhc05vUmVmZXJlbmNlczogcmVmZXJlbmNlcy5sZW5ndGggPT09IDAsIGlzRm9yY2VkQnlUZXN0T25seTogZmFsc2UgfSkpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY29uc3Qgbm9uVGVzdFJlZmVyZW5jZXMgPSBvdGhlckZpbGVSZWZlcmVuY2VzLmZpbHRlcigocmVmZXJlbmNlKSA9PiAhaXNUZXN0RmlsZSh0b0Nhbm9uaWNhbChyZWZlcmVuY2UuZmlsZU5hbWUpKSk7XG4gICAgaWYgKG5vblRlc3RSZWZlcmVuY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgY29udGV4dC5maW5kaW5ncy5wdXNoKGJ1aWxkRmluZGluZyhub2RlLCBuYW1lTm9kZSwgJ2V4cG9ydCcsICdmaWxlLWxvY2FsJywgeyBoYXNOb1JlZmVyZW5jZXM6IGZhbHNlLCBpc0ZvcmNlZEJ5VGVzdE9ubHk6IHRydWUgfSkpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhbmFseXplTWVtYmVyKG5vZGU6IE5vZGUsIGNvbnRleHQ6IEFuYWx5c2lzQ29udGV4dCk6IHZvaWQge1xuICBjb25zdCBuYW1lTm9kZSA9IGdldE1lbWJlck5hbWVOb2RlKG5vZGUpO1xuICBpZiAoIW5hbWVOb2RlKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IGRlY2xhcmluZ0NsYXNzID0gZ2V0RW5jbG9zaW5nQ2xhc3Mobm9kZSk7XG4gIGlmICghZGVjbGFyaW5nQ2xhc3MpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBtb2RpZmllcktpbmRzID0gZ2V0TW9kaWZpZXJLaW5kcyhub2RlKTtcbiAgaWYgKG1vZGlmaWVyS2luZHMuaGFzKFN5bnRheEtpbmQuU3RhdGljS2V5d29yZCkgfHwgbW9kaWZpZXJLaW5kcy5oYXMoU3ludGF4S2luZC5PdmVycmlkZUtleXdvcmQpIHx8IExJRkVDWUNMRV9BTExPV0xJU1QuaGFzKG5hbWVOb2RlLmdldFRleHQoKSkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBjdXJyZW50RXhwb3N1cmUgPSBnZXRDdXJyZW50TWVtYmVyRXhwb3N1cmUobW9kaWZpZXJLaW5kcyk7XG4gIGlmIChjdXJyZW50RXhwb3N1cmUgPT09ICdwcml2YXRlJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHNvdXJjZUZpbGUgPSBub2RlLmdldFNvdXJjZUZpbGUoKTtcbiAgY29uc3QgcmVmZXJlbmNlcyA9IGNvbGxlY3RSZWZlcmVuY2VzKGNvbnRleHQubGFuZ3VhZ2VTZXJ2aWNlLmZpbmRSZWZlcmVuY2VzKHNvdXJjZUZpbGUuZmlsZU5hbWUsIG5hbWVOb2RlLmdldFN0YXJ0KCkpKVxuICAgIC5maWx0ZXIoKHJlZmVyZW5jZSkgPT4gIWlzRGVjbGFyYXRpb25JdHNlbGYocmVmZXJlbmNlLCBuYW1lTm9kZSkpO1xuICBjb25zdCBub25UZXN0UmVmZXJlbmNlcyA9IHJlZmVyZW5jZXMuZmlsdGVyKChyZWZlcmVuY2UpID0+ICFpc1Rlc3RGaWxlKHRvQ2Fub25pY2FsKHJlZmVyZW5jZS5maWxlTmFtZSkpKTtcblxuICBjb25zdCBuZWVkZWRGb3JTcmMgPSBjb21wdXRlTmVlZGVkRXhwb3N1cmUobm9uVGVzdFJlZmVyZW5jZXMsIGRlY2xhcmluZ0NsYXNzLCBjb250ZXh0KTtcbiAgY29uc3QgbmVlZGVkV2l0aFRlc3RzID0gY29tcHV0ZU5lZWRlZEV4cG9zdXJlKHJlZmVyZW5jZXMsIGRlY2xhcmluZ0NsYXNzLCBjb250ZXh0KTtcblxuICBpZiAobmVlZGVkRm9yU3JjID09PSAncHVibGljJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChyYW5rRXhwb3N1cmUobmVlZGVkRm9yU3JjKSA+PSByYW5rRXhwb3N1cmUoY3VycmVudEV4cG9zdXJlKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnRleHQuZmluZGluZ3MucHVzaChidWlsZEZpbmRpbmcobm9kZSwgbmFtZU5vZGUsIGN1cnJlbnRFeHBvc3VyZSwgbmVlZGVkRm9yU3JjLCB7XG4gICAgaGFzTm9SZWZlcmVuY2VzOiByZWZlcmVuY2VzLmxlbmd0aCA9PT0gMCxcbiAgICBpc0ZvcmNlZEJ5VGVzdE9ubHk6IHJhbmtFeHBvc3VyZShuZWVkZWRXaXRoVGVzdHMpID4gcmFua0V4cG9zdXJlKG5lZWRlZEZvclNyYylcbiAgfSkpO1xufVxuXG5mdW5jdGlvbiBidWlsZEZpbmRpbmcoXG4gIG5vZGU6IE5vZGUsXG4gIG5hbWVOb2RlOiBOb2RlLFxuICBjdXJyZW50RXhwb3N1cmU6IEN1cnJlbnRFeHBvc3VyZSxcbiAgc3VnZ2VzdGVkRXhwb3N1cmU6IFN1Z2dlc3RlZEV4cG9zdXJlLFxuICBmbGFnczogRmluZGluZ0ZsYWdzXG4pOiBPdmVyRXhwb3N1cmVGaW5kaW5nIHtcbiAgY29uc3Qgc291cmNlRmlsZSA9IG5vZGUuZ2V0U291cmNlRmlsZSgpO1xuICBjb25zdCB7IGNoYXJhY3RlciwgbGluZSB9ID0gc291cmNlRmlsZS5nZXRMaW5lQW5kQ2hhcmFjdGVyT2ZQb3NpdGlvbihuYW1lTm9kZS5nZXRTdGFydCgpKTtcbiAgcmV0dXJuIHtcbiAgICBjb2x1bW46IGNoYXJhY3RlciArIDEsXG4gICAgY3VycmVudEV4cG9zdXJlLFxuICAgIGZpbGVQYXRoOiB0b0Nhbm9uaWNhbChzb3VyY2VGaWxlLmZpbGVOYW1lKSxcbiAgICBoYXNOb1JlZmVyZW5jZXM6IGZsYWdzLmhhc05vUmVmZXJlbmNlcyxcbiAgICBpc0ZvcmNlZEJ5VGVzdE9ubHk6IGZsYWdzLmlzRm9yY2VkQnlUZXN0T25seSxcbiAgICBpc01lbWJlcjogY3VycmVudEV4cG9zdXJlICE9PSAnZXhwb3J0JyxcbiAgICBsaW5lOiBsaW5lICsgMSxcbiAgICBuYW1lOiBuYW1lTm9kZS5nZXRUZXh0KCksXG4gICAgc3VnZ2VzdGVkRXhwb3N1cmVcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29sbGVjdFJlZmVyZW5jZXMocmVmZXJlbmNlZFN5bWJvbHM6IFJlZmVyZW5jZWRTeW1ib2xbXSB8IHVuZGVmaW5lZCk6IFJlZmVyZW5jZUxvY2F0aW9uW10ge1xuICBjb25zdCByZWZlcmVuY2VzOiBSZWZlcmVuY2VMb2NhdGlvbltdID0gW107XG4gIGZvciAoY29uc3QgcmVmZXJlbmNlZFN5bWJvbCBvZiByZWZlcmVuY2VkU3ltYm9scyA/PyBbXSkge1xuICAgIGZvciAoY29uc3QgcmVmZXJlbmNlIG9mIHJlZmVyZW5jZWRTeW1ib2wucmVmZXJlbmNlcykge1xuICAgICAgcmVmZXJlbmNlcy5wdXNoKHsgZmlsZU5hbWU6IHJlZmVyZW5jZS5maWxlTmFtZSwgc3RhcnQ6IHJlZmVyZW5jZS50ZXh0U3Bhbi5zdGFydCB9KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlZmVyZW5jZXM7XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVOZWVkZWRFeHBvc3VyZShcbiAgcmVmZXJlbmNlczogcmVhZG9ubHkgUmVmZXJlbmNlTG9jYXRpb25bXSxcbiAgZGVjbGFyaW5nQ2xhc3M6IENsYXNzTGlrZURlY2xhcmF0aW9uLFxuICBjb250ZXh0OiBBbmFseXNpc0NvbnRleHRcbik6IE1lbWJlckV4cG9zdXJlIHtcbiAgaWYgKHJlZmVyZW5jZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuICdwcml2YXRlJztcbiAgfVxuXG4gIGxldCBuZWVkZWQ6IE1lbWJlckV4cG9zdXJlID0gJ3ByaXZhdGUnO1xuICBmb3IgKGNvbnN0IHJlZmVyZW5jZSBvZiByZWZlcmVuY2VzKSB7XG4gICAgY29uc3QgcmVmZXJlbmNlQ2xhc3MgPSBnZXRDbGFzc0F0UG9zaXRpb24oY29udGV4dC5wcm9ncmFtLCByZWZlcmVuY2UuZmlsZU5hbWUsIHJlZmVyZW5jZS5zdGFydCk7XG4gICAgaWYgKHJlZmVyZW5jZUNsYXNzID09PSBkZWNsYXJpbmdDbGFzcykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChyZWZlcmVuY2VDbGFzcyAmJiBpc0Rlcml2ZWRGcm9tKHJlZmVyZW5jZUNsYXNzLCBkZWNsYXJpbmdDbGFzcywgY29udGV4dC5jaGVja2VyKSkge1xuICAgICAgbmVlZGVkID0gJ3Byb3RlY3RlZCc7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgcmV0dXJuICdwdWJsaWMnO1xuICB9XG4gIHJldHVybiBuZWVkZWQ7XG59XG5cbmZ1bmN0aW9uIGRlc2NyaWJlUmVhc29uKGZpbmRpbmc6IE92ZXJFeHBvc3VyZUZpbmRpbmcpOiBzdHJpbmcge1xuICBjb25zdCBiYXNlID0gYHJlZmVyZW5jZWQgb25seSAke1NDT1BFX0RFU0NSSVBUSU9OW2ZpbmRpbmcuc3VnZ2VzdGVkRXhwb3N1cmVdfWA7XG4gIGlmIChmaW5kaW5nLmlzRm9yY2VkQnlUZXN0T25seSkge1xuICAgIHJldHVybiBgJHtiYXNlfSAoZXhwb3NlZCBvbmx5IGZvciB0ZXN0cylgO1xuICB9XG4gIGlmIChmaW5kaW5nLmhhc05vUmVmZXJlbmNlcykge1xuICAgIHJldHVybiBgJHtiYXNlfSAobm8gcmVmZXJlbmNlcyBhdCBhbGwpYDtcbiAgfVxuICByZXR1cm4gYmFzZTtcbn1cblxuZnVuY3Rpb24gZmluZE5vZGVBdFBvc2l0aW9uKG5vZGU6IE5vZGUsIHBvc2l0aW9uOiBudW1iZXIpOiBOb2RlIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHBvc2l0aW9uIDwgbm9kZS5nZXRTdGFydCgpIHx8IHBvc2l0aW9uID49IG5vZGUuZ2V0RW5kKCkpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGxldCByZXN1bHQ6IE5vZGUgPSBub2RlO1xuICBub2RlLmZvckVhY2hDaGlsZCgoY2hpbGQpID0+IHtcbiAgICBjb25zdCBmb3VuZCA9IGZpbmROb2RlQXRQb3NpdGlvbihjaGlsZCwgcG9zaXRpb24pO1xuICAgIGlmIChmb3VuZCkge1xuICAgICAgcmVzdWx0ID0gZm91bmQ7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZ2V0Q2xhc3NBdFBvc2l0aW9uKHByb2dyYW06IFByb2dyYW0sIGZpbGVOYW1lOiBzdHJpbmcsIHBvc2l0aW9uOiBudW1iZXIpOiBDbGFzc0xpa2VEZWNsYXJhdGlvbiB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHNvdXJjZUZpbGUgPSBwcm9ncmFtLmdldFNvdXJjZUZpbGUoZmlsZU5hbWUpO1xuICBhc3NlcnROb25OdWxsYWJsZShzb3VyY2VGaWxlLCBgU291cmNlIGZpbGUgbm90IGZvdW5kIGluIHByb2dyYW06ICR7ZmlsZU5hbWV9YCk7XG4gIGNvbnN0IG5vZGUgPSBmaW5kTm9kZUF0UG9zaXRpb24oc291cmNlRmlsZSwgcG9zaXRpb24pO1xuICBhc3NlcnROb25OdWxsYWJsZShub2RlLCBgTm8gbm9kZSBmb3VuZCBhdCBwb3NpdGlvbiAke1N0cmluZyhwb3NpdGlvbil9IGluICR7ZmlsZU5hbWV9YCk7XG4gIHJldHVybiBnZXRFbmNsb3NpbmdDbGFzcyhub2RlKTtcbn1cblxuZnVuY3Rpb24gZ2V0Q3VycmVudE1lbWJlckV4cG9zdXJlKG1vZGlmaWVyS2luZHM6IFJlYWRvbmx5U2V0PFN5bnRheEtpbmQ+KTogTWVtYmVyRXhwb3N1cmUge1xuICBpZiAobW9kaWZpZXJLaW5kcy5oYXMoU3ludGF4S2luZC5Qcml2YXRlS2V5d29yZCkpIHtcbiAgICByZXR1cm4gJ3ByaXZhdGUnO1xuICB9XG4gIGlmIChtb2RpZmllcktpbmRzLmhhcyhTeW50YXhLaW5kLlByb3RlY3RlZEtleXdvcmQpKSB7XG4gICAgcmV0dXJuICdwcm90ZWN0ZWQnO1xuICB9XG4gIHJldHVybiAncHVibGljJztcbn1cblxuZnVuY3Rpb24gZ2V0RW5jbG9zaW5nQ2xhc3Mobm9kZTogTm9kZSk6IENsYXNzTGlrZURlY2xhcmF0aW9uIHwgdW5kZWZpbmVkIHtcbiAgbGV0IGN1cnJlbnQ6IE5vZGUgPSBub2RlO1xuICB3aGlsZSAoIWlzU291cmNlRmlsZShjdXJyZW50KSkge1xuICAgIGlmIChpc0NsYXNzTGlrZShjdXJyZW50KSkge1xuICAgICAgcmV0dXJuIGN1cnJlbnQ7XG4gICAgfVxuICAgIGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudDtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBnZXRFeHBvcnRlZE5hbWVOb2Rlcyhub2RlOiBOb2RlKTogTm9kZVtdIHtcbiAgaWYgKGlzRnVuY3Rpb25EZWNsYXJhdGlvbihub2RlKSB8fCBpc0NsYXNzRGVjbGFyYXRpb24obm9kZSkgfHwgaXNJbnRlcmZhY2VEZWNsYXJhdGlvbihub2RlKSB8fCBpc1R5cGVBbGlhc0RlY2xhcmF0aW9uKG5vZGUpIHx8IGlzRW51bURlY2xhcmF0aW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIG5vZGUubmFtZSA/IFtub2RlLm5hbWVdIDogW107XG4gIH1cbiAgaWYgKGlzVmFyaWFibGVTdGF0ZW1lbnQobm9kZSkpIHtcbiAgICByZXR1cm4gbm9kZS5kZWNsYXJhdGlvbkxpc3QuZGVjbGFyYXRpb25zLm1hcCgoZGVjbGFyYXRpb24pID0+IGRlY2xhcmF0aW9uLm5hbWUpLmZpbHRlcihpc0lkZW50aWZpZXIpO1xuICB9XG4gIHJldHVybiBbXTtcbn1cblxuZnVuY3Rpb24gZ2V0TWVtYmVyTmFtZU5vZGUobm9kZTogTm9kZSk6IE5vZGUgfCB1bmRlZmluZWQge1xuICBpZiAoaXNNZXRob2REZWNsYXJhdGlvbihub2RlKSB8fCBpc1Byb3BlcnR5RGVjbGFyYXRpb24obm9kZSkgfHwgaXNHZXRBY2Nlc3NvckRlY2xhcmF0aW9uKG5vZGUpIHx8IGlzU2V0QWNjZXNzb3JEZWNsYXJhdGlvbihub2RlKSkge1xuICAgIHJldHVybiBub2RlLm5hbWU7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gZ2V0TW9kaWZpZXJLaW5kcyhub2RlOiBOb2RlKTogUmVhZG9ubHlTZXQ8U3ludGF4S2luZD4ge1xuICBjb25zdCBraW5kcyA9IG5ldyBTZXQ8U3ludGF4S2luZD4oKTtcbiAgaWYgKGNhbkhhdmVNb2RpZmllcnMobm9kZSkpIHtcbiAgICBmb3IgKGNvbnN0IG1vZGlmaWVyIG9mIGdldE1vZGlmaWVycyhub2RlKSA/PyBbXSkge1xuICAgICAga2luZHMuYWRkKG1vZGlmaWVyLmtpbmQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4ga2luZHM7XG59XG5cbmZ1bmN0aW9uIGlzRGVjbGFyYXRpb25JdHNlbGYocmVmZXJlbmNlOiBSZWZlcmVuY2VMb2NhdGlvbiwgbmFtZU5vZGU6IE5vZGUpOiBib29sZWFuIHtcbiAgcmV0dXJuIHRvQ2Fub25pY2FsKHJlZmVyZW5jZS5maWxlTmFtZSkgPT09IHRvQ2Fub25pY2FsKG5hbWVOb2RlLmdldFNvdXJjZUZpbGUoKS5maWxlTmFtZSkgJiYgcmVmZXJlbmNlLnN0YXJ0ID09PSBuYW1lTm9kZS5nZXRTdGFydCgpO1xufVxuXG5mdW5jdGlvbiBpc0Rlcml2ZWRGcm9tKGRlcml2ZWQ6IENsYXNzTGlrZURlY2xhcmF0aW9uLCBiYXNlOiBDbGFzc0xpa2VEZWNsYXJhdGlvbiwgY2hlY2tlcjogVHlwZUNoZWNrZXIpOiBib29sZWFuIHtcbiAgY29uc3QgYmFzZVN5bWJvbCA9IGJhc2UubmFtZSA/IGNoZWNrZXIuZ2V0U3ltYm9sQXRMb2NhdGlvbihiYXNlLm5hbWUpIDogdW5kZWZpbmVkO1xuICBpZiAoIWJhc2VTeW1ib2wpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmb3IgKGNvbnN0IGNsYXVzZSBvZiBkZXJpdmVkLmhlcml0YWdlQ2xhdXNlcyA/PyBbXSkge1xuICAgIGlmIChjbGF1c2UudG9rZW4gIT09IFN5bnRheEtpbmQuRXh0ZW5kc0tleXdvcmQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHR5cGVFeHByZXNzaW9uIG9mIGNsYXVzZS50eXBlcykge1xuICAgICAgY29uc3Qgc3ltYm9sID0gY2hlY2tlci5nZXRUeXBlQXRMb2NhdGlvbih0eXBlRXhwcmVzc2lvbi5leHByZXNzaW9uKS5nZXRTeW1ib2woKTtcbiAgICAgIGlmIChzeW1ib2wgPT09IGJhc2VTeW1ib2wpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIHN5bWJvbD8uZGVjbGFyYXRpb25zID8/IFtdKSB7XG4gICAgICAgIGlmIChpc0NsYXNzTGlrZShkZWNsYXJhdGlvbikgJiYgaXNEZXJpdmVkRnJvbShkZWNsYXJhdGlvbiwgYmFzZSwgY2hlY2tlcikpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzT3duU291cmNlRmlsZShmaWxlUGF0aDogc3RyaW5nLCBzcmNGb2xkZXI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gZmlsZVBhdGguc3RhcnRzV2l0aChgJHtzcmNGb2xkZXJ9L2ApICYmIGZpbGVQYXRoLmVuZHNXaXRoKCcudHMnKSAmJiAhZmlsZVBhdGguZW5kc1dpdGgoJy5kLnRzJyk7XG59XG5cbmZ1bmN0aW9uIGlzVGVzdEZpbGUoZmlsZVBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gZmlsZVBhdGguaW5jbHVkZXMoJy50ZXN0LicpIHx8IGZpbGVQYXRoLmluY2x1ZGVzKCcuaW50ZWdyYXRpb24uJyk7XG59XG5cbmZ1bmN0aW9uIHJhbmtFeHBvc3VyZShleHBvc3VyZTogTWVtYmVyRXhwb3N1cmUpOiBudW1iZXIge1xuICByZXR1cm4gTUVNQkVSX0VYUE9TVVJFX09SREVSLmluZGV4T2YoZXhwb3N1cmUpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFzQ0E7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFB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
@@ -0,0 +1,12 @@
1
+ import process from 'node:process';
2
+
3
+ import { wrapCliTask } from 'obsidian-dev-utils/script-utils/cli-utils';
4
+ import {
5
+ findOverExposure,
6
+ formatOverExposureFindings
7
+ } from 'obsidian-dev-utils/script-utils/linters/over-exposure';
8
+
9
+ await wrapCliTask(() => {
10
+ const findings = findOverExposure({ projectFolder: process.cwd() });
11
+ process.stdout.write(formatOverExposureFindings(findings));
12
+ });
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../../../dist/lib/cjs/obsidian/components/case-insensitive-file-index-component.cjs",
3
+ "module": "../../../dist/lib/esm/obsidian/components/case-insensitive-file-index-component.mjs",
4
+ "type": "module",
5
+ "types": "../../../dist/lib/cjs/obsidian/components/case-insensitive-file-index-component.d.cts"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../../../dist/lib/cjs/obsidian/components/embed-extensions-component.cjs",
3
+ "module": "../../../dist/lib/esm/obsidian/components/embed-extensions-component.mjs",
4
+ "type": "module",
5
+ "types": "../../../dist/lib/cjs/obsidian/components/embed-extensions-component.d.cts"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../../dist/lib/cjs/obsidian/case-insensitive-file-index.cjs",
3
+ "module": "../../dist/lib/esm/obsidian/case-insensitive-file-index.mjs",
4
+ "type": "module",
5
+ "types": "../../dist/lib/cjs/obsidian/case-insensitive-file-index.d.cts"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../../dist/lib/cjs/obsidian/view-registrar.cjs",
3
+ "module": "../../dist/lib/esm/obsidian/view-registrar.mjs",
4
+ "type": "module",
5
+ "types": "../../dist/lib/cjs/obsidian/view-registrar.d.cts"
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "obsidian-dev-utils",
3
- "version": "76.1.0",
3
+ "version": "77.0.0",
4
4
  "description": "This is the collection of useful functions that you can use for your Obsidian plugin development.",
5
5
  "keywords": [
6
6
  "obsidian"
@@ -656,7 +656,7 @@
656
656
  "@eslint/config-helpers": "^0.6.0",
657
657
  "@eslint/js": "^10.0.1",
658
658
  "@lezer/common": "1.2.3",
659
- "@obsidian-typings/obsidian-public-latest": "^6.15.0",
659
+ "@obsidian-typings/obsidian-public-latest": "^6.18.0",
660
660
  "@stylistic/eslint-plugin": "^5.10.0",
661
661
  "@tsconfig/strictest": "^2.0.8",
662
662
  "@types/babel__core": "^7.20.5",
@@ -671,8 +671,8 @@
671
671
  "@types/react": "^19.2.17",
672
672
  "@types/semver": "^7.7.1",
673
673
  "@types/shell-quote": "^1.7.5",
674
- "@typescript-eslint/eslint-plugin": "^8.61.1",
675
- "@typescript-eslint/parser": "^8.61.1",
674
+ "@typescript-eslint/eslint-plugin": "^8.62.0",
675
+ "@typescript-eslint/parser": "^8.62.0",
676
676
  "commander": "^15.0.0",
677
677
  "compare-versions": "^6.1.1",
678
678
  "cspell": "^10.0.1",
@@ -684,13 +684,13 @@
684
684
  "esbuild-svelte": "^0.9.5",
685
685
  "eslint": "^10.5.0",
686
686
  "eslint-import-resolver-typescript": "^4.4.5",
687
- "eslint-plugin-import-x": "^4.16.2",
688
- "eslint-plugin-jsdoc": "^63.0.6",
687
+ "eslint-plugin-import-x": "^4.17.0",
688
+ "eslint-plugin-jsdoc": "^63.0.7",
689
689
  "eslint-plugin-no-unsanitized": "^4.1.5",
690
690
  "eslint-plugin-obsidianmd": "^0.3.0",
691
691
  "eslint-plugin-perfectionist": "^5.9.1",
692
692
  "eslint-plugin-tsdoc": "^0.5.2",
693
- "globals": "^17.6.0",
693
+ "globals": "^17.7.0",
694
694
  "i18next": "^26.3.1",
695
695
  "jiti": "^2.7.0",
696
696
  "linkinator": "^7.6.1",
@@ -712,20 +712,20 @@
712
712
  "sass": "^1.101.0",
713
713
  "semver": "^7.8.5",
714
714
  "shell-quote": "^1.8.4",
715
- "svelte-check": "^4.6.0",
715
+ "svelte-check": "^4.7.0",
716
716
  "svelte-preprocess": "^6.0.5",
717
717
  "type-fest": "^5.7.0",
718
718
  "typescript": "^6.0.3",
719
- "typescript-eslint": "^8.61.1",
719
+ "typescript-eslint": "^8.62.0",
720
720
  "unist-util-visit": "^5.1.0"
721
721
  },
722
722
  "devDependencies": {
723
- "@commitlint/cli": "^21.0.2",
724
- "@commitlint/config-conventional": "^21.0.2",
725
- "@commitlint/types": "^21.0.1",
723
+ "@commitlint/cli": "^21.1.0",
724
+ "@commitlint/config-conventional": "^21.1.0",
725
+ "@commitlint/types": "^21.1.0",
726
726
  "@jest/globals": "^30.4.1",
727
727
  "@total-typescript/ts-reset": "^0.6.1",
728
- "@typescript-eslint/rule-tester": "^8.61.1",
728
+ "@typescript-eslint/rule-tester": "^8.62.0",
729
729
  "@vitest/coverage-v8": "^4.1.9",
730
730
  "@vitest/runner": "^4.1.9",
731
731
  "better-typescript-lib": "^2.12.0",
@@ -736,8 +736,8 @@
736
736
  "jsdom": "^29.1.1",
737
737
  "moment": "^2.30.1",
738
738
  "nano-staged": "^1.0.2",
739
- "obsidian-integration-testing": "^4.2.6",
740
- "obsidian-test-mocks": "^3.1.1",
739
+ "obsidian-integration-testing": "^4.4.0",
740
+ "obsidian-test-mocks": "^3.3.0",
741
741
  "ts-declaration-location": "^1.0.7",
742
742
  "vitest": "^4.1.9",
743
743
  "yaml": "^2.9.0"
@@ -0,0 +1,6 @@
1
+ {
2
+ "main": "../../../dist/lib/cjs/script-utils/linters/over-exposure.cjs",
3
+ "module": "../../../dist/lib/esm/script-utils/linters/over-exposure.mjs",
4
+ "type": "module",
5
+ "types": "../../../dist/lib/cjs/script-utils/linters/over-exposure.d.cts"
6
+ }