@mnaoumov/obsidian-dev-toolkit 0.0.0 → 1.1.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 (293) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +15 -1
  3. package/bundlers/esbuild/package.json +6 -0
  4. package/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin/package.json +6 -0
  5. package/bundlers/esbuild-impl/dependency/package.json +6 -0
  6. package/bundlers/esbuild-impl/fix-source-maps-plugin/package.json +6 -0
  7. package/bundlers/esbuild-impl/index/package.json +6 -0
  8. package/bundlers/esbuild-impl/obsidian-plugin-builder/package.json +6 -0
  9. package/bundlers/esbuild-impl/package.json +6 -0
  10. package/bundlers/esbuild-impl/preprocess-plugin/package.json +6 -0
  11. package/bundlers/esbuild-impl/rename-css-plugin/package.json +6 -0
  12. package/bundlers/index/package.json +6 -0
  13. package/bundlers/package.json +6 -0
  14. package/dist/demo-vault-helper/main.js +1264 -0
  15. package/dist/demo-vault-helper/manifest.json +9 -0
  16. package/dist/integration-test-plugin/main.js +54167 -0
  17. package/dist/integration-test-plugin/manifest.json +8 -0
  18. package/dist/lib/cjs/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.cjs +322 -0
  19. package/dist/lib/cjs/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.d.cts +38 -0
  20. package/dist/lib/cjs/bundlers/esbuild-impl/dependency.cjs +240 -0
  21. package/dist/lib/cjs/bundlers/esbuild-impl/dependency.d.cts +20 -0
  22. package/dist/lib/cjs/bundlers/esbuild-impl/fix-source-maps-plugin.cjs +213 -0
  23. package/dist/lib/cjs/bundlers/esbuild-impl/fix-source-maps-plugin.d.cts +34 -0
  24. package/dist/lib/cjs/bundlers/esbuild-impl/index.cjs +179 -0
  25. package/dist/lib/cjs/bundlers/esbuild-impl/index.d.cts +7 -0
  26. package/dist/lib/cjs/bundlers/esbuild-impl/obsidian-plugin-builder.cjs +362 -0
  27. package/dist/lib/cjs/bundlers/esbuild-impl/obsidian-plugin-builder.d.cts +98 -0
  28. package/dist/lib/cjs/bundlers/esbuild-impl/preprocess-plugin.cjs +234 -0
  29. package/dist/lib/cjs/bundlers/esbuild-impl/preprocess-plugin.d.cts +30 -0
  30. package/dist/lib/cjs/bundlers/esbuild-impl/rename-css-plugin.cjs +171 -0
  31. package/dist/lib/cjs/bundlers/esbuild-impl/rename-css-plugin.d.cts +14 -0
  32. package/dist/lib/cjs/bundlers/esbuild.cjs +164 -0
  33. package/dist/lib/cjs/bundlers/esbuild.d.cts +11 -0
  34. package/dist/lib/cjs/bundlers/index.cjs +167 -0
  35. package/dist/lib/cjs/bundlers/index.d.cts +3 -0
  36. package/dist/lib/cjs/demo-vault-app-json.cjs +186 -0
  37. package/dist/lib/cjs/demo-vault-app-json.d.cts +93 -0
  38. package/dist/lib/cjs/demo-vault-buttons.cjs +567 -0
  39. package/dist/lib/cjs/demo-vault-buttons.d.cts +259 -0
  40. package/dist/lib/cjs/demo-vault-coverage.cjs +713 -0
  41. package/dist/lib/cjs/demo-vault-coverage.d.cts +533 -0
  42. package/dist/lib/cjs/demo-vault.cjs +296 -0
  43. package/dist/lib/cjs/demo-vault.d.cts +33 -0
  44. package/dist/lib/cjs/formatters/dprint.cjs +160 -0
  45. package/dist/lib/cjs/formatters/dprint.d.cts +15 -0
  46. package/dist/lib/cjs/formatters/index.cjs +164 -0
  47. package/dist/lib/cjs/formatters/index.d.cts +2 -0
  48. package/dist/lib/cjs/index.cjs +194 -0
  49. package/dist/lib/cjs/index.d.cts +16 -0
  50. package/dist/lib/cjs/integration-test-setup.cjs +129 -0
  51. package/dist/lib/cjs/integration-test-setup.d.cts +33 -0
  52. package/dist/lib/cjs/integration-test-vitest-global-setup.cjs +163 -0
  53. package/dist/lib/cjs/integration-test-vitest-global-setup.d.cts +39 -0
  54. package/dist/lib/cjs/jest-setup.cjs +134 -0
  55. package/dist/lib/cjs/jest-setup.d.cts +13 -0
  56. package/dist/lib/cjs/linters/eslint-config.cjs +403 -0
  57. package/dist/lib/cjs/linters/eslint-config.d.cts +25 -0
  58. package/dist/lib/cjs/linters/eslint-rules/index.cjs +200 -0
  59. package/dist/lib/cjs/linters/eslint-rules/index.d.cts +14 -0
  60. package/dist/lib/cjs/linters/eslint-rules/manifest-description.cjs +255 -0
  61. package/dist/lib/cjs/linters/eslint-rules/manifest-description.d.cts +54 -0
  62. package/dist/lib/cjs/linters/eslint-rules/manifest-helpers.cjs +218 -0
  63. package/dist/lib/cjs/linters/eslint-rules/manifest-helpers.d.cts +141 -0
  64. package/dist/lib/cjs/linters/eslint-rules/manifest-id.cjs +215 -0
  65. package/dist/lib/cjs/linters/eslint-rules/manifest-id.d.cts +32 -0
  66. package/dist/lib/cjs/linters/eslint-rules/manifest-name.cjs +216 -0
  67. package/dist/lib/cjs/linters/eslint-rules/manifest-name.d.cts +30 -0
  68. package/dist/lib/cjs/linters/eslint-rules/manifest-schema.cjs +316 -0
  69. package/dist/lib/cjs/linters/eslint-rules/manifest-schema.d.cts +45 -0
  70. package/dist/lib/cjs/linters/eslint-rules/no-local-obsidian-internals.cjs +259 -0
  71. package/dist/lib/cjs/linters/eslint-rules/no-local-obsidian-internals.d.cts +10 -0
  72. package/dist/lib/cjs/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.cjs +657 -0
  73. package/dist/lib/cjs/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.d.cts +10 -0
  74. package/dist/lib/cjs/linters/eslint-rules/no-untrusted-input-events.cjs +247 -0
  75. package/dist/lib/cjs/linters/eslint-rules/no-untrusted-input-events.d.cts +10 -0
  76. package/dist/lib/cjs/linters/eslint-rules/obsidian-dev-utils-plugin.cjs +181 -0
  77. package/dist/lib/cjs/linters/eslint-rules/obsidian-dev-utils-plugin.d.cts +13 -0
  78. package/dist/lib/cjs/linters/eslint-rules/plugin-name-as-code-in-ui.cjs +263 -0
  79. package/dist/lib/cjs/linters/eslint-rules/plugin-name-as-code-in-ui.d.cts +30 -0
  80. package/dist/lib/cjs/linters/eslint-rules/plugin-name-as-code.cjs +215 -0
  81. package/dist/lib/cjs/linters/eslint-rules/plugin-name-as-code.d.cts +29 -0
  82. package/dist/lib/cjs/linters/eslint-rules/require-component-suffix.cjs +278 -0
  83. package/dist/lib/cjs/linters/eslint-rules/require-component-suffix.d.cts +18 -0
  84. package/dist/lib/cjs/linters/eslint-rules/require-plugin-api-contract-schemas.cjs +306 -0
  85. package/dist/lib/cjs/linters/eslint-rules/require-plugin-api-contract-schemas.d.cts +10 -0
  86. package/dist/lib/cjs/linters/eslint.cjs +160 -0
  87. package/dist/lib/cjs/linters/eslint.d.cts +15 -0
  88. package/dist/lib/cjs/linters/index.cjs +185 -0
  89. package/dist/lib/cjs/linters/index.d.cts +9 -0
  90. package/dist/lib/cjs/linters/markdownlint-cli2-config.cjs +171 -0
  91. package/dist/lib/cjs/linters/markdownlint-cli2-config.d.cts +12 -0
  92. package/dist/lib/cjs/linters/markdownlint-rules/index.cjs +164 -0
  93. package/dist/lib/cjs/linters/markdownlint-rules/index.d.cts +2 -0
  94. package/dist/lib/cjs/linters/markdownlint-rules/plugin-name-as-code.cjs +246 -0
  95. package/dist/lib/cjs/linters/markdownlint-rules/plugin-name-as-code.d.cts +32 -0
  96. package/dist/lib/cjs/linters/markdownlint.cjs +160 -0
  97. package/dist/lib/cjs/linters/markdownlint.d.cts +15 -0
  98. package/dist/lib/cjs/linters/obsidianmd-rule-custom-message.cjs +176 -0
  99. package/dist/lib/cjs/linters/obsidianmd-rule-custom-message.d.cts +40 -0
  100. package/dist/lib/cjs/linters/plugin-names.cjs +249 -0
  101. package/dist/lib/cjs/linters/plugin-names.d.cts +81 -0
  102. package/dist/lib/cjs/obsidian-plugin-repo-paths.cjs +216 -0
  103. package/dist/lib/cjs/obsidian-plugin-repo-paths.d.cts +253 -0
  104. package/dist/lib/cjs/setup.cjs +163 -0
  105. package/dist/lib/cjs/setup.d.cts +21 -0
  106. package/dist/lib/cjs/templates.cjs +172 -0
  107. package/dist/lib/cjs/templates.d.cts +13 -0
  108. package/dist/lib/cjs/test-runners/index.cjs +170 -0
  109. package/dist/lib/cjs/test-runners/index.d.cts +4 -0
  110. package/dist/lib/cjs/test-runners/integration-test-plugin.cjs +211 -0
  111. package/dist/lib/cjs/test-runners/integration-test-plugin.d.cts +44 -0
  112. package/dist/lib/cjs/test-runners/performance-eval-cap.cjs +157 -0
  113. package/dist/lib/cjs/test-runners/performance-eval-cap.d.cts +27 -0
  114. package/dist/lib/cjs/test-runners/stale-build-global-setup.cjs +217 -0
  115. package/dist/lib/cjs/test-runners/stale-build-global-setup.d.cts +86 -0
  116. package/dist/lib/cjs/test-runners/vitest-config.cjs +484 -0
  117. package/dist/lib/cjs/test-runners/vitest-config.d.cts +200 -0
  118. package/dist/lib/cjs/version.cjs +262 -0
  119. package/dist/lib/cjs/version.d.cts +92 -0
  120. package/dist/lib/cjs/vitest-setup.cjs +134 -0
  121. package/dist/lib/cjs/vitest-setup.d.cts +11 -0
  122. package/dist/lib/esm/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.d.mts +38 -0
  123. package/dist/lib/esm/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.mjs +218 -0
  124. package/dist/lib/esm/bundlers/esbuild-impl/dependency.d.mts +20 -0
  125. package/dist/lib/esm/bundlers/esbuild-impl/dependency.mjs +130 -0
  126. package/dist/lib/esm/bundlers/esbuild-impl/fix-source-maps-plugin.d.mts +34 -0
  127. package/dist/lib/esm/bundlers/esbuild-impl/fix-source-maps-plugin.mjs +108 -0
  128. package/dist/lib/esm/bundlers/esbuild-impl/index.d.mts +7 -0
  129. package/dist/lib/esm/bundlers/esbuild-impl/index.mjs +56 -0
  130. package/dist/lib/esm/bundlers/esbuild-impl/obsidian-plugin-builder.d.mts +98 -0
  131. package/dist/lib/esm/bundlers/esbuild-impl/obsidian-plugin-builder.mjs +247 -0
  132. package/dist/lib/esm/bundlers/esbuild-impl/preprocess-plugin.d.mts +30 -0
  133. package/dist/lib/esm/bundlers/esbuild-impl/preprocess-plugin.mjs +126 -0
  134. package/dist/lib/esm/bundlers/esbuild-impl/rename-css-plugin.d.mts +14 -0
  135. package/dist/lib/esm/bundlers/esbuild-impl/rename-css-plugin.mjs +63 -0
  136. package/dist/lib/esm/bundlers/esbuild.d.mts +11 -0
  137. package/dist/lib/esm/bundlers/esbuild.mjs +58 -0
  138. package/dist/lib/esm/bundlers/index.d.mts +3 -0
  139. package/dist/lib/esm/bundlers/index.mjs +48 -0
  140. package/dist/lib/esm/demo-vault-app-json.d.mts +93 -0
  141. package/dist/lib/esm/demo-vault-app-json.mjs +75 -0
  142. package/dist/lib/esm/demo-vault-buttons.d.mts +259 -0
  143. package/dist/lib/esm/demo-vault-buttons.mjs +452 -0
  144. package/dist/lib/esm/demo-vault-coverage.d.mts +533 -0
  145. package/dist/lib/esm/demo-vault-coverage.mjs +619 -0
  146. package/dist/lib/esm/demo-vault.d.mts +33 -0
  147. package/dist/lib/esm/demo-vault.mjs +197 -0
  148. package/dist/lib/esm/formatters/dprint.d.mts +15 -0
  149. package/dist/lib/esm/formatters/dprint.mjs +52 -0
  150. package/dist/lib/esm/formatters/index.d.mts +2 -0
  151. package/dist/lib/esm/formatters/index.mjs +46 -0
  152. package/dist/lib/esm/index.d.mts +16 -0
  153. package/dist/lib/esm/index.mjs +66 -0
  154. package/dist/lib/esm/integration-test-setup.d.mts +33 -0
  155. package/dist/lib/esm/integration-test-setup.mjs +44 -0
  156. package/dist/lib/esm/integration-test-vitest-global-setup.d.mts +39 -0
  157. package/dist/lib/esm/integration-test-vitest-global-setup.mjs +57 -0
  158. package/dist/lib/esm/jest-setup.d.mts +13 -0
  159. package/dist/lib/esm/jest-setup.mjs +53 -0
  160. package/dist/lib/esm/linters/eslint-config.d.mts +25 -0
  161. package/dist/lib/esm/linters/eslint-config.mjs +290 -0
  162. package/dist/lib/esm/linters/eslint-rules/index.d.mts +14 -0
  163. package/dist/lib/esm/linters/eslint-rules/index.mjs +70 -0
  164. package/dist/lib/esm/linters/eslint-rules/manifest-description.d.mts +54 -0
  165. package/dist/lib/esm/linters/eslint-rules/manifest-description.mjs +146 -0
  166. package/dist/lib/esm/linters/eslint-rules/manifest-helpers.d.mts +141 -0
  167. package/dist/lib/esm/linters/eslint-rules/manifest-helpers.mjs +90 -0
  168. package/dist/lib/esm/linters/eslint-rules/manifest-id.d.mts +32 -0
  169. package/dist/lib/esm/linters/eslint-rules/manifest-id.mjs +109 -0
  170. package/dist/lib/esm/linters/eslint-rules/manifest-name.d.mts +30 -0
  171. package/dist/lib/esm/linters/eslint-rules/manifest-name.mjs +110 -0
  172. package/dist/lib/esm/linters/eslint-rules/manifest-schema.d.mts +45 -0
  173. package/dist/lib/esm/linters/eslint-rules/manifest-schema.mjs +212 -0
  174. package/dist/lib/esm/linters/eslint-rules/no-local-obsidian-internals.d.mts +10 -0
  175. package/dist/lib/esm/linters/eslint-rules/no-local-obsidian-internals.mjs +150 -0
  176. package/dist/lib/esm/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.d.mts +10 -0
  177. package/dist/lib/esm/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian.mjs +551 -0
  178. package/dist/lib/esm/linters/eslint-rules/no-untrusted-input-events.d.mts +10 -0
  179. package/dist/lib/esm/linters/eslint-rules/no-untrusted-input-events.mjs +138 -0
  180. package/dist/lib/esm/linters/eslint-rules/obsidian-dev-utils-plugin.d.mts +13 -0
  181. package/dist/lib/esm/linters/eslint-rules/obsidian-dev-utils-plugin.mjs +73 -0
  182. package/dist/lib/esm/linters/eslint-rules/plugin-name-as-code-in-ui.d.mts +30 -0
  183. package/dist/lib/esm/linters/eslint-rules/plugin-name-as-code-in-ui.mjs +157 -0
  184. package/dist/lib/esm/linters/eslint-rules/plugin-name-as-code.d.mts +29 -0
  185. package/dist/lib/esm/linters/eslint-rules/plugin-name-as-code.mjs +108 -0
  186. package/dist/lib/esm/linters/eslint-rules/require-component-suffix.d.mts +18 -0
  187. package/dist/lib/esm/linters/eslint-rules/require-component-suffix.mjs +167 -0
  188. package/dist/lib/esm/linters/eslint-rules/require-plugin-api-contract-schemas.d.mts +10 -0
  189. package/dist/lib/esm/linters/eslint-rules/require-plugin-api-contract-schemas.mjs +197 -0
  190. package/dist/lib/esm/linters/eslint.d.mts +15 -0
  191. package/dist/lib/esm/linters/eslint.mjs +52 -0
  192. package/dist/lib/esm/linters/index.d.mts +9 -0
  193. package/dist/lib/esm/linters/index.mjs +60 -0
  194. package/dist/lib/esm/linters/markdownlint-cli2-config.d.mts +12 -0
  195. package/dist/lib/esm/linters/markdownlint-cli2-config.mjs +66 -0
  196. package/dist/lib/esm/linters/markdownlint-rules/index.d.mts +2 -0
  197. package/dist/lib/esm/linters/markdownlint-rules/index.mjs +46 -0
  198. package/dist/lib/esm/linters/markdownlint-rules/plugin-name-as-code.d.mts +32 -0
  199. package/dist/lib/esm/linters/markdownlint-rules/plugin-name-as-code.mjs +130 -0
  200. package/dist/lib/esm/linters/markdownlint.d.mts +15 -0
  201. package/dist/lib/esm/linters/markdownlint.mjs +52 -0
  202. package/dist/lib/esm/linters/obsidianmd-rule-custom-message.d.mts +40 -0
  203. package/dist/lib/esm/linters/obsidianmd-rule-custom-message.mjs +67 -0
  204. package/dist/lib/esm/linters/plugin-names.d.mts +81 -0
  205. package/dist/lib/esm/linters/plugin-names.mjs +141 -0
  206. package/dist/lib/esm/obsidian-plugin-repo-paths.d.mts +253 -0
  207. package/dist/lib/esm/obsidian-plugin-repo-paths.mjs +108 -0
  208. package/dist/lib/esm/setup.d.mts +21 -0
  209. package/dist/lib/esm/setup.mjs +55 -0
  210. package/dist/lib/esm/templates.d.mts +13 -0
  211. package/dist/lib/esm/templates.mjs +57 -0
  212. package/dist/lib/esm/test-runners/index.d.mts +4 -0
  213. package/dist/lib/esm/test-runners/index.mjs +50 -0
  214. package/dist/lib/esm/test-runners/integration-test-plugin.d.mts +44 -0
  215. package/dist/lib/esm/test-runners/integration-test-plugin.mjs +94 -0
  216. package/dist/lib/esm/test-runners/performance-eval-cap.d.mts +27 -0
  217. package/dist/lib/esm/test-runners/performance-eval-cap.mjs +48 -0
  218. package/dist/lib/esm/test-runners/stale-build-global-setup.d.mts +86 -0
  219. package/dist/lib/esm/test-runners/stale-build-global-setup.mjs +115 -0
  220. package/dist/lib/esm/test-runners/vitest-config.d.mts +200 -0
  221. package/dist/lib/esm/test-runners/vitest-config.mjs +369 -0
  222. package/dist/lib/esm/version.d.mts +92 -0
  223. package/dist/lib/esm/version.mjs +160 -0
  224. package/dist/lib/esm/vitest-setup.d.mts +11 -0
  225. package/dist/lib/esm/vitest-setup.mjs +53 -0
  226. package/dist/templates/.markdownlint-cli2.mjs +4 -0
  227. package/dist/templates/.nano-staged.mjs +4 -0
  228. package/dist/templates/commitlint.config.ts +3 -0
  229. package/dist/templates/dprint.json +26 -0
  230. package/dist/templates/eslint.config.mts +3 -0
  231. package/dist/templates/scripts/build/build-clean.ts +4 -0
  232. package/dist/templates/scripts/build/build-compile-svelte.ts +4 -0
  233. package/dist/templates/scripts/build/build-compile-typescript.ts +4 -0
  234. package/dist/templates/scripts/build/build-compile.ts +4 -0
  235. package/dist/templates/scripts/build/build-templates.ts +4 -0
  236. package/dist/templates/scripts/bundlers/esbuild/build.ts +4 -0
  237. package/dist/templates/scripts/bundlers/esbuild/dev.ts +4 -0
  238. package/dist/templates/scripts/commitlint-config.ts +3 -0
  239. package/dist/templates/scripts/eslint-config.ts +10 -0
  240. package/dist/templates/scripts/formatters/dprint/format-check.ts +8 -0
  241. package/dist/templates/scripts/formatters/dprint/format.ts +8 -0
  242. package/dist/templates/scripts/gate/gate.ts +10 -0
  243. package/dist/templates/scripts/linters/cspell/spellcheck.ts +8 -0
  244. package/dist/templates/scripts/linters/eslint/lint-fix.ts +8 -0
  245. package/dist/templates/scripts/linters/eslint/lint.ts +8 -0
  246. package/dist/templates/scripts/linters/markdownlint/lint-md-fix.ts +8 -0
  247. package/dist/templates/scripts/linters/markdownlint/lint-md.ts +8 -0
  248. package/dist/templates/scripts/linters/over-exposure/find-overexposed-fix.ts +25 -0
  249. package/dist/templates/scripts/linters/over-exposure/find-overexposed.ts +15 -0
  250. package/dist/templates/scripts/markdownlint-cli2-config.ts +3 -0
  251. package/dist/templates/scripts/nano-staged-config.ts +3 -0
  252. package/dist/templates/scripts/test-runners/vitest/test-coverage.ts +4 -0
  253. package/dist/templates/scripts/test-runners/vitest/test-watch.ts +4 -0
  254. package/dist/templates/scripts/test-runners/vitest/test.ts +4 -0
  255. package/dist/templates/scripts/version/version.ts +10 -0
  256. package/dist/templates/scripts/vitest-config.ts +3 -0
  257. package/dist/templates/vitest.config.ts +3 -0
  258. package/formatters/dprint/package.json +6 -0
  259. package/formatters/index/package.json +6 -0
  260. package/formatters/package.json +6 -0
  261. package/linters/eslint/package.json +6 -0
  262. package/linters/eslint-config/package.json +6 -0
  263. package/linters/eslint-rules/index/package.json +6 -0
  264. package/linters/eslint-rules/manifest-description/package.json +6 -0
  265. package/linters/eslint-rules/manifest-helpers/package.json +6 -0
  266. package/linters/eslint-rules/manifest-id/package.json +6 -0
  267. package/linters/eslint-rules/manifest-name/package.json +6 -0
  268. package/linters/eslint-rules/manifest-schema/package.json +6 -0
  269. package/linters/eslint-rules/no-local-obsidian-internals/package.json +6 -0
  270. package/linters/eslint-rules/no-over-cap-wait-in-eval-in-obsidian/package.json +6 -0
  271. package/linters/eslint-rules/no-untrusted-input-events/package.json +6 -0
  272. package/linters/eslint-rules/obsidian-dev-utils-plugin/package.json +6 -0
  273. package/linters/eslint-rules/package.json +6 -0
  274. package/linters/eslint-rules/plugin-name-as-code/package.json +6 -0
  275. package/linters/eslint-rules/plugin-name-as-code-in-ui/package.json +6 -0
  276. package/linters/eslint-rules/require-component-suffix/package.json +6 -0
  277. package/linters/eslint-rules/require-plugin-api-contract-schemas/package.json +6 -0
  278. package/linters/index/package.json +6 -0
  279. package/linters/markdownlint/package.json +6 -0
  280. package/linters/markdownlint-cli2-config/package.json +6 -0
  281. package/linters/markdownlint-rules/index/package.json +6 -0
  282. package/linters/markdownlint-rules/package.json +6 -0
  283. package/linters/markdownlint-rules/plugin-name-as-code/package.json +6 -0
  284. package/linters/obsidianmd-rule-custom-message/package.json +6 -0
  285. package/linters/package.json +6 -0
  286. package/linters/plugin-names/package.json +6 -0
  287. package/package.json +302 -13
  288. package/test-runners/index/package.json +6 -0
  289. package/test-runners/integration-test-plugin/package.json +6 -0
  290. package/test-runners/package.json +6 -0
  291. package/test-runners/performance-eval-cap/package.json +6 -0
  292. package/test-runners/stale-build-global-setup/package.json +6 -0
  293. package/test-runners/vitest-config/package.json +6 -0
@@ -0,0 +1,369 @@
1
+ /*
2
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
3
+ if you want to view the source, please visit the github repository of this plugin
4
+ */
5
+
6
+ (function () {
7
+ function ensureDisposeSymbols(symbolConstructor = Symbol) {
8
+ symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
9
+ symbolConstructor.dispose ??= symbolConstructor.for("Symbol.dispose");
10
+ }
11
+
12
+ function ensureBrowserProcess() {
13
+ const browserProcess = {
14
+ browser: true,
15
+ cwd() {
16
+ return "/";
17
+ },
18
+ env: {},
19
+ platform: "android"
20
+ };
21
+ const existingProcess = globalThis.process;
22
+ if (!existingProcess) {
23
+ globalThis.process = browserProcess;
24
+ return;
25
+ }
26
+ if (existingProcess.versions?.node) {
27
+ return;
28
+ }
29
+ const existingProcessRecord = existingProcess;
30
+ for (const [key, value] of Object.entries(browserProcess)) {
31
+ existingProcessRecord[key] ??= value;
32
+ }
33
+ existingProcessRecord["browser"] = true;
34
+ }
35
+
36
+ (function initEsm() {
37
+ ensureDisposeSymbols();
38
+ ensureBrowserProcess();
39
+ })();
40
+ })();
41
+
42
+ import {
43
+ DEFAULT_VITEST_REPORTERS,
44
+ DEFAULT_VITEST_TEST_EXCLUDE
45
+ } from "@mnaoumov/typescript-dev-toolkit/test-runners/vitest-config";
46
+ import process from "node:process";
47
+ import { DEFAULT_EVAL_CAP_IN_MILLISECONDS } from "obsidian-integration-testing";
48
+ import { defineConfig } from "vitest/config";
49
+ import {
50
+ DESKTOP_PERFORMANCE_TEST_FILE_SUFFIX,
51
+ PERFORMANCE_EVAL_CAP_IN_MILLISECONDS
52
+ } from "./performance-eval-cap.mjs";
53
+ const TRANSPORT_EVAL_CAP_MARGIN_IN_MILLISECONDS = 15e3;
54
+ const ANDROID_TIMEOUT_IN_MILLISECONDS = 6e4;
55
+ const HOOK_TIMEOUT_MULTIPLIER = 4;
56
+ const PERFORMANCE_TIMEOUT_IN_MILLISECONDS = PERFORMANCE_EVAL_CAP_IN_MILLISECONDS + TRANSPORT_EVAL_CAP_MARGIN_IN_MILLISECONDS;
57
+ const INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS = DEFAULT_EVAL_CAP_IN_MILLISECONDS + TRANSPORT_EVAL_CAP_MARGIN_IN_MILLISECONDS;
58
+ const ANDROID_TEST_FILES = "src/**/*.android.integration.test.ts";
59
+ const CROSS_PLATFORM_TEST_FILES = "src/**/*.cross-platform.integration.test.ts";
60
+ const DECLARATION_FILES = "src/**/*.d.ts";
61
+ const DESKTOP_PERFORMANCE_TEST_FILES = `src/**/*${DESKTOP_PERFORMANCE_TEST_FILE_SUFFIX}`;
62
+ const DESKTOP_TEST_FILES = "src/**/*.desktop.integration.test.ts";
63
+ const INTEGRATION_TEST_FILES = "src/**/*.integration.test.ts";
64
+ const NO_APP_TEST_FILES = "src/**/*.no-app.integration.test.ts";
65
+ const UNIT_TEST_FILES = "src/**/*.test.ts";
66
+ const UNIT_TEST_GLOBAL_STUBS_PROJECT_NAME = "unit-tests:global-stubs";
67
+ const STALE_BUILD_GLOBAL_SETUP = "obsidian-dev-utils/script-utils/test-runners/stale-build-global-setup";
68
+ const OBSIDIAN_VERSION_ENV_VARIABLE_NAME = "OBSIDIAN_VERSION";
69
+ const SHARED_EXCLUDE = DEFAULT_VITEST_TEST_EXCLUDE;
70
+ class ObsidianPluginVitestConfigContext {
71
+ /**
72
+ * The `integration-tests:android` project, running the mobile-only and cross-platform suites against an
73
+ * Android emulator through Appium.
74
+ */
75
+ android = {
76
+ environment: "node",
77
+ environmentOptions: {
78
+ obsidianTransport: {
79
+ appiumUrl: "http://localhost:4723",
80
+ avdName: "obsidian_test",
81
+ type: "obsidian-android-appium"
82
+ }
83
+ },
84
+ fileParallelism: false,
85
+ globalSetup: [STALE_BUILD_GLOBAL_SETUP, "obsidian-integration-testing/vitest-global-setup-plugin"],
86
+ hookTimeout: ANDROID_TIMEOUT_IN_MILLISECONDS * HOOK_TIMEOUT_MULTIPLIER,
87
+ include: [ANDROID_TEST_FILES, CROSS_PLATFORM_TEST_FILES],
88
+ name: "integration-tests:android",
89
+ setupFiles: ["obsidian-integration-testing/vitest-setup"],
90
+ testTimeout: ANDROID_TIMEOUT_IN_MILLISECONDS
91
+ };
92
+ /**
93
+ * The per-test budget of the Android integration project, in milliseconds. Booting an emulator and
94
+ * driving it over Appium is slower than the desktop path, hence its own constant.
95
+ *
96
+ * @default `60000`
97
+ */
98
+ androidTimeoutInMilliseconds = ANDROID_TIMEOUT_IN_MILLISECONDS;
99
+ /**
100
+ * The per-test budget of the regular integration projects, in milliseconds.
101
+ *
102
+ * It deliberately CLEARS the transports' per-eval cap rather than matching it, so that a closure which
103
+ * outruns the cap fails with the harness's `EvalCapExceededError` — naming the cap and the remedy —
104
+ * instead of with vitest's anonymous timeout. Lowering it to the cap restores that blind spot.
105
+ *
106
+ * @default `45000`
107
+ */
108
+ bigTimeoutInMilliseconds = INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS;
109
+ /**
110
+ * The coverage `exclude` globs. Push onto it to drop more files from the coverage report.
111
+ *
112
+ * Declaration files are excluded by default because the coverage `include` below is `src/**\/*.ts`,
113
+ * which a `.d.ts` matches. A declaration file emits no runtime code, so it reports 0% and no test can
114
+ * ever raise it — a plugin that grows one under `src/` silently loses its 100% gate, and the usual
115
+ * remedy of an inline `v8 ignore` comment does not apply to a type-only file.
116
+ */
117
+ coverageExclude = [UNIT_TEST_FILES, DECLARATION_FILES];
118
+ /**
119
+ * The `integration-tests:desktop` project, running the desktop-only and cross-platform suites against a
120
+ * real desktop Obsidian over CDP.
121
+ */
122
+ desktop = {
123
+ environment: "node",
124
+ fileParallelism: false,
125
+ globalSetup: [STALE_BUILD_GLOBAL_SETUP, "obsidian-integration-testing/vitest-global-setup-plugin"],
126
+ hookTimeout: INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS * HOOK_TIMEOUT_MULTIPLIER,
127
+ include: [DESKTOP_TEST_FILES, CROSS_PLATFORM_TEST_FILES],
128
+ name: "integration-tests:desktop",
129
+ setupFiles: ["obsidian-integration-testing/vitest-setup"],
130
+ testTimeout: INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS
131
+ };
132
+ /**
133
+ * The `integration-tests:desktop-performance` project, running the at-scale suites. It is declared for
134
+ * every plugin even when there is no such suite yet — `passWithNoTests` makes an empty project free,
135
+ * and the matching `test:integration:desktop:performance` script exists in every plugin built on this library.
136
+ *
137
+ * A plugin's `test:integration` aggregate leaves this project out on purpose, and it stays out even on a
138
+ * machine with a desktop Obsidian set up. The reason is the fixture rather than the cost: a perf suite
139
+ * needs its own generated, populated vault, sized through env vars, and the aggregate's small temporary
140
+ * vault is the wrong one. The 600 s below is a timeout, not a duration — measured end to end, most perf
141
+ * suites finish in seconds, and only one that generates tens of thousands of notes takes minutes.
142
+ *
143
+ * Its CDP transport's per-eval cap is raised to 600 s as well (the budget clears it by the usual
144
+ * margin), because a perf suite's whole measurement is typically ONE long in-page evaluation, which the
145
+ * transport's 30 s default killed as a bare `CDP command timed out … Runtime.evaluate` naming neither the
146
+ * wait nor the assertion. Three plugins had each hand-written this raise in their own `editContext`
147
+ * before it moved here. Unlike a raised desktop cap, which is a backstop rather than a budget a closure
148
+ * may spend, this one IS a budget: `no-over-cap-wait-in-eval-in-obsidian` reads it for these files and
149
+ * for no other.
150
+ *
151
+ * No routine command runs them, but something does: a weekly sweep runs every plugin's
152
+ * `test:integration:desktop:performance`, which is also how to reach them by hand. Adding them to that
153
+ * aggregate is drift, not a gap to close.
154
+ */
155
+ desktopPerformance = {
156
+ environment: "node",
157
+ environmentOptions: {
158
+ obsidianTransport: {
159
+ commandTimeoutInMilliseconds: PERFORMANCE_EVAL_CAP_IN_MILLISECONDS,
160
+ type: "obsidian-cdp"
161
+ }
162
+ },
163
+ fileParallelism: false,
164
+ globalSetup: [STALE_BUILD_GLOBAL_SETUP, "obsidian-integration-testing/vitest-global-setup-plugin"],
165
+ hookTimeout: PERFORMANCE_TIMEOUT_IN_MILLISECONDS,
166
+ include: [DESKTOP_PERFORMANCE_TEST_FILES],
167
+ name: "integration-tests:desktop-performance",
168
+ setupFiles: ["obsidian-integration-testing/vitest-setup"],
169
+ testTimeout: PERFORMANCE_TIMEOUT_IN_MILLISECONDS
170
+ };
171
+ /**
172
+ * The unit test files that redefine `window`, `document`, `location` or `top`, which the `unit-tests`
173
+ * project's VM pool cannot run.
174
+ *
175
+ * Under `pool: 'vmThreads'` those four are non-configurable properties of the VM global, so
176
+ * `vi.stubGlobal('window', …)` or `Object.defineProperty(window, 'location', …)` throws
177
+ * `Cannot redefine property`. That is JS semantics, not a bug to route around. Every other global stays
178
+ * configurable and stubs normally.
179
+ *
180
+ * Push a file here and it leaves `unit-tests` for a sibling `unit-tests:global-stubs` project that is
181
+ * identical except for the pool, which is the default one. A plugin's `test` and `test:coverage` scripts
182
+ * name `unit-tests`, which also selects every `unit-tests:*` project, so the sibling runs and is covered
183
+ * without a script change. It is emitted only when this list is non-empty.
184
+ *
185
+ * To keep a whole suite on the default pool instead, set `unitTests.pool` to `'forks'` and say why.
186
+ */
187
+ globalStubTestFiles = [];
188
+ /**
189
+ * The multiplier applied to a project's test budget to get its hook budget. A hook typically populates
190
+ * and opens a vault, so it needs several times what a single test does.
191
+ *
192
+ * @default `4`
193
+ */
194
+ hookTimeoutMultiplier = HOOK_TIMEOUT_MULTIPLIER;
195
+ /**
196
+ * The `integration-tests:no-app` project, running the suites that need no Obsidian instance at all.
197
+ */
198
+ noApp = {
199
+ environment: "node",
200
+ fileParallelism: false,
201
+ hookTimeout: INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS * HOOK_TIMEOUT_MULTIPLIER,
202
+ include: [NO_APP_TEST_FILES],
203
+ name: "integration-tests:no-app",
204
+ testTimeout: INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS
205
+ };
206
+ /**
207
+ * The per-eval cap the performance integration project gives its CDP transport, in milliseconds.
208
+ *
209
+ * @default `600000`
210
+ */
211
+ performanceEvalCapInMilliseconds = PERFORMANCE_EVAL_CAP_IN_MILLISECONDS;
212
+ /**
213
+ * The per-test budget of the performance integration project, in milliseconds. A performance vault is
214
+ * pre-populated with tens of thousands of notes before Obsidian opens, so both its setup and its tests
215
+ * need far more time than the regular integration projects.
216
+ *
217
+ * Like the regular budget, it CLEARS the project's per-eval cap
218
+ * ({@link ObsidianPluginVitestConfigContext.performanceEvalCapInMilliseconds}) rather than matching it,
219
+ * so an evaluation that outruns the cap reports itself instead of dying as vitest's anonymous timeout.
220
+ *
221
+ * @default `615000`
222
+ */
223
+ performanceTimeoutInMilliseconds = PERFORMANCE_TIMEOUT_IN_MILLISECONDS;
224
+ /**
225
+ * The reporters the run prints through.
226
+ *
227
+ * Pinned rather than left to vitest, which resolves an unset `reporters` differently for a developer
228
+ * and for an AI coding session — see {@link DEFAULT_VITEST_REPORTERS} for the whole of why, and for
229
+ * what it deliberately leaves to vitest 5 itself.
230
+ *
231
+ * Push onto it to add a reporter beside the pinned one.
232
+ *
233
+ * @default {@link DEFAULT_VITEST_REPORTERS}
234
+ */
235
+ reporters = [...DEFAULT_VITEST_REPORTERS];
236
+ /**
237
+ * The `unit-tests` project, running the mocked-Obsidian suites in `jsdom`.
238
+ */
239
+ unitTests = {
240
+ environment: "jsdom",
241
+ exclude: [...SHARED_EXCLUDE, INTEGRATION_TEST_FILES],
242
+ // A threads/forks pool option that still reaches the worker under the VM pool below: measured
243
+ // 2026-09-16, `process.execArgv` carries it and Node's own `localStorage` descriptor is gone, as it
244
+ // is under `threads`. Without the flag the descriptor is back under both pools.
245
+ execArgv: ["--no-webstorage"],
246
+ include: [UNIT_TEST_FILES],
247
+ name: "unit-tests",
248
+ /*
249
+ * The default pool constructs one jsdom per test file, and that construction, not the tests, was
250
+ * the unit suite's cost: 67% of tracked time in `obsidian-dev-utils`' own suite. A VM pool builds
251
+ * the jsdom once per worker and gives each file a fresh VM context, so per-file isolation holds.
252
+ * Measured there on 2026-09-15: the jsdom project 36.06s -> 9.92s, `coverage/lcov.info`
253
+ * byte-identical to the default pool's, and no DOM, `globalThis` or prototype state crossing files.
254
+ * `isolate: false`, the other remedy vitest suggests, was slower (91.62s) and broke 68 tests.
255
+ * The one cost is redefining `window`, `document`, `location` or `top`: see `globalStubTestFiles`.
256
+ */
257
+ pool: "vmThreads",
258
+ server: {
259
+ // eslint-disable-next-line unicorn/name-replacements -- `deps` is declared by `vitest`; renaming it here would not match the API.
260
+ deps: {
261
+ inline: ["@obsidian-typings", "obsidian-dev-utils"]
262
+ }
263
+ },
264
+ setupFiles: [
265
+ "obsidian-test-mocks/vitest-setup",
266
+ "obsidian-dev-utils/vitest-setup"
267
+ ]
268
+ };
269
+ /**
270
+ * Creates a new context seeded with the standard projects.
271
+ */
272
+ constructor() {
273
+ const obsidianVersion = process.env[OBSIDIAN_VERSION_ENV_VARIABLE_NAME];
274
+ if (obsidianVersion !== void 0) {
275
+ this.desktop.environmentOptions = {
276
+ obsidianTransport: {
277
+ obsidianVersion,
278
+ type: "obsidian-cdp"
279
+ }
280
+ };
281
+ }
282
+ }
283
+ }
284
+ function defineObsidianPluginVitestConfig(options = {}) {
285
+ const context = new ObsidianPluginVitestConfigContext();
286
+ if (options.editContext) {
287
+ options.editContext(context);
288
+ }
289
+ const customProjects = options.customProjects?.(context) ?? [];
290
+ validateCustomProjects(customProjects);
291
+ const unitTestsResolve = {
292
+ alias: {
293
+ obsidian: "obsidian-test-mocks/obsidian"
294
+ }
295
+ };
296
+ const globalStubTestFiles = [...context.globalStubTestFiles];
297
+ const unitTests = globalStubTestFiles.length === 0 ? context.unitTests : { ...context.unitTests, exclude: [...context.unitTests.exclude ?? [], ...globalStubTestFiles] };
298
+ const globalStubsProjects = globalStubTestFiles.length === 0 ? [] : [{
299
+ resolve: unitTestsResolve,
300
+ test: {
301
+ ...context.unitTests,
302
+ include: globalStubTestFiles,
303
+ name: UNIT_TEST_GLOBAL_STUBS_PROJECT_NAME,
304
+ // The default pool, named rather than omitted so the spread above cannot carry the VM pool over.
305
+ pool: "forks"
306
+ }
307
+ }];
308
+ return defineConfig({
309
+ test: {
310
+ coverage: {
311
+ exclude: context.coverageExclude,
312
+ include: ["src/**/*.ts"],
313
+ provider: "v8",
314
+ reporter: ["text", "lcov", "html"],
315
+ reportsDirectory: "./coverage"
316
+ },
317
+ exclude: [...SHARED_EXCLUDE],
318
+ globals: false,
319
+ /*
320
+ * There is deliberately NO root-level `include` here, and restoring one breaks every project.
321
+ * Under vitest 4 a project's own `include` replaced the root one, so a root
322
+ * `include: [UNIT_TEST_FILES]` was merely redundant — the `unit-tests` project already declares
323
+ * that same glob for itself. Under vitest 5 the project glob no longer replaces it, and
324
+ * `src/**\/*.test.ts` is a superset of every project glob, so EVERY project collected EVERY test
325
+ * file: unit suites ran in the CDP integration environment and died on `Failed to resolve entry
326
+ * for package "obsidian"`, the screenshot-capture suites ran and rewrote checked-in PNGs, and the
327
+ * android / demo-vault suites ran under the desktop transport. Measured in a consumer: the desktop
328
+ * project collected 227 files instead of its own 105, and deleting this one line restored 105.
329
+ */
330
+ passWithNoTests: true,
331
+ projects: [
332
+ {
333
+ resolve: unitTestsResolve,
334
+ test: unitTests
335
+ },
336
+ { test: context.noApp },
337
+ { test: context.desktop },
338
+ { test: context.desktopPerformance },
339
+ { test: context.android },
340
+ ...globalStubsProjects,
341
+ ...customProjects
342
+ ],
343
+ reporters: [...context.reporters]
344
+ }
345
+ });
346
+ }
347
+ function validateCustomProjects(customProjects) {
348
+ for (const [index, customProject] of customProjects.entries()) {
349
+ if (typeof customProject !== "object" || "then" in customProject) {
350
+ continue;
351
+ }
352
+ const include = customProject.test?.include;
353
+ if (include && include.length > 0) {
354
+ continue;
355
+ }
356
+ const name = customProject.test?.name;
357
+ const label = typeof name === "string" ? name : name?.label ?? `at index ${String(index)}`;
358
+ throw new Error(
359
+ `The custom vitest project ${label} declares no \`test.include\`, so vitest falls back to its default glob and the project collects EVERY test file \u2014 including the \`*-capture.\` suites that rewrite checked-in screenshots. Declare an explicit \`include\`, or spread a standard project (\`...context.desktop\`) and override it.`
360
+ );
361
+ }
362
+ }
363
+ export {
364
+ DEFAULT_VITEST_REPORTERS,
365
+ INTEGRATION_TEST_TIMEOUT_IN_MILLISECONDS,
366
+ ObsidianPluginVitestConfigContext,
367
+ defineObsidianPluginVitestConfig
368
+ };
369
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL3Rlc3QtcnVubmVycy92aXRlc3QtY29uZmlnLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogU2hhcmVkIHZpdGVzdCBjb25maWd1cmF0aW9uIGZvciBPYnNpZGlhbiBwbHVnaW5zLlxuICpcbiAqIEV2ZXJ5IHBsdWdpbiBpbiB0aGUgd29ya3NwYWNlIGRlY2xhcmVzIHRoZSBzYW1lIGZpdmUgdml0ZXN0IHByb2plY3RzIFx1MjAxNCBgdW5pdC10ZXN0c2AgcGx1cyB0aGVcbiAqIGBpbnRlZ3JhdGlvbi10ZXN0czp7bm8tYXBwLGRlc2t0b3AsZGVza3RvcC1wZXJmb3JtYW5jZSxhbmRyb2lkfWAgZmFtaWx5IFx1MjAxNCB3aXRoIHRoZSBzYW1lIHRpbWVvdXRzLFxuICogYHNldHVwRmlsZXNgLCBhbmQgYGdsb2JhbFNldHVwYCB3aXJpbmcuIE1haW50YWluaW5nIHRoYXQgcGVyIHJlcG8gbWVhbnMgYSBjb252ZW50aW9uIGNoYW5nZSBjb3N0cyBvbmVcbiAqIG5lYXItaWRlbnRpY2FsIGVkaXQgcGVyIHBsdWdpbiwgYW5kIGFueSByZXBvIHRoYXQgaXMgbWlzc2VkIGRyaWZ0cyBzaWxlbnRseS4gVGhpcyBtb2R1bGUgb3ducyB0aGF0XG4gKiBjb25maWd1cmF0aW9uIG9uY2UsIHNvIGEgcGx1Z2luJ3MgYHNjcmlwdHMvdml0ZXN0LWNvbmZpZy50c2AgY29sbGFwc2VzIHRvIGEgc2luZ2xlIGNhbGwuXG4gKlxuICogVGhlIHNlYW0gbWlycm9ycyB7QGxpbmsgaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2Uvb2JzaWRpYW4tZGV2LXV0aWxzIHwgdGhlIEVTTGludCBvbmV9XG4gKiAoYGRlZmluZUVzbGludENvbmZpZ3NgKTogdGhlIGZhY3RvcnkgYnVpbGRzIGEgY29udGV4dCBob2xkaW5nIHRoZSBzdGFuZGFyZCBwcm9qZWN0cywgdGhlIGNhbGxlciBlZGl0c1xuICogaXQgaW4gcGxhY2UgdGhyb3VnaCB7QGxpbmsgRGVmaW5lT2JzaWRpYW5QbHVnaW5WaXRlc3RDb25maWdPcHRpb25zLmVkaXRDb250ZXh0fSwgYW5kIGFwcGVuZHMgYW55XG4gKiBwcm9qZWN0IHRoZSBiYXNlIGRvZXMgbm90IGtub3cgYWJvdXQgdGhyb3VnaFxuICoge0BsaW5rIERlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnT3B0aW9ucy5jdXN0b21Qcm9qZWN0c30uXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBWaXRlc3RSZXBvcnRlciB9IGZyb20gJ0BtbmFvdW1vdi90eXBlc2NyaXB0LWRldi10b29sa2l0L3Rlc3QtcnVubmVycy92aXRlc3QtY29uZmlnJztcbmltcG9ydCB0eXBlIHtcbiAgVGVzdFByb2plY3RDb25maWd1cmF0aW9uLFxuICBUZXN0UHJvamVjdElubGluZUNvbmZpZ3VyYXRpb24sXG4gIFZpdGVVc2VyQ29uZmlnXG59IGZyb20gJ3ZpdGVzdC9jb25maWcnO1xuXG5pbXBvcnQge1xuICBERUZBVUxUX1ZJVEVTVF9SRVBPUlRFUlMsXG4gIERFRkFVTFRfVklURVNUX1RFU1RfRVhDTFVERVxufSBmcm9tICdAbW5hb3Vtb3YvdHlwZXNjcmlwdC1kZXYtdG9vbGtpdC90ZXN0LXJ1bm5lcnMvdml0ZXN0LWNvbmZpZyc7XG5pbXBvcnQgcHJvY2VzcyBmcm9tICdub2RlOnByb2Nlc3MnO1xuaW1wb3J0IHsgREVGQVVMVF9FVkFMX0NBUF9JTl9NSUxMSVNFQ09ORFMgfSBmcm9tICdvYnNpZGlhbi1pbnRlZ3JhdGlvbi10ZXN0aW5nJztcbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gJ3ZpdGVzdC9jb25maWcnO1xuXG5pbXBvcnQge1xuICBERVNLVE9QX1BFUkZPUk1BTkNFX1RFU1RfRklMRV9TVUZGSVgsXG4gIFBFUkZPUk1BTkNFX0VWQUxfQ0FQX0lOX01JTExJU0VDT05EU1xufSBmcm9tICcuL3BlcmZvcm1hbmNlLWV2YWwtY2FwLnRzJztcblxuLyoqXG4gKiBUaGUgYHRlc3RgIHNlY3Rpb24gb2YgYSBzaW5nbGUgdml0ZXN0IHByb2plY3QgZW50cnkuXG4gKi9cbmV4cG9ydCB0eXBlIE9ic2lkaWFuUGx1Z2luVml0ZXN0UHJvamVjdENvbmZpZyA9IE5vbk51bGxhYmxlPFRlc3RQcm9qZWN0SW5saW5lQ29uZmlndXJhdGlvblsndGVzdCddPjtcblxuLyoqXG4gKiBPbmUgZW50cnkgb2YgYSB2aXRlc3QgYHJlcG9ydGVyc2AgbGlzdDogdGhlIG5hbWUgb2YgYSBidWlsdC1pbiByZXBvcnRlciBvciBhIHJlcG9ydGVyIGluc3RhbmNlLiBUaGUgc2FtZSBzaGFwZSBhc1xuICogdGhlIGxpYnJhcnkgY29uZmlndXJhdGlvbidzIHtAbGluayBWaXRlc3RSZXBvcnRlcn0uXG4gKi9cbmV4cG9ydCB0eXBlIE9ic2lkaWFuUGx1Z2luVml0ZXN0UmVwb3J0ZXIgPSBWaXRlc3RSZXBvcnRlcjtcblxuLy8gVGhlIGxpYnJhcnkgY29uZmlndXJhdGlvbidzIHBpbm5lZCByZXBvcnRlcnMsIHJlLWV4cG9ydGVkIHNvIGEgcGx1Z2luIHJlcG8gdGhhdCBhc3NlbWJsZXMgaXRzIHZpdGVzdCBwcm9qZWN0cyBieVxuLy8gaGFuZCBuZWVkcyBvbmx5IHRoaXMgcGFja2FnZS5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB1bmljb3JuL3ByZWZlci1leHBvcnQtZnJvbSAtLSBUaGUgYmluZGluZyBpcyBhbHNvIHVzZWQgYmVsb3csIHNvIGl0IGlzIGltcG9ydGVkIG9uY2UuXG5leHBvcnQgeyBERUZBVUxUX1ZJVEVTVF9SRVBPUlRFUlMgfTtcblxuLypcbiAqIEhvdyBtdWNoIGEgcHJvamVjdCdzIHBlci10ZXN0IGJ1ZGdldCBjbGVhcnMgYERFRkFVTFRfRVZBTF9DQVBfSU5fTUlMTElTRUNPTkRTYCBieSBcdTIwMTQgdGhlIHBlci1ldmFsIGNhcFxuICogQk9USCB0cmFuc3BvcnRzIGVuZm9yY2UsIGltcG9ydGVkIGZyb20gYG9ic2lkaWFuLWludGVncmF0aW9uLXRlc3RpbmdgIHJhdGhlciB0aGFuIHJlc3RhdGVkIHNvIHRoZVxuICogYnVkZ2V0cyBiZWxvdyBhbmQgdGhlIGNhcCB0aGV5IGFyZSBzaXplZCBhZ2FpbnN0IGNhbiBuZXZlciBiZSB0d28gbnVtYmVycy4gT25lIGBldmFsSW5PYnNpZGlhbmAgY2xvc3VyZVxuICogZ2V0cyB0aGF0IG11Y2ggYW5kIG5vIG1vcmUsIG1lYXN1cmVkIGZyb20gdGhlIG1vbWVudCB0aGUgdHJhbnNwb3J0IGRpc3BhdGNoZXMgaXQ7IG91dHJ1bm5pbmcgaXQgcmFpc2VzXG4gKiBgRXZhbENhcEV4Y2VlZGVkRXJyb3JgLCB3aGljaCBuYW1lcyB0aGUgY2FwLCB0aGUgdHJhbnNwb3J0IHRoYXQgZW5mb3JjZWQgaXQsIGFuZCB0aGUgYHBvbGxJbk9ic2lkaWFuYFxuICogcmVtZWR5IFx1MjAxNCB0aGUgb25lIG1lc3NhZ2UgdGhhdCB0dXJucyBcInRoaXMgdGltZWQgb3V0XCIgaW50byBcInRoaXMgY2xvc3VyZSBhc2tlZCBmb3IgbW9yZSB0aW1lIHRoYW5cbiAqIGV4aXN0c1wiLlxuICpcbiAqIEEgdGVzdCBidWRnZXQgRVFVQUwgdG8gdGhlIGNhcCBtYWtlcyB0aGUgY2FwJ3Mgb3duIGRpYWdub3NpcyB1bnJlYWNoYWJsZTogdml0ZXN0IHN0YXJ0cyBpdHMgY2xvY2sgYXRcbiAqIHRoZSB0b3Agb2YgdGhlIHRlc3QgYW5kIHRoZSB0cmFuc3BvcnQgc3RhcnRzIGl0cyBvd24gb25seSBvbmNlIHRoZSBldmFsIGlzIGRpc3BhdGNoZWQsIHNvIHZpdGVzdCBhbHdheXNcbiAqIHdpbnMgYnkgdGhlIGZldyBtaWxsaXNlY29uZHMgaW4gYmV0d2VlbiBhbmQgcmVwb3J0cyBpdHMgYW5vbnltb3VzIGBUZXN0IHRpbWVkIG91dCBpbiAzMDAwMG1zYC4gVGhhdCBpc1xuICogbm90IGEgaHlwb3RoZXRpY2FsIFx1MjAxNCBpdCBpcyBob3cgZXZlcnkgb3Zlci1jYXAgZGVza3RvcCBldmFsIGhhZCBzdXJmYWNlZCBoZXJlIHVudGlsIHRoaXMgbWFyZ2luIGV4aXN0ZWQsXG4gKiBhbmQgb25lIG9mIHRoZW0gYWJvcnRlZCBhbiBvdGhlcndpc2UgZ3JlZW4gcmVsZWFzZSBmaXZlIG1pbnV0ZXMgaW50byB0aGUgcHJlZmxpZ2h0IHdpdGggbm8gaW5kaWNhdGlvblxuICogb2Ygd2hpY2ggd2FpdCB3YXMgdG8gYmxhbWUgKG1lYXN1cmVkIDIwMjYtMDktMTU6IDMwMDQ0IG1zIGJ1cm5lZCBhZ2FpbnN0IGEgMzAwMDAgbXMgYnVkZ2V0KS5cbiAqXG4gKiBUaGUgbWFyZ2luIGhhcyB0byBjb3ZlciBldmVyeXRoaW5nIGEgdGVzdCBkb2VzIEJFRk9SRSB0aGUgZXZhbCB0aGF0IGhhbmdzIFx1MjAxNCBlYXJsaWVyIG9uZXMgaW5jbHVkZWQgXHUyMDE0XG4gKiBzbyBpdCBpcyBhIGhlYWx0aHkgZnJhY3Rpb24gb2YgdGhlIGNhcCByYXRoZXIgdGhhbiBhIGNvdXBsZSBvZiBzZWNvbmRzLlxuICovXG5jb25zdCBUUkFOU1BPUlRfRVZBTF9DQVBfTUFSR0lOX0lOX01JTExJU0VDT05EUyA9IDE1XzAwMDtcblxuLypcbiAqIEFuZHJvaWQgd2FzIG5ldmVyIGFmZmVjdGVkLCBhbmQgdGhhdCBhc3ltbWV0cnkgaXMgdGhlIGV2aWRlbmNlIHRoZSBkZXNrdG9wIGVxdWFsaXR5IHdhcyBhbiBvdmVyc2lnaHRcbiAqIHJhdGhlciB0aGFuIGEgZGVjaXNpb246IGl0cyBidWRnZXQgaGFzIGFsd2F5cyBiZWVuIGRvdWJsZSB0aGUgQXBwaXVtIGNhcCwgc28gYW4gb3Zlci1jYXAgbW9iaWxlIGNsb3N1cmVcbiAqIGhhcyBhbHdheXMgYmVlbiBhYmxlIHRvIHJlcG9ydCBpdHNlbGYuXG4gKi9cbmNvbnN0IEFORFJPSURfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSA2MF8wMDA7XG5jb25zdCBIT09LX1RJTUVPVVRfTVVMVElQTElFUiA9IDQ7XG5cbi8qXG4gKiBUaGUgcGVyZm9ybWFuY2UgcHJvamVjdCdzIGJ1ZGdldCBjbGVhcnMgaXRzIG93biBwZXItZXZhbCBjYXAgYnkgdGhlIHNhbWUgbWFyZ2luLCBmb3IgdGhlIHNhbWUgcmVhc29uXG4gKiB0aGUgcmVndWxhciBidWRnZXQgY2xlYXJzIHRoZSB0cmFuc3BvcnQgZGVmYXVsdDogYW4gZXF1YWwgYnVkZ2V0IGxldHMgdml0ZXN0J3MgYW5vbnltb3VzIHRpbWVvdXQgd2luXG4gKiB0aGUgcmFjZSBhZ2FpbnN0IHRoZSBjYXAncyBvd24gYEV2YWxDYXBFeGNlZWRlZEVycm9yYC5cbiAqL1xuY29uc3QgUEVSRk9STUFOQ0VfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSBQRVJGT1JNQU5DRV9FVkFMX0NBUF9JTl9NSUxMSVNFQ09ORFMgKyBUUkFOU1BPUlRfRVZBTF9DQVBfTUFSR0lOX0lOX01JTExJU0VDT05EUztcblxuLyoqXG4gKiBUaGUgcGVyLXRlc3QgYnVkZ2V0IG9mIHRoZSByZWd1bGFyIGludGVncmF0aW9uIHByb2plY3RzLCBpbiBtaWxsaXNlY29uZHMuXG4gKlxuICogRXhwb3J0ZWQgYmVjYXVzZSBhIHJlcG8gdGhhdCBhc3NlbWJsZXMgaXRzIHZpdGVzdCBwcm9qZWN0cyBieSBoYW5kIGluc3RlYWQgb2YgdGhyb3VnaFxuICoge0BsaW5rIGRlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnfSBzdGlsbCBuZWVkcyB0aGUgc2FtZSByZWxhdGlvbnNoaXAgdG8gdGhlIHBlci1ldmFsIGNhcCwgYW5kXG4gKiByZXN0YXRpbmcgdGhlIG51bWJlciB0aGVyZSBpcyBob3cgdGhlIHR3byBkcmlmdCBhcGFydC5cbiAqL1xuZXhwb3J0IGNvbnN0IElOVEVHUkFUSU9OX1RFU1RfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFMgPSBERUZBVUxUX0VWQUxfQ0FQX0lOX01JTExJU0VDT05EUyArIFRSQU5TUE9SVF9FVkFMX0NBUF9NQVJHSU5fSU5fTUlMTElTRUNPTkRTO1xuXG5jb25zdCBBTkRST0lEX1RFU1RfRklMRVMgPSAnc3JjLyoqLyouYW5kcm9pZC5pbnRlZ3JhdGlvbi50ZXN0LnRzJztcbmNvbnN0IENST1NTX1BMQVRGT1JNX1RFU1RfRklMRVMgPSAnc3JjLyoqLyouY3Jvc3MtcGxhdGZvcm0uaW50ZWdyYXRpb24udGVzdC50cyc7XG5jb25zdCBERUNMQVJBVElPTl9GSUxFUyA9ICdzcmMvKiovKi5kLnRzJztcbmNvbnN0IERFU0tUT1BfUEVSRk9STUFOQ0VfVEVTVF9GSUxFUyA9IGBzcmMvKiovKiR7REVTS1RPUF9QRVJGT1JNQU5DRV9URVNUX0ZJTEVfU1VGRklYfWA7XG5jb25zdCBERVNLVE9QX1RFU1RfRklMRVMgPSAnc3JjLyoqLyouZGVza3RvcC5pbnRlZ3JhdGlvbi50ZXN0LnRzJztcbmNvbnN0IElOVEVHUkFUSU9OX1RFU1RfRklMRVMgPSAnc3JjLyoqLyouaW50ZWdyYXRpb24udGVzdC50cyc7XG5jb25zdCBOT19BUFBfVEVTVF9GSUxFUyA9ICdzcmMvKiovKi5uby1hcHAuaW50ZWdyYXRpb24udGVzdC50cyc7XG5jb25zdCBVTklUX1RFU1RfRklMRVMgPSAnc3JjLyoqLyoudGVzdC50cyc7XG5jb25zdCBVTklUX1RFU1RfR0xPQkFMX1NUVUJTX1BST0pFQ1RfTkFNRSA9ICd1bml0LXRlc3RzOmdsb2JhbC1zdHVicyc7XG5cbi8qXG4gKiBSdW5zIGJlZm9yZSB0aGUgaGFybmVzcydzIG93biBzZXR1cCBpbiBldmVyeSBwcm9qZWN0IHRoYXQgbG9hZHMgdGhlIHBsdWdpbiBmcm9tIGBkaXN0L2J1aWxkL21haW4uanNgLFxuICogYW5kIHJlZnVzZXMgdG8gc3RhcnQgd2hlbiB0aGF0IGJ1aWxkIGlzIG1pc3Npbmcgb3Igb2xkZXIgdGhhbiB0aGUgc291cmNlLiBBIHBsdWdpbidzXG4gKiBgdGVzdDppbnRlZ3JhdGlvbipgIHNjcmlwdHMgY2FsbCB2aXRlc3QgZGlyZWN0bHkgYW5kIG5ldmVyIGJ1aWxkLCBzbyB3aXRob3V0IGl0IGEgc2Vzc2lvbiB0aGF0IGVkaXRzXG4gKiBgc3JjL2AgYW5kIHJ1bnMgb25lIGludGVncmF0aW9uIHByb2plY3QgdGVzdHMgdGhlIHByZXZpb3VzIGJ1aWxkIGFuZCByZWFkcyB0aGUgcmVzdWx0IGFzIGEgZGVmZWN0LlxuICovXG5jb25zdCBTVEFMRV9CVUlMRF9HTE9CQUxfU0VUVVAgPSAnb2JzaWRpYW4tZGV2LXV0aWxzL3NjcmlwdC11dGlscy90ZXN0LXJ1bm5lcnMvc3RhbGUtYnVpbGQtZ2xvYmFsLXNldHVwJztcblxuY29uc3QgT0JTSURJQU5fVkVSU0lPTl9FTlZfVkFSSUFCTEVfTkFNRSA9ICdPQlNJRElBTl9WRVJTSU9OJztcbmNvbnN0IFNIQVJFRF9FWENMVURFID0gREVGQVVMVF9WSVRFU1RfVEVTVF9FWENMVURFO1xuXG4vKipcbiAqIFRoZSBvcHRpb25zIGZvciBkZWZpbmluZyBhIHBsdWdpbidzIHZpdGVzdCBjb25maWd1cmF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBBIGZ1bmN0aW9uIHRoYXQgYnVpbGRzIHByb2plY3RzIHRoZSBiYXNlIGNvbmZpZ3VyYXRpb24gZG9lcyBub3Qga25vdyBhYm91dCwgc3VjaCBhcyBhIHBsdWdpbidzIG93blxuICAgKiBgaW50ZWdyYXRpb24tdGVzdHM6ZGVtby12YXVsdGAgcHJvamVjdC4gVGhlIHJldHVybmVkIHByb2plY3RzIGFyZSBhcHBlbmRlZCBhZnRlciB0aGUgc3RhbmRhcmQgZml2ZS5cbiAgICpcbiAgICogQHBhcmFtIGNvbnRleHQgLSBUaGUgdml0ZXN0IGNvbmZpZ3VyYXRpb24gY29udGV4dC5cbiAgICogQHJldHVybnMgVGhlIGV4dHJhIHByb2plY3RzLlxuICAgKi9cbiAgcmVhZG9ubHkgY3VzdG9tUHJvamVjdHM/OiAoY29udGV4dDogT2JzaWRpYW5QbHVnaW5WaXRlc3RDb25maWdDb250ZXh0KSA9PiBUZXN0UHJvamVjdENvbmZpZ3VyYXRpb25bXTtcblxuICAvKipcbiAgICogQSBmdW5jdGlvbiB0aGF0IGVkaXRzIHRoZSB2aXRlc3QgY29uZmlndXJhdGlvbiBjb250ZXh0IGJlZm9yZSBpdCBpcyBhc3NlbWJsZWQgaW50byBhIGNvbmZpZ3VyYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSBjb250ZXh0IC0gVGhlIHZpdGVzdCBjb25maWd1cmF0aW9uIGNvbnRleHQuXG4gICAqL1xuICByZWFkb25seSBlZGl0Q29udGV4dD86IChjb250ZXh0OiBPYnNpZGlhblBsdWdpblZpdGVzdENvbmZpZ0NvbnRleHQpID0+IHZvaWQ7XG59XG5cbi8qKlxuICogVGhlIGNvbnRleHQgZm9yIGRlZmluaW5nIGEgcGx1Z2luJ3Mgdml0ZXN0IGNvbmZpZ3VyYXRpb24uXG4gKlxuICogRXZlcnkgbWVtYmVyIGlzIGxpdmU6IHRoZSBhcnJheXMgYW5kIG9iamVjdHMgaXQgZXhwb3NlcyBhcmUgdGhlIHZlcnkgb25lcyB0aGUgYXNzZW1ibGVkIGNvbmZpZ3VyYXRpb25cbiAqIGlzIGJ1aWx0IGZyb20sIHNvIGVkaXRpbmcgdGhlbSBpbiBwbGFjZSB0aHJvdWdoXG4gKiB7QGxpbmsgRGVmaW5lT2JzaWRpYW5QbHVnaW5WaXRlc3RDb25maWdPcHRpb25zLmVkaXRDb250ZXh0fSBpcyB3aGF0IGN1c3RvbWl6ZXMgdGhlIHJlc3VsdC5cbiAqL1xuZXhwb3J0IGNsYXNzIE9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnQ29udGV4dCB7XG4gIC8qKlxuICAgKiBUaGUgYGludGVncmF0aW9uLXRlc3RzOmFuZHJvaWRgIHByb2plY3QsIHJ1bm5pbmcgdGhlIG1vYmlsZS1vbmx5IGFuZCBjcm9zcy1wbGF0Zm9ybSBzdWl0ZXMgYWdhaW5zdCBhblxuICAgKiBBbmRyb2lkIGVtdWxhdG9yIHRocm91Z2ggQXBwaXVtLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFuZHJvaWQ6IE9ic2lkaWFuUGx1Z2luVml0ZXN0UHJvamVjdENvbmZpZyA9IHtcbiAgICBlbnZpcm9ubWVudDogJ25vZGUnLFxuICAgIGVudmlyb25tZW50T3B0aW9uczoge1xuICAgICAgb2JzaWRpYW5UcmFuc3BvcnQ6IHtcbiAgICAgICAgYXBwaXVtVXJsOiAnaHR0cDovL2xvY2FsaG9zdDo0NzIzJyxcbiAgICAgICAgYXZkTmFtZTogJ29ic2lkaWFuX3Rlc3QnLFxuICAgICAgICB0eXBlOiAnb2JzaWRpYW4tYW5kcm9pZC1hcHBpdW0nXG4gICAgICB9XG4gICAgfSxcbiAgICBmaWxlUGFyYWxsZWxpc206IGZhbHNlLFxuICAgIGdsb2JhbFNldHVwOiBbU1RBTEVfQlVJTERfR0xPQkFMX1NFVFVQLCAnb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZy92aXRlc3QtZ2xvYmFsLXNldHVwLXBsdWdpbiddLFxuICAgIGhvb2tUaW1lb3V0OiBBTkRST0lEX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTICogSE9PS19USU1FT1VUX01VTFRJUExJRVIsXG4gICAgaW5jbHVkZTogW0FORFJPSURfVEVTVF9GSUxFUywgQ1JPU1NfUExBVEZPUk1fVEVTVF9GSUxFU10sXG4gICAgbmFtZTogJ2ludGVncmF0aW9uLXRlc3RzOmFuZHJvaWQnLFxuICAgIHNldHVwRmlsZXM6IFsnb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZy92aXRlc3Qtc2V0dXAnXSxcbiAgICB0ZXN0VGltZW91dDogQU5EUk9JRF9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICB9O1xuXG4gIC8qKlxuICAgKiBUaGUgcGVyLXRlc3QgYnVkZ2V0IG9mIHRoZSBBbmRyb2lkIGludGVncmF0aW9uIHByb2plY3QsIGluIG1pbGxpc2Vjb25kcy4gQm9vdGluZyBhbiBlbXVsYXRvciBhbmRcbiAgICogZHJpdmluZyBpdCBvdmVyIEFwcGl1bSBpcyBzbG93ZXIgdGhhbiB0aGUgZGVza3RvcCBwYXRoLCBoZW5jZSBpdHMgb3duIGNvbnN0YW50LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgNjAwMDBgXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYW5kcm9pZFRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IEFORFJPSURfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFM7XG5cbiAgLyoqXG4gICAqIFRoZSBwZXItdGVzdCBidWRnZXQgb2YgdGhlIHJlZ3VsYXIgaW50ZWdyYXRpb24gcHJvamVjdHMsIGluIG1pbGxpc2Vjb25kcy5cbiAgICpcbiAgICogSXQgZGVsaWJlcmF0ZWx5IENMRUFSUyB0aGUgdHJhbnNwb3J0cycgcGVyLWV2YWwgY2FwIHJhdGhlciB0aGFuIG1hdGNoaW5nIGl0LCBzbyB0aGF0IGEgY2xvc3VyZSB3aGljaFxuICAgKiBvdXRydW5zIHRoZSBjYXAgZmFpbHMgd2l0aCB0aGUgaGFybmVzcydzIGBFdmFsQ2FwRXhjZWVkZWRFcnJvcmAgXHUyMDE0IG5hbWluZyB0aGUgY2FwIGFuZCB0aGUgcmVtZWR5IFx1MjAxNFxuICAgKiBpbnN0ZWFkIG9mIHdpdGggdml0ZXN0J3MgYW5vbnltb3VzIHRpbWVvdXQuIExvd2VyaW5nIGl0IHRvIHRoZSBjYXAgcmVzdG9yZXMgdGhhdCBibGluZCBzcG90LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgNDUwMDBgXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYmlnVGltZW91dEluTWlsbGlzZWNvbmRzID0gSU5URUdSQVRJT05fVEVTVF9USU1FT1VUX0lOX01JTExJU0VDT05EUztcblxuICAvKipcbiAgICogVGhlIGNvdmVyYWdlIGBleGNsdWRlYCBnbG9icy4gUHVzaCBvbnRvIGl0IHRvIGRyb3AgbW9yZSBmaWxlcyBmcm9tIHRoZSBjb3ZlcmFnZSByZXBvcnQuXG4gICAqXG4gICAqIERlY2xhcmF0aW9uIGZpbGVzIGFyZSBleGNsdWRlZCBieSBkZWZhdWx0IGJlY2F1c2UgdGhlIGNvdmVyYWdlIGBpbmNsdWRlYCBiZWxvdyBpcyBgc3JjLyoqXFwvKi50c2AsXG4gICAqIHdoaWNoIGEgYC5kLnRzYCBtYXRjaGVzLiBBIGRlY2xhcmF0aW9uIGZpbGUgZW1pdHMgbm8gcnVudGltZSBjb2RlLCBzbyBpdCByZXBvcnRzIDAlIGFuZCBubyB0ZXN0IGNhblxuICAgKiBldmVyIHJhaXNlIGl0IFx1MjAxNCBhIHBsdWdpbiB0aGF0IGdyb3dzIG9uZSB1bmRlciBgc3JjL2Agc2lsZW50bHkgbG9zZXMgaXRzIDEwMCUgZ2F0ZSwgYW5kIHRoZSB1c3VhbFxuICAgKiByZW1lZHkgb2YgYW4gaW5saW5lIGB2OCBpZ25vcmVgIGNvbW1lbnQgZG9lcyBub3QgYXBwbHkgdG8gYSB0eXBlLW9ubHkgZmlsZS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjb3ZlcmFnZUV4Y2x1ZGU6IHN0cmluZ1tdID0gW1VOSVRfVEVTVF9GSUxFUywgREVDTEFSQVRJT05fRklMRVNdO1xuXG4gIC8qKlxuICAgKiBUaGUgYGludGVncmF0aW9uLXRlc3RzOmRlc2t0b3BgIHByb2plY3QsIHJ1bm5pbmcgdGhlIGRlc2t0b3Atb25seSBhbmQgY3Jvc3MtcGxhdGZvcm0gc3VpdGVzIGFnYWluc3QgYVxuICAgKiByZWFsIGRlc2t0b3AgT2JzaWRpYW4gb3ZlciBDRFAuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZGVza3RvcDogT2JzaWRpYW5QbHVnaW5WaXRlc3RQcm9qZWN0Q29uZmlnID0ge1xuICAgIGVudmlyb25tZW50OiAnbm9kZScsXG4gICAgZmlsZVBhcmFsbGVsaXNtOiBmYWxzZSxcbiAgICBnbG9iYWxTZXR1cDogW1NUQUxFX0JVSUxEX0dMT0JBTF9TRVRVUCwgJ29ic2lkaWFuLWludGVncmF0aW9uLXRlc3Rpbmcvdml0ZXN0LWdsb2JhbC1zZXR1cC1wbHVnaW4nXSxcbiAgICBob29rVGltZW91dDogSU5URUdSQVRJT05fVEVTVF9USU1FT1VUX0lOX01JTExJU0VDT05EUyAqIEhPT0tfVElNRU9VVF9NVUxUSVBMSUVSLFxuICAgIGluY2x1ZGU6IFtERVNLVE9QX1RFU1RfRklMRVMsIENST1NTX1BMQVRGT1JNX1RFU1RfRklMRVNdLFxuICAgIG5hbWU6ICdpbnRlZ3JhdGlvbi10ZXN0czpkZXNrdG9wJyxcbiAgICBzZXR1cEZpbGVzOiBbJ29ic2lkaWFuLWludGVncmF0aW9uLXRlc3Rpbmcvdml0ZXN0LXNldHVwJ10sXG4gICAgdGVzdFRpbWVvdXQ6IElOVEVHUkFUSU9OX1RFU1RfVElNRU9VVF9JTl9NSUxMSVNFQ09ORFNcbiAgfTtcblxuICAvKipcbiAgICogVGhlIGBpbnRlZ3JhdGlvbi10ZXN0czpkZXNrdG9wLXBlcmZvcm1hbmNlYCBwcm9qZWN0LCBydW5uaW5nIHRoZSBhdC1zY2FsZSBzdWl0ZXMuIEl0IGlzIGRlY2xhcmVkIGZvclxuICAgKiBldmVyeSBwbHVnaW4gZXZlbiB3aGVuIHRoZXJlIGlzIG5vIHN1Y2ggc3VpdGUgeWV0IFx1MjAxNCBgcGFzc1dpdGhOb1Rlc3RzYCBtYWtlcyBhbiBlbXB0eSBwcm9qZWN0IGZyZWUsXG4gICAqIGFuZCB0aGUgbWF0Y2hpbmcgYHRlc3Q6aW50ZWdyYXRpb246ZGVza3RvcDpwZXJmb3JtYW5jZWAgc2NyaXB0IGV4aXN0cyBpbiBldmVyeSBwbHVnaW4gYnVpbHQgb24gdGhpcyBsaWJyYXJ5LlxuICAgKlxuICAgKiBBIHBsdWdpbidzIGB0ZXN0OmludGVncmF0aW9uYCBhZ2dyZWdhdGUgbGVhdmVzIHRoaXMgcHJvamVjdCBvdXQgb24gcHVycG9zZSwgYW5kIGl0IHN0YXlzIG91dCBldmVuIG9uIGFcbiAgICogbWFjaGluZSB3aXRoIGEgZGVza3RvcCBPYnNpZGlhbiBzZXQgdXAuIFRoZSByZWFzb24gaXMgdGhlIGZpeHR1cmUgcmF0aGVyIHRoYW4gdGhlIGNvc3Q6IGEgcGVyZiBzdWl0ZVxuICAgKiBuZWVkcyBpdHMgb3duIGdlbmVyYXRlZCwgcG9wdWxhdGVkIHZhdWx0LCBzaXplZCB0aHJvdWdoIGVudiB2YXJzLCBhbmQgdGhlIGFnZ3JlZ2F0ZSdzIHNtYWxsIHRlbXBvcmFyeVxuICAgKiB2YXVsdCBpcyB0aGUgd3Jvbmcgb25lLiBUaGUgNjAwIHMgYmVsb3cgaXMgYSB0aW1lb3V0LCBub3QgYSBkdXJhdGlvbiBcdTIwMTQgbWVhc3VyZWQgZW5kIHRvIGVuZCwgbW9zdCBwZXJmXG4gICAqIHN1aXRlcyBmaW5pc2ggaW4gc2Vjb25kcywgYW5kIG9ubHkgb25lIHRoYXQgZ2VuZXJhdGVzIHRlbnMgb2YgdGhvdXNhbmRzIG9mIG5vdGVzIHRha2VzIG1pbnV0ZXMuXG4gICAqXG4gICAqIEl0cyBDRFAgdHJhbnNwb3J0J3MgcGVyLWV2YWwgY2FwIGlzIHJhaXNlZCB0byA2MDAgcyBhcyB3ZWxsICh0aGUgYnVkZ2V0IGNsZWFycyBpdCBieSB0aGUgdXN1YWxcbiAgICogbWFyZ2luKSwgYmVjYXVzZSBhIHBlcmYgc3VpdGUncyB3aG9sZSBtZWFzdXJlbWVudCBpcyB0eXBpY2FsbHkgT05FIGxvbmcgaW4tcGFnZSBldmFsdWF0aW9uLCB3aGljaCB0aGVcbiAgICogdHJhbnNwb3J0J3MgMzAgcyBkZWZhdWx0IGtpbGxlZCBhcyBhIGJhcmUgYENEUCBjb21tYW5kIHRpbWVkIG91dCBcdTIwMjYgUnVudGltZS5ldmFsdWF0ZWAgbmFtaW5nIG5laXRoZXIgdGhlXG4gICAqIHdhaXQgbm9yIHRoZSBhc3NlcnRpb24uIFRocmVlIHBsdWdpbnMgaGFkIGVhY2ggaGFuZC13cml0dGVuIHRoaXMgcmFpc2UgaW4gdGhlaXIgb3duIGBlZGl0Q29udGV4dGBcbiAgICogYmVmb3JlIGl0IG1vdmVkIGhlcmUuIFVubGlrZSBhIHJhaXNlZCBkZXNrdG9wIGNhcCwgd2hpY2ggaXMgYSBiYWNrc3RvcCByYXRoZXIgdGhhbiBhIGJ1ZGdldCBhIGNsb3N1cmVcbiAgICogbWF5IHNwZW5kLCB0aGlzIG9uZSBJUyBhIGJ1ZGdldDogYG5vLW92ZXItY2FwLXdhaXQtaW4tZXZhbC1pbi1vYnNpZGlhbmAgcmVhZHMgaXQgZm9yIHRoZXNlIGZpbGVzIGFuZFxuICAgKiBmb3Igbm8gb3RoZXIuXG4gICAqXG4gICAqIE5vIHJvdXRpbmUgY29tbWFuZCBydW5zIHRoZW0sIGJ1dCBzb21ldGhpbmcgZG9lczogYSB3ZWVrbHkgc3dlZXAgcnVucyBldmVyeSBwbHVnaW4nc1xuICAgKiBgdGVzdDppbnRlZ3JhdGlvbjpkZXNrdG9wOnBlcmZvcm1hbmNlYCwgd2hpY2ggaXMgYWxzbyBob3cgdG8gcmVhY2ggdGhlbSBieSBoYW5kLiBBZGRpbmcgdGhlbSB0byB0aGF0XG4gICAqIGFnZ3JlZ2F0ZSBpcyBkcmlmdCwgbm90IGEgZ2FwIHRvIGNsb3NlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGRlc2t0b3BQZXJmb3JtYW5jZTogT2JzaWRpYW5QbHVnaW5WaXRlc3RQcm9qZWN0Q29uZmlnID0ge1xuICAgIGVudmlyb25tZW50OiAnbm9kZScsXG4gICAgZW52aXJvbm1lbnRPcHRpb25zOiB7XG4gICAgICBvYnNpZGlhblRyYW5zcG9ydDoge1xuICAgICAgICBjb21tYW5kVGltZW91dEluTWlsbGlzZWNvbmRzOiBQRVJGT1JNQU5DRV9FVkFMX0NBUF9JTl9NSUxMSVNFQ09ORFMsXG4gICAgICAgIHR5cGU6ICdvYnNpZGlhbi1jZHAnXG4gICAgICB9XG4gICAgfSxcbiAgICBmaWxlUGFyYWxsZWxpc206IGZhbHNlLFxuICAgIGdsb2JhbFNldHVwOiBbU1RBTEVfQlVJTERfR0xPQkFMX1NFVFVQLCAnb2JzaWRpYW4taW50ZWdyYXRpb24tdGVzdGluZy92aXRlc3QtZ2xvYmFsLXNldHVwLXBsdWdpbiddLFxuICAgIGhvb2tUaW1lb3V0OiBQRVJGT1JNQU5DRV9USU1FT1VUX0lOX01JTExJU0VDT05EUyxcbiAgICBpbmNsdWRlOiBbREVTS1RPUF9QRVJGT1JNQU5DRV9URVNUX0ZJTEVTXSxcbiAgICBuYW1lOiAnaW50ZWdyYXRpb24tdGVzdHM6ZGVza3RvcC1wZXJmb3JtYW5jZScsXG4gICAgc2V0dXBGaWxlczogWydvYnNpZGlhbi1pbnRlZ3JhdGlvbi10ZXN0aW5nL3ZpdGVzdC1zZXR1cCddLFxuICAgIHRlc3RUaW1lb3V0OiBQRVJGT1JNQU5DRV9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICB9O1xuXG4gIC8qKlxuICAgKiBUaGUgdW5pdCB0ZXN0IGZpbGVzIHRoYXQgcmVkZWZpbmUgYHdpbmRvd2AsIGBkb2N1bWVudGAsIGBsb2NhdGlvbmAgb3IgYHRvcGAsIHdoaWNoIHRoZSBgdW5pdC10ZXN0c2BcbiAgICogcHJvamVjdCdzIFZNIHBvb2wgY2Fubm90IHJ1bi5cbiAgICpcbiAgICogVW5kZXIgYHBvb2w6ICd2bVRocmVhZHMnYCB0aG9zZSBmb3VyIGFyZSBub24tY29uZmlndXJhYmxlIHByb3BlcnRpZXMgb2YgdGhlIFZNIGdsb2JhbCwgc29cbiAgICogYHZpLnN0dWJHbG9iYWwoJ3dpbmRvdycsIFx1MjAyNilgIG9yIGBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LCAnbG9jYXRpb24nLCBcdTIwMjYpYCB0aHJvd3NcbiAgICogYENhbm5vdCByZWRlZmluZSBwcm9wZXJ0eWAuIFRoYXQgaXMgSlMgc2VtYW50aWNzLCBub3QgYSBidWcgdG8gcm91dGUgYXJvdW5kLiBFdmVyeSBvdGhlciBnbG9iYWwgc3RheXNcbiAgICogY29uZmlndXJhYmxlIGFuZCBzdHVicyBub3JtYWxseS5cbiAgICpcbiAgICogUHVzaCBhIGZpbGUgaGVyZSBhbmQgaXQgbGVhdmVzIGB1bml0LXRlc3RzYCBmb3IgYSBzaWJsaW5nIGB1bml0LXRlc3RzOmdsb2JhbC1zdHVic2AgcHJvamVjdCB0aGF0IGlzXG4gICAqIGlkZW50aWNhbCBleGNlcHQgZm9yIHRoZSBwb29sLCB3aGljaCBpcyB0aGUgZGVmYXVsdCBvbmUuIEEgcGx1Z2luJ3MgYHRlc3RgIGFuZCBgdGVzdDpjb3ZlcmFnZWAgc2NyaXB0c1xuICAgKiBuYW1lIGB1bml0LXRlc3RzYCwgd2hpY2ggYWxzbyBzZWxlY3RzIGV2ZXJ5IGB1bml0LXRlc3RzOipgIHByb2plY3QsIHNvIHRoZSBzaWJsaW5nIHJ1bnMgYW5kIGlzIGNvdmVyZWRcbiAgICogd2l0aG91dCBhIHNjcmlwdCBjaGFuZ2UuIEl0IGlzIGVtaXR0ZWQgb25seSB3aGVuIHRoaXMgbGlzdCBpcyBub24tZW1wdHkuXG4gICAqXG4gICAqIFRvIGtlZXAgYSB3aG9sZSBzdWl0ZSBvbiB0aGUgZGVmYXVsdCBwb29sIGluc3RlYWQsIHNldCBgdW5pdFRlc3RzLnBvb2xgIHRvIGAnZm9ya3MnYCBhbmQgc2F5IHdoeS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBnbG9iYWxTdHViVGVzdEZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIC8qKlxuICAgKiBUaGUgbXVsdGlwbGllciBhcHBsaWVkIHRvIGEgcHJvamVjdCdzIHRlc3QgYnVkZ2V0IHRvIGdldCBpdHMgaG9vayBidWRnZXQuIEEgaG9vayB0eXBpY2FsbHkgcG9wdWxhdGVzXG4gICAqIGFuZCBvcGVucyBhIHZhdWx0LCBzbyBpdCBuZWVkcyBzZXZlcmFsIHRpbWVzIHdoYXQgYSBzaW5nbGUgdGVzdCBkb2VzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgNGBcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBob29rVGltZW91dE11bHRpcGxpZXIgPSBIT09LX1RJTUVPVVRfTVVMVElQTElFUjtcblxuICAvKipcbiAgICogVGhlIGBpbnRlZ3JhdGlvbi10ZXN0czpuby1hcHBgIHByb2plY3QsIHJ1bm5pbmcgdGhlIHN1aXRlcyB0aGF0IG5lZWQgbm8gT2JzaWRpYW4gaW5zdGFuY2UgYXQgYWxsLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG5vQXBwOiBPYnNpZGlhblBsdWdpblZpdGVzdFByb2plY3RDb25maWcgPSB7XG4gICAgZW52aXJvbm1lbnQ6ICdub2RlJyxcbiAgICBmaWxlUGFyYWxsZWxpc206IGZhbHNlLFxuICAgIGhvb2tUaW1lb3V0OiBJTlRFR1JBVElPTl9URVNUX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTICogSE9PS19USU1FT1VUX01VTFRJUExJRVIsXG4gICAgaW5jbHVkZTogW05PX0FQUF9URVNUX0ZJTEVTXSxcbiAgICBuYW1lOiAnaW50ZWdyYXRpb24tdGVzdHM6bm8tYXBwJyxcbiAgICB0ZXN0VGltZW91dDogSU5URUdSQVRJT05fVEVTVF9USU1FT1VUX0lOX01JTExJU0VDT05EU1xuICB9O1xuXG4gIC8qKlxuICAgKiBUaGUgcGVyLWV2YWwgY2FwIHRoZSBwZXJmb3JtYW5jZSBpbnRlZ3JhdGlvbiBwcm9qZWN0IGdpdmVzIGl0cyBDRFAgdHJhbnNwb3J0LCBpbiBtaWxsaXNlY29uZHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IGA2MDAwMDBgXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcGVyZm9ybWFuY2VFdmFsQ2FwSW5NaWxsaXNlY29uZHMgPSBQRVJGT1JNQU5DRV9FVkFMX0NBUF9JTl9NSUxMSVNFQ09ORFM7XG5cbiAgLyoqXG4gICAqIFRoZSBwZXItdGVzdCBidWRnZXQgb2YgdGhlIHBlcmZvcm1hbmNlIGludGVncmF0aW9uIHByb2plY3QsIGluIG1pbGxpc2Vjb25kcy4gQSBwZXJmb3JtYW5jZSB2YXVsdCBpc1xuICAgKiBwcmUtcG9wdWxhdGVkIHdpdGggdGVucyBvZiB0aG91c2FuZHMgb2Ygbm90ZXMgYmVmb3JlIE9ic2lkaWFuIG9wZW5zLCBzbyBib3RoIGl0cyBzZXR1cCBhbmQgaXRzIHRlc3RzXG4gICAqIG5lZWQgZmFyIG1vcmUgdGltZSB0aGFuIHRoZSByZWd1bGFyIGludGVncmF0aW9uIHByb2plY3RzLlxuICAgKlxuICAgKiBMaWtlIHRoZSByZWd1bGFyIGJ1ZGdldCwgaXQgQ0xFQVJTIHRoZSBwcm9qZWN0J3MgcGVyLWV2YWwgY2FwXG4gICAqICh7QGxpbmsgT2JzaWRpYW5QbHVnaW5WaXRlc3RDb25maWdDb250ZXh0LnBlcmZvcm1hbmNlRXZhbENhcEluTWlsbGlzZWNvbmRzfSkgcmF0aGVyIHRoYW4gbWF0Y2hpbmcgaXQsXG4gICAqIHNvIGFuIGV2YWx1YXRpb24gdGhhdCBvdXRydW5zIHRoZSBjYXAgcmVwb3J0cyBpdHNlbGYgaW5zdGVhZCBvZiBkeWluZyBhcyB2aXRlc3QncyBhbm9ueW1vdXMgdGltZW91dC5cbiAgICpcbiAgICogQGRlZmF1bHQgYDYxNTAwMGBcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBwZXJmb3JtYW5jZVRpbWVvdXRJbk1pbGxpc2Vjb25kcyA9IFBFUkZPUk1BTkNFX1RJTUVPVVRfSU5fTUlMTElTRUNPTkRTO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVwb3J0ZXJzIHRoZSBydW4gcHJpbnRzIHRocm91Z2guXG4gICAqXG4gICAqIFBpbm5lZCByYXRoZXIgdGhhbiBsZWZ0IHRvIHZpdGVzdCwgd2hpY2ggcmVzb2x2ZXMgYW4gdW5zZXQgYHJlcG9ydGVyc2AgZGlmZmVyZW50bHkgZm9yIGEgZGV2ZWxvcGVyXG4gICAqIGFuZCBmb3IgYW4gQUkgY29kaW5nIHNlc3Npb24gXHUyMDE0IHNlZSB7QGxpbmsgREVGQVVMVF9WSVRFU1RfUkVQT1JURVJTfSBmb3IgdGhlIHdob2xlIG9mIHdoeSwgYW5kIGZvclxuICAgKiB3aGF0IGl0IGRlbGliZXJhdGVseSBsZWF2ZXMgdG8gdml0ZXN0IDUgaXRzZWxmLlxuICAgKlxuICAgKiBQdXNoIG9udG8gaXQgdG8gYWRkIGEgcmVwb3J0ZXIgYmVzaWRlIHRoZSBwaW5uZWQgb25lLlxuICAgKlxuICAgKiBAZGVmYXVsdCB7QGxpbmsgREVGQVVMVF9WSVRFU1RfUkVQT1JURVJTfVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHJlcG9ydGVyczogT2JzaWRpYW5QbHVnaW5WaXRlc3RSZXBvcnRlcltdID0gWy4uLkRFRkFVTFRfVklURVNUX1JFUE9SVEVSU107XG5cbiAgLyoqXG4gICAqIFRoZSBgdW5pdC10ZXN0c2AgcHJvamVjdCwgcnVubmluZyB0aGUgbW9ja2VkLU9ic2lkaWFuIHN1aXRlcyBpbiBganNkb21gLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHVuaXRUZXN0czogT2JzaWRpYW5QbHVnaW5WaXRlc3RQcm9qZWN0Q29uZmlnID0ge1xuICAgIGVudmlyb25tZW50OiAnanNkb20nLFxuICAgIGV4Y2x1ZGU6IFsuLi5TSEFSRURfRVhDTFVERSwgSU5URUdSQVRJT05fVEVTVF9GSUxFU10sXG4gICAgLy8gQSB0aHJlYWRzL2ZvcmtzIHBvb2wgb3B0aW9uIHRoYXQgc3RpbGwgcmVhY2hlcyB0aGUgd29ya2VyIHVuZGVyIHRoZSBWTSBwb29sIGJlbG93OiBtZWFzdXJlZFxuICAgIC8vIDIwMjYtMDktMTYsIGBwcm9jZXNzLmV4ZWNBcmd2YCBjYXJyaWVzIGl0IGFuZCBOb2RlJ3Mgb3duIGBsb2NhbFN0b3JhZ2VgIGRlc2NyaXB0b3IgaXMgZ29uZSwgYXMgaXRcbiAgICAvLyBpcyB1bmRlciBgdGhyZWFkc2AuIFdpdGhvdXQgdGhlIGZsYWcgdGhlIGRlc2NyaXB0b3IgaXMgYmFjayB1bmRlciBib3RoIHBvb2xzLlxuICAgIGV4ZWNBcmd2OiBbJy0tbm8td2Vic3RvcmFnZSddLFxuICAgIGluY2x1ZGU6IFtVTklUX1RFU1RfRklMRVNdLFxuICAgIG5hbWU6ICd1bml0LXRlc3RzJyxcbiAgICAvKlxuICAgICAqIFRoZSBkZWZhdWx0IHBvb2wgY29uc3RydWN0cyBvbmUganNkb20gcGVyIHRlc3QgZmlsZSwgYW5kIHRoYXQgY29uc3RydWN0aW9uLCBub3QgdGhlIHRlc3RzLCB3YXNcbiAgICAgKiB0aGUgdW5pdCBzdWl0ZSdzIGNvc3Q6IDY3JSBvZiB0cmFja2VkIHRpbWUgaW4gYG9ic2lkaWFuLWRldi11dGlsc2AnIG93biBzdWl0ZS4gQSBWTSBwb29sIGJ1aWxkc1xuICAgICAqIHRoZSBqc2RvbSBvbmNlIHBlciB3b3JrZXIgYW5kIGdpdmVzIGVhY2ggZmlsZSBhIGZyZXNoIFZNIGNvbnRleHQsIHNvIHBlci1maWxlIGlzb2xhdGlvbiBob2xkcy5cbiAgICAgKiBNZWFzdXJlZCB0aGVyZSBvbiAyMDI2LTA5LTE1OiB0aGUganNkb20gcHJvamVjdCAzNi4wNnMgLT4gOS45MnMsIGBjb3ZlcmFnZS9sY292LmluZm9gXG4gICAgICogYnl0ZS1pZGVudGljYWwgdG8gdGhlIGRlZmF1bHQgcG9vbCdzLCBhbmQgbm8gRE9NLCBgZ2xvYmFsVGhpc2Agb3IgcHJvdG90eXBlIHN0YXRlIGNyb3NzaW5nIGZpbGVzLlxuICAgICAqIGBpc29sYXRlOiBmYWxzZWAsIHRoZSBvdGhlciByZW1lZHkgdml0ZXN0IHN1Z2dlc3RzLCB3YXMgc2xvd2VyICg5MS42MnMpIGFuZCBicm9rZSA2OCB0ZXN0cy5cbiAgICAgKiBUaGUgb25lIGNvc3QgaXMgcmVkZWZpbmluZyBgd2luZG93YCwgYGRvY3VtZW50YCwgYGxvY2F0aW9uYCBvciBgdG9wYDogc2VlIGBnbG9iYWxTdHViVGVzdEZpbGVzYC5cbiAgICAgKi9cbiAgICBwb29sOiAndm1UaHJlYWRzJyxcbiAgICBzZXJ2ZXI6IHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB1bmljb3JuL25hbWUtcmVwbGFjZW1lbnRzIC0tIGBkZXBzYCBpcyBkZWNsYXJlZCBieSBgdml0ZXN0YDsgcmVuYW1pbmcgaXQgaGVyZSB3b3VsZCBub3QgbWF0Y2ggdGhlIEFQSS5cbiAgICAgIGRlcHM6IHtcbiAgICAgICAgaW5saW5lOiBbJ0BvYnNpZGlhbi10eXBpbmdzJywgJ29ic2lkaWFuLWRldi11dGlscyddXG4gICAgICB9XG4gICAgfSxcbiAgICBzZXR1cEZpbGVzOiBbXG4gICAgICAnb2JzaWRpYW4tdGVzdC1tb2Nrcy92aXRlc3Qtc2V0dXAnLFxuICAgICAgJ29ic2lkaWFuLWRldi11dGlscy92aXRlc3Qtc2V0dXAnXG4gICAgXVxuICB9O1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGNvbnRleHQgc2VlZGVkIHdpdGggdGhlIHN0YW5kYXJkIHByb2plY3RzLlxuICAgKi9cbiAgcHVibGljIGNvbnN0cnVjdG9yKCkge1xuICAgIGNvbnN0IG9ic2lkaWFuVmVyc2lvbiA9IHByb2Nlc3MuZW52W09CU0lESUFOX1ZFUlNJT05fRU5WX1ZBUklBQkxFX05BTUVdO1xuXG4gICAgLypcbiAgICAgKiBTdXBwb3J0IGlzIHRoZSByYW5nZSBbbGF0ZXN0IHB1YmxpYywgbGF0ZXN0IGNhdGFseXN0XSBhbmQgQk9USCBlbmRzIG11c3Qgd29yaywgc28gdGhlIHZlcnNpb25cbiAgICAgKiBpcyBhIGtub2IgcmF0aGVyIHRoYW4gYSBjb25zdGFudC4gVGhlIGtleSBpcyBhZGRlZCBPTkxZIHdoZW4gdGhlIHZhcmlhYmxlIGlzIHNldDogYW4gZXhwbGljaXRcbiAgICAgKiBgb2JzaWRpYW5WZXJzaW9uYCBtYWtlcyB0aGUgaGFybmVzcyByZXNvbHZlIGEgY29uY3JldGUgdmVyc2lvbiBhbmQgc3dhcCB0aGUgYXNhciwgd2hpY2ggaXMgbm90IHdoYXRcbiAgICAgKiBhbiB1bnBpbm5lZCBydW4gZG9lcywgc28gc2VlZGluZyBhIGRlZmF1bHQgaGVyZSB3b3VsZCBjaGFuZ2UgdGhlIGJlaGF2aW9yIG9mIGV2ZXJ5IHBsdWdpbi5cbiAgICAgKi9cbiAgICBpZiAob2JzaWRpYW5WZXJzaW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuZGVza3RvcC5lbnZpcm9ubWVudE9wdGlvbnMgPSB7XG4gICAgICAgIG9ic2lkaWFuVHJhbnNwb3J0OiB7XG4gICAgICAgICAgb2JzaWRpYW5WZXJzaW9uLFxuICAgICAgICAgIHR5cGU6ICdvYnNpZGlhbi1jZHAnXG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRGVmaW5lcyB0aGUgdml0ZXN0IGNvbmZpZ3VyYXRpb24gZm9yIGFuIE9ic2lkaWFuIHBsdWdpbi5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciBkZWZpbmluZyB0aGUgY29uZmlndXJhdGlvbi5cbiAqIEByZXR1cm5zIFRoZSB2aXRlc3QgY29uZmlndXJhdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnKG9wdGlvbnM6IERlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnT3B0aW9ucyA9IHt9KTogVml0ZVVzZXJDb25maWcge1xuICBjb25zdCBjb250ZXh0ID0gbmV3IE9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnQ29udGV4dCgpO1xuXG4gIGlmIChvcHRpb25zLmVkaXRDb250ZXh0KSB7XG4gICAgb3B0aW9ucy5lZGl0Q29udGV4dChjb250ZXh0KTtcbiAgfVxuXG4gIGNvbnN0IGN1c3RvbVByb2plY3RzID0gb3B0aW9ucy5jdXN0b21Qcm9qZWN0cz8uKGNvbnRleHQpID8/IFtdO1xuICB2YWxpZGF0ZUN1c3RvbVByb2plY3RzKGN1c3RvbVByb2plY3RzKTtcblxuICBjb25zdCB1bml0VGVzdHNSZXNvbHZlID0ge1xuICAgIGFsaWFzOiB7XG4gICAgICBvYnNpZGlhbjogJ29ic2lkaWFuLXRlc3QtbW9ja3Mvb2JzaWRpYW4nXG4gICAgfVxuICB9O1xuICBjb25zdCBnbG9iYWxTdHViVGVzdEZpbGVzID0gWy4uLmNvbnRleHQuZ2xvYmFsU3R1YlRlc3RGaWxlc107XG4gIGNvbnN0IHVuaXRUZXN0czogT2JzaWRpYW5QbHVnaW5WaXRlc3RQcm9qZWN0Q29uZmlnID0gZ2xvYmFsU3R1YlRlc3RGaWxlcy5sZW5ndGggPT09IDBcbiAgICA/IGNvbnRleHQudW5pdFRlc3RzXG4gICAgOiB7IC4uLmNvbnRleHQudW5pdFRlc3RzLCBleGNsdWRlOiBbLi4uY29udGV4dC51bml0VGVzdHMuZXhjbHVkZSA/PyBbXSwgLi4uZ2xvYmFsU3R1YlRlc3RGaWxlc10gfTtcbiAgY29uc3QgZ2xvYmFsU3R1YnNQcm9qZWN0czogVGVzdFByb2plY3RDb25maWd1cmF0aW9uW10gPSBnbG9iYWxTdHViVGVzdEZpbGVzLmxlbmd0aCA9PT0gMFxuICAgID8gW11cbiAgICA6IFt7XG4gICAgICByZXNvbHZlOiB1bml0VGVzdHNSZXNvbHZlLFxuICAgICAgdGVzdDoge1xuICAgICAgICAuLi5jb250ZXh0LnVuaXRUZXN0cyxcbiAgICAgICAgaW5jbHVkZTogZ2xvYmFsU3R1YlRlc3RGaWxlcyxcbiAgICAgICAgbmFtZTogVU5JVF9URVNUX0dMT0JBTF9TVFVCU19QUk9KRUNUX05BTUUsXG4gICAgICAgIC8vIFRoZSBkZWZhdWx0IHBvb2wsIG5hbWVkIHJhdGhlciB0aGFuIG9taXR0ZWQgc28gdGhlIHNwcmVhZCBhYm92ZSBjYW5ub3QgY2FycnkgdGhlIFZNIHBvb2wgb3Zlci5cbiAgICAgICAgcG9vbDogJ2ZvcmtzJ1xuICAgICAgfVxuICAgIH1dO1xuXG4gIHJldHVybiBkZWZpbmVDb25maWcoe1xuICAgIHRlc3Q6IHtcbiAgICAgIGNvdmVyYWdlOiB7XG4gICAgICAgIGV4Y2x1ZGU6IGNvbnRleHQuY292ZXJhZ2VFeGNsdWRlLFxuICAgICAgICBpbmNsdWRlOiBbJ3NyYy8qKi8qLnRzJ10sXG4gICAgICAgIHByb3ZpZGVyOiAndjgnLFxuICAgICAgICByZXBvcnRlcjogWyd0ZXh0JywgJ2xjb3YnLCAnaHRtbCddLFxuICAgICAgICByZXBvcnRzRGlyZWN0b3J5OiAnLi9jb3ZlcmFnZSdcbiAgICAgIH0sXG4gICAgICBleGNsdWRlOiBbLi4uU0hBUkVEX0VYQ0xVREVdLFxuICAgICAgZ2xvYmFsczogZmFsc2UsXG4gICAgICAvKlxuICAgICAgICogVGhlcmUgaXMgZGVsaWJlcmF0ZWx5IE5PIHJvb3QtbGV2ZWwgYGluY2x1ZGVgIGhlcmUsIGFuZCByZXN0b3Jpbmcgb25lIGJyZWFrcyBldmVyeSBwcm9qZWN0LlxuICAgICAgICogVW5kZXIgdml0ZXN0IDQgYSBwcm9qZWN0J3Mgb3duIGBpbmNsdWRlYCByZXBsYWNlZCB0aGUgcm9vdCBvbmUsIHNvIGEgcm9vdFxuICAgICAgICogYGluY2x1ZGU6IFtVTklUX1RFU1RfRklMRVNdYCB3YXMgbWVyZWx5IHJlZHVuZGFudCBcdTIwMTQgdGhlIGB1bml0LXRlc3RzYCBwcm9qZWN0IGFscmVhZHkgZGVjbGFyZXNcbiAgICAgICAqIHRoYXQgc2FtZSBnbG9iIGZvciBpdHNlbGYuIFVuZGVyIHZpdGVzdCA1IHRoZSBwcm9qZWN0IGdsb2Igbm8gbG9uZ2VyIHJlcGxhY2VzIGl0LCBhbmRcbiAgICAgICAqIGBzcmMvKipcXC8qLnRlc3QudHNgIGlzIGEgc3VwZXJzZXQgb2YgZXZlcnkgcHJvamVjdCBnbG9iLCBzbyBFVkVSWSBwcm9qZWN0IGNvbGxlY3RlZCBFVkVSWSB0ZXN0XG4gICAgICAgKiBmaWxlOiB1bml0IHN1aXRlcyByYW4gaW4gdGhlIENEUCBpbnRlZ3JhdGlvbiBlbnZpcm9ubWVudCBhbmQgZGllZCBvbiBgRmFpbGVkIHRvIHJlc29sdmUgZW50cnlcbiAgICAgICAqIGZvciBwYWNrYWdlIFwib2JzaWRpYW5cImAsIHRoZSBzY3JlZW5zaG90LWNhcHR1cmUgc3VpdGVzIHJhbiBhbmQgcmV3cm90ZSBjaGVja2VkLWluIFBOR3MsIGFuZCB0aGVcbiAgICAgICAqIGFuZHJvaWQgLyBkZW1vLXZhdWx0IHN1aXRlcyByYW4gdW5kZXIgdGhlIGRlc2t0b3AgdHJhbnNwb3J0LiBNZWFzdXJlZCBpbiBhIGNvbnN1bWVyOiB0aGUgZGVza3RvcFxuICAgICAgICogcHJvamVjdCBjb2xsZWN0ZWQgMjI3IGZpbGVzIGluc3RlYWQgb2YgaXRzIG93biAxMDUsIGFuZCBkZWxldGluZyB0aGlzIG9uZSBsaW5lIHJlc3RvcmVkIDEwNS5cbiAgICAgICAqL1xuICAgICAgcGFzc1dpdGhOb1Rlc3RzOiB0cnVlLFxuICAgICAgcHJvamVjdHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHJlc29sdmU6IHVuaXRUZXN0c1Jlc29sdmUsXG4gICAgICAgICAgdGVzdDogdW5pdFRlc3RzXG4gICAgICAgIH0sXG4gICAgICAgIHsgdGVzdDogY29udGV4dC5ub0FwcCB9LFxuICAgICAgICB7IHRlc3Q6IGNvbnRleHQuZGVza3RvcCB9LFxuICAgICAgICB7IHRlc3Q6IGNvbnRleHQuZGVza3RvcFBlcmZvcm1hbmNlIH0sXG4gICAgICAgIHsgdGVzdDogY29udGV4dC5hbmRyb2lkIH0sXG4gICAgICAgIC4uLmdsb2JhbFN0dWJzUHJvamVjdHMsXG4gICAgICAgIC4uLmN1c3RvbVByb2plY3RzXG4gICAgICBdLFxuICAgICAgcmVwb3J0ZXJzOiBbLi4uY29udGV4dC5yZXBvcnRlcnNdXG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBSZWZ1c2VzIGEgY3VzdG9tIHByb2plY3QgdGhhdCBkZWNsYXJlcyBubyBgaW5jbHVkZWAgZ2xvYiBvZiBpdHMgb3duLlxuICpcbiAqIFRoZSByb290IHNlY3Rpb24gZGVsaWJlcmF0ZWx5IGRlY2xhcmVzIG5vIGBpbmNsdWRlYCAoc2VlIHRoZSBjb21tZW50IG9uIGl0IGFib3ZlKSwgc28gYSBwcm9qZWN0IHRoYXRcbiAqIGRlY2xhcmVzIG5vbmUgZmFsbHMgYmFjayB0byB2aXRlc3QncyBvd24gZGVmYXVsdCBnbG9iIFx1MjAxNCB3aGljaCBtYXRjaGVzIEVWRVJZIHRlc3QgZmlsZSBpbiB0aGUgcmVwby5cbiAqIFRoYXQgcHJvamVjdCB0aGVuIHJ1bnMgdGhlIHVuaXQgc3VpdGVzIGluIGFuIE9ic2lkaWFuIGVudmlyb25tZW50LCB0aGUgYW5kcm9pZCBzdWl0ZXMgdW5kZXIgdGhlXG4gKiBkZXNrdG9wIHRyYW5zcG9ydCwgYW5kIHRoZSBgKi1jYXB0dXJlLmAgc2NyZWVuc2hvdCBzdWl0ZXMgdGhhdCBvcGVuIGEgd2luZG93IGFuZCByZXdyaXRlIGNoZWNrZWQtaW5cbiAqIFBOR3MuIEEgd2lkZW5lZCBwcm9qZWN0IGlzIHNpbGVudDogaXQgcGFzc2VzLCBzbG93bHksIGhhdmluZyBkb25lIGFsbCBvZiB0aGF0LlxuICpcbiAqIE9ubHkgYSBwbGFpbiBpbmxpbmUgY29uZmlndXJhdGlvbiBjYW4gYmUgY2hlY2tlZCBoZXJlLiBBIHByb2plY3QgbmFtZWQgYnkgYSBnbG9iIHN0cmluZywgYnVpbHQgYnkgYVxuICogZnVuY3Rpb24sIG9yIGF3YWl0ZWQgZnJvbSBhIHByb21pc2UgaXMgcmVzb2x2ZWQgYnkgdml0ZXN0IGl0c2VsZiwgb3V0IG9mIHRoaXMgZnVuY3Rpb24ncyByZWFjaC5cbiAqXG4gKiBAcGFyYW0gY3VzdG9tUHJvamVjdHMgLSBUaGUgcHJvamVjdHMgcmV0dXJuZWQgYnkge0BsaW5rIERlZmluZU9ic2lkaWFuUGx1Z2luVml0ZXN0Q29uZmlnT3B0aW9ucy5jdXN0b21Qcm9qZWN0c30uXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlQ3VzdG9tUHJvamVjdHMoY3VzdG9tUHJvamVjdHM6IFRlc3RQcm9qZWN0Q29uZmlndXJhdGlvbltdKTogdm9pZCB7XG4gIGZvciAoY29uc3QgW2luZGV4LCBjdXN0b21Qcm9qZWN0XSBvZiBjdXN0b21Qcm9qZWN0cy5lbnRyaWVzKCkpIHtcbiAgICBpZiAodHlwZW9mIGN1c3RvbVByb2plY3QgIT09ICdvYmplY3QnIHx8ICd0aGVuJyBpbiBjdXN0b21Qcm9qZWN0KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBpbmNsdWRlID0gY3VzdG9tUHJvamVjdC50ZXN0Py5pbmNsdWRlO1xuXG4gICAgaWYgKGluY2x1ZGUgJiYgaW5jbHVkZS5sZW5ndGggPiAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBuYW1lID0gY3VzdG9tUHJvamVjdC50ZXN0Py5uYW1lO1xuICAgIGNvbnN0IGxhYmVsID0gdHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnID8gbmFtZSA6IG5hbWU/LmxhYmVsID8/IGBhdCBpbmRleCAke1N0cmluZyhpbmRleCl9YDtcblxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBUaGUgY3VzdG9tIHZpdGVzdCBwcm9qZWN0ICR7bGFiZWx9IGRlY2xhcmVzIG5vIFxcYHRlc3QuaW5jbHVkZVxcYCwgc28gdml0ZXN0IGZhbGxzIGJhY2sgdG8gaXRzIGRlZmF1bHQgZ2xvYiBhbmQgdGhlIHByb2plY3QgY29sbGVjdHMgRVZFUlkgdGVzdCBmaWxlIFx1MjAxNCBpbmNsdWRpbmcgdGhlIFxcYCotY2FwdHVyZS5cXGAgc3VpdGVzIHRoYXQgcmV3cml0ZSBjaGVja2VkLWluIHNjcmVlbnNob3RzLiBEZWNsYXJlIGFuIGV4cGxpY2l0IFxcYGluY2x1ZGVcXGAsIG9yIHNwcmVhZCBhIHN0YW5kYXJkIHByb2plY3QgKFxcYC4uLmNvbnRleHQuZGVza3RvcFxcYCkgYW5kIG92ZXJyaWRlIGl0LmBcbiAgICApO1xuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXlCQTtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLE9BQU8sYUFBYTtBQUNwQixTQUFTLHdDQUF3QztBQUNqRCxTQUFTLG9CQUFvQjtBQUU3QjtBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQXFDUCxNQUFNLDRDQUE0QztBQU9sRCxNQUFNLGtDQUFrQztB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
@@ -0,0 +1,92 @@
1
+ /// <reference path="./index.d.mts" />
2
+ /**
3
+ * @file
4
+ *
5
+ * Releases an Obsidian plugin: the generic release from `@mnaoumov/typescript-dev-toolkit/version`, plus what only a
6
+ * plugin has — `manifest.json` (and `manifest-beta.json` for a pre-release) and `versions.json` bumped with the
7
+ * plugin's `minAppVersion`, the updated manifest copied into `dist/build`, the demo vault archived as a release
8
+ * asset, and the files in `dist/build` attached to the GitHub release instead of an `npm pack` tarball.
9
+ */
10
+ import type { ParsedVersionArguments as GenericParsedVersionArguments, UpdateVersionOptions as GenericUpdateVersionOptions } from '@mnaoumov/typescript-dev-toolkit/version';
11
+ /**
12
+ * Type representing the structure of Obsidian's `desktop-releases.json` feed.
13
+ *
14
+ * This is the feed the desktop app itself updates from, so it is the only source that states a version
15
+ * desktop users can actually run.
16
+ */
17
+ export interface DesktopReleasesJson {
18
+ /**
19
+ * The latest Obsidian version available for desktop.
20
+ */
21
+ latestVersion: string;
22
+ }
23
+ /**
24
+ * Type representing the manifest file format for Obsidian plugins.
25
+ */
26
+ export interface Manifest {
27
+ /**
28
+ * A minimum Obsidian version required for the plugin.
29
+ */
30
+ minAppVersion: string;
31
+ /**
32
+ * A version of the plugin.
33
+ */
34
+ version: string;
35
+ }
36
+ /**
37
+ * The result of parsing the command-line arguments for a plugin release.
38
+ */
39
+ export interface ParsedVersionArguments extends GenericParsedVersionArguments {
40
+ /**
41
+ * The {@link UpdateVersionOptions} parsed from the flags.
42
+ */
43
+ readonly options: UpdateVersionOptions;
44
+ }
45
+ /**
46
+ * Options for {@link updateVersion}: the generic release options plus the plugin's own.
47
+ */
48
+ export interface UpdateVersionOptions extends GenericUpdateVersionOptions {
49
+ /**
50
+ * An explicit `minAppVersion` to write into the plugin's `manifest.json` and its new `versions.json`
51
+ * entry. When set, it is used verbatim and the latest Obsidian desktop version is not fetched at all.
52
+ *
53
+ * Set this when the plugin has a known minimum it actually requires, rather than tracking whatever
54
+ * Obsidian released most recently. Only applies to non-pre-release versions (a pre-release copies the
55
+ * existing `manifest.json` and never writes `minAppVersion`).
56
+ *
57
+ * @default the latest Obsidian desktop version
58
+ */
59
+ readonly minAppVersion?: string | undefined;
60
+ /**
61
+ * Whether to archive the plugin's demo vault (`demo-vault/` in the repo root) as a release artifact. Ignored
62
+ * when the repo has no `demo-vault/` folder.
63
+ *
64
+ * @default `true`
65
+ */
66
+ readonly shouldArchiveDemoVault?: boolean;
67
+ }
68
+ /**
69
+ * Copies the updated manifest file to the distribution build folder.
70
+ *
71
+ * @returns A {@link Promise} that resolves when the copy operation is complete.
72
+ */
73
+ export declare function copyUpdatedManifest(): Promise<void>;
74
+ /**
75
+ * Parses the command-line arguments for a plugin release: every flag the generic `parseVersionArguments`
76
+ * recognizes, plus two of the plugin's own:
77
+ * - `--min-app-version=<x.y.z>` — write this `minAppVersion` into the plugin's `manifest.json` and its new
78
+ * `versions.json` entry instead of tracking the latest Obsidian desktop version.
79
+ * - `--no-demo-vault` — skip archiving the plugin's demo vault (`demo-vault/`) as a release artifact.
80
+ *
81
+ * @param $arguments - The command-line arguments to parse (typically `process.argv.slice(2)`).
82
+ * @returns The {@link ParsedVersionArguments} containing the version update type and the options.
83
+ */
84
+ export declare function parseVersionArguments($arguments: string[]): ParsedVersionArguments;
85
+ /**
86
+ * Releases the plugin. See the `@file` overview for what it adds to the generic release.
87
+ *
88
+ * @param versionUpdateType - The type of version update to perform (major, minor, patch, premajor, preminor, prepatch, prerelease, or x.y.z[-suffix]).
89
+ * @param options - The {@link UpdateVersionOptions} controlling the release behavior.
90
+ * @returns A {@link Promise} that resolves when the release is complete.
91
+ */
92
+ export declare function updateVersion(versionUpdateType?: string, options?: UpdateVersionOptions): Promise<void>;