@codeperfect/eslint-plugin 2.4.0 → 2.6.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 (163) hide show
  1. package/README.md +2 -0
  2. package/dist/application/custom-rules.d.ts +3 -0
  3. package/dist/application/custom-rules.d.ts.map +1 -1
  4. package/dist/application/custom-rules.js +6 -2
  5. package/dist/application/index.d.ts +1 -1
  6. package/dist/application/index.d.ts.map +1 -1
  7. package/dist/application/index.js +2 -2
  8. package/dist/codeperfect-eslint-plugin-1.0.0.tgz +0 -0
  9. package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.d.ts +1 -11
  10. package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.d.ts.map +1 -1
  11. package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.js +6 -14
  12. package/dist/domain/architecture/consistent-barrel-files/exports-only-rule.d.ts.map +1 -1
  13. package/dist/domain/architecture/consistent-barrel-files/exports-only-rule.js +2 -4
  14. package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-rule.d.ts.map +1 -1
  15. package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-rule.js +4 -134
  16. package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-utilities.d.ts +14 -0
  17. package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-utilities.d.ts.map +1 -0
  18. package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-utilities.js +154 -0
  19. package/dist/domain/architecture/consistent-barrel-files/no-import-export-extensions-rule.d.ts.map +1 -1
  20. package/dist/domain/architecture/consistent-barrel-files/no-import-export-extensions-rule.js +10 -12
  21. package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-rule.d.ts.map +1 -1
  22. package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-rule.js +4 -11
  23. package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-utilities.d.ts.map +1 -1
  24. package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-utilities.js +2 -12
  25. package/dist/domain/architecture/consistent-barrel-files/rule.d.ts.map +1 -1
  26. package/dist/domain/architecture/consistent-barrel-files/rule.js +4 -3
  27. package/dist/domain/architecture/no-unused-exports/no-unused-exports-declaration-utilities.d.ts +14 -0
  28. package/dist/domain/architecture/no-unused-exports/no-unused-exports-declaration-utilities.d.ts.map +1 -0
  29. package/dist/domain/architecture/no-unused-exports/no-unused-exports-declaration-utilities.js +187 -0
  30. package/dist/domain/architecture/no-unused-exports/no-unused-exports-identifier-utilities.d.ts +26 -0
  31. package/dist/domain/architecture/no-unused-exports/no-unused-exports-identifier-utilities.d.ts.map +1 -0
  32. package/dist/domain/architecture/no-unused-exports/no-unused-exports-identifier-utilities.js +95 -0
  33. package/dist/domain/architecture/no-unused-exports/no-unused-exports-pattern-utilities.d.ts +32 -0
  34. package/dist/domain/architecture/no-unused-exports/no-unused-exports-pattern-utilities.d.ts.map +1 -0
  35. package/dist/domain/architecture/no-unused-exports/no-unused-exports-pattern-utilities.js +78 -0
  36. package/dist/domain/architecture/no-unused-exports/no-unused-exports-public-api-usage-utilities.d.ts +18 -0
  37. package/dist/domain/architecture/no-unused-exports/no-unused-exports-public-api-usage-utilities.d.ts.map +1 -0
  38. package/dist/domain/architecture/no-unused-exports/no-unused-exports-public-api-usage-utilities.js +45 -0
  39. package/dist/domain/architecture/no-unused-exports/no-unused-exports-record-utilities.d.ts +34 -0
  40. package/dist/domain/architecture/no-unused-exports/no-unused-exports-record-utilities.d.ts.map +1 -0
  41. package/dist/domain/architecture/no-unused-exports/no-unused-exports-record-utilities.js +44 -0
  42. package/dist/domain/architecture/no-unused-exports/no-unused-exports-symbol-utilities.d.ts +59 -0
  43. package/dist/domain/architecture/no-unused-exports/no-unused-exports-symbol-utilities.d.ts.map +1 -0
  44. package/dist/domain/architecture/no-unused-exports/no-unused-exports-symbol-utilities.js +133 -0
  45. package/dist/domain/architecture/no-unused-exports/{no-unused-exports-utilities.d.ts → no-unused-exports-usage-utilities.d.ts} +2 -23
  46. package/dist/domain/architecture/no-unused-exports/no-unused-exports-usage-utilities.d.ts.map +1 -0
  47. package/dist/domain/architecture/no-unused-exports/no-unused-exports-usage-utilities.js +106 -0
  48. package/dist/domain/architecture/no-unused-exports/rule.js +4 -2
  49. package/dist/domain/core/index.d.ts +1 -0
  50. package/dist/domain/core/index.d.ts.map +1 -1
  51. package/dist/domain/core/index.js +2 -1
  52. package/dist/domain/core/no-multiple-declarators/rule-utilities.d.ts +58 -0
  53. package/dist/domain/core/no-multiple-declarators/rule-utilities.d.ts.map +1 -0
  54. package/dist/domain/core/no-multiple-declarators/rule-utilities.js +204 -0
  55. package/dist/domain/core/no-multiple-declarators/rule.d.ts.map +1 -1
  56. package/dist/domain/core/no-multiple-declarators/rule.js +9 -211
  57. package/dist/domain/core/no-multiple-declarators/types.js +2 -2
  58. package/dist/domain/core/no-useless-delegation/index.d.ts +2 -0
  59. package/dist/domain/core/no-useless-delegation/index.d.ts.map +1 -0
  60. package/dist/domain/core/no-useless-delegation/index.js +2 -0
  61. package/dist/domain/core/no-useless-delegation/rule.d.ts +5 -0
  62. package/dist/domain/core/no-useless-delegation/rule.d.ts.map +1 -0
  63. package/dist/domain/core/no-useless-delegation/rule.js +200 -0
  64. package/dist/domain/core/prefer-interface-types/rule-utilities.d.ts +57 -0
  65. package/dist/domain/core/prefer-interface-types/rule-utilities.d.ts.map +1 -0
  66. package/dist/domain/core/prefer-interface-types/rule-utilities.js +105 -0
  67. package/dist/domain/core/prefer-interface-types/rule.d.ts.map +1 -1
  68. package/dist/domain/core/prefer-interface-types/rule.js +2 -104
  69. package/dist/domain/docs/no-interface-member-docs/comment-removal-ranges.d.ts +25 -0
  70. package/dist/domain/docs/no-interface-member-docs/comment-removal-ranges.d.ts.map +1 -0
  71. package/dist/domain/docs/no-interface-member-docs/comment-removal-ranges.js +64 -0
  72. package/dist/domain/docs/no-interface-member-docs/comment-utilities.d.ts +2 -24
  73. package/dist/domain/docs/no-interface-member-docs/comment-utilities.d.ts.map +1 -1
  74. package/dist/domain/docs/no-interface-member-docs/comment-utilities.js +3 -65
  75. package/dist/domain/docs/no-interface-member-docs/parameter-tags.js +2 -2
  76. package/dist/domain/docs/no-interface-member-docs/parameter-utilities.js +2 -2
  77. package/dist/domain/docs/no-interface-member-docs/rule.d.ts.map +1 -1
  78. package/dist/domain/docs/no-interface-member-docs/rule.js +3 -2
  79. package/dist/domain/docs/require-example-language/examples-collect.d.ts +15 -0
  80. package/dist/domain/docs/require-example-language/examples-collect.d.ts.map +1 -0
  81. package/dist/domain/docs/require-example-language/examples-collect.js +113 -0
  82. package/dist/domain/docs/require-example-language/examples.d.ts +24 -13
  83. package/dist/domain/docs/require-example-language/examples.d.ts.map +1 -1
  84. package/dist/domain/docs/require-example-language/examples.js +2 -111
  85. package/dist/domain/docs/require-example-language/fixes.js +4 -4
  86. package/dist/domain/docs/require-example-language/rule.d.ts.map +1 -1
  87. package/dist/domain/docs/require-example-language/rule.js +9 -8
  88. package/dist/domain/docs/require-example-language/types.d.ts.map +1 -1
  89. package/dist/domain/docs/require-example-language/types.js +1 -1
  90. package/dist/domain/index.d.ts +1 -1
  91. package/dist/domain/index.d.ts.map +1 -1
  92. package/dist/domain/index.js +2 -2
  93. package/dist/domain/testing/aaa/analyzer.analysis.helpers.d.ts.map +1 -1
  94. package/dist/domain/testing/aaa/analyzer.analysis.helpers.js +8 -8
  95. package/dist/domain/testing/aaa/analyzer.assertions.helpers.d.ts.map +1 -1
  96. package/dist/domain/testing/aaa/analyzer.assertions.helpers.js +10 -9
  97. package/dist/domain/testing/aaa/analyzer.assertions.operands.d.ts.map +1 -1
  98. package/dist/domain/testing/aaa/analyzer.assertions.operands.js +2 -5
  99. package/dist/domain/testing/aaa/analyzer.classification.helpers.js +14 -16
  100. package/dist/domain/testing/aaa/analyzer.classification.traversal.js +6 -4
  101. package/dist/domain/testing/aaa/analyzer.super.d.ts.map +1 -1
  102. package/dist/domain/testing/aaa/analyzer.super.js +10 -8
  103. package/dist/domain/testing/assert-actual-expected-names/rule.d.ts.map +1 -1
  104. package/dist/domain/testing/assert-actual-expected-names/rule.js +21 -23
  105. package/dist/domain/testing/enforce-aaa-phase-purity/pattern-identifiers.d.ts.map +1 -1
  106. package/dist/domain/testing/enforce-aaa-phase-purity/pattern-identifiers.js +1 -1
  107. package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.d.ts.map +1 -1
  108. package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.js +2 -160
  109. package/dist/domain/testing/enforce-aaa-phase-purity/statement-purity-reporters.d.ts +41 -0
  110. package/dist/domain/testing/enforce-aaa-phase-purity/statement-purity-reporters.d.ts.map +1 -0
  111. package/dist/domain/testing/enforce-aaa-phase-purity/statement-purity-reporters.js +161 -0
  112. package/dist/domain/testing/enforce-aaa-structure/missing-section-fixes.d.ts.map +1 -1
  113. package/dist/domain/testing/enforce-aaa-structure/missing-section-fixes.js +2 -2
  114. package/dist/domain/testing/enforce-aaa-structure/rule-section-reporting.d.ts +81 -0
  115. package/dist/domain/testing/enforce-aaa-structure/rule-section-reporting.d.ts.map +1 -0
  116. package/dist/domain/testing/enforce-aaa-structure/rule-section-reporting.js +181 -0
  117. package/dist/domain/testing/enforce-aaa-structure/rule.d.ts.map +1 -1
  118. package/dist/domain/testing/enforce-aaa-structure/rule.js +28 -217
  119. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-detection.d.ts +29 -0
  120. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-detection.d.ts.map +1 -0
  121. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-detection.js +200 -0
  122. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-names.d.ts +12 -0
  123. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-names.d.ts.map +1 -0
  124. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-names.js +151 -0
  125. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-reporting.d.ts +16 -0
  126. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-reporting.d.ts.map +1 -0
  127. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-reporting.js +109 -0
  128. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule.d.ts.map +1 -1
  129. package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule.js +18 -450
  130. package/dist/domain/testing/prefer-vi-mocked-import/fix-import-updates.d.ts.map +1 -1
  131. package/dist/domain/testing/prefer-vi-mocked-import/fix-import-updates.js +7 -4
  132. package/dist/domain/testing/prefer-vi-mocked-import/fix-imports.d.ts.map +1 -1
  133. package/dist/domain/testing/prefer-vi-mocked-import/fix-imports.js +7 -4
  134. package/dist/domain/testing/prefer-vi-mocked-import/fix.js +2 -2
  135. package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.d.ts +18 -0
  136. package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.d.ts.map +1 -0
  137. package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.js +162 -0
  138. package/dist/domain/testing/prefer-vi-mocked-import/match-rewrites.d.ts.map +1 -1
  139. package/dist/domain/testing/prefer-vi-mocked-import/match-rewrites.js +5 -4
  140. package/dist/domain/testing/prefer-vi-mocked-import/match-seeds.d.ts +29 -0
  141. package/dist/domain/testing/prefer-vi-mocked-import/match-seeds.d.ts.map +1 -0
  142. package/dist/domain/testing/prefer-vi-mocked-import/match-seeds.js +100 -0
  143. package/dist/domain/testing/prefer-vi-mocked-import/match.d.ts.map +1 -1
  144. package/dist/domain/testing/prefer-vi-mocked-import/match.js +5 -246
  145. package/dist/domain/testing/prefer-vi-mocked-import/rule.d.ts.map +1 -1
  146. package/dist/domain/testing/prefer-vi-mocked-import/rule.js +18 -20
  147. package/dist/domain/testing/require-act-result-capture/rule.d.ts.map +1 -1
  148. package/dist/domain/testing/require-act-result-capture/rule.js +47 -21
  149. package/dist/domain/testing/require-test-companion/rule.d.ts.map +1 -1
  150. package/dist/domain/testing/require-test-companion/rule.js +2 -4
  151. package/dist/domain/testing/single-act-statement/rule.d.ts.map +1 -1
  152. package/dist/domain/testing/single-act-statement/rule.js +20 -22
  153. package/dist/index.d.ts +1 -1
  154. package/dist/index.d.ts.map +1 -1
  155. package/dist/index.js +2 -2
  156. package/dist/infrastructure/codeperfect-plugin.d.ts +2 -0
  157. package/dist/infrastructure/codeperfect-plugin.d.ts.map +1 -1
  158. package/dist/infrastructure/codeperfect-plugin.js +3 -2
  159. package/dist/infrastructure/presets.d.ts.map +1 -1
  160. package/dist/infrastructure/presets.js +3 -1
  161. package/package.json +60 -69
  162. package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.d.ts.map +0 -1
  163. package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.js +0 -612
@@ -1,612 +0,0 @@
1
- import { ESLintUtils } from "@typescript-eslint/utils";
2
- import path from "node:path";
3
- import * as ts from "typescript";
4
- import { isPublicApiFile, isTestFile } from "./no-unused-exports-options.js";
5
- /**
6
- * Normalizes an absolute file path for safe equality checks.
7
- * @param inputPath Candidate path.
8
- * @returns Normalized absolute path suitable for cross-platform comparisons.
9
- * @example
10
- * ```typescript
11
- * const comparable = toComparableAbsolutePath("/repo/src/feature.ts");
12
- * ```
13
- */
14
- const toComparableAbsolutePath = (inputPath) => {
15
- const absolutePath = path.normalize(path.resolve(inputPath));
16
- return absolutePath.toLowerCase();
17
- };
18
- /**
19
- * Converts one unknown value into an indexable record.
20
- * @param value Candidate value.
21
- * @returns Record view when the value is object-like.
22
- * @example
23
- * ```typescript
24
- * const record = asRecord({ type: "Identifier" });
25
- * ```
26
- */
27
- const asRecord = (value) => value !== null && typeof value === "object"
28
- ? value
29
- : void 0;
30
- /**
31
- * Reads one string property from an object-like value.
32
- * @param value Candidate object.
33
- * @param key Lookup key used to read the property.
34
- * @returns String value when present.
35
- * @example
36
- * ```typescript
37
- * const name = readStringProperty({ name: "feature" }, "name");
38
- * ```
39
- */
40
- const readStringProperty = (value, key) => {
41
- const record = asRecord(value);
42
- const property = record?.[key];
43
- return typeof property === "string" ? property : void 0;
44
- };
45
- /**
46
- * Reads one array property from an object-like value.
47
- * @param value Candidate object.
48
- * @param key Lookup key used to read the property.
49
- * @returns Array value when present.
50
- * @example
51
- * ```typescript
52
- * const items = readArrayProperty({ elements: [1, 2] }, "elements");
53
- * ```
54
- */
55
- const readArrayProperty = (value, key) => {
56
- const record = asRecord(value);
57
- const property = record?.[key];
58
- return Array.isArray(property) ? property : void 0;
59
- };
60
- /**
61
- * Resolves TypeScript parser services program when available.
62
- * @param context Rule context.
63
- * @returns TypeScript program when available.
64
- * @example
65
- * ```typescript
66
- * const program = getTypeScriptProgram(context);
67
- * ```
68
- */
69
- const getTypeScriptProgram = (context) => {
70
- try {
71
- const services = ESLintUtils.getParserServices(context);
72
- return services.program;
73
- }
74
- catch {
75
- return void 0;
76
- }
77
- };
78
- /**
79
- * Collects identifier names from one variable pattern.
80
- * @param node Variable pattern candidate.
81
- * @returns Identifier names declared by the pattern.
82
- * @example
83
- * ```typescript
84
- * const names = collectPatternIdentifierNames(pattern);
85
- * ```
86
- */
87
- const collectPatternIdentifierNames = (node) => {
88
- const pattern = asRecord(node);
89
- if (pattern === void 0) {
90
- return [];
91
- }
92
- const patternType = readStringProperty(pattern, "type");
93
- if (patternType === "Identifier") {
94
- const name = readStringProperty(pattern, "name");
95
- return name === void 0 ? [] : [name];
96
- }
97
- if (patternType === "RestElement") {
98
- return collectPatternIdentifierNames(pattern["argument"]);
99
- }
100
- if (patternType === "AssignmentPattern") {
101
- return collectPatternIdentifierNames(pattern["left"]);
102
- }
103
- if (patternType === "ArrayPattern") {
104
- return (readArrayProperty(pattern, "elements") ?? []).flatMap((element) => collectPatternIdentifierNames(element));
105
- }
106
- if (patternType === "ObjectPattern") {
107
- return (readArrayProperty(pattern, "properties") ?? []).flatMap((property) => {
108
- if (readStringProperty(property, "type") === "RestElement") {
109
- return collectPatternIdentifierNames(asRecord(property)?.["argument"]);
110
- }
111
- return collectPatternIdentifierNames(asRecord(property)?.["value"]);
112
- });
113
- }
114
- return [];
115
- };
116
- /**
117
- * Reads one export specifier name.
118
- * @param specifier Export specifier candidate.
119
- * @returns Exported name when available.
120
- * @example
121
- * ```typescript
122
- * const name = getExportSpecifierName(specifier);
123
- * ```
124
- */
125
- const getExportSpecifierName = (specifier) => {
126
- const candidate = asRecord(specifier);
127
- const exportedName = readStringProperty(candidate?.["exported"], "name");
128
- if (typeof exportedName === "string") {
129
- return exportedName;
130
- }
131
- const localName = readStringProperty(candidate?.["local"], "name");
132
- return typeof localName === "string" ? localName : void 0;
133
- };
134
- /**
135
- * Reads one local export specifier name.
136
- * @param specifier Export specifier candidate.
137
- * @returns Local specifier name when available.
138
- * @example
139
- * ```typescript
140
- * const name = getExportSpecifierLocalName(specifier);
141
- * ```
142
- */
143
- const getExportSpecifierLocalName = (specifier) => {
144
- const candidate = asRecord(specifier);
145
- return readStringProperty(candidate?.["local"], "name");
146
- };
147
- /**
148
- * Collects top-level declaration names owned by the current module.
149
- * @param body Program body statements.
150
- * @returns Map from locally declared name to its declaration metadata.
151
- * @example
152
- * ```typescript
153
- * const declarations = collectLocalDeclarationNames(program.body);
154
- * ```
155
- */
156
- const collectLocalDeclarationNames = (body) => {
157
- const declarationNames = new Map();
158
- for (const statement of body) {
159
- const declarationCandidate = statement.type === "ExportNamedDeclaration" &&
160
- statement.declaration !== null &&
161
- statement.declaration !== void 0
162
- ? statement.declaration
163
- : statement;
164
- const declarationCandidateRecord = asRecord(declarationCandidate);
165
- const declarationCandidateType = readStringProperty(declarationCandidate, "type");
166
- if (declarationCandidateRecord === void 0 ||
167
- declarationCandidateType === void 0) {
168
- continue;
169
- }
170
- if (declarationCandidateType === "FunctionDeclaration" ||
171
- declarationCandidateType === "ClassDeclaration" ||
172
- declarationCandidateType === "TSEnumDeclaration" ||
173
- declarationCandidateType === "TSInterfaceDeclaration" ||
174
- declarationCandidateType === "TSTypeAliasDeclaration") {
175
- const declarationName = readStringProperty(declarationCandidateRecord["id"], "name");
176
- if (declarationName !== void 0) {
177
- declarationNames.set(declarationName, {
178
- kind: declarationCandidateType === "TSInterfaceDeclaration" ||
179
- declarationCandidateType === "TSTypeAliasDeclaration"
180
- ? "type"
181
- : "value",
182
- node: statement,
183
- });
184
- }
185
- continue;
186
- }
187
- if (declarationCandidateType !== "VariableDeclaration") {
188
- continue;
189
- }
190
- const declarations = readArrayProperty(declarationCandidateRecord, "declarations");
191
- if (declarations === void 0) {
192
- continue;
193
- }
194
- for (const declaration of declarations) {
195
- const declarationRecord = asRecord(declaration);
196
- if (declarationRecord === void 0) {
197
- continue;
198
- }
199
- for (const name of collectPatternIdentifierNames(declarationRecord["id"])) {
200
- declarationNames.set(name, { kind: "value", node: statement });
201
- }
202
- }
203
- }
204
- return declarationNames;
205
- };
206
- /**
207
- * Collects exported elements from one program body.
208
- * @param body Program body statements.
209
- * @returns Exported elements in declaration order.
210
- * @example
211
- * ```typescript
212
- * const exported = collectExportedElements(program.body);
213
- * ```
214
- */
215
- const collectExportedElements = (body) => {
216
- const exportedElements = [];
217
- const localDeclarationNames = collectLocalDeclarationNames(body);
218
- for (const statement of body) {
219
- if (statement.type === "ExportDefaultDeclaration") {
220
- exportedElements.push({
221
- exportedName: "default",
222
- exportKind: "value",
223
- node: statement,
224
- });
225
- continue;
226
- }
227
- if (statement.type !== "ExportNamedDeclaration") {
228
- continue;
229
- }
230
- if (statement.source !== null && statement.source !== void 0) {
231
- continue;
232
- }
233
- if (statement.declaration !== null && statement.declaration !== void 0) {
234
- const declaration = asRecord(statement.declaration);
235
- if (readStringProperty(declaration, "type") === "VariableDeclaration") {
236
- for (const variable of readArrayProperty(declaration, "declarations") ??
237
- []) {
238
- for (const name of collectPatternIdentifierNames(asRecord(variable)?.["id"])) {
239
- exportedElements.push({
240
- exportedName: name,
241
- exportKind: "value",
242
- node: statement,
243
- });
244
- }
245
- }
246
- }
247
- else {
248
- const declarationName = readStringProperty(declaration?.["id"], "name");
249
- const declarationType = readStringProperty(declaration, "type");
250
- const exportKind = declarationType === "TSInterfaceDeclaration" ||
251
- declarationType === "TSTypeAliasDeclaration"
252
- ? "type"
253
- : "value";
254
- if (typeof declarationName === "string") {
255
- exportedElements.push({
256
- exportedName: declarationName,
257
- exportKind,
258
- node: statement,
259
- });
260
- }
261
- }
262
- continue;
263
- }
264
- for (const specifier of statement.specifiers) {
265
- const localName = getExportSpecifierLocalName(specifier);
266
- const localDeclaration = localName === void 0 ? void 0 : localDeclarationNames.get(localName);
267
- if (localDeclaration === void 0) {
268
- continue;
269
- }
270
- const exportedName = getExportSpecifierName(specifier);
271
- if (exportedName !== void 0) {
272
- const statementExportKind = readStringProperty(statement, "exportKind");
273
- const specifierExportKind = readStringProperty(specifier, "exportKind");
274
- const isTypeOnlyExport = statementExportKind === "type" || specifierExportKind === "type";
275
- exportedElements.push({
276
- exportedName,
277
- exportKind: isTypeOnlyExport ? "type" : localDeclaration.kind,
278
- node: localDeclaration.node,
279
- });
280
- }
281
- }
282
- }
283
- return exportedElements;
284
- };
285
- /**
286
- * Resolves one symbol to its canonical target.
287
- * @param symbol Candidate symbol.
288
- * @param checker TypeScript checker.
289
- * @returns Resolved canonical symbol.
290
- * @example
291
- * ```typescript
292
- * const resolved = resolveCanonicalSymbol(symbol, checker);
293
- * ```
294
- */
295
- const resolveCanonicalSymbol = (symbol, checker) => {
296
- if ((symbol.flags & ts.SymbolFlags.Alias) === 0) {
297
- return symbol;
298
- }
299
- try {
300
- return checker.getAliasedSymbol(symbol);
301
- }
302
- catch {
303
- return symbol;
304
- }
305
- };
306
- /**
307
- * Builds declaration-site keys for symbol identity matching.
308
- * @param symbol Symbol being compared.
309
- * @returns Declaration keys describing where this symbol is declared.
310
- * @example
311
- * ```typescript
312
- * const keys = getDeclarationKeys(symbol);
313
- * ```
314
- */
315
- const getDeclarationKeys = (symbol) => {
316
- const declarations = symbol.declarations ?? [];
317
- return new Set(declarations.map((declaration) => {
318
- const sourceFilename = declaration.getSourceFile().fileName;
319
- return `${sourceFilename}:${String(declaration.pos)}:${String(declaration.end)}`;
320
- }));
321
- };
322
- /**
323
- * Checks whether two symbols reference the same declaration site.
324
- * @param left Left-hand symbol candidate.
325
- * @param right Right-hand symbol candidate.
326
- * @returns True when both symbols identify the same declaration.
327
- * @example
328
- * ```typescript
329
- * const same = isSameSymbol(left, right);
330
- * ```
331
- */
332
- const isSameSymbol = (left, right) => {
333
- if (left === right) {
334
- return true;
335
- }
336
- const leftKeys = getDeclarationKeys(left);
337
- const rightKeys = getDeclarationKeys(right);
338
- for (const key of leftKeys) {
339
- if (rightKeys.has(key)) {
340
- return true;
341
- }
342
- }
343
- return false;
344
- };
345
- /**
346
- * Resolves one exported symbol by name from a source file.
347
- * @param program TypeScript program.
348
- * @param sourceFilename Source file path.
349
- * @param exportedName Public name exposed by the module export list.
350
- * @returns Symbol when found.
351
- * @example
352
- * ```typescript
353
- * const symbol = getExportedSymbol(program, sourceFilename, "feature");
354
- * ```
355
- */
356
- const getExportedSymbol = (program, sourceFilename, exportedName) => {
357
- const checker = program.getTypeChecker();
358
- const sourceFile = program
359
- .getSourceFiles()
360
- .find((file) => toComparableAbsolutePath(file.fileName) ===
361
- toComparableAbsolutePath(sourceFilename));
362
- if (sourceFile === void 0) {
363
- return void 0;
364
- }
365
- const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
366
- if (moduleSymbol === void 0) {
367
- return void 0;
368
- }
369
- const exportedSymbol = checker
370
- .getExportsOfModule(moduleSymbol)
371
- .find((symbol) => symbol.getName() === exportedName);
372
- if (exportedSymbol === void 0) {
373
- return void 0;
374
- }
375
- return resolveCanonicalSymbol(exportedSymbol, checker);
376
- };
377
- /**
378
- * Checks whether one source file exports the target symbol.
379
- * @param sourceFile Source file that may expose the symbol.
380
- * @param checker TypeScript checker.
381
- * @param targetSymbol Symbol being classified.
382
- * @returns True when one module export resolves to the target symbol.
383
- * @example
384
- * ```typescript
385
- * const exposed = sourceFileExportsSymbol(sourceFile, checker, targetSymbol);
386
- * ```
387
- */
388
- const sourceFileExportsSymbol = (sourceFile, checker, targetSymbol) => {
389
- const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
390
- if (moduleSymbol === void 0) {
391
- return false;
392
- }
393
- for (const exportedSymbol of checker.getExportsOfModule(moduleSymbol)) {
394
- const resolvedSymbol = resolveCanonicalSymbol(exportedSymbol, checker);
395
- if (isSameSymbol(resolvedSymbol, targetSymbol)) {
396
- return true;
397
- }
398
- }
399
- return false;
400
- };
401
- /**
402
- * Checks whether an identifier participates in one declaration/import/export site.
403
- * @param identifier Identifier node to evaluate.
404
- * @returns True when the identifier is declaration-only syntax.
405
- * @example
406
- * ```typescript
407
- * const declaration = isDeclarationOnlyIdentifier(identifier);
408
- * ```
409
- */
410
- const isDeclarationOnlyIdentifier = (identifier) => {
411
- const parent = identifier.parent;
412
- return (ts.isImportSpecifier(parent) ||
413
- ts.isImportClause(parent) ||
414
- ts.isNamespaceImport(parent) ||
415
- ts.isImportEqualsDeclaration(parent) ||
416
- ts.isExportSpecifier(parent) ||
417
- ts.isTypeAliasDeclaration(parent) ||
418
- ts.isInterfaceDeclaration(parent) ||
419
- ts.isTypeParameterDeclaration(parent) ||
420
- (ts.isVariableDeclaration(parent) && parent.name === identifier) ||
421
- (ts.isFunctionDeclaration(parent) && parent.name === identifier) ||
422
- (ts.isClassDeclaration(parent) && parent.name === identifier) ||
423
- (ts.isParameter(parent) && parent.name === identifier));
424
- };
425
- /**
426
- * Checks whether one identifier node appears under a type node.
427
- * @param identifier Candidate identifier.
428
- * @returns True when the identifier is inside type-only syntax.
429
- * @example
430
- * ```typescript
431
- * const typePosition = isTypePositionIdentifier(identifier);
432
- * ```
433
- */
434
- const isTypePositionIdentifier = (identifier) => {
435
- const visitNode = (current) => {
436
- if (ts.isTypeQueryNode(current)) {
437
- return false;
438
- }
439
- if (ts.isTypeNode(current)) {
440
- return true;
441
- }
442
- if (ts.isExpressionStatement(current) ||
443
- ts.isCallExpression(current) ||
444
- ts.isPropertyAccessExpression(current) ||
445
- ts.isElementAccessExpression(current) ||
446
- ts.isVariableDeclaration(current) ||
447
- ts.isReturnStatement(current)) {
448
- return false;
449
- }
450
- if (ts.isSourceFile(current)) {
451
- return false;
452
- }
453
- return visitNode(current.parent);
454
- };
455
- return visitNode(identifier);
456
- };
457
- /**
458
- * Checks whether one identifier is one concrete usage candidate for the export kind.
459
- * @param identifier Identifier node.
460
- * @param exportKind Whether type-only or value usage is required.
461
- * @returns True when the identifier can satisfy usage.
462
- * @example
463
- * ```typescript
464
- * const concrete = isConcreteUsageIdentifier(identifier, "value");
465
- * ```
466
- */
467
- const isConcreteUsageIdentifier = (identifier, exportKind) => {
468
- if (isDeclarationOnlyIdentifier(identifier)) {
469
- return false;
470
- }
471
- const inTypePosition = isTypePositionIdentifier(identifier);
472
- return exportKind === "type" ? inTypePosition : !inTypePosition;
473
- };
474
- /**
475
- * Appends concrete usages from one source file into the accumulator.
476
- * @param sourceFile Source file to scan.
477
- * @param checker TypeScript checker.
478
- * @param targetSymbol Export symbol being classified.
479
- * @param exportedElement Export metadata.
480
- * @param consumerIsTestFile Whether source file is a test file.
481
- * @param usages Mutable usage accumulator.
482
- * @example
483
- * ```typescript
484
- * collectConcreteUsagesFromSourceFile(sourceFile, checker, targetSymbolKey, exportedElement, false, usages);
485
- * ```
486
- */
487
- const collectConcreteUsagesFromSourceFile = (sourceFile, checker, targetSymbol, exportedElement, consumerIsTestFile, usages) => {
488
- const visitNode = (node) => {
489
- if (!ts.isIdentifier(node)) {
490
- ts.forEachChild(node, visitNode);
491
- return;
492
- }
493
- if (!isConcreteUsageIdentifier(node, exportedElement.exportKind)) {
494
- ts.forEachChild(node, visitNode);
495
- return;
496
- }
497
- const isShorthandName = ts.isShorthandPropertyAssignment(node.parent) &&
498
- node.parent.name === node;
499
- const candidateSymbol = isShorthandName
500
- ? checker.getShorthandAssignmentValueSymbol(node.parent)
501
- : checker.getSymbolAtLocation(node);
502
- if (candidateSymbol === void 0) {
503
- ts.forEachChild(node, visitNode);
504
- return;
505
- }
506
- const resolvedSymbol = resolveCanonicalSymbol(candidateSymbol, checker);
507
- if (!isSameSymbol(resolvedSymbol, targetSymbol)) {
508
- ts.forEachChild(node, visitNode);
509
- return;
510
- }
511
- usages.push({ isTestFile: consumerIsTestFile });
512
- ts.forEachChild(node, visitNode);
513
- };
514
- visitNode(sourceFile);
515
- };
516
- /**
517
- * Collects public API exposure usages for one exported symbol.
518
- * @param program TypeScript program.
519
- * @param sourceFilename Source filename where export is defined.
520
- * @param state Normalized rule options.
521
- * @param repoRoot Absolute repository root used for file classification.
522
- * @param targetSymbol Export symbol being classified.
523
- * @returns Public API exposure usages for the exported symbol.
524
- * @example
525
- * ```typescript
526
- * const usages = collectPublicApiExposureUsages(program, sourceFilename, state, repoRoot, targetSymbol);
527
- * ```
528
- */
529
- const collectPublicApiExposureUsages = (program, sourceFilename, state, repoRoot, targetSymbol) => {
530
- const checker = program.getTypeChecker();
531
- const normalizedSourceFilename = toComparableAbsolutePath(sourceFilename);
532
- const normalizedRepoRoot = path.resolve(repoRoot);
533
- const usages = [];
534
- for (const sourceFile of program.getSourceFiles()) {
535
- if (sourceFile.isDeclarationFile) {
536
- continue;
537
- }
538
- const publicApiFilename = path.resolve(sourceFile.fileName);
539
- const normalizedPublicApiFilename = toComparableAbsolutePath(publicApiFilename);
540
- if (normalizedPublicApiFilename === normalizedSourceFilename) {
541
- continue;
542
- }
543
- if (!isPublicApiFile(publicApiFilename, state, normalizedRepoRoot)) {
544
- continue;
545
- }
546
- if (!sourceFileExportsSymbol(sourceFile, checker, targetSymbol)) {
547
- continue;
548
- }
549
- usages.push({
550
- isTestFile: isTestFile(publicApiFilename, state, normalizedRepoRoot),
551
- });
552
- }
553
- return usages;
554
- };
555
- /**
556
- * Collects concrete usages of one exported element across the program.
557
- * @param program TypeScript program.
558
- * @param sourceFilename Source filename where export is defined.
559
- * @param state Normalized rule options.
560
- * @param repoRoot Absolute repository root used for test-file classification.
561
- * @param exportedElement Exported element to classify.
562
- * @returns Concrete usages for the exported element.
563
- * @example
564
- * ```typescript
565
- * const usages = collectCrossFileUsages(program, "/repo/src/feature.ts", state, "/repo", exportedElement);
566
- * ```
567
- */
568
- const collectCrossFileUsages = (program, sourceFilename, state, repoRoot, exportedElement) => {
569
- const checker = program.getTypeChecker();
570
- const targetSymbol = getExportedSymbol(program, sourceFilename, exportedElement.exportedName);
571
- if (targetSymbol === void 0) {
572
- return [];
573
- }
574
- const normalizedSourceFilename = toComparableAbsolutePath(sourceFilename);
575
- const normalizedRepoRoot = path.resolve(repoRoot);
576
- const usages = collectPublicApiExposureUsages(program, sourceFilename, state, repoRoot, targetSymbol);
577
- for (const sourceFile of program.getSourceFiles()) {
578
- if (sourceFile.isDeclarationFile) {
579
- continue;
580
- }
581
- const consumerFilename = path.resolve(sourceFile.fileName);
582
- const normalizedConsumerFilename = toComparableAbsolutePath(consumerFilename);
583
- if (normalizedConsumerFilename === normalizedSourceFilename) {
584
- continue;
585
- }
586
- const consumerIsTestFile = isTestFile(consumerFilename, state, normalizedRepoRoot);
587
- collectConcreteUsagesFromSourceFile(sourceFile, checker, targetSymbol, exportedElement, consumerIsTestFile, usages);
588
- }
589
- return usages;
590
- };
591
- /**
592
- * Classifies one exported name based on cross-file usages.
593
- * @param usages Collected usages.
594
- * @returns Classification label.
595
- * @example
596
- * ```typescript
597
- * const classification = classifyExportUsage("feature", usages);
598
- * ```
599
- */
600
- const classifyExportUsage = (usages) => {
601
- if (usages.length === 0) {
602
- return "unused";
603
- }
604
- for (const usage of usages) {
605
- if (!usage.isTestFile) {
606
- return "production";
607
- }
608
- }
609
- return "test-only";
610
- };
611
- export { classifyExportUsage, collectCrossFileUsages, collectExportedElements, getTypeScriptProgram, };
612
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tdW51c2VkLWV4cG9ydHMtdXRpbGl0aWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RvbWFpbi9hcmNoaXRlY3R1cmUvbm8tdW51c2VkLWV4cG9ydHMvbm8tdW51c2VkLWV4cG9ydHMtdXRpbGl0aWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN2RCxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFTakMsT0FBTyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQVcxRTs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxTQUFpQixFQUFVLEVBQUU7SUFDN0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFFN0QsT0FBTyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7QUFDcEMsQ0FBQyxDQUFDO0FBRUY7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFFBQVEsR0FBRyxDQUFDLEtBQWMsRUFBdUMsRUFBRSxDQUN2RSxLQUFLLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7SUFDekMsQ0FBQyxDQUFFLEtBQWlDO0lBQ3BDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUViOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sa0JBQWtCLEdBQUcsQ0FDekIsS0FBYyxFQUNkLEdBQVcsRUFDUyxFQUFFO0lBQ3RCLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvQixNQUFNLFFBQVEsR0FBRyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMvQixPQUFPLE9BQU8sUUFBUSxLQUFLLFFB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O0FBQ0gsTUFBTSxtQkFBbUIsR0FBRyxDQUMxQixNQUFxQixFQUNrQixFQUFFO0lBQ3pDLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN4QixPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRUQsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3RCLE9BQU8sWUFBWSxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQyxDQUFDO0FBRUYsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixzQkFBc0IsRUFDdEIsdUJBQXVCLEVBQ3ZCLG9CQUFvQixHQUNyQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBBU1QsIFJ1bGUgfSBmcm9tIFwiZXNsaW50XCI7XG5cbmltcG9ydCB7IEVTTGludFV0aWxzIH0gZnJvbSBcIkB0eXBlc2NyaXB0LWVzbGludC91dGlsc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0ICogYXMgdHMgZnJvbSBcInR5cGVzY3JpcHRcIjtcblxuaW1wb3J0IHR5cGUge1xuICBFeHBvcnRlZEVsZW1lbnQsXG4gIEV4cG9ydEtpbmQsXG4gIEV4cG9ydFVzYWdlLFxuICBOb1VudXNlZEV4cG9ydHNTdGF0ZSxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcblxuaW1wb3J0IHsgaXNQdWJsaWNBcGlGaWxlLCBpc1Rlc3RGaWxlIH0gZnJvbSBcIi4vbm8tdW51c2VkLWV4cG9ydHMtb3B0aW9uc1wiO1xuXG4vKiogTG9jYWwgdG9wLWxldmVsIGRlY2xhcmF0aW9uIGRpc2NvdmVyZWQgd2hlbiBjb2xsZWN0aW5nIGV4cG9ydCBzb3VyY2VzLiAqL1xuaW50ZXJmYWNlIExvY2FsRGVjbGFyYXRpb24ge1xuICAvKiogRXhwb3J0IGtpbmQgaW1wbGllZCBieSB0aGUgZGVjbGFyYXRpb24uICovXG4gIGtpbmQ6IEV4cG9ydEtpbmQ7XG5cbiAgLyoqIERlY2xhcmF0aW9uIHN0YXRlbWVudCB1c2VkIGZvciBkaWFnbm9zdGljcy4gKi9cbiAgbm9kZTogQVNULlByb2dyYW1bXCJib2R5XCJdW251bWJlcl07XG59XG5cbi8qKlxuICogTm9ybWFsaXplcyBhbiBhYnNvbHV0ZSBmaWxlIHBhdGggZm9yIHNhZmUgZXF1YWxpdHkgY2hlY2tzLlxuICogQHBhcmFtIGlucHV0UGF0aCBDYW5kaWRhdGUgcGF0aC5cbiAqIEByZXR1cm5zIE5vcm1hbGl6ZWQgYWJzb2x1dGUgcGF0aCBzdWl0YWJsZSBmb3IgY3Jvc3MtcGxhdGZvcm0gY29tcGFyaXNvbnMuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY29tcGFyYWJsZSA9IHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aChcIi9yZXBvL3NyYy9mZWF0dXJlLnRzXCIpO1xuICogYGBgXG4gKi9cbmNvbnN0IHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aCA9IChpbnB1dFBhdGg6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGFic29sdXRlUGF0aCA9IHBhdGgubm9ybWFsaXplKHBhdGgucmVzb2x2ZShpbnB1dFBhdGgpKTtcblxuICByZXR1cm4gYWJzb2x1dGVQYXRoLnRvTG93ZXJDYXNlKCk7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIG9uZSB1bmtub3duIHZhbHVlIGludG8gYW4gaW5kZXhhYmxlIHJlY29yZC5cbiAqIEBwYXJhbSB2YWx1ZSBDYW5kaWRhdGUgdmFsdWUuXG4gKiBAcmV0dXJucyBSZWNvcmQgdmlldyB3aGVuIHRoZSB2YWx1ZSBpcyBvYmplY3QtbGlrZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZWNvcmQgPSBhc1JlY29yZCh7IHR5cGU6IFwiSWRlbnRpZmllclwiIH0pO1xuICogYGBgXG4gKi9cbmNvbnN0IGFzUmVjb3JkID0gKHZhbHVlOiB1bmtub3duKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQgPT5cbiAgdmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiXG4gICAgPyAodmFsdWUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pXG4gICAgOiB2b2lkIDA7XG5cbi8qKlxuICogUmVhZHMgb25lIHN0cmluZyBwcm9wZXJ0eSBmcm9tIGFuIG9iamVjdC1saWtlIHZhbHVlLlxuICogQHBhcmFtIHZhbHVlIENhbmRpZGF0ZSBvYmplY3QuXG4gKiBAcGFyYW0ga2V5IExvb2t1cCBrZXkgdXNlZCB0byByZWFkIHRoZSBwcm9wZXJ0eS5cbiAqIEByZXR1cm5zIFN0cmluZyB2YWx1ZSB3aGVuIHByZXNlbnQuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbmFtZSA9IHJlYWRTdHJpbmdQcm9wZXJ0eSh7IG5hbWU6IFwiZmVhdHVyZVwiIH0sIFwibmFtZVwiKTtcbiAqIGBgYFxuICovXG5jb25zdCByZWFkU3RyaW5nUHJvcGVydHkgPSAoXG4gIHZhbHVlOiB1bmtub3duLFxuICBrZXk6IHN0cmluZyxcbik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IHJlY29yZCA9IGFzUmVjb3JkKHZhbHVlKTtcbiAgY29uc3QgcHJvcGVydHkgPSByZWNvcmQ/LltrZXldO1xuICByZXR1cm4gdHlwZW9mIHByb3BlcnR5ID09PSBcInN0cmluZ1wiID8gcHJvcGVydHkgOiB2b2lkIDA7XG59O1xuXG4vKipcbiAqIFJlYWRzIG9uZSBhcnJheSBwcm9wZXJ0eSBmcm9tIGFuIG9iamVjdC1saWtlIHZhbHVlLlxuICogQHBhcmFtIHZhbHVlIENhbmRpZGF0ZSBvYmplY3QuXG4gKiBAcGFyYW0ga2V5IExvb2t1cCBrZXkgdXNlZCB0byByZWFkIHRoZSBwcm9wZXJ0eS5cbiAqIEByZXR1cm5zIEFycmF5IHZhbHVlIHdoZW4gcHJlc2VudC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBpdGVtcyA9IHJlYWRBcnJheVByb3BlcnR5KHsgZWxlbWVudHM6IFsxLCAyXSB9LCBcImVsZW1lbnRzXCIpO1xuICogYGBgXG4gKi9cbmNvbnN0IHJlYWRBcnJheVByb3BlcnR5ID0gKFxuICB2YWx1ZTogdW5rbm93bixcbiAga2V5OiBzdHJpbmcsXG4pOiB1bmRlZmluZWQgfCB1bmtub3duW10gPT4ge1xuICBjb25zdCByZWNvcmQgPSBhc1JlY29yZCh2YWx1ZSk7XG4gIGNvbnN0IHByb3BlcnR5ID0gcmVjb3JkPy5ba2V5XTtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkocHJvcGVydHkpID8gcHJvcGVydHkgOiB2b2lkIDA7XG59O1xuXG4vKipcbiAqIFJlc29sdmVzIFR5cGVTY3JpcHQgcGFyc2VyIHNlcnZpY2VzIHByb2dyYW0gd2hlbiBhdmFpbGFibGUuXG4gKiBAcGFyYW0gY29udGV4dCBSdWxlIGNvbnRleHQuXG4gKiBAcmV0dXJucyBUeXBlU2NyaXB0IHByb2dyYW0gd2hlbiBhdmFpbGFibGUuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcHJvZ3JhbSA9IGdldFR5cGVTY3JpcHRQcm9ncmFtKGNvbnRleHQpO1xuICogYGBgXG4gKi9cbmNvbnN0IGdldFR5cGVTY3JpcHRQcm9ncmFtID0gKFxuICBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0LFxuKTogdHMuUHJvZ3JhbSB8IHVuZGVmaW5lZCA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc2VydmljZXMgPSBFU0xpbnRVdGlscy5nZXRQYXJzZXJTZXJ2aWNlcyhjb250ZXh0IGFzIG5ldmVyKTtcbiAgICByZXR1cm4gc2VydmljZXMucHJvZ3JhbTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxufTtcblxuLyoqXG4gKiBDb2xsZWN0cyBpZGVudGlmaWVyIG5hbWVzIGZyb20gb25lIHZhcmlhYmxlIHBhdHRlcm4uXG4gKiBAcGFyYW0gbm9kZSBWYXJpYWJsZSBwYXR0ZXJuIGNhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIElkZW50aWZpZXIgbmFtZXMgZGVjbGFyZWQgYnkgdGhlIHBhdHRlcm4uXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbmFtZXMgPSBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyhwYXR0ZXJuKTtcbiAqIGBgYFxuICovXG5jb25zdCBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyA9IChub2RlOiB1bmtub3duKTogc3RyaW5nW10gPT4ge1xuICBjb25zdCBwYXR0ZXJuID0gYXNSZWNvcmQobm9kZSk7XG5cbiAgaWYgKHBhdHRlcm4gPT09IHZvaWQgMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHBhdHRlcm5UeXBlID0gcmVhZFN0cmluZ1Byb3BlcnR5KHBhdHRlcm4sIFwidHlwZVwiKTtcblxuICBpZiAocGF0dGVyblR5cGUgPT09IFwiSWRlbnRpZmllclwiKSB7XG4gICAgY29uc3QgbmFtZSA9IHJlYWRTdHJpbmdQcm9wZXJ0eShwYXR0ZXJuLCBcIm5hbWVcIik7XG4gICAgcmV0dXJuIG5hbWUgPT09IHZvaWQgMCA/IFtdIDogW25hbWVdO1xuICB9XG5cbiAgaWYgKHBhdHRlcm5UeXBlID09PSBcIlJlc3RFbGVtZW50XCIpIHtcbiAgICByZXR1cm4gY29sbGVjdFBhdHRlcm5JZGVudGlmaWVyTmFtZXMocGF0dGVybltcImFyZ3VtZW50XCJdKTtcbiAgfVxuXG4gIGlmIChwYXR0ZXJuVHlwZSA9PT0gXCJBc3NpZ25tZW50UGF0dGVyblwiKSB7XG4gICAgcmV0dXJuIGNvbGxlY3RQYXR0ZXJuSWRlbnRpZmllck5hbWVzKHBhdHRlcm5bXCJsZWZ0XCJdKTtcbiAgfVxuXG4gIGlmIChwYXR0ZXJuVHlwZSA9PT0gXCJBcnJheVBhdHRlcm5cIikge1xuICAgIHJldHVybiAocmVhZEFycmF5UHJvcGVydHkocGF0dGVybiwgXCJlbGVtZW50c1wiKSA/PyBbXSkuZmxhdE1hcCgoZWxlbWVudCkgPT5cbiAgICAgIGNvbGxlY3RQYXR0ZXJuSWRlbnRpZmllck5hbWVzKGVsZW1lbnQpLFxuICAgICk7XG4gIH1cblxuICBpZiAocGF0dGVyblR5cGUgPT09IFwiT2JqZWN0UGF0dGVyblwiKSB7XG4gICAgcmV0dXJuIChyZWFkQXJyYXlQcm9wZXJ0eShwYXR0ZXJuLCBcInByb3BlcnRpZXNcIikgPz8gW10pLmZsYXRNYXAoXG4gICAgICAocHJvcGVydHkpID0+IHtcbiAgICAgICAgaWYgKHJlYWRTdHJpbmdQcm9wZXJ0eShwcm9wZXJ0eSwgXCJ0eXBlXCIpID09PSBcIlJlc3RFbGVtZW50XCIpIHtcbiAgICAgICAgICByZXR1cm4gY29sbGVjdFBhdHRlcm5JZGVudGlmaWVyTmFtZXMoXG4gICAgICAgICAgICBhc1JlY29yZChwcm9wZXJ0eSk/LltcImFyZ3VtZW50XCJdLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29sbGVjdFBhdHRlcm5JZGVudGlmaWVyTmFtZXMoYXNSZWNvcmQocHJvcGVydHkpPy5bXCJ2YWx1ZVwiXSk7XG4gICAgICB9LFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gW107XG59O1xuXG4vKipcbiAqIFJlYWRzIG9uZSBleHBvcnQgc3BlY2lmaWVyIG5hbWUuXG4gKiBAcGFyYW0gc3BlY2lmaWVyIEV4cG9ydCBzcGVjaWZpZXIgY2FuZGlkYXRlLlxuICogQHJldHVybnMgRXhwb3J0ZWQgbmFtZSB3aGVuIGF2YWlsYWJsZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBuYW1lID0gZ2V0RXhwb3J0U3BlY2lmaWVyTmFtZShzcGVjaWZpZXIpO1xuICogYGBgXG4gKi9cbmNvbnN0IGdldEV4cG9ydFNwZWNpZmllck5hbWUgPSAoc3BlY2lmaWVyOiB1bmtub3duKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgY2FuZGlkYXRlID0gYXNSZWNvcmQoc3BlY2lmaWVyKTtcbiAgY29uc3QgZXhwb3J0ZWROYW1lID0gcmVhZFN0cmluZ1Byb3BlcnR5KGNhbmRpZGF0ZT8uW1wiZXhwb3J0ZWRcIl0sIFwibmFtZVwiKTtcblxuICBpZiAodHlwZW9mIGV4cG9ydGVkTmFtZSA9PT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBleHBvcnRlZE5hbWU7XG4gIH1cblxuICBjb25zdCBsb2NhbE5hbWUgPSByZWFkU3RyaW5nUHJvcGVydHkoY2FuZGlkYXRlPy5bXCJsb2NhbFwiXSwgXCJuYW1lXCIpO1xuXG4gIHJldHVybiB0eXBlb2YgbG9jYWxOYW1lID09PSBcInN0cmluZ1wiID8gbG9jYWxOYW1lIDogdm9pZCAwO1xufTtcblxuLyoqXG4gKiBSZWFkcyBvbmUgbG9jYWwgZXhwb3J0IHNwZWNpZmllciBuYW1lLlxuICogQHBhcmFtIHNwZWNpZmllciBFeHBvcnQgc3BlY2lmaWVyIGNhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIExvY2FsIHNwZWNpZmllciBuYW1lIHdoZW4gYXZhaWxhYmxlLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IG5hbWUgPSBnZXRFeHBvcnRTcGVjaWZpZXJMb2NhbE5hbWUoc3BlY2lmaWVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBnZXRFeHBvcnRTcGVjaWZpZXJMb2NhbE5hbWUgPSAoXG4gIHNwZWNpZmllcjogdW5rbm93bixcbik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IGNhbmRpZGF0ZSA9IGFzUmVjb3JkKHNwZWNpZmllcik7XG5cbiAgcmV0dXJuIHJlYWRTdHJpbmdQcm9wZXJ0eShjYW5kaWRhdGU/LltcImxvY2FsXCJdLCBcIm5hbWVcIik7XG59O1xuXG4vKipcbiAqIENvbGxlY3RzIHRvcC1sZXZlbCBkZWNsYXJhdGlvbiBuYW1lcyBvd25lZCBieSB0aGUgY3VycmVudCBtb2R1bGUuXG4gKiBAcGFyYW0gYm9keSBQcm9ncmFtIGJvZHkgc3RhdGVtZW50cy5cbiAqIEByZXR1cm5zIE1hcCBmcm9tIGxvY2FsbHkgZGVjbGFyZWQgbmFtZSB0byBpdHMgZGVjbGFyYXRpb24gbWV0YWRhdGEuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZGVjbGFyYXRpb25zID0gY29sbGVjdExvY2FsRGVjbGFyYXRpb25OYW1lcyhwcm9ncmFtLmJvZHkpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNvbGxlY3RMb2NhbERlY2xhcmF0aW9uTmFtZXMgPSAoXG4gIGJvZHk6IEFTVC5Qcm9ncmFtW1wiYm9keVwiXSxcbik6IE1hcDxzdHJpbmcsIExvY2FsRGVjbGFyYXRpb24+ID0+IHtcbiAgY29uc3QgZGVjbGFyYXRpb25OYW1lcyA9IG5ldyBNYXA8c3RyaW5nLCBMb2NhbERlY2xhcmF0aW9uPigpO1xuXG4gIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJvZHkpIHtcbiAgICBjb25zdCBkZWNsYXJhdGlvbkNhbmRpZGF0ZSA9XG4gICAgICBzdGF0ZW1lbnQudHlwZSA9PT0gXCJFeHBvcnROYW1lZERlY2xhcmF0aW9uXCIgJiZcbiAgICAgIHN0YXRlbWVudC5kZWNsYXJhdGlvbiAhPT0gbnVsbCAmJlxuICAgICAgc3RhdGVtZW50LmRlY2xhcmF0aW9uICE9PSB2b2lkIDBcbiAgICAgICAgPyBzdGF0ZW1lbnQuZGVjbGFyYXRpb25cbiAgICAgICAgOiBzdGF0ZW1lbnQ7XG4gICAgY29uc3QgZGVjbGFyYXRpb25DYW5kaWRhdGVSZWNvcmQgPSBhc1JlY29yZChkZWNsYXJhdGlvbkNhbmRpZGF0ZSk7XG4gICAgY29uc3QgZGVjbGFyYXRpb25DYW5kaWRhdGVUeXBlID0gcmVhZFN0cmluZ1Byb3BlcnR5KFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGUsXG4gICAgICBcInR5cGVcIixcbiAgICApO1xuXG4gICAgaWYgKFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGVSZWNvcmQgPT09IHZvaWQgMCB8fFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGVUeXBlID09PSB2b2lkIDBcbiAgICApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSA9PT0gXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIgfHxcbiAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSA9PT0gXCJDbGFzc0RlY2xhcmF0aW9uXCIgfHxcbiAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSA9PT0gXCJUU0VudW1EZWNsYXJhdGlvblwiIHx8XG4gICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNJbnRlcmZhY2VEZWNsYXJhdGlvblwiIHx8XG4gICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNUeXBlQWxpYXNEZWNsYXJhdGlvblwiXG4gICAgKSB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvbk5hbWUgPSByZWFkU3RyaW5nUHJvcGVydHkoXG4gICAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlUmVjb3JkW1wiaWRcIl0sXG4gICAgICAgIFwibmFtZVwiLFxuICAgICAgKTtcblxuICAgICAgaWYgKGRlY2xhcmF0aW9uTmFtZSAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGRlY2xhcmF0aW9uTmFtZXMuc2V0KGRlY2xhcmF0aW9uTmFtZSwge1xuICAgICAgICAgIGtpbmQ6XG4gICAgICAgICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNJbnRlcmZhY2VEZWNsYXJhdGlvblwiIHx8XG4gICAgICAgICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNUeXBlQWxpYXNEZWNsYXJhdGlvblwiXG4gICAgICAgICAgICAgID8gXCJ0eXBlXCJcbiAgICAgICAgICAgICAgOiBcInZhbHVlXCIsXG4gICAgICAgICAgbm9kZTogc3RhdGVtZW50LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSAhPT0gXCJWYXJpYWJsZURlY2xhcmF0aW9uXCIpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGRlY2xhcmF0aW9ucyA9IHJlYWRBcnJheVByb3BlcnR5KFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGVSZWNvcmQsXG4gICAgICBcImRlY2xhcmF0aW9uc1wiLFxuICAgICk7XG5cbiAgICBpZiAoZGVjbGFyYXRpb25zID09PSB2b2lkIDApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgZGVjbGFyYXRpb25zKSB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvblJlY29yZCA9IGFzUmVjb3JkKGRlY2xhcmF0aW9uKTtcblxuICAgICAgaWYgKGRlY2xhcmF0aW9uUmVjb3JkID09PSB2b2lkIDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyhcbiAgICAgICAgZGVjbGFyYXRpb25SZWNvcmRbXCJpZFwiXSxcbiAgICAgICkpIHtcbiAgICAgICAgZGVjbGFyYXRpb25OYW1lcy5zZXQobmFtZSwgeyBraW5kOiBcInZhbHVlXCIsIG5vZGU6IHN0YXRlbWVudCB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZGVjbGFyYXRpb25OYW1lcztcbn07XG5cbi8qKlxuICogQ29sbGVjdHMgZXhwb3J0ZWQgZWxlbWVudHMgZnJvbSBvbmUgcHJvZ3JhbSBib2R5LlxuICogQHBhcmFtIGJvZHkgUHJvZ3JhbSBib2R5IHN0YXRlbWVudHMuXG4gKiBAcmV0dXJucyBFeHBvcnRlZCBlbGVtZW50cyBpbiBkZWNsYXJhdGlvbiBvcmRlci5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBleHBvcnRlZCA9IGNvbGxlY3RFeHBvcnRlZEVsZW1lbnRzKHByb2dyYW0uYm9keSk7XG4gKiBgYGBcbiAqL1xuY29uc3QgY29sbGVjdEV4cG9ydGVkRWxlbWVudHMgPSAoXG4gIGJvZHk6IEFTVC5Qcm9ncmFtW1wiYm9keVwiXSxcbik6IEV4cG9ydGVkRWxlbWVudFtdID0+IHtcbiAgY29uc3QgZXhwb3J0ZWRFbGVtZW50czogRXhwb3J0ZWRFbGVtZW50W10gPSBbXTtcbiAgY29uc3QgbG9jYWxEZWNsYXJhdGlvbk5hbWVzID0gY29sbGVjdExvY2FsRGVjbGFyYXRpb25OYW1lcyhib2R5KTtcblxuICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBib2R5KSB7XG4gICAgaWYgKHN0YXRlbWVudC50eXBlID09PSBcIkV4cG9ydERlZmF1bHREZWNsYXJhdGlvblwiKSB7XG4gICAgICBleHBvcnRlZEVsZW1lbnRzLnB1c2goe1xuICAgICAgICBleHBvcnRlZE5hbWU6IFwiZGVmYXVsdFwiLFxuICAgICAgICBleHBvcnRLaW5kOiBcInZhbHVlXCIsXG4gICAgICAgIG5vZGU6IHN0YXRlbWVudCxcbiAgICAgIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlbWVudC50eXBlICE9PSBcIkV4cG9ydE5hbWVkRGVjbGFyYXRpb25cIikge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlbWVudC5zb3VyY2UgIT09IG51bGwgJiYgc3RhdGVtZW50LnNvdXJjZSAhPT0gdm9pZCAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGVtZW50LmRlY2xhcmF0aW9uICE9PSBudWxsICYmIHN0YXRlbWVudC5kZWNsYXJhdGlvbiAhPT0gdm9pZCAwKSB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGFzUmVjb3JkKHN0YXRlbWVudC5kZWNsYXJhdGlvbik7XG5cbiAgICAgIGlmIChyZWFkU3RyaW5nUHJvcGVydHkoZGVjbGFyYXRpb24sIFwidHlwZVwiKSA9PT0gXCJWYXJpYWJsZURlY2xhcmF0aW9uXCIpIHtcbiAgICAgICAgZm9yIChjb25zdCB2YXJpYWJsZSBvZiByZWFkQXJyYXlQcm9wZXJ0eShkZWNsYXJhdGlvbiwgXCJkZWNsYXJhdGlvbnNcIikgPz9cbiAgICAgICAgICBbXSkge1xuICAgICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyhcbiAgICAgICAgICAgIGFzUmVjb3JkKHZhcmlhYmxlKT8uW1wiaWRcIl0sXG4gICAgICAgICAgKSkge1xuICAgICAgICAgICAgZXhwb3J0ZWRFbGVtZW50cy5wdXNoKHtcbiAgICAgICAgICAgICAgZXhwb3J0ZWROYW1lOiBuYW1lLFxuICAgICAgICAgICAgICBleHBvcnRLaW5kOiBcInZhbHVlXCIsXG4gICAgICAgICAgICAgIG5vZGU6IHN0YXRlbWVudCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZGVjbGFyYXRpb25OYW1lID0gcmVhZFN0cmluZ1Byb3BlcnR5KGRlY2xhcmF0aW9uPy5bXCJpZFwiXSwgXCJuYW1lXCIpO1xuICAgICAgICBjb25zdCBkZWNsYXJhdGlvblR5cGUgPSByZWFkU3RyaW5nUHJvcGVydHkoZGVjbGFyYXRpb24sIFwidHlwZVwiKTtcbiAgICAgICAgY29uc3QgZXhwb3J0S2luZDogRXhwb3J0S2luZCA9XG4gICAgICAgICAgZGVjbGFyYXRpb25UeXBlID09PSBcIlRTSW50ZXJmYWNlRGVjbGFyYXRpb25cIiB8fFxuICAgICAgICAgIGRlY2xhcmF0aW9uVHlwZSA9PT0gXCJUU1R5cGVBbGlhc0RlY2xhcmF0aW9uXCJcbiAgICAgICAgICAgID8gXCJ0eXBlXCJcbiAgICAgICAgICAgIDogXCJ2YWx1ZVwiO1xuXG4gICAgICAgIGlmICh0eXBlb2YgZGVjbGFyYXRpb25OYW1lID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgZXhwb3J0ZWRFbGVtZW50cy5wdXNoKHtcbiAgICAgICAgICAgIGV4cG9ydGVkTmFtZTogZGVjbGFyYXRpb25OYW1lLFxuICAgICAgICAgICAgZXhwb3J0S2luZCxcbiAgICAgICAgICAgIG5vZGU6IHN0YXRlbWVudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNwZWNpZmllciBvZiBzdGF0ZW1lbnQuc3BlY2lmaWVycykge1xuICAgICAgY29uc3QgbG9jYWxOYW1lID0gZ2V0RXhwb3J0U3BlY2lmaWVyTG9jYWxOYW1lKHNwZWNpZmllcik7XG4gICAgICBjb25zdCBsb2NhbERlY2xhcmF0aW9uID1cbiAgICAgICAgbG9jYWxOYW1lID09PSB2b2lkIDAgPyB2b2lkIDAgOiBsb2NhbERlY2xhcmF0aW9uTmFtZXMuZ2V0KGxvY2FsTmFtZSk7XG5cbiAgICAgIGlmIChsb2NhbERlY2xhcmF0aW9uID09PSB2b2lkIDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4cG9ydGVkTmFtZSA9IGdldEV4cG9ydFNwZWNpZmllck5hbWUoc3BlY2lmaWVyKTtcblxuICAgICAgaWYgKGV4cG9ydGVkTmFtZSAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGNvbnN0IHN0YXRlbWVudEV4cG9ydEtpbmQgPSByZWFkU3RyaW5nUHJvcGVydHkoc3RhdGVtZW50LCBcImV4cG9ydEtpbmRcIik7XG4gICAgICAgIGNvbnN0IHNwZWNpZmllckV4cG9ydEtpbmQgPSByZWFkU3RyaW5nUHJvcGVydHkoc3BlY2lmaWVyLCBcImV4cG9ydEtpbmRcIik7XG4gICAgICAgIGNvbnN0IGlzVHlwZU9ubHlFeHBvcnQgPVxuICAgICAgICAgIHN0YXRlbWVudEV4cG9ydEtpbmQgPT09IFwidHlwZVwiIHx8IHNwZWNpZmllckV4cG9ydEtpbmQgPT09IFwidHlwZVwiO1xuXG4gICAgICAgIGV4cG9ydGVkRWxlbWVudHMucHVzaCh7XG4gICAgICAgICAgZXhwb3J0ZWROYW1lLFxuICAgICAgICAgIGV4cG9ydEtpbmQ6IGlzVHlwZU9ubHlFeHBvcnQgPyBcInR5cGVcIiA6IGxvY2FsRGVjbGFyYXRpb24ua2luZCxcbiAgICAgICAgICBub2RlOiBsb2NhbERlY2xhcmF0aW9uLm5vZGUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBleHBvcnRlZEVsZW1lbnRzO1xufTtcblxuLyoqXG4gKiBSZXNvbHZlcyBvbmUgc3ltYm9sIHRvIGl0cyBjYW5vbmljYWwgdGFyZ2V0LlxuICogQHBhcmFtIHN5bWJvbCBDYW5kaWRhdGUgc3ltYm9sLlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCBjaGVja2VyLlxuICogQHJldHVybnMgUmVzb2x2ZWQgY2Fub25pY2FsIHN5bWJvbC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZXNvbHZlZCA9IHJlc29sdmVDYW5vbmljYWxTeW1ib2woc3ltYm9sLCBjaGVja2VyKTtcbiAqIGBgYFxuICovXG5jb25zdCByZXNvbHZlQ2Fub25pY2FsU3ltYm9sID0gKFxuICBzeW1ib2w6IHRzLlN5bWJvbCxcbiAgY2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4pOiB0cy5TeW1ib2wgPT4ge1xuICBpZiAoKHN5bWJvbC5mbGFncyAmIHRzLlN5bWJvbEZsYWdzLkFsaWFzKSA9PT0gMCkge1xuICAgIHJldHVybiBzeW1ib2w7XG4gIH1cblxuICB0cnkge1xuICAgIHJldHVybiBjaGVja2VyLmdldEFsaWFzZWRTeW1ib2woc3ltYm9sKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHN5bWJvbDtcbiAgfVxufTtcblxuLyoqXG4gKiBCdWlsZHMgZGVjbGFyYXRpb24tc2l0ZSBrZXlzIGZvciBzeW1ib2wgaWRlbnRpdHkgbWF0Y2hpbmcuXG4gKiBAcGFyYW0gc3ltYm9sIFN5bWJvbCBiZWluZyBjb21wYXJlZC5cbiAqIEByZXR1cm5zIERlY2xhcmF0aW9uIGtleXMgZGVzY3JpYmluZyB3aGVyZSB0aGlzIHN5bWJvbCBpcyBkZWNsYXJlZC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBrZXlzID0gZ2V0RGVjbGFyYXRpb25LZXlzKHN5bWJvbCk7XG4gKiBgYGBcbiAqL1xuY29uc3QgZ2V0RGVjbGFyYXRpb25LZXlzID0gKHN5bWJvbDogdHMuU3ltYm9sKTogU2V0PHN0cmluZz4gPT4ge1xuICBjb25zdCBkZWNsYXJhdGlvbnMgPSBzeW1ib2wuZGVjbGFyYXRpb25zID8/IFtdO1xuXG4gIHJldHVybiBuZXcgU2V0KFxuICAgIGRlY2xhcmF0aW9ucy5tYXAoKGRlY2xhcmF0aW9uKSA9PiB7XG4gICAgICBjb25zdCBzb3VyY2VGaWxlbmFtZSA9IGRlY2xhcmF0aW9uLmdldFNvdXJjZUZpbGUoKS5maWxlTmFtZTtcbiAgICAgIHJldHVybiBgJHtzb3VyY2VGaWxlbmFtZX06JHtTdHJpbmcoZGVjbGFyYXRpb24ucG9zKX06JHtTdHJpbmcoZGVjbGFyYXRpb24uZW5kKX1gO1xuICAgIH0pLFxuICApO1xufTtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0d28gc3ltYm9scyByZWZlcmVuY2UgdGhlIHNhbWUgZGVjbGFyYXRpb24gc2l0ZS5cbiAqIEBwYXJhbSBsZWZ0IExlZnQtaGFuZCBzeW1ib2wgY2FuZGlkYXRlLlxuICogQHBhcmFtIHJpZ2h0IFJpZ2h0LWhhbmQgc3ltYm9sIGNhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiBib3RoIHN5bWJvbHMgaWRlbnRpZnkgdGhlIHNhbWUgZGVjbGFyYXRpb24uXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3Qgc2FtZSA9IGlzU2FtZVN5bWJvbChsZWZ0LCByaWdodCk7XG4gKiBgYGBcbiAqL1xuY29uc3QgaXNTYW1lU3ltYm9sID0gKGxlZnQ6IHRzLlN5bWJvbCwgcmlnaHQ6IHRzLlN5bWJvbCk6IGJvb2xlYW4gPT4ge1xuICBpZiAobGVmdCA9PT0gcmlnaHQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGNvbnN0IGxlZnRLZXlzID0gZ2V0RGVjbGFyYXRpb25LZXlzKGxlZnQpO1xuICBjb25zdCByaWdodEtleXMgPSBnZXREZWNsYXJhdGlvbktleXMocmlnaHQpO1xuXG4gIGZvciAoY29uc3Qga2V5IG9mIGxlZnRLZXlzKSB7XG4gICAgaWYgKHJpZ2h0S2V5cy5oYXMoa2V5KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuLyoqXG4gKiBSZXNvbHZlcyBvbmUgZXhwb3J0ZWQgc3ltYm9sIGJ5IG5hbWUgZnJvbSBhIHNvdXJjZSBmaWxlLlxuICogQHBhcmFtIHByb2dyYW0gVHlwZVNjcmlwdCBwcm9ncmFtLlxuICogQHBhcmFtIHNvdXJjZUZpbGVuYW1lIFNvdXJjZSBmaWxlIHBhdGguXG4gKiBAcGFyYW0gZXhwb3J0ZWROYW1lIFB1YmxpYyBuYW1lIGV4cG9zZWQgYnkgdGhlIG1vZHVsZSBleHBvcnQgbGlzdC5cbiAqIEByZXR1cm5zIFN5bWJvbCB3aGVuIGZvdW5kLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHN5bWJvbCA9IGdldEV4cG9ydGVkU3ltYm9sKHByb2dyYW0sIHNvdXJjZUZpbGVuYW1lLCBcImZlYXR1cmVcIik7XG4gKiBgYGBcbiAqL1xuY29uc3QgZ2V0RXhwb3J0ZWRTeW1ib2wgPSAoXG4gIHByb2dyYW06IHRzLlByb2dyYW0sXG4gIHNvdXJjZUZpbGVuYW1lOiBzdHJpbmcsXG4gIGV4cG9ydGVkTmFtZTogc3RyaW5nLFxuKTogdHMuU3ltYm9sIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgY2hlY2tlciA9IHByb2dyYW0uZ2V0VHlwZUNoZWNrZXIoKTtcbiAgY29uc3Qgc291cmNlRmlsZSA9IHByb2dyYW1cbiAgICAuZ2V0U291cmNlRmlsZXMoKVxuICAgIC5maW5kKFxuICAgICAgKGZpbGUpID0+XG4gICAgICAgIHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aChmaWxlLmZpbGVOYW1lKSA9PT1cbiAgICAgICAgdG9Db21wYXJhYmxlQWJzb2x1dGVQYXRoKHNvdXJjZUZpbGVuYW1lKSxcbiAgICApO1xuXG4gIGlmIChzb3VyY2VGaWxlID09PSB2b2lkIDApIHtcbiAgICByZXR1cm4gdm9pZCAwO1xuICB9XG5cbiAgY29uc3QgbW9kdWxlU3ltYm9sID0gY2hlY2tlci5nZXRTeW1ib2xBdExvY2F0aW9uKHNvdXJjZUZpbGUpO1xuXG4gIGlmIChtb2R1bGVTeW1ib2wgPT09IHZvaWQgMCkge1xuICAgIHJldHVybiB2b2lkIDA7XG4gIH1cblxuICBjb25zdCBleHBvcnRlZFN5bWJvbCA9IGNoZWNrZXJcbiAgICAuZ2V0RXhwb3J0c09mTW9kdWxlKG1vZHVsZVN5bWJvbClcbiAgICAuZmluZCgoc3ltYm9sKSA9PiBzeW1ib2wuZ2V0TmFtZSgpID09PSBleHBvcnRlZE5hbWUpO1xuXG4gIGlmIChleHBvcnRlZFN5bWJvbCA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxuXG4gIHJldHVybiByZXNvbHZlQ2Fub25pY2FsU3ltYm9sKGV4cG9ydGVkU3ltYm9sLCBjaGVja2VyKTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgb25lIHNvdXJjZSBmaWxlIGV4cG9ydHMgdGhlIHRhcmdldCBzeW1ib2wuXG4gKiBAcGFyYW0gc291cmNlRmlsZSBTb3VyY2UgZmlsZSB0aGF0IG1heSBleHBvc2UgdGhlIHN5bWJvbC5cbiAqIEBwYXJhbSBjaGVja2VyIFR5cGVTY3JpcHQgY2hlY2tlci5cbiAqIEBwYXJhbSB0YXJnZXRTeW1ib2wgU3ltYm9sIGJlaW5nIGNsYXNzaWZpZWQuXG4gKiBAcmV0dXJucyBUcnVlIHdoZW4gb25lIG1vZHVsZSBleHBvcnQgcmVzb2x2ZXMgdG8gdGhlIHRhcmdldCBzeW1ib2wuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZXhwb3NlZCA9IHNvdXJjZUZpbGVFeHBvcnRzU3ltYm9sKHNvdXJjZUZpbGUsIGNoZWNrZXIsIHRhcmdldFN5bWJvbCk7XG4gKiBgYGBcbiAqL1xuY29uc3Qgc291cmNlRmlsZUV4cG9ydHNTeW1ib2wgPSAoXG4gIHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUsXG4gIGNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuICB0YXJnZXRTeW1ib2w6IHRzLlN5bWJvbCxcbik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCBtb2R1bGVTeW1ib2wgPSBjaGVja2VyLmdldFN5bWJvbEF0TG9jYXRpb24oc291cmNlRmlsZSk7XG5cbiAgaWYgKG1vZHVsZVN5bWJvbCA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9yIChjb25zdCBleHBvcnRlZFN5bWJvbCBvZiBjaGVja2VyLmdldEV4cG9ydHNPZk1vZHVsZShtb2R1bGVTeW1ib2wpKSB7XG4gICAgY29uc3QgcmVzb2x2ZWRTeW1ib2wgPSByZXNvbHZlQ2Fub25pY2FsU3ltYm9sKGV4cG9ydGVkU3ltYm9sLCBjaGVja2VyKTtcblxuICAgIGlmIChpc1NhbWVTeW1ib2wocmVzb2x2ZWRTeW1ib2wsIHRhcmdldFN5bWJvbCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYW4gaWRlbnRpZmllciBwYXJ0aWNpcGF0ZXMgaW4gb25lIGRlY2xhcmF0aW9uL2ltcG9ydC9leHBvcnQgc2l0ZS5cbiAqIEBwYXJhbSBpZGVudGlmaWVyIElkZW50aWZpZXIgbm9kZSB0byBldmFsdWF0ZS5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiB0aGUgaWRlbnRpZmllciBpcyBkZWNsYXJhdGlvbi1vbmx5IHN5bnRheC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBkZWNsYXJhdGlvbiA9IGlzRGVjbGFyYXRpb25Pbmx5SWRlbnRpZmllcihpZGVudGlmaWVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc0RlY2xhcmF0aW9uT25seUlkZW50aWZpZXIgPSAoaWRlbnRpZmllcjogdHMuSWRlbnRpZmllcik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCBwYXJlbnQgPSBpZGVudGlmaWVyLnBhcmVudDtcblxuICByZXR1cm4gKFxuICAgIHRzLmlzSW1wb3J0U3BlY2lmaWVyKHBhcmVudCkgfHxcbiAgICB0cy5pc0ltcG9ydENsYXVzZShwYXJlbnQpIHx8XG4gICAgdHMuaXNOYW1lc3BhY2VJbXBvcnQocGFyZW50KSB8fFxuICAgIHRzLmlzSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24ocGFyZW50KSB8fFxuICAgIHRzLmlzRXhwb3J0U3BlY2lmaWVyKHBhcmVudCkgfHxcbiAgICB0cy5pc1R5cGVBbGlhc0RlY2xhcmF0aW9uKHBhcmVudCkgfHxcbiAgICB0cy5pc0ludGVyZmFjZURlY2xhcmF0aW9uKHBhcmVudCkgfHxcbiAgICB0cy5pc1R5cGVQYXJhbWV0ZXJEZWNsYXJhdGlvbihwYXJlbnQpIHx8XG4gICAgKHRzLmlzVmFyaWFibGVEZWNsYXJhdGlvbihwYXJlbnQpICYmIHBhcmVudC5uYW1lID09PSBpZGVudGlmaWVyKSB8fFxuICAgICh0cy5pc0Z1bmN0aW9uRGVjbGFyYXRpb24ocGFyZW50KSAmJiBwYXJlbnQubmFtZSA9PT0gaWRlbnRpZmllcikgfHxcbiAgICAodHMuaXNDbGFzc0RlY2xhcmF0aW9uKHBhcmVudCkgJiYgcGFyZW50Lm5hbWUgPT09IGlkZW50aWZpZXIpIHx8XG4gICAgKHRzLmlzUGFyYW1ldGVyKHBhcmVudCkgJiYgcGFyZW50Lm5hbWUgPT09IGlkZW50aWZpZXIpXG4gICk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIG9uZSBpZGVudGlmaWVyIG5vZGUgYXBwZWFycyB1bmRlciBhIHR5cGUgbm9kZS5cbiAqIEBwYXJhbSBpZGVudGlmaWVyIENhbmRpZGF0ZSBpZGVudGlmaWVyLlxuICogQHJldHVybnMgVHJ1ZSB3aGVuIHRoZSBpZGVudGlmaWVyIGlzIGluc2lkZSB0eXBlLW9ubHkgc3ludGF4LlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHR5cGVQb3NpdGlvbiA9IGlzVHlwZVBvc2l0aW9uSWRlbnRpZmllcihpZGVudGlmaWVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc1R5cGVQb3NpdGlvbklkZW50aWZpZXIgPSAoaWRlbnRpZmllcjogdHMuSWRlbnRpZmllcik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCB2aXNpdE5vZGUgPSAoY3VycmVudDogdHMuTm9kZSk6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh0cy5pc1R5cGVRdWVyeU5vZGUoY3VycmVudCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAodHMuaXNUeXBlTm9kZShjdXJyZW50KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdHMuaXNFeHByZXNzaW9uU3RhdGVtZW50KGN1cnJlbnQpIHx8XG4gICAgICB0cy5pc0NhbGxFeHByZXNzaW9uKGN1cnJlbnQpIHx8XG4gICAgICB0cy5pc1Byb3BlcnR5QWNjZXNzRXhwcmVzc2lvbihjdXJyZW50KSB8fFxuICAgICAgdHMuaXNFbGVtZW50QWNjZXNzRXhwcmVzc2lvbihjdXJyZW50KSB8fFxuICAgICAgdHMuaXNWYXJpYWJsZURlY2xhcmF0aW9uKGN1cnJlbnQpIHx8XG4gICAgICB0cy5pc1JldHVyblN0YXRlbWVudChjdXJyZW50KVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICh0cy5pc1NvdXJjZUZpbGUoY3VycmVudCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmlzaXROb2RlKGN1cnJlbnQucGFyZW50KTtcbiAgfTtcblxuICByZXR1cm4gdmlzaXROb2RlKGlkZW50aWZpZXIpO1xufTtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBvbmUgaWRlbnRpZmllciBpcyBvbmUgY29uY3JldGUgdXNhZ2UgY2FuZGlkYXRlIGZvciB0aGUgZXhwb3J0IGtpbmQuXG4gKiBAcGFyYW0gaWRlbnRpZmllciBJZGVudGlmaWVyIG5vZGUuXG4gKiBAcGFyYW0gZXhwb3J0S2luZCBXaGV0aGVyIHR5cGUtb25seSBvciB2YWx1ZSB1c2FnZSBpcyByZXF1aXJlZC5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiB0aGUgaWRlbnRpZmllciBjYW4gc2F0aXNmeSB1c2FnZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBjb25jcmV0ZSA9IGlzQ29uY3JldGVVc2FnZUlkZW50aWZpZXIoaWRlbnRpZmllciwgXCJ2YWx1ZVwiKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc0NvbmNyZXRlVXNhZ2VJZGVudGlmaWVyID0gKFxuICBpZGVudGlmaWVyOiB0cy5JZGVudGlmaWVyLFxuICBleHBvcnRLaW5kOiBFeHBvcnRLaW5kLFxuKTogYm9vbGVhbiA9PiB7XG4gIGlmIChpc0RlY2xhcmF0aW9uT25seUlkZW50aWZpZXIoaWRlbnRpZmllcikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBpblR5cGVQb3NpdGlvbiA9IGlzVHlwZVBvc2l0aW9uSWRlbnRpZmllcihpZGVudGlmaWVyKTtcblxuICByZXR1cm4gZXhwb3J0S2luZCA9PT0gXCJ0eXBlXCIgPyBpblR5cGVQb3NpdGlvbiA6ICFpblR5cGVQb3NpdGlvbjtcbn07XG5cbi8qKlxuICogQXBwZW5kcyBjb25jcmV0ZSB1c2FnZXMgZnJvbSBvbmUgc291cmNlIGZpbGUgaW50byB0aGUgYWNjdW11bGF0b3IuXG4gKiBAcGFyYW0gc291cmNlRmlsZSBTb3VyY2UgZmlsZSB0byBzY2FuLlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCBjaGVja2VyLlxuICogQHBhcmFtIHRhcmdldFN5bWJvbCBFeHBvcnQgc3ltYm9sIGJlaW5nIGNsYXNzaWZpZWQuXG4gKiBAcGFyYW0gZXhwb3J0ZWRFbGVtZW50IEV4cG9ydCBtZXRhZGF0YS5cbiAqIEBwYXJhbSBjb25zdW1lcklzVGVzdEZpbGUgV2hldGhlciBzb3VyY2UgZmlsZSBpcyBhIHRlc3QgZmlsZS5cbiAqIEBwYXJhbSB1c2FnZXMgTXV0YWJsZSB1c2FnZSBhY2N1bXVsYXRvci5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb2xsZWN0Q29uY3JldGVVc2FnZXNGcm9tU291cmNlRmlsZShzb3VyY2VGaWxlLCBjaGVja2VyLCB0YXJnZXRTeW1ib2xLZXksIGV4cG9ydGVkRWxlbWVudCwgZmFsc2UsIHVzYWdlcyk7XG4gKiBgYGBcbiAqL1xuY29uc3QgY29sbGVjdENvbmNyZXRlVXNhZ2VzRnJvbVNvdXJjZUZpbGUgPSAoXG4gIHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUsXG4gIGNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuICB0YXJnZXRTeW1ib2w6IHRzLlN5bWJvbCxcbiAgZXhwb3J0ZWRFbGVtZW50OiBFeHBvcnRlZEVsZW1lbnQsXG4gIGNvbnN1bWVySXNUZXN0RmlsZTogYm9vbGVhbixcbiAgdXNhZ2VzOiBFeHBvcnRVc2FnZVtdLFxuKTogdm9pZCA9PiB7XG4gIGNvbnN0IHZpc2l0Tm9kZSA9IChub2RlOiB0cy5Ob2RlKTogdm9pZCA9PiB7XG4gICAgaWYgKCF0cy5pc0lkZW50aWZpZXIobm9kZSkpIHtcbiAgICAgIHRzLmZvckVhY2hDaGlsZChub2RlLCB2aXNpdE5vZGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaXNDb25jcmV0ZVVzYWdlSWRlbnRpZmllcihub2RlLCBleHBvcnRlZEVsZW1lbnQuZXhwb3J0S2luZCkpIHtcbiAgICAgIHRzLmZvckVhY2hDaGlsZChub2RlLCB2aXNpdE5vZGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGlzU2hvcnRoYW5kTmFtZSA9XG4gICAgICB0cy5pc1Nob3J0aGFuZFByb3BlcnR5QXNzaWdubWVudChub2RlLnBhcmVudCkgJiZcbiAgICAgIG5vZGUucGFyZW50Lm5hbWUgPT09IG5vZGU7XG5cbiAgICBjb25zdCBjYW5kaWRhdGVTeW1ib2wgPSBpc1Nob3J0aGFuZE5hbWVcbiAgICAgID8gY2hlY2tlci5nZXRTaG9ydGhhbmRBc3NpZ25tZW50VmFsdWVTeW1ib2wobm9kZS5wYXJlbnQpXG4gICAgICA6IGNoZWNrZXIuZ2V0U3ltYm9sQXRMb2NhdGlvbihub2RlKTtcblxuICAgIGlmIChjYW5kaWRhdGVTeW1ib2wgPT09IHZvaWQgMCkge1xuICAgICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0Tm9kZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb2x2ZWRTeW1ib2wgPSByZXNvbHZlQ2Fub25pY2FsU3ltYm9sKGNhbmRpZGF0ZVN5bWJvbCwgY2hlY2tlcik7XG5cbiAgICBpZiAoIWlzU2FtZVN5bWJvbChyZXNvbHZlZFN5bWJvbCwgdGFyZ2V0U3ltYm9sKSkge1xuICAgICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0Tm9kZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdXNhZ2VzLnB1c2goeyBpc1Rlc3RGaWxlOiBjb25zdW1lcklzVGVzdEZpbGUgfSk7XG4gICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0Tm9kZSk7XG4gIH07XG5cbiAgdmlzaXROb2RlKHNvdXJjZUZpbGUpO1xufTtcblxuLyoqXG4gKiBDb2xsZWN0cyBwdWJsaWMgQVBJIGV4cG9zdXJlIHVzYWdlcyBmb3Igb25lIGV4cG9ydGVkIHN5bWJvbC5cbiAqIEBwYXJhbSBwcm9ncmFtIFR5cGVTY3JpcHQgcHJvZ3JhbS5cbiAqIEBwYXJhbSBzb3VyY2VGaWxlbmFtZSBTb3VyY2UgZmlsZW5hbWUgd2hlcmUgZXhwb3J0IGlzIGRlZmluZWQuXG4gKiBAcGFyYW0gc3RhdGUgTm9ybWFsaXplZCBydWxlIG9wdGlvbnMuXG4gKiBAcGFyYW0gcmVwb1Jvb3QgQWJzb2x1dGUgcmVwb3NpdG9yeSByb290IHVzZWQgZm9yIGZpbGUgY2xhc3NpZmljYXRpb24uXG4gKiBAcGFyYW0gdGFyZ2V0U3ltYm9sIEV4cG9ydCBzeW1ib2wgYmVpbmcgY2xhc3NpZmllZC5cbiAqIEByZXR1cm5zIFB1YmxpYyBBUEkgZXhwb3N1cmUgdXNhZ2VzIGZvciB0aGUgZXhwb3J0ZWQgc3ltYm9sLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHVzYWdlcyA9IGNvbGxlY3RQdWJsaWNBcGlFeHBvc3VyZVVzYWdlcyhwcm9ncmFtLCBzb3VyY2VGaWxlbmFtZSwgc3RhdGUsIHJlcG9Sb290LCB0YXJnZXRTeW1ib2wpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNvbGxlY3RQdWJsaWNBcGlFeHBvc3VyZVVzYWdlcyA9IChcbiAgcHJvZ3JhbTogdHMuUHJvZ3JhbSxcbiAgc291cmNlRmlsZW5hbWU6IHN0cmluZyxcbiAgc3RhdGU6IE5vVW51c2VkRXhwb3J0c1N0YXRlLFxuICByZXBvUm9vdDogc3RyaW5nLFxuICB0YXJnZXRTeW1ib2w6IHRzLlN5bWJvbCxcbik6IEV4cG9ydFVzYWdlW10gPT4ge1xuICBjb25zdCBjaGVja2VyID0gcHJvZ3JhbS5nZXRUeXBlQ2hlY2tlcigpO1xuICBjb25zdCBub3JtYWxpemVkU291cmNlRmlsZW5hbWUgPSB0b0NvbXBhcmFibGVBYnNvbHV0ZVBhdGgoc291cmNlRmlsZW5hbWUpO1xuICBjb25zdCBub3JtYWxpemVkUmVwb1Jvb3QgPSBwYXRoLnJlc29sdmUocmVwb1Jvb3QpO1xuICBjb25zdCB1c2FnZXM6IEV4cG9ydFVzYWdlW10gPSBbXTtcblxuICBmb3IgKGNvbnN0IHNvdXJjZUZpbGUgb2YgcHJvZ3JhbS5nZXRTb3VyY2VGaWxlcygpKSB7XG4gICAgaWYgKHNvdXJjZUZpbGUuaXNEZWNsYXJhdGlvbkZpbGUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHB1YmxpY0FwaUZpbGVuYW1lID0gcGF0aC5yZXNvbHZlKHNvdXJjZUZpbGUuZmlsZU5hbWUpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRQdWJsaWNBcGlGaWxlbmFtZSA9XG4gICAgICB0b0NvbXBhcmFibGVBYnNvbHV0ZVBhdGgocHVibGljQXBpRmlsZW5hbWUpO1xuXG4gICAgaWYgKG5vcm1hbGl6ZWRQdWJsaWNBcGlGaWxlbmFtZSA9PT0gbm9ybWFsaXplZFNvdXJjZUZpbGVuYW1lKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoIWlzUHVibGljQXBpRmlsZShwdWJsaWNBcGlGaWxlbmFtZSwgc3RhdGUsIG5vcm1hbGl6ZWRSZXBvUm9vdCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmICghc291cmNlRmlsZUV4cG9ydHNTeW1ib2woc291cmNlRmlsZSwgY2hlY2tlciwgdGFyZ2V0U3ltYm9sKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdXNhZ2VzLnB1c2goe1xuICAgICAgaXNUZXN0RmlsZTogaXNUZXN0RmlsZShwdWJsaWNBcGlGaWxlbmFtZSwgc3RhdGUsIG5vcm1hbGl6ZWRSZXBvUm9vdCksXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gdXNhZ2VzO1xufTtcblxuLyoqXG4gKiBDb2xsZWN0cyBjb25jcmV0ZSB1c2FnZXMgb2Ygb25lIGV4cG9ydGVkIGVsZW1lbnQgYWNyb3NzIHRoZSBwcm9ncmFtLlxuICogQHBhcmFtIHByb2dyYW0gVHlwZVNjcmlwdCBwcm9ncmFtLlxuICogQHBhcmFtIHNvdXJjZUZpbGVuYW1lIFNvdXJjZSBmaWxlbmFtZSB3aGVyZSBleHBvcnQgaXMgZGVmaW5lZC5cbiAqIEBwYXJhbSBzdGF0ZSBOb3JtYWxpemVkIHJ1bGUgb3B0aW9ucy5cbiAqIEBwYXJhbSByZXBvUm9vdCBBYnNvbHV0ZSByZXBvc2l0b3J5IHJvb3QgdXNlZCBmb3IgdGVzdC1maWxlIGNsYXNzaWZpY2F0aW9uLlxuICogQHBhcmFtIGV4cG9ydGVkRWxlbWVudCBFeHBvcnRlZCBlbGVtZW50IHRvIGNsYXNzaWZ5LlxuICogQHJldHVybnMgQ29uY3JldGUgdXNhZ2VzIGZvciB0aGUgZXhwb3J0ZWQgZWxlbWVudC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCB1c2FnZXMgPSBjb2xsZWN0Q3Jvc3NGaWxlVXNhZ2VzKHByb2dyYW0sIFwiL3JlcG8vc3JjL2ZlYXR1cmUudHNcIiwgc3RhdGUsIFwiL3JlcG9cIiwgZXhwb3J0ZWRFbGVtZW50KTtcbiAqIGBgYFxuICovXG5jb25zdCBjb2xsZWN0Q3Jvc3NGaWxlVXNhZ2VzID0gKFxuICBwcm9ncmFtOiB0cy5Qcm9ncmFtLFxuICBzb3VyY2VGaWxlbmFtZTogc3RyaW5nLFxuICBzdGF0ZTogTm9VbnVzZWRFeHBvcnRzU3RhdGUsXG4gIHJlcG9Sb290OiBzdHJpbmcsXG4gIGV4cG9ydGVkRWxlbWVudDogRXhwb3J0ZWRFbGVtZW50LFxuKTogRXhwb3J0VXNhZ2VbXSA9PiB7XG4gIGNvbnN0IGNoZWNrZXIgPSBwcm9ncmFtLmdldFR5cGVDaGVja2VyKCk7XG4gIGNvbnN0IHRhcmdldFN5bWJvbCA9IGdldEV4cG9ydGVkU3ltYm9sKFxuICAgIHByb2dyYW0sXG4gICAgc291cmNlRmlsZW5hbWUsXG4gICAgZXhwb3J0ZWRFbGVtZW50LmV4cG9ydGVkTmFtZSxcbiAgKTtcblxuICBpZiAodGFyZ2V0U3ltYm9sID09PSB2b2lkIDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBub3JtYWxpemVkU291cmNlRmlsZW5hbWUgPSB0b0NvbXBhcmFibGVBYnNvbHV0ZVBhdGgoc291cmNlRmlsZW5hbWUpO1xuICBjb25zdCBub3JtYWxpemVkUmVwb1Jvb3QgPSBwYXRoLnJlc29sdmUocmVwb1Jvb3QpO1xuICBjb25zdCB1c2FnZXM6IEV4cG9ydFVzYWdlW10gPSBjb2xsZWN0UHVibGljQXBpRXhwb3N1cmVVc2FnZXMoXG4gICAgcHJvZ3JhbSxcbiAgICBzb3VyY2VGaWxlbmFtZSxcbiAgICBzdGF0ZSxcbiAgICByZXBvUm9vdCxcbiAgICB0YXJnZXRTeW1ib2wsXG4gICk7XG5cbiAgZm9yIChjb25zdCBzb3VyY2VGaWxlIG9mIHByb2dyYW0uZ2V0U291cmNlRmlsZXMoKSkge1xuICAgIGlmIChzb3VyY2VGaWxlLmlzRGVjbGFyYXRpb25GaWxlKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBjb25zdW1lckZpbGVuYW1lID0gcGF0aC5yZXNvbHZlKHNvdXJjZUZpbGUuZmlsZU5hbWUpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRDb25zdW1lckZpbGVuYW1lID1cbiAgICAgIHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aChjb25zdW1lckZpbGVuYW1lKTtcblxuICAgIGlmIChub3JtYWxpemVkQ29uc3VtZXJGaWxlbmFtZSA9PT0gbm9ybWFsaXplZFNvdXJjZUZpbGVuYW1lKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBjb25zdW1lcklzVGVzdEZpbGUgPSBpc1Rlc3RGaWxlKFxuICAgICAgY29uc3VtZXJGaWxlbmFtZSxcbiAgICAgIHN0YXRlLFxuICAgICAgbm9ybWFsaXplZFJlcG9Sb290LFxuICAgICk7XG5cbiAgICBjb2xsZWN0Q29uY3JldGVVc2FnZXNGcm9tU291cmNlRmlsZShcbiAgICAgIHNvdXJjZUZpbGUsXG4gICAgICBjaGVja2VyLFxuICAgICAgdGFyZ2V0U3ltYm9sLFxuICAgICAgZXhwb3J0ZWRFbGVtZW50LFxuICAgICAgY29uc3VtZXJJc1Rlc3RGaWxlLFxuICAgICAgdXNhZ2VzLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gdXNhZ2VzO1xufTtcblxuLyoqXG4gKiBDbGFzc2lmaWVzIG9uZSBleHBvcnRlZCBuYW1lIGJhc2VkIG9uIGNyb3NzLWZpbGUgdXNhZ2VzLlxuICogQHBhcmFtIHVzYWdlcyBDb2xsZWN0ZWQgdXNhZ2VzLlxuICogQHJldHVybnMgQ2xhc3NpZmljYXRpb24gbGFiZWwuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY2xhc3NpZmljYXRpb24gPSBjbGFzc2lmeUV4cG9ydFVzYWdlKFwiZmVhdHVyZVwiLCB1c2FnZXMpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNsYXNzaWZ5RXhwb3J0VXNhZ2UgPSAoXG4gIHVzYWdlczogRXhwb3J0VXNhZ2VbXSxcbik6IFwicHJvZHVjdGlvblwiIHwgXCJ0ZXN0LW9ubHlcIiB8IFwidW51c2VkXCIgPT4ge1xuICBpZiAodXNhZ2VzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBcInVudXNlZFwiO1xuICB9XG5cbiAgZm9yIChjb25zdCB1c2FnZSBvZiB1c2FnZXMpIHtcbiAgICBpZiAoIXVzYWdlLmlzVGVzdEZpbGUpIHtcbiAgICAgIHJldHVybiBcInByb2R1Y3Rpb25cIjtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gXCJ0ZXN0LW9ubHlcIjtcbn07XG5cbmV4cG9ydCB7XG4gIGNsYXNzaWZ5RXhwb3J0VXNhZ2UsXG4gIGNvbGxlY3RDcm9zc0ZpbGVVc2FnZXMsXG4gIGNvbGxlY3RFeHBvcnRlZEVsZW1lbnRzLFxuICBnZXRUeXBlU2NyaXB0UHJvZ3JhbSxcbn07XG4iXX0=