@codeperfect/eslint-plugin 2.0.0 → 2.2.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 (301) hide show
  1. package/README.md +3 -2
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/application/custom-rules.d.ts +8 -8
  4. package/dist/application/custom-rules.js +14 -14
  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/barrel-file-utilities.d.ts +3 -4
  10. package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.d.ts.map +1 -1
  11. package/dist/domain/architecture/consistent-barrel-files/barrel-file-utilities.js +5 -3
  12. package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-listeners.d.ts.map +1 -1
  13. package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-listeners.js +17 -7
  14. package/dist/domain/architecture/consistent-barrel-files/exports-only-rule.d.ts.map +1 -1
  15. package/dist/domain/architecture/consistent-barrel-files/exports-only-rule.js +36 -4
  16. package/dist/domain/architecture/consistent-barrel-files/index.d.ts +2 -0
  17. package/dist/domain/architecture/consistent-barrel-files/index.d.ts.map +1 -1
  18. package/dist/domain/architecture/consistent-barrel-files/index.js +3 -1
  19. package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-rule.d.ts +5 -0
  20. package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-rule.d.ts.map +1 -0
  21. package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-rule.js +247 -0
  22. package/dist/domain/architecture/consistent-barrel-files/no-import-export-extensions-rule.d.ts +5 -0
  23. package/dist/domain/architecture/consistent-barrel-files/no-import-export-extensions-rule.d.ts.map +1 -0
  24. package/dist/domain/architecture/consistent-barrel-files/no-import-export-extensions-rule.js +136 -0
  25. package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-rule.d.ts.map +1 -1
  26. package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-rule.js +8 -3
  27. package/dist/domain/architecture/consistent-barrel-files/rule.d.ts.map +1 -1
  28. package/dist/domain/architecture/consistent-barrel-files/rule.js +12 -5
  29. package/dist/domain/architecture/index.d.ts +2 -1
  30. package/dist/domain/architecture/index.d.ts.map +1 -1
  31. package/dist/domain/architecture/index.js +3 -2
  32. package/dist/domain/architecture/no-unused-exports/index.d.ts +3 -0
  33. package/dist/domain/architecture/no-unused-exports/index.d.ts.map +1 -0
  34. package/dist/domain/architecture/no-unused-exports/index.js +2 -0
  35. package/dist/domain/architecture/no-unused-exports/no-unused-exports-options.d.ts +50 -0
  36. package/dist/domain/architecture/no-unused-exports/no-unused-exports-options.d.ts.map +1 -0
  37. package/dist/domain/architecture/no-unused-exports/no-unused-exports-options.js +141 -0
  38. package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.d.ts +49 -0
  39. package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.d.ts.map +1 -0
  40. package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.js +608 -0
  41. package/dist/domain/architecture/no-unused-exports/rule.d.ts +5 -0
  42. package/dist/domain/architecture/no-unused-exports/rule.d.ts.map +1 -0
  43. package/dist/domain/architecture/no-unused-exports/rule.js +82 -0
  44. package/dist/domain/architecture/no-unused-exports/types.d.ts +32 -0
  45. package/dist/domain/architecture/no-unused-exports/types.d.ts.map +1 -0
  46. package/dist/domain/architecture/no-unused-exports/types.js +2 -0
  47. package/dist/domain/core/no-multiple-declarators/rule.d.ts.map +1 -1
  48. package/dist/domain/core/no-multiple-declarators/rule.js +58 -6
  49. package/dist/domain/core/no-multiple-declarators/types.d.ts +3 -1
  50. package/dist/domain/core/no-multiple-declarators/types.d.ts.map +1 -1
  51. package/dist/domain/core/no-multiple-declarators/types.js +5 -2
  52. package/dist/domain/core/prefer-interface-types/rule.d.ts.map +1 -1
  53. package/dist/domain/core/prefer-interface-types/rule.js +94 -23
  54. package/dist/domain/custom-rule-documentation.d.ts +3 -14
  55. package/dist/domain/custom-rule-documentation.d.ts.map +1 -1
  56. package/dist/domain/custom-rule-documentation.js +3 -2
  57. package/dist/domain/docs/no-interface-member-docs/comment-utilities.d.ts.map +1 -1
  58. package/dist/domain/docs/no-interface-member-docs/comment-utilities.js +11 -2
  59. package/dist/domain/docs/no-interface-member-docs/parameter-tags.d.ts.map +1 -1
  60. package/dist/domain/docs/no-interface-member-docs/parameter-tags.js +1 -1
  61. package/dist/domain/docs/no-interface-member-docs/parameter-utilities.js +1 -1
  62. package/dist/domain/docs/no-interface-member-docs/rule.d.ts.map +1 -1
  63. package/dist/domain/docs/no-interface-member-docs/rule.js +12 -4
  64. package/dist/domain/docs/require-example-language/examples.d.ts +4 -15
  65. package/dist/domain/docs/require-example-language/examples.d.ts.map +1 -1
  66. package/dist/domain/docs/require-example-language/examples.js +119 -26
  67. package/dist/domain/docs/require-example-language/fixes.d.ts +1 -21
  68. package/dist/domain/docs/require-example-language/fixes.d.ts.map +1 -1
  69. package/dist/domain/docs/require-example-language/fixes.js +5 -2
  70. package/dist/domain/docs/require-example-language/reporting.d.ts +2 -38
  71. package/dist/domain/docs/require-example-language/reporting.d.ts.map +1 -1
  72. package/dist/domain/docs/require-example-language/reporting.js +2 -2
  73. package/dist/domain/docs/require-example-language/rule.d.ts.map +1 -1
  74. package/dist/domain/docs/require-example-language/rule.js +7 -3
  75. package/dist/domain/docs/require-example-language/types.d.ts +1 -1
  76. package/dist/domain/docs/require-example-language/types.d.ts.map +1 -1
  77. package/dist/domain/docs/require-example-language/types.js +1 -1
  78. package/dist/domain/docs/single-line-jsdoc/rule.d.ts +1 -2
  79. package/dist/domain/docs/single-line-jsdoc/rule.d.ts.map +1 -1
  80. package/dist/domain/docs/single-line-jsdoc/rule.js +18 -13
  81. package/dist/domain/index.d.ts +2 -3
  82. package/dist/domain/index.d.ts.map +1 -1
  83. package/dist/domain/index.js +3 -4
  84. package/dist/domain/testing/aaa/analyzer.analysis.d.ts +2 -78
  85. package/dist/domain/testing/aaa/analyzer.analysis.d.ts.map +1 -1
  86. package/dist/domain/testing/aaa/analyzer.analysis.helpers.d.ts +121 -3
  87. package/dist/domain/testing/aaa/analyzer.analysis.helpers.d.ts.map +1 -1
  88. package/dist/domain/testing/aaa/analyzer.analysis.helpers.js +199 -4
  89. package/dist/domain/testing/aaa/analyzer.analysis.js +30 -188
  90. package/dist/domain/testing/aaa/analyzer.assertions.d.ts +1 -92
  91. package/dist/domain/testing/aaa/analyzer.assertions.d.ts.map +1 -1
  92. package/dist/domain/testing/aaa/analyzer.assertions.helpers.d.ts +93 -0
  93. package/dist/domain/testing/aaa/analyzer.assertions.helpers.d.ts.map +1 -0
  94. package/dist/domain/testing/aaa/analyzer.assertions.helpers.js +184 -0
  95. package/dist/domain/testing/aaa/analyzer.assertions.js +5 -283
  96. package/dist/domain/testing/aaa/analyzer.assertions.operands.d.ts +62 -0
  97. package/dist/domain/testing/aaa/analyzer.assertions.operands.d.ts.map +1 -0
  98. package/dist/domain/testing/aaa/analyzer.assertions.operands.js +106 -0
  99. package/dist/domain/testing/aaa/analyzer.classification.d.ts +1 -74
  100. package/dist/domain/testing/aaa/analyzer.classification.d.ts.map +1 -1
  101. package/dist/domain/testing/aaa/analyzer.classification.helpers.d.ts +75 -0
  102. package/dist/domain/testing/aaa/analyzer.classification.helpers.d.ts.map +1 -0
  103. package/dist/domain/testing/aaa/analyzer.classification.helpers.js +202 -0
  104. package/dist/domain/testing/aaa/analyzer.classification.js +5 -201
  105. package/dist/domain/testing/aaa/analyzer.classification.traversal.d.ts +13 -0
  106. package/dist/domain/testing/aaa/analyzer.classification.traversal.d.ts.map +1 -0
  107. package/dist/domain/testing/aaa/analyzer.classification.traversal.js +32 -0
  108. package/dist/domain/testing/aaa/analyzer.super.d.ts +6 -13
  109. package/dist/domain/testing/aaa/analyzer.super.d.ts.map +1 -1
  110. package/dist/domain/testing/aaa/analyzer.super.helpers.d.ts +14 -0
  111. package/dist/domain/testing/aaa/analyzer.super.helpers.d.ts.map +1 -0
  112. package/dist/domain/testing/aaa/analyzer.super.helpers.js +64 -0
  113. package/dist/domain/testing/aaa/analyzer.super.js +29 -61
  114. package/dist/domain/testing/aaa/index.d.ts +1 -2
  115. package/dist/domain/testing/aaa/index.d.ts.map +1 -1
  116. package/dist/domain/testing/aaa/index.js +2 -2
  117. package/dist/domain/testing/aaa/types.d.ts +1 -1
  118. package/dist/domain/testing/aaa/types.d.ts.map +1 -1
  119. package/dist/domain/testing/aaa/types.js +1 -1
  120. package/dist/domain/testing/assert-actual-expected-names/rule.d.ts.map +1 -1
  121. package/dist/domain/testing/assert-actual-expected-names/rule.js +33 -5
  122. package/dist/domain/testing/enforce-aaa-phase-purity/index.d.ts +2 -1
  123. package/dist/domain/testing/enforce-aaa-phase-purity/index.d.ts.map +1 -1
  124. package/dist/domain/testing/enforce-aaa-phase-purity/index.js +3 -2
  125. package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-identifiers.d.ts +1 -1
  126. package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-identifiers.d.ts.map +1 -1
  127. package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-identifiers.js +1 -1
  128. package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.d.ts +1 -1
  129. package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.d.ts.map +1 -1
  130. package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.js +78 -16
  131. package/dist/domain/testing/{require-aaa-sections → enforce-aaa-structure}/missing-section-fixes.d.ts +1 -1
  132. package/dist/domain/testing/enforce-aaa-structure/missing-section-fixes.d.ts.map +1 -0
  133. package/dist/domain/testing/enforce-aaa-structure/missing-section-fixes.js +150 -0
  134. package/dist/domain/testing/enforce-aaa-structure/rule.d.ts.map +1 -1
  135. package/dist/domain/testing/enforce-aaa-structure/rule.js +165 -3
  136. package/dist/domain/testing/index.d.ts +0 -3
  137. package/dist/domain/testing/index.d.ts.map +1 -1
  138. package/dist/domain/testing/index.js +1 -4
  139. package/dist/domain/testing/prefer-vi-mocked-import/fix-import-statements.d.ts +1 -15
  140. package/dist/domain/testing/prefer-vi-mocked-import/fix-import-statements.d.ts.map +1 -1
  141. package/dist/domain/testing/prefer-vi-mocked-import/fix-import-statements.js +2 -71
  142. package/dist/domain/testing/prefer-vi-mocked-import/fix-imports.d.ts.map +1 -1
  143. package/dist/domain/testing/prefer-vi-mocked-import/fix-imports.js +4 -2
  144. package/dist/domain/testing/prefer-vi-mocked-import/fix.d.ts +1 -13
  145. package/dist/domain/testing/prefer-vi-mocked-import/fix.d.ts.map +1 -1
  146. package/dist/domain/testing/prefer-vi-mocked-import/fix.js +3 -21
  147. package/dist/domain/testing/prefer-vi-mocked-import/match-bindings.d.ts.map +1 -1
  148. package/dist/domain/testing/prefer-vi-mocked-import/match-bindings.js +2 -1
  149. package/dist/domain/testing/prefer-vi-mocked-import/match-declarations.d.ts.map +1 -1
  150. package/dist/domain/testing/prefer-vi-mocked-import/match-declarations.js +1 -1
  151. package/dist/domain/testing/prefer-vi-mocked-import/match-rewrites.js +6 -6
  152. package/dist/domain/testing/prefer-vi-mocked-import/match.d.ts +1 -12
  153. package/dist/domain/testing/prefer-vi-mocked-import/match.d.ts.map +1 -1
  154. package/dist/domain/testing/prefer-vi-mocked-import/match.js +149 -15
  155. package/dist/domain/testing/prefer-vi-mocked-import/rule.d.ts.map +1 -1
  156. package/dist/domain/testing/prefer-vi-mocked-import/rule.js +6 -3
  157. package/dist/domain/testing/require-act-result-capture/rule.d.ts.map +1 -1
  158. package/dist/domain/testing/require-act-result-capture/rule.js +42 -10
  159. package/dist/domain/testing/require-test-companion/index.d.ts +0 -1
  160. package/dist/domain/testing/require-test-companion/index.d.ts.map +1 -1
  161. package/dist/domain/testing/require-test-companion/index.js +1 -2
  162. package/dist/domain/testing/require-test-companion/require-test-companion-listeners.d.ts +2 -1
  163. package/dist/domain/testing/require-test-companion/require-test-companion-listeners.d.ts.map +1 -1
  164. package/dist/domain/testing/require-test-companion/require-test-companion-listeners.js +13 -58
  165. package/dist/domain/testing/require-test-companion/require-test-companion-options.d.ts +2 -1
  166. package/dist/domain/testing/require-test-companion/require-test-companion-options.d.ts.map +1 -1
  167. package/dist/domain/testing/require-test-companion/require-test-companion-options.js +6 -5
  168. package/dist/domain/testing/require-test-companion/rule.d.ts.map +1 -1
  169. package/dist/domain/testing/require-test-companion/rule.js +34 -9
  170. package/dist/domain/testing/single-act-statement/rule.d.ts.map +1 -1
  171. package/dist/domain/testing/single-act-statement/rule.js +11 -5
  172. package/dist/index.d.ts +1 -1
  173. package/dist/index.d.ts.map +1 -1
  174. package/dist/index.js +2 -2
  175. package/dist/infrastructure/codeperfect-plugin.d.ts +6 -6
  176. package/dist/infrastructure/codeperfect-plugin.js +5 -5
  177. package/dist/infrastructure/presets.d.ts.map +1 -1
  178. package/dist/infrastructure/presets.js +23 -7
  179. package/package.json +37 -38
  180. package/dist/domain/architecture/consistent-barrel-files/exports-only-rule-test-utilities.d.ts +0 -41
  181. package/dist/domain/architecture/consistent-barrel-files/exports-only-rule-test-utilities.d.ts.map +0 -1
  182. package/dist/domain/architecture/consistent-barrel-files/exports-only-rule-test-utilities.js +0 -87
  183. package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-test-utilities.d.ts +0 -40
  184. package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-test-utilities.d.ts.map +0 -1
  185. package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-test-utilities.js +0 -91
  186. package/dist/domain/architecture/consistent-barrel-files/rule.repeat-runs.d.ts +0 -4
  187. package/dist/domain/architecture/consistent-barrel-files/rule.repeat-runs.d.ts.map +0 -1
  188. package/dist/domain/architecture/consistent-barrel-files/rule.repeat-runs.js +0 -4
  189. package/dist/domain/architecture/consistent-barrel-files/test-helpers.d.ts +0 -141
  190. package/dist/domain/architecture/consistent-barrel-files/test-helpers.d.ts.map +0 -1
  191. package/dist/domain/architecture/consistent-barrel-files/test-helpers.file-writers.d.ts +0 -20
  192. package/dist/domain/architecture/consistent-barrel-files/test-helpers.file-writers.d.ts.map +0 -1
  193. package/dist/domain/architecture/consistent-barrel-files/test-helpers.file-writers.js +0 -25
  194. package/dist/domain/architecture/consistent-barrel-files/test-helpers.js +0 -235
  195. package/dist/domain/core/no-multiple-declarators/rule-test-helpers.d.ts +0 -101
  196. package/dist/domain/core/no-multiple-declarators/rule-test-helpers.d.ts.map +0 -1
  197. package/dist/domain/core/no-multiple-declarators/rule-test-helpers.js +0 -108
  198. package/dist/domain/core/no-multiple-declarators/rule.fixes.d.ts +0 -35
  199. package/dist/domain/core/no-multiple-declarators/rule.fixes.d.ts.map +0 -1
  200. package/dist/domain/core/no-multiple-declarators/rule.fixes.js +0 -95
  201. package/dist/domain/core/no-multiple-declarators/rule.guardrails.d.ts +0 -4
  202. package/dist/domain/core/no-multiple-declarators/rule.guardrails.d.ts.map +0 -1
  203. package/dist/domain/core/no-multiple-declarators/rule.guardrails.js +0 -4
  204. package/dist/domain/core/no-multiple-declarators/rule.mocked-types.d.ts +0 -4
  205. package/dist/domain/core/no-multiple-declarators/rule.mocked-types.d.ts.map +0 -1
  206. package/dist/domain/core/no-multiple-declarators/rule.mocked-types.js +0 -4
  207. package/dist/domain/core/prefer-interface-types/test-helpers.d.ts +0 -110
  208. package/dist/domain/core/prefer-interface-types/test-helpers.d.ts.map +0 -1
  209. package/dist/domain/core/prefer-interface-types/test-helpers.js +0 -116
  210. package/dist/domain/docs/no-interface-member-docs/comment-utilities-test-helpers.d.ts +0 -89
  211. package/dist/domain/docs/no-interface-member-docs/comment-utilities-test-helpers.d.ts.map +0 -1
  212. package/dist/domain/docs/no-interface-member-docs/comment-utilities-test-helpers.js +0 -129
  213. package/dist/domain/docs/no-interface-member-docs/test-helpers.d.ts +0 -103
  214. package/dist/domain/docs/no-interface-member-docs/test-helpers.d.ts.map +0 -1
  215. package/dist/domain/docs/no-interface-member-docs/test-helpers.js +0 -157
  216. package/dist/domain/docs/require-example-language/create-fixer.d.ts +0 -5
  217. package/dist/domain/docs/require-example-language/create-fixer.d.ts.map +0 -1
  218. package/dist/domain/docs/require-example-language/create-fixer.js +0 -5
  219. package/dist/domain/docs/single-line-jsdoc/rule.edge-cases.d.ts +0 -4
  220. package/dist/domain/docs/single-line-jsdoc/rule.edge-cases.d.ts.map +0 -1
  221. package/dist/domain/docs/single-line-jsdoc/rule.edge-cases.js +0 -5
  222. package/dist/domain/docs/single-line-jsdoc/rule.node-lookups.d.ts +0 -4
  223. package/dist/domain/docs/single-line-jsdoc/rule.node-lookups.d.ts.map +0 -1
  224. package/dist/domain/docs/single-line-jsdoc/rule.node-lookups.js +0 -5
  225. package/dist/domain/docs/test-helpers.d.ts +0 -50
  226. package/dist/domain/docs/test-helpers.d.ts.map +0 -1
  227. package/dist/domain/docs/test-helpers.js +0 -107
  228. package/dist/domain/testing/aaa/analyzer.classification.member-patterns.d.ts +0 -9
  229. package/dist/domain/testing/aaa/analyzer.classification.member-patterns.d.ts.map +0 -1
  230. package/dist/domain/testing/aaa/analyzer.classification.member-patterns.js +0 -10
  231. package/dist/domain/testing/aaa/analyzer.d.ts +0 -46
  232. package/dist/domain/testing/aaa/analyzer.d.ts.map +0 -1
  233. package/dist/domain/testing/aaa/analyzer.js +0 -59
  234. package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.behavior.d.ts +0 -4
  235. package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.behavior.d.ts.map +0 -1
  236. package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.behavior.js +0 -4
  237. package/dist/domain/testing/enforce-aaa-phase-purity/rule-test-helpers.d.ts +0 -42
  238. package/dist/domain/testing/enforce-aaa-phase-purity/rule-test-helpers.d.ts.map +0 -1
  239. package/dist/domain/testing/enforce-aaa-phase-purity/rule-test-helpers.js +0 -188
  240. package/dist/domain/testing/enforce-aaa-phase-purity/rule.d.ts +0 -5
  241. package/dist/domain/testing/enforce-aaa-phase-purity/rule.d.ts.map +0 -1
  242. package/dist/domain/testing/enforce-aaa-phase-purity/rule.js +0 -34
  243. package/dist/domain/testing/prefer-vi-mocked-import/rule-test-helpers.d.ts +0 -20
  244. package/dist/domain/testing/prefer-vi-mocked-import/rule-test-helpers.d.ts.map +0 -1
  245. package/dist/domain/testing/prefer-vi-mocked-import/rule-test-helpers.js +0 -39
  246. package/dist/domain/testing/prefer-vitest-incremental-casts/ast-helpers.d.ts +0 -86
  247. package/dist/domain/testing/prefer-vitest-incremental-casts/ast-helpers.d.ts.map +0 -1
  248. package/dist/domain/testing/prefer-vitest-incremental-casts/ast-helpers.js +0 -150
  249. package/dist/domain/testing/prefer-vitest-incremental-casts/index.d.ts +0 -2
  250. package/dist/domain/testing/prefer-vitest-incremental-casts/index.d.ts.map +0 -1
  251. package/dist/domain/testing/prefer-vitest-incremental-casts/index.js +0 -2
  252. package/dist/domain/testing/prefer-vitest-incremental-casts/match-input.d.ts +0 -14
  253. package/dist/domain/testing/prefer-vitest-incremental-casts/match-input.d.ts.map +0 -1
  254. package/dist/domain/testing/prefer-vitest-incremental-casts/match-input.js +0 -81
  255. package/dist/domain/testing/prefer-vitest-incremental-casts/match.d.ts +0 -13
  256. package/dist/domain/testing/prefer-vitest-incremental-casts/match.d.ts.map +0 -1
  257. package/dist/domain/testing/prefer-vitest-incremental-casts/match.js +0 -189
  258. package/dist/domain/testing/prefer-vitest-incremental-casts/replacement-helpers.d.ts +0 -25
  259. package/dist/domain/testing/prefer-vitest-incremental-casts/replacement-helpers.d.ts.map +0 -1
  260. package/dist/domain/testing/prefer-vitest-incremental-casts/replacement-helpers.js +0 -92
  261. package/dist/domain/testing/prefer-vitest-incremental-casts/rule-test-helpers.d.ts +0 -32
  262. package/dist/domain/testing/prefer-vitest-incremental-casts/rule-test-helpers.d.ts.map +0 -1
  263. package/dist/domain/testing/prefer-vitest-incremental-casts/rule-test-helpers.js +0 -164
  264. package/dist/domain/testing/prefer-vitest-incremental-casts/rule.d.ts +0 -5
  265. package/dist/domain/testing/prefer-vitest-incremental-casts/rule.d.ts.map +0 -1
  266. package/dist/domain/testing/prefer-vitest-incremental-casts/rule.guardrails.d.ts +0 -4
  267. package/dist/domain/testing/prefer-vitest-incremental-casts/rule.guardrails.d.ts.map +0 -1
  268. package/dist/domain/testing/prefer-vitest-incremental-casts/rule.guardrails.js +0 -4
  269. package/dist/domain/testing/prefer-vitest-incremental-casts/rule.input-shapes.d.ts +0 -4
  270. package/dist/domain/testing/prefer-vitest-incremental-casts/rule.input-shapes.d.ts.map +0 -1
  271. package/dist/domain/testing/prefer-vitest-incremental-casts/rule.input-shapes.js +0 -4
  272. package/dist/domain/testing/prefer-vitest-incremental-casts/rule.js +0 -62
  273. package/dist/domain/testing/prefer-vitest-incremental-casts/rule.signature-fallback.d.ts +0 -4
  274. package/dist/domain/testing/prefer-vitest-incremental-casts/rule.signature-fallback.d.ts.map +0 -1
  275. package/dist/domain/testing/prefer-vitest-incremental-casts/rule.signature-fallback.js +0 -4
  276. package/dist/domain/testing/prefer-vitest-incremental-casts/type-helpers.d.ts +0 -24
  277. package/dist/domain/testing/prefer-vitest-incremental-casts/type-helpers.d.ts.map +0 -1
  278. package/dist/domain/testing/prefer-vitest-incremental-casts/type-helpers.js +0 -113
  279. package/dist/domain/testing/prefer-vitest-incremental-casts/type-shape-helpers.d.ts +0 -36
  280. package/dist/domain/testing/prefer-vitest-incremental-casts/type-shape-helpers.d.ts.map +0 -1
  281. package/dist/domain/testing/prefer-vitest-incremental-casts/type-shape-helpers.js +0 -138
  282. package/dist/domain/testing/prefer-vitest-incremental-casts/types.d.ts +0 -203
  283. package/dist/domain/testing/prefer-vitest-incremental-casts/types.d.ts.map +0 -1
  284. package/dist/domain/testing/prefer-vitest-incremental-casts/types.js +0 -2
  285. package/dist/domain/testing/require-aaa-sections/index.d.ts +0 -2
  286. package/dist/domain/testing/require-aaa-sections/index.d.ts.map +0 -1
  287. package/dist/domain/testing/require-aaa-sections/index.js +0 -2
  288. package/dist/domain/testing/require-aaa-sections/missing-section-fixes.d.ts.map +0 -1
  289. package/dist/domain/testing/require-aaa-sections/missing-section-fixes.js +0 -150
  290. package/dist/domain/testing/require-aaa-sections/rule.d.ts +0 -5
  291. package/dist/domain/testing/require-aaa-sections/rule.d.ts.map +0 -1
  292. package/dist/domain/testing/require-aaa-sections/rule.js +0 -129
  293. package/dist/domain/testing/require-aaa-sections/rule.reporting.d.ts +0 -104
  294. package/dist/domain/testing/require-aaa-sections/rule.reporting.d.ts.map +0 -1
  295. package/dist/domain/testing/require-aaa-sections/rule.reporting.js +0 -217
  296. package/dist/domain/testing/require-test-companion/require-test-companion-test-helpers.d.ts +0 -51
  297. package/dist/domain/testing/require-test-companion/require-test-companion-test-helpers.d.ts.map +0 -1
  298. package/dist/domain/testing/require-test-companion/require-test-companion-test-helpers.js +0 -184
  299. package/dist/domain/testing/require-test-companion/require-test-companion-utilities.d.ts +0 -28
  300. package/dist/domain/testing/require-test-companion/require-test-companion-utilities.d.ts.map +0 -1
  301. package/dist/domain/testing/require-test-companion/require-test-companion-utilities.js +0 -26
@@ -0,0 +1,608 @@
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 candidateSymbol = checker.getSymbolAtLocation(node);
498
+ if (candidateSymbol === void 0) {
499
+ ts.forEachChild(node, visitNode);
500
+ return;
501
+ }
502
+ const resolvedSymbol = resolveCanonicalSymbol(candidateSymbol, checker);
503
+ if (!isSameSymbol(resolvedSymbol, targetSymbol)) {
504
+ ts.forEachChild(node, visitNode);
505
+ return;
506
+ }
507
+ usages.push({ isTestFile: consumerIsTestFile });
508
+ ts.forEachChild(node, visitNode);
509
+ };
510
+ visitNode(sourceFile);
511
+ };
512
+ /**
513
+ * Collects public API exposure usages for one exported symbol.
514
+ * @param program TypeScript program.
515
+ * @param sourceFilename Source filename where export is defined.
516
+ * @param state Normalized rule options.
517
+ * @param repoRoot Absolute repository root used for file classification.
518
+ * @param targetSymbol Export symbol being classified.
519
+ * @returns Public API exposure usages for the exported symbol.
520
+ * @example
521
+ * ```typescript
522
+ * const usages = collectPublicApiExposureUsages(program, sourceFilename, state, repoRoot, targetSymbol);
523
+ * ```
524
+ */
525
+ const collectPublicApiExposureUsages = (program, sourceFilename, state, repoRoot, targetSymbol) => {
526
+ const checker = program.getTypeChecker();
527
+ const normalizedSourceFilename = toComparableAbsolutePath(sourceFilename);
528
+ const normalizedRepoRoot = path.resolve(repoRoot);
529
+ const usages = [];
530
+ for (const sourceFile of program.getSourceFiles()) {
531
+ if (sourceFile.isDeclarationFile) {
532
+ continue;
533
+ }
534
+ const publicApiFilename = path.resolve(sourceFile.fileName);
535
+ const normalizedPublicApiFilename = toComparableAbsolutePath(publicApiFilename);
536
+ if (normalizedPublicApiFilename === normalizedSourceFilename) {
537
+ continue;
538
+ }
539
+ if (!isPublicApiFile(publicApiFilename, state, normalizedRepoRoot)) {
540
+ continue;
541
+ }
542
+ if (!sourceFileExportsSymbol(sourceFile, checker, targetSymbol)) {
543
+ continue;
544
+ }
545
+ usages.push({
546
+ isTestFile: isTestFile(publicApiFilename, state, normalizedRepoRoot),
547
+ });
548
+ }
549
+ return usages;
550
+ };
551
+ /**
552
+ * Collects concrete usages of one exported element across the program.
553
+ * @param program TypeScript program.
554
+ * @param sourceFilename Source filename where export is defined.
555
+ * @param state Normalized rule options.
556
+ * @param repoRoot Absolute repository root used for test-file classification.
557
+ * @param exportedElement Exported element to classify.
558
+ * @returns Concrete usages for the exported element.
559
+ * @example
560
+ * ```typescript
561
+ * const usages = collectCrossFileUsages(program, "/repo/src/feature.ts", state, "/repo", exportedElement);
562
+ * ```
563
+ */
564
+ const collectCrossFileUsages = (program, sourceFilename, state, repoRoot, exportedElement) => {
565
+ const checker = program.getTypeChecker();
566
+ const targetSymbol = getExportedSymbol(program, sourceFilename, exportedElement.exportedName);
567
+ if (targetSymbol === void 0) {
568
+ return [];
569
+ }
570
+ const normalizedSourceFilename = toComparableAbsolutePath(sourceFilename);
571
+ const normalizedRepoRoot = path.resolve(repoRoot);
572
+ const usages = collectPublicApiExposureUsages(program, sourceFilename, state, repoRoot, targetSymbol);
573
+ for (const sourceFile of program.getSourceFiles()) {
574
+ if (sourceFile.isDeclarationFile) {
575
+ continue;
576
+ }
577
+ const consumerFilename = path.resolve(sourceFile.fileName);
578
+ const normalizedConsumerFilename = toComparableAbsolutePath(consumerFilename);
579
+ if (normalizedConsumerFilename === normalizedSourceFilename) {
580
+ continue;
581
+ }
582
+ const consumerIsTestFile = isTestFile(consumerFilename, state, normalizedRepoRoot);
583
+ collectConcreteUsagesFromSourceFile(sourceFile, checker, targetSymbol, exportedElement, consumerIsTestFile, usages);
584
+ }
585
+ return usages;
586
+ };
587
+ /**
588
+ * Classifies one exported name based on cross-file usages.
589
+ * @param usages Collected usages.
590
+ * @returns Classification label.
591
+ * @example
592
+ * ```typescript
593
+ * const classification = classifyExportUsage("feature", usages);
594
+ * ```
595
+ */
596
+ const classifyExportUsage = (usages) => {
597
+ if (usages.length === 0) {
598
+ return "unused";
599
+ }
600
+ for (const usage of usages) {
601
+ if (!usage.isTestFile) {
602
+ return "production";
603
+ }
604
+ }
605
+ return "test-only";
606
+ };
607
+ export { classifyExportUsage, collectCrossFileUsages, collectExportedElements, getTypeScriptProgram, };
608
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tdW51c2VkLWV4cG9ydHMtdXRpbGl0aWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RvbWFpbi9hcmNoaXRlY3R1cmUvbm8tdW51c2VkLWV4cG9ydHMvbm8tdW51c2VkLWV4cG9ydHMtdXRpbGl0aWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN2RCxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFTakMsT0FBTyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQVcxRTs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxTQUFpQixFQUFVLEVBQUU7SUFDN0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFFN0QsT0FBTyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7QUFDcEMsQ0FBQyxDQUFDO0FBRUY7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFFBQVEsR0FBRyxDQUFDLEtBQWMsRUFBdUMsRUFBRSxDQUN2RSxLQUFLLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7SUFDekMsQ0FBQyxDQUFFLEtBQWlDO0lBQ3BDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUViOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sa0JBQWtCLEdBQUcsQ0FDekIsS0FBYyxFQUNkLEdBQVcsRUFDUyxFQUFFO0lBQ3RCLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvQixNQUFNLFFBQVEsR0FBRyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMvQixPQUFPLE9BQU8sUUFBUSxLQUFLLFFB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LFVBQVUsRUFBRSxDQUFDO1lBQ3RCLE9BQU8sWUFBWSxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQyxDQUFDO0FBRUYsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixzQkFBc0IsRUFDdEIsdUJBQXVCLEVBQ3ZCLG9CQUFvQixHQUNyQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBBU1QsIFJ1bGUgfSBmcm9tIFwiZXNsaW50XCI7XG5cbmltcG9ydCB7IEVTTGludFV0aWxzIH0gZnJvbSBcIkB0eXBlc2NyaXB0LWVzbGludC91dGlsc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0ICogYXMgdHMgZnJvbSBcInR5cGVzY3JpcHRcIjtcblxuaW1wb3J0IHR5cGUge1xuICBFeHBvcnRlZEVsZW1lbnQsXG4gIEV4cG9ydEtpbmQsXG4gIEV4cG9ydFVzYWdlLFxuICBOb1VudXNlZEV4cG9ydHNTdGF0ZSxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcblxuaW1wb3J0IHsgaXNQdWJsaWNBcGlGaWxlLCBpc1Rlc3RGaWxlIH0gZnJvbSBcIi4vbm8tdW51c2VkLWV4cG9ydHMtb3B0aW9uc1wiO1xuXG4vKiogTG9jYWwgdG9wLWxldmVsIGRlY2xhcmF0aW9uIGRpc2NvdmVyZWQgd2hlbiBjb2xsZWN0aW5nIGV4cG9ydCBzb3VyY2VzLiAqL1xuaW50ZXJmYWNlIExvY2FsRGVjbGFyYXRpb24ge1xuICAvKiogRXhwb3J0IGtpbmQgaW1wbGllZCBieSB0aGUgZGVjbGFyYXRpb24uICovXG4gIGtpbmQ6IEV4cG9ydEtpbmQ7XG5cbiAgLyoqIERlY2xhcmF0aW9uIHN0YXRlbWVudCB1c2VkIGZvciBkaWFnbm9zdGljcy4gKi9cbiAgbm9kZTogQVNULlByb2dyYW1bXCJib2R5XCJdW251bWJlcl07XG59XG5cbi8qKlxuICogTm9ybWFsaXplcyBhbiBhYnNvbHV0ZSBmaWxlIHBhdGggZm9yIHNhZmUgZXF1YWxpdHkgY2hlY2tzLlxuICogQHBhcmFtIGlucHV0UGF0aCBDYW5kaWRhdGUgcGF0aC5cbiAqIEByZXR1cm5zIE5vcm1hbGl6ZWQgYWJzb2x1dGUgcGF0aCBzdWl0YWJsZSBmb3IgY3Jvc3MtcGxhdGZvcm0gY29tcGFyaXNvbnMuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY29tcGFyYWJsZSA9IHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aChcIi9yZXBvL3NyYy9mZWF0dXJlLnRzXCIpO1xuICogYGBgXG4gKi9cbmNvbnN0IHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aCA9IChpbnB1dFBhdGg6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGFic29sdXRlUGF0aCA9IHBhdGgubm9ybWFsaXplKHBhdGgucmVzb2x2ZShpbnB1dFBhdGgpKTtcblxuICByZXR1cm4gYWJzb2x1dGVQYXRoLnRvTG93ZXJDYXNlKCk7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIG9uZSB1bmtub3duIHZhbHVlIGludG8gYW4gaW5kZXhhYmxlIHJlY29yZC5cbiAqIEBwYXJhbSB2YWx1ZSBDYW5kaWRhdGUgdmFsdWUuXG4gKiBAcmV0dXJucyBSZWNvcmQgdmlldyB3aGVuIHRoZSB2YWx1ZSBpcyBvYmplY3QtbGlrZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZWNvcmQgPSBhc1JlY29yZCh7IHR5cGU6IFwiSWRlbnRpZmllclwiIH0pO1xuICogYGBgXG4gKi9cbmNvbnN0IGFzUmVjb3JkID0gKHZhbHVlOiB1bmtub3duKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQgPT5cbiAgdmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiXG4gICAgPyAodmFsdWUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pXG4gICAgOiB2b2lkIDA7XG5cbi8qKlxuICogUmVhZHMgb25lIHN0cmluZyBwcm9wZXJ0eSBmcm9tIGFuIG9iamVjdC1saWtlIHZhbHVlLlxuICogQHBhcmFtIHZhbHVlIENhbmRpZGF0ZSBvYmplY3QuXG4gKiBAcGFyYW0ga2V5IExvb2t1cCBrZXkgdXNlZCB0byByZWFkIHRoZSBwcm9wZXJ0eS5cbiAqIEByZXR1cm5zIFN0cmluZyB2YWx1ZSB3aGVuIHByZXNlbnQuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbmFtZSA9IHJlYWRTdHJpbmdQcm9wZXJ0eSh7IG5hbWU6IFwiZmVhdHVyZVwiIH0sIFwibmFtZVwiKTtcbiAqIGBgYFxuICovXG5jb25zdCByZWFkU3RyaW5nUHJvcGVydHkgPSAoXG4gIHZhbHVlOiB1bmtub3duLFxuICBrZXk6IHN0cmluZyxcbik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IHJlY29yZCA9IGFzUmVjb3JkKHZhbHVlKTtcbiAgY29uc3QgcHJvcGVydHkgPSByZWNvcmQ/LltrZXldO1xuICByZXR1cm4gdHlwZW9mIHByb3BlcnR5ID09PSBcInN0cmluZ1wiID8gcHJvcGVydHkgOiB2b2lkIDA7XG59O1xuXG4vKipcbiAqIFJlYWRzIG9uZSBhcnJheSBwcm9wZXJ0eSBmcm9tIGFuIG9iamVjdC1saWtlIHZhbHVlLlxuICogQHBhcmFtIHZhbHVlIENhbmRpZGF0ZSBvYmplY3QuXG4gKiBAcGFyYW0ga2V5IExvb2t1cCBrZXkgdXNlZCB0byByZWFkIHRoZSBwcm9wZXJ0eS5cbiAqIEByZXR1cm5zIEFycmF5IHZhbHVlIHdoZW4gcHJlc2VudC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBpdGVtcyA9IHJlYWRBcnJheVByb3BlcnR5KHsgZWxlbWVudHM6IFsxLCAyXSB9LCBcImVsZW1lbnRzXCIpO1xuICogYGBgXG4gKi9cbmNvbnN0IHJlYWRBcnJheVByb3BlcnR5ID0gKFxuICB2YWx1ZTogdW5rbm93bixcbiAga2V5OiBzdHJpbmcsXG4pOiB1bmRlZmluZWQgfCB1bmtub3duW10gPT4ge1xuICBjb25zdCByZWNvcmQgPSBhc1JlY29yZCh2YWx1ZSk7XG4gIGNvbnN0IHByb3BlcnR5ID0gcmVjb3JkPy5ba2V5XTtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkocHJvcGVydHkpID8gcHJvcGVydHkgOiB2b2lkIDA7XG59O1xuXG4vKipcbiAqIFJlc29sdmVzIFR5cGVTY3JpcHQgcGFyc2VyIHNlcnZpY2VzIHByb2dyYW0gd2hlbiBhdmFpbGFibGUuXG4gKiBAcGFyYW0gY29udGV4dCBSdWxlIGNvbnRleHQuXG4gKiBAcmV0dXJucyBUeXBlU2NyaXB0IHByb2dyYW0gd2hlbiBhdmFpbGFibGUuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcHJvZ3JhbSA9IGdldFR5cGVTY3JpcHRQcm9ncmFtKGNvbnRleHQpO1xuICogYGBgXG4gKi9cbmNvbnN0IGdldFR5cGVTY3JpcHRQcm9ncmFtID0gKFxuICBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0LFxuKTogdHMuUHJvZ3JhbSB8IHVuZGVmaW5lZCA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc2VydmljZXMgPSBFU0xpbnRVdGlscy5nZXRQYXJzZXJTZXJ2aWNlcyhjb250ZXh0IGFzIG5ldmVyKTtcbiAgICByZXR1cm4gc2VydmljZXMucHJvZ3JhbTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxufTtcblxuLyoqXG4gKiBDb2xsZWN0cyBpZGVudGlmaWVyIG5hbWVzIGZyb20gb25lIHZhcmlhYmxlIHBhdHRlcm4uXG4gKiBAcGFyYW0gbm9kZSBWYXJpYWJsZSBwYXR0ZXJuIGNhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIElkZW50aWZpZXIgbmFtZXMgZGVjbGFyZWQgYnkgdGhlIHBhdHRlcm4uXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbmFtZXMgPSBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyhwYXR0ZXJuKTtcbiAqIGBgYFxuICovXG5jb25zdCBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyA9IChub2RlOiB1bmtub3duKTogc3RyaW5nW10gPT4ge1xuICBjb25zdCBwYXR0ZXJuID0gYXNSZWNvcmQobm9kZSk7XG5cbiAgaWYgKHBhdHRlcm4gPT09IHZvaWQgMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHBhdHRlcm5UeXBlID0gcmVhZFN0cmluZ1Byb3BlcnR5KHBhdHRlcm4sIFwidHlwZVwiKTtcblxuICBpZiAocGF0dGVyblR5cGUgPT09IFwiSWRlbnRpZmllclwiKSB7XG4gICAgY29uc3QgbmFtZSA9IHJlYWRTdHJpbmdQcm9wZXJ0eShwYXR0ZXJuLCBcIm5hbWVcIik7XG4gICAgcmV0dXJuIG5hbWUgPT09IHZvaWQgMCA/IFtdIDogW25hbWVdO1xuICB9XG5cbiAgaWYgKHBhdHRlcm5UeXBlID09PSBcIlJlc3RFbGVtZW50XCIpIHtcbiAgICByZXR1cm4gY29sbGVjdFBhdHRlcm5JZGVudGlmaWVyTmFtZXMocGF0dGVybltcImFyZ3VtZW50XCJdKTtcbiAgfVxuXG4gIGlmIChwYXR0ZXJuVHlwZSA9PT0gXCJBc3NpZ25tZW50UGF0dGVyblwiKSB7XG4gICAgcmV0dXJuIGNvbGxlY3RQYXR0ZXJuSWRlbnRpZmllck5hbWVzKHBhdHRlcm5bXCJsZWZ0XCJdKTtcbiAgfVxuXG4gIGlmIChwYXR0ZXJuVHlwZSA9PT0gXCJBcnJheVBhdHRlcm5cIikge1xuICAgIHJldHVybiAocmVhZEFycmF5UHJvcGVydHkocGF0dGVybiwgXCJlbGVtZW50c1wiKSA/PyBbXSkuZmxhdE1hcCgoZWxlbWVudCkgPT5cbiAgICAgIGNvbGxlY3RQYXR0ZXJuSWRlbnRpZmllck5hbWVzKGVsZW1lbnQpLFxuICAgICk7XG4gIH1cblxuICBpZiAocGF0dGVyblR5cGUgPT09IFwiT2JqZWN0UGF0dGVyblwiKSB7XG4gICAgcmV0dXJuIChyZWFkQXJyYXlQcm9wZXJ0eShwYXR0ZXJuLCBcInByb3BlcnRpZXNcIikgPz8gW10pLmZsYXRNYXAoXG4gICAgICAocHJvcGVydHkpID0+IHtcbiAgICAgICAgaWYgKHJlYWRTdHJpbmdQcm9wZXJ0eShwcm9wZXJ0eSwgXCJ0eXBlXCIpID09PSBcIlJlc3RFbGVtZW50XCIpIHtcbiAgICAgICAgICByZXR1cm4gY29sbGVjdFBhdHRlcm5JZGVudGlmaWVyTmFtZXMoXG4gICAgICAgICAgICBhc1JlY29yZChwcm9wZXJ0eSk/LltcImFyZ3VtZW50XCJdLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29sbGVjdFBhdHRlcm5JZGVudGlmaWVyTmFtZXMoYXNSZWNvcmQocHJvcGVydHkpPy5bXCJ2YWx1ZVwiXSk7XG4gICAgICB9LFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gW107XG59O1xuXG4vKipcbiAqIFJlYWRzIG9uZSBleHBvcnQgc3BlY2lmaWVyIG5hbWUuXG4gKiBAcGFyYW0gc3BlY2lmaWVyIEV4cG9ydCBzcGVjaWZpZXIgY2FuZGlkYXRlLlxuICogQHJldHVybnMgRXhwb3J0ZWQgbmFtZSB3aGVuIGF2YWlsYWJsZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBuYW1lID0gZ2V0RXhwb3J0U3BlY2lmaWVyTmFtZShzcGVjaWZpZXIpO1xuICogYGBgXG4gKi9cbmNvbnN0IGdldEV4cG9ydFNwZWNpZmllck5hbWUgPSAoc3BlY2lmaWVyOiB1bmtub3duKTogc3RyaW5nIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgY2FuZGlkYXRlID0gYXNSZWNvcmQoc3BlY2lmaWVyKTtcbiAgY29uc3QgZXhwb3J0ZWROYW1lID0gcmVhZFN0cmluZ1Byb3BlcnR5KGNhbmRpZGF0ZT8uW1wiZXhwb3J0ZWRcIl0sIFwibmFtZVwiKTtcblxuICBpZiAodHlwZW9mIGV4cG9ydGVkTmFtZSA9PT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBleHBvcnRlZE5hbWU7XG4gIH1cblxuICBjb25zdCBsb2NhbE5hbWUgPSByZWFkU3RyaW5nUHJvcGVydHkoY2FuZGlkYXRlPy5bXCJsb2NhbFwiXSwgXCJuYW1lXCIpO1xuXG4gIHJldHVybiB0eXBlb2YgbG9jYWxOYW1lID09PSBcInN0cmluZ1wiID8gbG9jYWxOYW1lIDogdm9pZCAwO1xufTtcblxuLyoqXG4gKiBSZWFkcyBvbmUgbG9jYWwgZXhwb3J0IHNwZWNpZmllciBuYW1lLlxuICogQHBhcmFtIHNwZWNpZmllciBFeHBvcnQgc3BlY2lmaWVyIGNhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIExvY2FsIHNwZWNpZmllciBuYW1lIHdoZW4gYXZhaWxhYmxlLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IG5hbWUgPSBnZXRFeHBvcnRTcGVjaWZpZXJMb2NhbE5hbWUoc3BlY2lmaWVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBnZXRFeHBvcnRTcGVjaWZpZXJMb2NhbE5hbWUgPSAoXG4gIHNwZWNpZmllcjogdW5rbm93bixcbik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XG4gIGNvbnN0IGNhbmRpZGF0ZSA9IGFzUmVjb3JkKHNwZWNpZmllcik7XG5cbiAgcmV0dXJuIHJlYWRTdHJpbmdQcm9wZXJ0eShjYW5kaWRhdGU/LltcImxvY2FsXCJdLCBcIm5hbWVcIik7XG59O1xuXG4vKipcbiAqIENvbGxlY3RzIHRvcC1sZXZlbCBkZWNsYXJhdGlvbiBuYW1lcyBvd25lZCBieSB0aGUgY3VycmVudCBtb2R1bGUuXG4gKiBAcGFyYW0gYm9keSBQcm9ncmFtIGJvZHkgc3RhdGVtZW50cy5cbiAqIEByZXR1cm5zIE1hcCBmcm9tIGxvY2FsbHkgZGVjbGFyZWQgbmFtZSB0byBpdHMgZGVjbGFyYXRpb24gbWV0YWRhdGEuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZGVjbGFyYXRpb25zID0gY29sbGVjdExvY2FsRGVjbGFyYXRpb25OYW1lcyhwcm9ncmFtLmJvZHkpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNvbGxlY3RMb2NhbERlY2xhcmF0aW9uTmFtZXMgPSAoXG4gIGJvZHk6IEFTVC5Qcm9ncmFtW1wiYm9keVwiXSxcbik6IE1hcDxzdHJpbmcsIExvY2FsRGVjbGFyYXRpb24+ID0+IHtcbiAgY29uc3QgZGVjbGFyYXRpb25OYW1lcyA9IG5ldyBNYXA8c3RyaW5nLCBMb2NhbERlY2xhcmF0aW9uPigpO1xuXG4gIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJvZHkpIHtcbiAgICBjb25zdCBkZWNsYXJhdGlvbkNhbmRpZGF0ZSA9XG4gICAgICBzdGF0ZW1lbnQudHlwZSA9PT0gXCJFeHBvcnROYW1lZERlY2xhcmF0aW9uXCIgJiZcbiAgICAgIHN0YXRlbWVudC5kZWNsYXJhdGlvbiAhPT0gbnVsbCAmJlxuICAgICAgc3RhdGVtZW50LmRlY2xhcmF0aW9uICE9PSB2b2lkIDBcbiAgICAgICAgPyBzdGF0ZW1lbnQuZGVjbGFyYXRpb25cbiAgICAgICAgOiBzdGF0ZW1lbnQ7XG4gICAgY29uc3QgZGVjbGFyYXRpb25DYW5kaWRhdGVSZWNvcmQgPSBhc1JlY29yZChkZWNsYXJhdGlvbkNhbmRpZGF0ZSk7XG4gICAgY29uc3QgZGVjbGFyYXRpb25DYW5kaWRhdGVUeXBlID0gcmVhZFN0cmluZ1Byb3BlcnR5KFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGUsXG4gICAgICBcInR5cGVcIixcbiAgICApO1xuXG4gICAgaWYgKFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGVSZWNvcmQgPT09IHZvaWQgMCB8fFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGVUeXBlID09PSB2b2lkIDBcbiAgICApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSA9PT0gXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIgfHxcbiAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSA9PT0gXCJDbGFzc0RlY2xhcmF0aW9uXCIgfHxcbiAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSA9PT0gXCJUU0VudW1EZWNsYXJhdGlvblwiIHx8XG4gICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNJbnRlcmZhY2VEZWNsYXJhdGlvblwiIHx8XG4gICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNUeXBlQWxpYXNEZWNsYXJhdGlvblwiXG4gICAgKSB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvbk5hbWUgPSByZWFkU3RyaW5nUHJvcGVydHkoXG4gICAgICAgIGRlY2xhcmF0aW9uQ2FuZGlkYXRlUmVjb3JkW1wiaWRcIl0sXG4gICAgICAgIFwibmFtZVwiLFxuICAgICAgKTtcblxuICAgICAgaWYgKGRlY2xhcmF0aW9uTmFtZSAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGRlY2xhcmF0aW9uTmFtZXMuc2V0KGRlY2xhcmF0aW9uTmFtZSwge1xuICAgICAgICAgIGtpbmQ6XG4gICAgICAgICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNJbnRlcmZhY2VEZWNsYXJhdGlvblwiIHx8XG4gICAgICAgICAgICBkZWNsYXJhdGlvbkNhbmRpZGF0ZVR5cGUgPT09IFwiVFNUeXBlQWxpYXNEZWNsYXJhdGlvblwiXG4gICAgICAgICAgICAgID8gXCJ0eXBlXCJcbiAgICAgICAgICAgICAgOiBcInZhbHVlXCIsXG4gICAgICAgICAgbm9kZTogc3RhdGVtZW50LFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKGRlY2xhcmF0aW9uQ2FuZGlkYXRlVHlwZSAhPT0gXCJWYXJpYWJsZURlY2xhcmF0aW9uXCIpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGRlY2xhcmF0aW9ucyA9IHJlYWRBcnJheVByb3BlcnR5KFxuICAgICAgZGVjbGFyYXRpb25DYW5kaWRhdGVSZWNvcmQsXG4gICAgICBcImRlY2xhcmF0aW9uc1wiLFxuICAgICk7XG5cbiAgICBpZiAoZGVjbGFyYXRpb25zID09PSB2b2lkIDApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgZGVjbGFyYXRpb25zKSB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvblJlY29yZCA9IGFzUmVjb3JkKGRlY2xhcmF0aW9uKTtcblxuICAgICAgaWYgKGRlY2xhcmF0aW9uUmVjb3JkID09PSB2b2lkIDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyhcbiAgICAgICAgZGVjbGFyYXRpb25SZWNvcmRbXCJpZFwiXSxcbiAgICAgICkpIHtcbiAgICAgICAgZGVjbGFyYXRpb25OYW1lcy5zZXQobmFtZSwgeyBraW5kOiBcInZhbHVlXCIsIG5vZGU6IHN0YXRlbWVudCB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZGVjbGFyYXRpb25OYW1lcztcbn07XG5cbi8qKlxuICogQ29sbGVjdHMgZXhwb3J0ZWQgZWxlbWVudHMgZnJvbSBvbmUgcHJvZ3JhbSBib2R5LlxuICogQHBhcmFtIGJvZHkgUHJvZ3JhbSBib2R5IHN0YXRlbWVudHMuXG4gKiBAcmV0dXJucyBFeHBvcnRlZCBlbGVtZW50cyBpbiBkZWNsYXJhdGlvbiBvcmRlci5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBleHBvcnRlZCA9IGNvbGxlY3RFeHBvcnRlZEVsZW1lbnRzKHByb2dyYW0uYm9keSk7XG4gKiBgYGBcbiAqL1xuY29uc3QgY29sbGVjdEV4cG9ydGVkRWxlbWVudHMgPSAoXG4gIGJvZHk6IEFTVC5Qcm9ncmFtW1wiYm9keVwiXSxcbik6IEV4cG9ydGVkRWxlbWVudFtdID0+IHtcbiAgY29uc3QgZXhwb3J0ZWRFbGVtZW50czogRXhwb3J0ZWRFbGVtZW50W10gPSBbXTtcbiAgY29uc3QgbG9jYWxEZWNsYXJhdGlvbk5hbWVzID0gY29sbGVjdExvY2FsRGVjbGFyYXRpb25OYW1lcyhib2R5KTtcblxuICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBib2R5KSB7XG4gICAgaWYgKHN0YXRlbWVudC50eXBlID09PSBcIkV4cG9ydERlZmF1bHREZWNsYXJhdGlvblwiKSB7XG4gICAgICBleHBvcnRlZEVsZW1lbnRzLnB1c2goe1xuICAgICAgICBleHBvcnRlZE5hbWU6IFwiZGVmYXVsdFwiLFxuICAgICAgICBleHBvcnRLaW5kOiBcInZhbHVlXCIsXG4gICAgICAgIG5vZGU6IHN0YXRlbWVudCxcbiAgICAgIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlbWVudC50eXBlICE9PSBcIkV4cG9ydE5hbWVkRGVjbGFyYXRpb25cIikge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlbWVudC5zb3VyY2UgIT09IG51bGwgJiYgc3RhdGVtZW50LnNvdXJjZSAhPT0gdm9pZCAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGVtZW50LmRlY2xhcmF0aW9uICE9PSBudWxsICYmIHN0YXRlbWVudC5kZWNsYXJhdGlvbiAhPT0gdm9pZCAwKSB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGFzUmVjb3JkKHN0YXRlbWVudC5kZWNsYXJhdGlvbik7XG5cbiAgICAgIGlmIChyZWFkU3RyaW5nUHJvcGVydHkoZGVjbGFyYXRpb24sIFwidHlwZVwiKSA9PT0gXCJWYXJpYWJsZURlY2xhcmF0aW9uXCIpIHtcbiAgICAgICAgZm9yIChjb25zdCB2YXJpYWJsZSBvZiByZWFkQXJyYXlQcm9wZXJ0eShkZWNsYXJhdGlvbiwgXCJkZWNsYXJhdGlvbnNcIikgPz9cbiAgICAgICAgICBbXSkge1xuICAgICAgICAgIGZvciAoY29uc3QgbmFtZSBvZiBjb2xsZWN0UGF0dGVybklkZW50aWZpZXJOYW1lcyhcbiAgICAgICAgICAgIGFzUmVjb3JkKHZhcmlhYmxlKT8uW1wiaWRcIl0sXG4gICAgICAgICAgKSkge1xuICAgICAgICAgICAgZXhwb3J0ZWRFbGVtZW50cy5wdXNoKHtcbiAgICAgICAgICAgICAgZXhwb3J0ZWROYW1lOiBuYW1lLFxuICAgICAgICAgICAgICBleHBvcnRLaW5kOiBcInZhbHVlXCIsXG4gICAgICAgICAgICAgIG5vZGU6IHN0YXRlbWVudCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZGVjbGFyYXRpb25OYW1lID0gcmVhZFN0cmluZ1Byb3BlcnR5KGRlY2xhcmF0aW9uPy5bXCJpZFwiXSwgXCJuYW1lXCIpO1xuICAgICAgICBjb25zdCBkZWNsYXJhdGlvblR5cGUgPSByZWFkU3RyaW5nUHJvcGVydHkoZGVjbGFyYXRpb24sIFwidHlwZVwiKTtcbiAgICAgICAgY29uc3QgZXhwb3J0S2luZDogRXhwb3J0S2luZCA9XG4gICAgICAgICAgZGVjbGFyYXRpb25UeXBlID09PSBcIlRTSW50ZXJmYWNlRGVjbGFyYXRpb25cIiB8fFxuICAgICAgICAgIGRlY2xhcmF0aW9uVHlwZSA9PT0gXCJUU1R5cGVBbGlhc0RlY2xhcmF0aW9uXCJcbiAgICAgICAgICAgID8gXCJ0eXBlXCJcbiAgICAgICAgICAgIDogXCJ2YWx1ZVwiO1xuXG4gICAgICAgIGlmICh0eXBlb2YgZGVjbGFyYXRpb25OYW1lID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgZXhwb3J0ZWRFbGVtZW50cy5wdXNoKHtcbiAgICAgICAgICAgIGV4cG9ydGVkTmFtZTogZGVjbGFyYXRpb25OYW1lLFxuICAgICAgICAgICAgZXhwb3J0S2luZCxcbiAgICAgICAgICAgIG5vZGU6IHN0YXRlbWVudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNwZWNpZmllciBvZiBzdGF0ZW1lbnQuc3BlY2lmaWVycykge1xuICAgICAgY29uc3QgbG9jYWxOYW1lID0gZ2V0RXhwb3J0U3BlY2lmaWVyTG9jYWxOYW1lKHNwZWNpZmllcik7XG4gICAgICBjb25zdCBsb2NhbERlY2xhcmF0aW9uID1cbiAgICAgICAgbG9jYWxOYW1lID09PSB2b2lkIDAgPyB2b2lkIDAgOiBsb2NhbERlY2xhcmF0aW9uTmFtZXMuZ2V0KGxvY2FsTmFtZSk7XG5cbiAgICAgIGlmIChsb2NhbERlY2xhcmF0aW9uID09PSB2b2lkIDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4cG9ydGVkTmFtZSA9IGdldEV4cG9ydFNwZWNpZmllck5hbWUoc3BlY2lmaWVyKTtcblxuICAgICAgaWYgKGV4cG9ydGVkTmFtZSAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGNvbnN0IHN0YXRlbWVudEV4cG9ydEtpbmQgPSByZWFkU3RyaW5nUHJvcGVydHkoc3RhdGVtZW50LCBcImV4cG9ydEtpbmRcIik7XG4gICAgICAgIGNvbnN0IHNwZWNpZmllckV4cG9ydEtpbmQgPSByZWFkU3RyaW5nUHJvcGVydHkoc3BlY2lmaWVyLCBcImV4cG9ydEtpbmRcIik7XG4gICAgICAgIGNvbnN0IGlzVHlwZU9ubHlFeHBvcnQgPVxuICAgICAgICAgIHN0YXRlbWVudEV4cG9ydEtpbmQgPT09IFwidHlwZVwiIHx8IHNwZWNpZmllckV4cG9ydEtpbmQgPT09IFwidHlwZVwiO1xuXG4gICAgICAgIGV4cG9ydGVkRWxlbWVudHMucHVzaCh7XG4gICAgICAgICAgZXhwb3J0ZWROYW1lLFxuICAgICAgICAgIGV4cG9ydEtpbmQ6IGlzVHlwZU9ubHlFeHBvcnQgPyBcInR5cGVcIiA6IGxvY2FsRGVjbGFyYXRpb24ua2luZCxcbiAgICAgICAgICBub2RlOiBsb2NhbERlY2xhcmF0aW9uLm5vZGUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBleHBvcnRlZEVsZW1lbnRzO1xufTtcblxuLyoqXG4gKiBSZXNvbHZlcyBvbmUgc3ltYm9sIHRvIGl0cyBjYW5vbmljYWwgdGFyZ2V0LlxuICogQHBhcmFtIHN5bWJvbCBDYW5kaWRhdGUgc3ltYm9sLlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCBjaGVja2VyLlxuICogQHJldHVybnMgUmVzb2x2ZWQgY2Fub25pY2FsIHN5bWJvbC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCByZXNvbHZlZCA9IHJlc29sdmVDYW5vbmljYWxTeW1ib2woc3ltYm9sLCBjaGVja2VyKTtcbiAqIGBgYFxuICovXG5jb25zdCByZXNvbHZlQ2Fub25pY2FsU3ltYm9sID0gKFxuICBzeW1ib2w6IHRzLlN5bWJvbCxcbiAgY2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4pOiB0cy5TeW1ib2wgPT4ge1xuICBpZiAoKHN5bWJvbC5mbGFncyAmIHRzLlN5bWJvbEZsYWdzLkFsaWFzKSA9PT0gMCkge1xuICAgIHJldHVybiBzeW1ib2w7XG4gIH1cblxuICB0cnkge1xuICAgIHJldHVybiBjaGVja2VyLmdldEFsaWFzZWRTeW1ib2woc3ltYm9sKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHN5bWJvbDtcbiAgfVxufTtcblxuLyoqXG4gKiBCdWlsZHMgZGVjbGFyYXRpb24tc2l0ZSBrZXlzIGZvciBzeW1ib2wgaWRlbnRpdHkgbWF0Y2hpbmcuXG4gKiBAcGFyYW0gc3ltYm9sIFN5bWJvbCBiZWluZyBjb21wYXJlZC5cbiAqIEByZXR1cm5zIERlY2xhcmF0aW9uIGtleXMgZGVzY3JpYmluZyB3aGVyZSB0aGlzIHN5bWJvbCBpcyBkZWNsYXJlZC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBrZXlzID0gZ2V0RGVjbGFyYXRpb25LZXlzKHN5bWJvbCk7XG4gKiBgYGBcbiAqL1xuY29uc3QgZ2V0RGVjbGFyYXRpb25LZXlzID0gKHN5bWJvbDogdHMuU3ltYm9sKTogU2V0PHN0cmluZz4gPT4ge1xuICBjb25zdCBkZWNsYXJhdGlvbnMgPSBzeW1ib2wuZGVjbGFyYXRpb25zID8/IFtdO1xuXG4gIHJldHVybiBuZXcgU2V0KFxuICAgIGRlY2xhcmF0aW9ucy5tYXAoKGRlY2xhcmF0aW9uKSA9PiB7XG4gICAgICBjb25zdCBzb3VyY2VGaWxlbmFtZSA9IGRlY2xhcmF0aW9uLmdldFNvdXJjZUZpbGUoKS5maWxlTmFtZTtcbiAgICAgIHJldHVybiBgJHtzb3VyY2VGaWxlbmFtZX06JHtTdHJpbmcoZGVjbGFyYXRpb24ucG9zKX06JHtTdHJpbmcoZGVjbGFyYXRpb24uZW5kKX1gO1xuICAgIH0pLFxuICApO1xufTtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0d28gc3ltYm9scyByZWZlcmVuY2UgdGhlIHNhbWUgZGVjbGFyYXRpb24gc2l0ZS5cbiAqIEBwYXJhbSBsZWZ0IExlZnQtaGFuZCBzeW1ib2wgY2FuZGlkYXRlLlxuICogQHBhcmFtIHJpZ2h0IFJpZ2h0LWhhbmQgc3ltYm9sIGNhbmRpZGF0ZS5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiBib3RoIHN5bWJvbHMgaWRlbnRpZnkgdGhlIHNhbWUgZGVjbGFyYXRpb24uXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3Qgc2FtZSA9IGlzU2FtZVN5bWJvbChsZWZ0LCByaWdodCk7XG4gKiBgYGBcbiAqL1xuY29uc3QgaXNTYW1lU3ltYm9sID0gKGxlZnQ6IHRzLlN5bWJvbCwgcmlnaHQ6IHRzLlN5bWJvbCk6IGJvb2xlYW4gPT4ge1xuICBpZiAobGVmdCA9PT0gcmlnaHQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGNvbnN0IGxlZnRLZXlzID0gZ2V0RGVjbGFyYXRpb25LZXlzKGxlZnQpO1xuICBjb25zdCByaWdodEtleXMgPSBnZXREZWNsYXJhdGlvbktleXMocmlnaHQpO1xuXG4gIGZvciAoY29uc3Qga2V5IG9mIGxlZnRLZXlzKSB7XG4gICAgaWYgKHJpZ2h0S2V5cy5oYXMoa2V5KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuLyoqXG4gKiBSZXNvbHZlcyBvbmUgZXhwb3J0ZWQgc3ltYm9sIGJ5IG5hbWUgZnJvbSBhIHNvdXJjZSBmaWxlLlxuICogQHBhcmFtIHByb2dyYW0gVHlwZVNjcmlwdCBwcm9ncmFtLlxuICogQHBhcmFtIHNvdXJjZUZpbGVuYW1lIFNvdXJjZSBmaWxlIHBhdGguXG4gKiBAcGFyYW0gZXhwb3J0ZWROYW1lIFB1YmxpYyBuYW1lIGV4cG9zZWQgYnkgdGhlIG1vZHVsZSBleHBvcnQgbGlzdC5cbiAqIEByZXR1cm5zIFN5bWJvbCB3aGVuIGZvdW5kLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHN5bWJvbCA9IGdldEV4cG9ydGVkU3ltYm9sKHByb2dyYW0sIHNvdXJjZUZpbGVuYW1lLCBcImZlYXR1cmVcIik7XG4gKiBgYGBcbiAqL1xuY29uc3QgZ2V0RXhwb3J0ZWRTeW1ib2wgPSAoXG4gIHByb2dyYW06IHRzLlByb2dyYW0sXG4gIHNvdXJjZUZpbGVuYW1lOiBzdHJpbmcsXG4gIGV4cG9ydGVkTmFtZTogc3RyaW5nLFxuKTogdHMuU3ltYm9sIHwgdW5kZWZpbmVkID0+IHtcbiAgY29uc3QgY2hlY2tlciA9IHByb2dyYW0uZ2V0VHlwZUNoZWNrZXIoKTtcbiAgY29uc3Qgc291cmNlRmlsZSA9IHByb2dyYW1cbiAgICAuZ2V0U291cmNlRmlsZXMoKVxuICAgIC5maW5kKFxuICAgICAgKGZpbGUpID0+XG4gICAgICAgIHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aChmaWxlLmZpbGVOYW1lKSA9PT1cbiAgICAgICAgdG9Db21wYXJhYmxlQWJzb2x1dGVQYXRoKHNvdXJjZUZpbGVuYW1lKSxcbiAgICApO1xuXG4gIGlmIChzb3VyY2VGaWxlID09PSB2b2lkIDApIHtcbiAgICByZXR1cm4gdm9pZCAwO1xuICB9XG5cbiAgY29uc3QgbW9kdWxlU3ltYm9sID0gY2hlY2tlci5nZXRTeW1ib2xBdExvY2F0aW9uKHNvdXJjZUZpbGUpO1xuXG4gIGlmIChtb2R1bGVTeW1ib2wgPT09IHZvaWQgMCkge1xuICAgIHJldHVybiB2b2lkIDA7XG4gIH1cblxuICBjb25zdCBleHBvcnRlZFN5bWJvbCA9IGNoZWNrZXJcbiAgICAuZ2V0RXhwb3J0c09mTW9kdWxlKG1vZHVsZVN5bWJvbClcbiAgICAuZmluZCgoc3ltYm9sKSA9PiBzeW1ib2wuZ2V0TmFtZSgpID09PSBleHBvcnRlZE5hbWUpO1xuXG4gIGlmIChleHBvcnRlZFN5bWJvbCA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxuXG4gIHJldHVybiByZXNvbHZlQ2Fub25pY2FsU3ltYm9sKGV4cG9ydGVkU3ltYm9sLCBjaGVja2VyKTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgb25lIHNvdXJjZSBmaWxlIGV4cG9ydHMgdGhlIHRhcmdldCBzeW1ib2wuXG4gKiBAcGFyYW0gc291cmNlRmlsZSBTb3VyY2UgZmlsZSB0aGF0IG1heSBleHBvc2UgdGhlIHN5bWJvbC5cbiAqIEBwYXJhbSBjaGVja2VyIFR5cGVTY3JpcHQgY2hlY2tlci5cbiAqIEBwYXJhbSB0YXJnZXRTeW1ib2wgU3ltYm9sIGJlaW5nIGNsYXNzaWZpZWQuXG4gKiBAcmV0dXJucyBUcnVlIHdoZW4gb25lIG1vZHVsZSBleHBvcnQgcmVzb2x2ZXMgdG8gdGhlIHRhcmdldCBzeW1ib2wuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZXhwb3NlZCA9IHNvdXJjZUZpbGVFeHBvcnRzU3ltYm9sKHNvdXJjZUZpbGUsIGNoZWNrZXIsIHRhcmdldFN5bWJvbCk7XG4gKiBgYGBcbiAqL1xuY29uc3Qgc291cmNlRmlsZUV4cG9ydHNTeW1ib2wgPSAoXG4gIHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUsXG4gIGNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuICB0YXJnZXRTeW1ib2w6IHRzLlN5bWJvbCxcbik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCBtb2R1bGVTeW1ib2wgPSBjaGVja2VyLmdldFN5bWJvbEF0TG9jYXRpb24oc291cmNlRmlsZSk7XG5cbiAgaWYgKG1vZHVsZVN5bWJvbCA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9yIChjb25zdCBleHBvcnRlZFN5bWJvbCBvZiBjaGVja2VyLmdldEV4cG9ydHNPZk1vZHVsZShtb2R1bGVTeW1ib2wpKSB7XG4gICAgY29uc3QgcmVzb2x2ZWRTeW1ib2wgPSByZXNvbHZlQ2Fub25pY2FsU3ltYm9sKGV4cG9ydGVkU3ltYm9sLCBjaGVja2VyKTtcblxuICAgIGlmIChpc1NhbWVTeW1ib2wocmVzb2x2ZWRTeW1ib2wsIHRhcmdldFN5bWJvbCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgYW4gaWRlbnRpZmllciBwYXJ0aWNpcGF0ZXMgaW4gb25lIGRlY2xhcmF0aW9uL2ltcG9ydC9leHBvcnQgc2l0ZS5cbiAqIEBwYXJhbSBpZGVudGlmaWVyIElkZW50aWZpZXIgbm9kZSB0byBldmFsdWF0ZS5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiB0aGUgaWRlbnRpZmllciBpcyBkZWNsYXJhdGlvbi1vbmx5IHN5bnRheC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBkZWNsYXJhdGlvbiA9IGlzRGVjbGFyYXRpb25Pbmx5SWRlbnRpZmllcihpZGVudGlmaWVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc0RlY2xhcmF0aW9uT25seUlkZW50aWZpZXIgPSAoaWRlbnRpZmllcjogdHMuSWRlbnRpZmllcik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCBwYXJlbnQgPSBpZGVudGlmaWVyLnBhcmVudDtcblxuICByZXR1cm4gKFxuICAgIHRzLmlzSW1wb3J0U3BlY2lmaWVyKHBhcmVudCkgfHxcbiAgICB0cy5pc0ltcG9ydENsYXVzZShwYXJlbnQpIHx8XG4gICAgdHMuaXNOYW1lc3BhY2VJbXBvcnQocGFyZW50KSB8fFxuICAgIHRzLmlzSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24ocGFyZW50KSB8fFxuICAgIHRzLmlzRXhwb3J0U3BlY2lmaWVyKHBhcmVudCkgfHxcbiAgICB0cy5pc1R5cGVBbGlhc0RlY2xhcmF0aW9uKHBhcmVudCkgfHxcbiAgICB0cy5pc0ludGVyZmFjZURlY2xhcmF0aW9uKHBhcmVudCkgfHxcbiAgICB0cy5pc1R5cGVQYXJhbWV0ZXJEZWNsYXJhdGlvbihwYXJlbnQpIHx8XG4gICAgKHRzLmlzVmFyaWFibGVEZWNsYXJhdGlvbihwYXJlbnQpICYmIHBhcmVudC5uYW1lID09PSBpZGVudGlmaWVyKSB8fFxuICAgICh0cy5pc0Z1bmN0aW9uRGVjbGFyYXRpb24ocGFyZW50KSAmJiBwYXJlbnQubmFtZSA9PT0gaWRlbnRpZmllcikgfHxcbiAgICAodHMuaXNDbGFzc0RlY2xhcmF0aW9uKHBhcmVudCkgJiYgcGFyZW50Lm5hbWUgPT09IGlkZW50aWZpZXIpIHx8XG4gICAgKHRzLmlzUGFyYW1ldGVyKHBhcmVudCkgJiYgcGFyZW50Lm5hbWUgPT09IGlkZW50aWZpZXIpXG4gICk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIG9uZSBpZGVudGlmaWVyIG5vZGUgYXBwZWFycyB1bmRlciBhIHR5cGUgbm9kZS5cbiAqIEBwYXJhbSBpZGVudGlmaWVyIENhbmRpZGF0ZSBpZGVudGlmaWVyLlxuICogQHJldHVybnMgVHJ1ZSB3aGVuIHRoZSBpZGVudGlmaWVyIGlzIGluc2lkZSB0eXBlLW9ubHkgc3ludGF4LlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHR5cGVQb3NpdGlvbiA9IGlzVHlwZVBvc2l0aW9uSWRlbnRpZmllcihpZGVudGlmaWVyKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc1R5cGVQb3NpdGlvbklkZW50aWZpZXIgPSAoaWRlbnRpZmllcjogdHMuSWRlbnRpZmllcik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCB2aXNpdE5vZGUgPSAoY3VycmVudDogdHMuTm9kZSk6IGJvb2xlYW4gPT4ge1xuICAgIGlmICh0cy5pc1R5cGVRdWVyeU5vZGUoY3VycmVudCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAodHMuaXNUeXBlTm9kZShjdXJyZW50KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdHMuaXNFeHByZXNzaW9uU3RhdGVtZW50KGN1cnJlbnQpIHx8XG4gICAgICB0cy5pc0NhbGxFeHByZXNzaW9uKGN1cnJlbnQpIHx8XG4gICAgICB0cy5pc1Byb3BlcnR5QWNjZXNzRXhwcmVzc2lvbihjdXJyZW50KSB8fFxuICAgICAgdHMuaXNFbGVtZW50QWNjZXNzRXhwcmVzc2lvbihjdXJyZW50KSB8fFxuICAgICAgdHMuaXNWYXJpYWJsZURlY2xhcmF0aW9uKGN1cnJlbnQpIHx8XG4gICAgICB0cy5pc1JldHVyblN0YXRlbWVudChjdXJyZW50KVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICh0cy5pc1NvdXJjZUZpbGUoY3VycmVudCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmlzaXROb2RlKGN1cnJlbnQucGFyZW50KTtcbiAgfTtcblxuICByZXR1cm4gdmlzaXROb2RlKGlkZW50aWZpZXIpO1xufTtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBvbmUgaWRlbnRpZmllciBpcyBvbmUgY29uY3JldGUgdXNhZ2UgY2FuZGlkYXRlIGZvciB0aGUgZXhwb3J0IGtpbmQuXG4gKiBAcGFyYW0gaWRlbnRpZmllciBJZGVudGlmaWVyIG5vZGUuXG4gKiBAcGFyYW0gZXhwb3J0S2luZCBXaGV0aGVyIHR5cGUtb25seSBvciB2YWx1ZSB1c2FnZSBpcyByZXF1aXJlZC5cbiAqIEByZXR1cm5zIFRydWUgd2hlbiB0aGUgaWRlbnRpZmllciBjYW4gc2F0aXNmeSB1c2FnZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBjb25jcmV0ZSA9IGlzQ29uY3JldGVVc2FnZUlkZW50aWZpZXIoaWRlbnRpZmllciwgXCJ2YWx1ZVwiKTtcbiAqIGBgYFxuICovXG5jb25zdCBpc0NvbmNyZXRlVXNhZ2VJZGVudGlmaWVyID0gKFxuICBpZGVudGlmaWVyOiB0cy5JZGVudGlmaWVyLFxuICBleHBvcnRLaW5kOiBFeHBvcnRLaW5kLFxuKTogYm9vbGVhbiA9PiB7XG4gIGlmIChpc0RlY2xhcmF0aW9uT25seUlkZW50aWZpZXIoaWRlbnRpZmllcikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBpblR5cGVQb3NpdGlvbiA9IGlzVHlwZVBvc2l0aW9uSWRlbnRpZmllcihpZGVudGlmaWVyKTtcblxuICByZXR1cm4gZXhwb3J0S2luZCA9PT0gXCJ0eXBlXCIgPyBpblR5cGVQb3NpdGlvbiA6ICFpblR5cGVQb3NpdGlvbjtcbn07XG5cbi8qKlxuICogQXBwZW5kcyBjb25jcmV0ZSB1c2FnZXMgZnJvbSBvbmUgc291cmNlIGZpbGUgaW50byB0aGUgYWNjdW11bGF0b3IuXG4gKiBAcGFyYW0gc291cmNlRmlsZSBTb3VyY2UgZmlsZSB0byBzY2FuLlxuICogQHBhcmFtIGNoZWNrZXIgVHlwZVNjcmlwdCBjaGVja2VyLlxuICogQHBhcmFtIHRhcmdldFN5bWJvbCBFeHBvcnQgc3ltYm9sIGJlaW5nIGNsYXNzaWZpZWQuXG4gKiBAcGFyYW0gZXhwb3J0ZWRFbGVtZW50IEV4cG9ydCBtZXRhZGF0YS5cbiAqIEBwYXJhbSBjb25zdW1lcklzVGVzdEZpbGUgV2hldGhlciBzb3VyY2UgZmlsZSBpcyBhIHRlc3QgZmlsZS5cbiAqIEBwYXJhbSB1c2FnZXMgTXV0YWJsZSB1c2FnZSBhY2N1bXVsYXRvci5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb2xsZWN0Q29uY3JldGVVc2FnZXNGcm9tU291cmNlRmlsZShzb3VyY2VGaWxlLCBjaGVja2VyLCB0YXJnZXRTeW1ib2xLZXksIGV4cG9ydGVkRWxlbWVudCwgZmFsc2UsIHVzYWdlcyk7XG4gKiBgYGBcbiAqL1xuY29uc3QgY29sbGVjdENvbmNyZXRlVXNhZ2VzRnJvbVNvdXJjZUZpbGUgPSAoXG4gIHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUsXG4gIGNoZWNrZXI6IHRzLlR5cGVDaGVja2VyLFxuICB0YXJnZXRTeW1ib2w6IHRzLlN5bWJvbCxcbiAgZXhwb3J0ZWRFbGVtZW50OiBFeHBvcnRlZEVsZW1lbnQsXG4gIGNvbnN1bWVySXNUZXN0RmlsZTogYm9vbGVhbixcbiAgdXNhZ2VzOiBFeHBvcnRVc2FnZVtdLFxuKTogdm9pZCA9PiB7XG4gIGNvbnN0IHZpc2l0Tm9kZSA9IChub2RlOiB0cy5Ob2RlKTogdm9pZCA9PiB7XG4gICAgaWYgKCF0cy5pc0lkZW50aWZpZXIobm9kZSkpIHtcbiAgICAgIHRzLmZvckVhY2hDaGlsZChub2RlLCB2aXNpdE5vZGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaXNDb25jcmV0ZVVzYWdlSWRlbnRpZmllcihub2RlLCBleHBvcnRlZEVsZW1lbnQuZXhwb3J0S2luZCkpIHtcbiAgICAgIHRzLmZvckVhY2hDaGlsZChub2RlLCB2aXNpdE5vZGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNhbmRpZGF0ZVN5bWJvbCA9IGNoZWNrZXIuZ2V0U3ltYm9sQXRMb2NhdGlvbihub2RlKTtcblxuICAgIGlmIChjYW5kaWRhdGVTeW1ib2wgPT09IHZvaWQgMCkge1xuICAgICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0Tm9kZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb2x2ZWRTeW1ib2wgPSByZXNvbHZlQ2Fub25pY2FsU3ltYm9sKGNhbmRpZGF0ZVN5bWJvbCwgY2hlY2tlcik7XG5cbiAgICBpZiAoIWlzU2FtZVN5bWJvbChyZXNvbHZlZFN5bWJvbCwgdGFyZ2V0U3ltYm9sKSkge1xuICAgICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0Tm9kZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdXNhZ2VzLnB1c2goeyBpc1Rlc3RGaWxlOiBjb25zdW1lcklzVGVzdEZpbGUgfSk7XG4gICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0Tm9kZSk7XG4gIH07XG5cbiAgdmlzaXROb2RlKHNvdXJjZUZpbGUpO1xufTtcblxuLyoqXG4gKiBDb2xsZWN0cyBwdWJsaWMgQVBJIGV4cG9zdXJlIHVzYWdlcyBmb3Igb25lIGV4cG9ydGVkIHN5bWJvbC5cbiAqIEBwYXJhbSBwcm9ncmFtIFR5cGVTY3JpcHQgcHJvZ3JhbS5cbiAqIEBwYXJhbSBzb3VyY2VGaWxlbmFtZSBTb3VyY2UgZmlsZW5hbWUgd2hlcmUgZXhwb3J0IGlzIGRlZmluZWQuXG4gKiBAcGFyYW0gc3RhdGUgTm9ybWFsaXplZCBydWxlIG9wdGlvbnMuXG4gKiBAcGFyYW0gcmVwb1Jvb3QgQWJzb2x1dGUgcmVwb3NpdG9yeSByb290IHVzZWQgZm9yIGZpbGUgY2xhc3NpZmljYXRpb24uXG4gKiBAcGFyYW0gdGFyZ2V0U3ltYm9sIEV4cG9ydCBzeW1ib2wgYmVpbmcgY2xhc3NpZmllZC5cbiAqIEByZXR1cm5zIFB1YmxpYyBBUEkgZXhwb3N1cmUgdXNhZ2VzIGZvciB0aGUgZXhwb3J0ZWQgc3ltYm9sLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHVzYWdlcyA9IGNvbGxlY3RQdWJsaWNBcGlFeHBvc3VyZVVzYWdlcyhwcm9ncmFtLCBzb3VyY2VGaWxlbmFtZSwgc3RhdGUsIHJlcG9Sb290LCB0YXJnZXRTeW1ib2wpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNvbGxlY3RQdWJsaWNBcGlFeHBvc3VyZVVzYWdlcyA9IChcbiAgcHJvZ3JhbTogdHMuUHJvZ3JhbSxcbiAgc291cmNlRmlsZW5hbWU6IHN0cmluZyxcbiAgc3RhdGU6IE5vVW51c2VkRXhwb3J0c1N0YXRlLFxuICByZXBvUm9vdDogc3RyaW5nLFxuICB0YXJnZXRTeW1ib2w6IHRzLlN5bWJvbCxcbik6IEV4cG9ydFVzYWdlW10gPT4ge1xuICBjb25zdCBjaGVja2VyID0gcHJvZ3JhbS5nZXRUeXBlQ2hlY2tlcigpO1xuICBjb25zdCBub3JtYWxpemVkU291cmNlRmlsZW5hbWUgPSB0b0NvbXBhcmFibGVBYnNvbHV0ZVBhdGgoc291cmNlRmlsZW5hbWUpO1xuICBjb25zdCBub3JtYWxpemVkUmVwb1Jvb3QgPSBwYXRoLnJlc29sdmUocmVwb1Jvb3QpO1xuICBjb25zdCB1c2FnZXM6IEV4cG9ydFVzYWdlW10gPSBbXTtcblxuICBmb3IgKGNvbnN0IHNvdXJjZUZpbGUgb2YgcHJvZ3JhbS5nZXRTb3VyY2VGaWxlcygpKSB7XG4gICAgaWYgKHNvdXJjZUZpbGUuaXNEZWNsYXJhdGlvbkZpbGUpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHB1YmxpY0FwaUZpbGVuYW1lID0gcGF0aC5yZXNvbHZlKHNvdXJjZUZpbGUuZmlsZU5hbWUpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRQdWJsaWNBcGlGaWxlbmFtZSA9XG4gICAgICB0b0NvbXBhcmFibGVBYnNvbHV0ZVBhdGgocHVibGljQXBpRmlsZW5hbWUpO1xuXG4gICAgaWYgKG5vcm1hbGl6ZWRQdWJsaWNBcGlGaWxlbmFtZSA9PT0gbm9ybWFsaXplZFNvdXJjZUZpbGVuYW1lKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoIWlzUHVibGljQXBpRmlsZShwdWJsaWNBcGlGaWxlbmFtZSwgc3RhdGUsIG5vcm1hbGl6ZWRSZXBvUm9vdCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmICghc291cmNlRmlsZUV4cG9ydHNTeW1ib2woc291cmNlRmlsZSwgY2hlY2tlciwgdGFyZ2V0U3ltYm9sKSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdXNhZ2VzLnB1c2goe1xuICAgICAgaXNUZXN0RmlsZTogaXNUZXN0RmlsZShwdWJsaWNBcGlGaWxlbmFtZSwgc3RhdGUsIG5vcm1hbGl6ZWRSZXBvUm9vdCksXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gdXNhZ2VzO1xufTtcblxuLyoqXG4gKiBDb2xsZWN0cyBjb25jcmV0ZSB1c2FnZXMgb2Ygb25lIGV4cG9ydGVkIGVsZW1lbnQgYWNyb3NzIHRoZSBwcm9ncmFtLlxuICogQHBhcmFtIHByb2dyYW0gVHlwZVNjcmlwdCBwcm9ncmFtLlxuICogQHBhcmFtIHNvdXJjZUZpbGVuYW1lIFNvdXJjZSBmaWxlbmFtZSB3aGVyZSBleHBvcnQgaXMgZGVmaW5lZC5cbiAqIEBwYXJhbSBzdGF0ZSBOb3JtYWxpemVkIHJ1bGUgb3B0aW9ucy5cbiAqIEBwYXJhbSByZXBvUm9vdCBBYnNvbHV0ZSByZXBvc2l0b3J5IHJvb3QgdXNlZCBmb3IgdGVzdC1maWxlIGNsYXNzaWZpY2F0aW9uLlxuICogQHBhcmFtIGV4cG9ydGVkRWxlbWVudCBFeHBvcnRlZCBlbGVtZW50IHRvIGNsYXNzaWZ5LlxuICogQHJldHVybnMgQ29uY3JldGUgdXNhZ2VzIGZvciB0aGUgZXhwb3J0ZWQgZWxlbWVudC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCB1c2FnZXMgPSBjb2xsZWN0Q3Jvc3NGaWxlVXNhZ2VzKHByb2dyYW0sIFwiL3JlcG8vc3JjL2ZlYXR1cmUudHNcIiwgc3RhdGUsIFwiL3JlcG9cIiwgZXhwb3J0ZWRFbGVtZW50KTtcbiAqIGBgYFxuICovXG5jb25zdCBjb2xsZWN0Q3Jvc3NGaWxlVXNhZ2VzID0gKFxuICBwcm9ncmFtOiB0cy5Qcm9ncmFtLFxuICBzb3VyY2VGaWxlbmFtZTogc3RyaW5nLFxuICBzdGF0ZTogTm9VbnVzZWRFeHBvcnRzU3RhdGUsXG4gIHJlcG9Sb290OiBzdHJpbmcsXG4gIGV4cG9ydGVkRWxlbWVudDogRXhwb3J0ZWRFbGVtZW50LFxuKTogRXhwb3J0VXNhZ2VbXSA9PiB7XG4gIGNvbnN0IGNoZWNrZXIgPSBwcm9ncmFtLmdldFR5cGVDaGVja2VyKCk7XG4gIGNvbnN0IHRhcmdldFN5bWJvbCA9IGdldEV4cG9ydGVkU3ltYm9sKFxuICAgIHByb2dyYW0sXG4gICAgc291cmNlRmlsZW5hbWUsXG4gICAgZXhwb3J0ZWRFbGVtZW50LmV4cG9ydGVkTmFtZSxcbiAgKTtcblxuICBpZiAodGFyZ2V0U3ltYm9sID09PSB2b2lkIDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBub3JtYWxpemVkU291cmNlRmlsZW5hbWUgPSB0b0NvbXBhcmFibGVBYnNvbHV0ZVBhdGgoc291cmNlRmlsZW5hbWUpO1xuICBjb25zdCBub3JtYWxpemVkUmVwb1Jvb3QgPSBwYXRoLnJlc29sdmUocmVwb1Jvb3QpO1xuICBjb25zdCB1c2FnZXM6IEV4cG9ydFVzYWdlW10gPSBjb2xsZWN0UHVibGljQXBpRXhwb3N1cmVVc2FnZXMoXG4gICAgcHJvZ3JhbSxcbiAgICBzb3VyY2VGaWxlbmFtZSxcbiAgICBzdGF0ZSxcbiAgICByZXBvUm9vdCxcbiAgICB0YXJnZXRTeW1ib2wsXG4gICk7XG5cbiAgZm9yIChjb25zdCBzb3VyY2VGaWxlIG9mIHByb2dyYW0uZ2V0U291cmNlRmlsZXMoKSkge1xuICAgIGlmIChzb3VyY2VGaWxlLmlzRGVjbGFyYXRpb25GaWxlKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBjb25zdW1lckZpbGVuYW1lID0gcGF0aC5yZXNvbHZlKHNvdXJjZUZpbGUuZmlsZU5hbWUpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRDb25zdW1lckZpbGVuYW1lID1cbiAgICAgIHRvQ29tcGFyYWJsZUFic29sdXRlUGF0aChjb25zdW1lckZpbGVuYW1lKTtcblxuICAgIGlmIChub3JtYWxpemVkQ29uc3VtZXJGaWxlbmFtZSA9PT0gbm9ybWFsaXplZFNvdXJjZUZpbGVuYW1lKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBjb25zdW1lcklzVGVzdEZpbGUgPSBpc1Rlc3RGaWxlKFxuICAgICAgY29uc3VtZXJGaWxlbmFtZSxcbiAgICAgIHN0YXRlLFxuICAgICAgbm9ybWFsaXplZFJlcG9Sb290LFxuICAgICk7XG5cbiAgICBjb2xsZWN0Q29uY3JldGVVc2FnZXNGcm9tU291cmNlRmlsZShcbiAgICAgIHNvdXJjZUZpbGUsXG4gICAgICBjaGVja2VyLFxuICAgICAgdGFyZ2V0U3ltYm9sLFxuICAgICAgZXhwb3J0ZWRFbGVtZW50LFxuICAgICAgY29uc3VtZXJJc1Rlc3RGaWxlLFxuICAgICAgdXNhZ2VzLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gdXNhZ2VzO1xufTtcblxuLyoqXG4gKiBDbGFzc2lmaWVzIG9uZSBleHBvcnRlZCBuYW1lIGJhc2VkIG9uIGNyb3NzLWZpbGUgdXNhZ2VzLlxuICogQHBhcmFtIHVzYWdlcyBDb2xsZWN0ZWQgdXNhZ2VzLlxuICogQHJldHVybnMgQ2xhc3NpZmljYXRpb24gbGFiZWwuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY2xhc3NpZmljYXRpb24gPSBjbGFzc2lmeUV4cG9ydFVzYWdlKFwiZmVhdHVyZVwiLCB1c2FnZXMpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNsYXNzaWZ5RXhwb3J0VXNhZ2UgPSAoXG4gIHVzYWdlczogRXhwb3J0VXNhZ2VbXSxcbik6IFwicHJvZHVjdGlvblwiIHwgXCJ0ZXN0LW9ubHlcIiB8IFwidW51c2VkXCIgPT4ge1xuICBpZiAodXNhZ2VzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBcInVudXNlZFwiO1xuICB9XG5cbiAgZm9yIChjb25zdCB1c2FnZSBvZiB1c2FnZXMpIHtcbiAgICBpZiAoIXVzYWdlLmlzVGVzdEZpbGUpIHtcbiAgICAgIHJldHVybiBcInByb2R1Y3Rpb25cIjtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gXCJ0ZXN0LW9ubHlcIjtcbn07XG5cbmV4cG9ydCB7XG4gIGNsYXNzaWZ5RXhwb3J0VXNhZ2UsXG4gIGNvbGxlY3RDcm9zc0ZpbGVVc2FnZXMsXG4gIGNvbGxlY3RFeHBvcnRlZEVsZW1lbnRzLFxuICBnZXRUeXBlU2NyaXB0UHJvZ3JhbSxcbn07XG4iXX0=