sonamu 0.6.0 → 0.7.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 (406) hide show
  1. package/.swcrc.project-default +18 -0
  2. package/bin/cli.js +24 -0
  3. package/dist/ai/agents/agent.d.ts +11 -0
  4. package/dist/ai/agents/agent.d.ts.map +1 -0
  5. package/dist/ai/agents/agent.js +65 -0
  6. package/dist/ai/agents/index.d.ts +3 -0
  7. package/dist/ai/agents/index.d.ts.map +1 -0
  8. package/dist/ai/agents/index.js +4 -0
  9. package/dist/ai/agents/types.d.ts +43 -0
  10. package/dist/ai/agents/types.d.ts.map +1 -0
  11. package/dist/ai/agents/types.js +3 -0
  12. package/dist/ai/index.d.ts +2 -0
  13. package/dist/ai/index.d.ts.map +1 -0
  14. package/dist/ai/index.js +3 -0
  15. package/dist/ai/providers/rtzr/api.d.ts +22 -0
  16. package/dist/ai/providers/rtzr/api.d.ts.map +1 -0
  17. package/dist/ai/providers/rtzr/api.js +28 -0
  18. package/dist/ai/providers/rtzr/error.d.ts +18 -0
  19. package/dist/ai/providers/rtzr/error.d.ts.map +1 -0
  20. package/dist/ai/providers/rtzr/error.js +29 -0
  21. package/dist/ai/providers/rtzr/index.d.ts +5 -0
  22. package/dist/ai/providers/rtzr/index.d.ts.map +1 -0
  23. package/dist/ai/providers/rtzr/index.js +6 -0
  24. package/dist/ai/providers/rtzr/model.d.ts +52 -0
  25. package/dist/ai/providers/rtzr/model.d.ts.map +1 -0
  26. package/dist/ai/providers/rtzr/model.js +137 -0
  27. package/dist/ai/providers/rtzr/options.d.ts +7 -0
  28. package/dist/ai/providers/rtzr/options.d.ts.map +1 -0
  29. package/dist/ai/providers/rtzr/options.js +47 -0
  30. package/dist/ai/providers/rtzr/provider.d.ts +18 -0
  31. package/dist/ai/providers/rtzr/provider.d.ts.map +1 -0
  32. package/dist/ai/providers/rtzr/provider.js +54 -0
  33. package/dist/ai/providers/rtzr/utils.d.ts +19 -0
  34. package/dist/ai/providers/rtzr/utils.d.ts.map +1 -0
  35. package/dist/ai/providers/rtzr/utils.js +88 -0
  36. package/dist/api/base-frame.d.ts +2 -2
  37. package/dist/api/base-frame.d.ts.map +1 -1
  38. package/dist/api/base-frame.js +2 -1
  39. package/dist/api/caster.d.ts.map +1 -1
  40. package/dist/api/caster.js +6 -1
  41. package/dist/api/code-converters.d.ts +58 -14
  42. package/dist/api/code-converters.d.ts.map +1 -1
  43. package/dist/api/code-converters.js +178 -409
  44. package/dist/api/config.d.ts +27 -13
  45. package/dist/api/config.d.ts.map +1 -1
  46. package/dist/api/config.js +19 -26
  47. package/dist/api/context.d.ts +4 -3
  48. package/dist/api/context.d.ts.map +1 -1
  49. package/dist/api/context.js +1 -1
  50. package/dist/api/decorators.d.ts +20 -6
  51. package/dist/api/decorators.d.ts.map +1 -1
  52. package/dist/api/decorators.js +111 -18
  53. package/dist/api/index.d.ts +2 -2
  54. package/dist/api/index.d.ts.map +1 -1
  55. package/dist/api/index.js +3 -3
  56. package/dist/api/sonamu.d.ts +7 -7
  57. package/dist/api/sonamu.d.ts.map +1 -1
  58. package/dist/api/sonamu.js +83 -51
  59. package/dist/api/validator.d.ts +6 -0
  60. package/dist/api/validator.d.ts.map +1 -0
  61. package/dist/api/validator.js +81 -0
  62. package/dist/bin/build-config.d.ts +5 -1
  63. package/dist/bin/build-config.d.ts.map +1 -1
  64. package/dist/bin/build-config.js +5 -2
  65. package/dist/bin/cli.js +165 -64
  66. package/dist/bin/loader-register.d.ts +2 -0
  67. package/dist/bin/loader-register.d.ts.map +1 -0
  68. package/dist/bin/loader-register.js +34 -0
  69. package/dist/database/_batch_update.d.ts +5 -3
  70. package/dist/database/_batch_update.d.ts.map +1 -1
  71. package/dist/database/_batch_update.js +30 -13
  72. package/dist/database/base-model.d.ts +96 -10
  73. package/dist/database/base-model.d.ts.map +1 -1
  74. package/dist/database/base-model.js +232 -89
  75. package/dist/database/base-model.types.d.ts +93 -0
  76. package/dist/database/base-model.types.d.ts.map +1 -0
  77. package/dist/database/base-model.types.js +10 -0
  78. package/dist/database/code-generator.d.ts +1 -1
  79. package/dist/database/code-generator.d.ts.map +1 -1
  80. package/dist/database/code-generator.js +11 -10
  81. package/dist/database/db.d.ts +5 -6
  82. package/dist/database/db.d.ts.map +1 -1
  83. package/dist/database/db.js +22 -25
  84. package/dist/database/puri-subset.test-d.js +81 -0
  85. package/dist/database/puri-subset.types.d.ts +123 -0
  86. package/dist/database/puri-subset.types.d.ts.map +1 -0
  87. package/dist/database/puri-subset.types.js +16 -0
  88. package/dist/database/puri-wrapper.d.ts +13 -11
  89. package/dist/database/puri-wrapper.d.ts.map +1 -1
  90. package/dist/database/puri-wrapper.js +2 -2
  91. package/dist/database/puri.d.ts +25 -14
  92. package/dist/database/puri.d.ts.map +1 -1
  93. package/dist/database/puri.js +83 -21
  94. package/dist/database/puri.types.d.ts +21 -7
  95. package/dist/database/puri.types.d.ts.map +1 -1
  96. package/dist/database/puri.types.js +4 -1
  97. package/dist/database/transaction-context.d.ts +1 -1
  98. package/dist/database/transaction-context.d.ts.map +1 -1
  99. package/dist/database/transaction-context.js +1 -1
  100. package/dist/database/upsert-builder.d.ts +9 -3
  101. package/dist/database/upsert-builder.d.ts.map +1 -1
  102. package/dist/database/upsert-builder.js +228 -78
  103. package/dist/entity/entity-manager.d.ts +165 -2
  104. package/dist/entity/entity-manager.d.ts.map +1 -1
  105. package/dist/entity/entity-manager.js +26 -10
  106. package/dist/entity/entity.d.ts +5 -3
  107. package/dist/entity/entity.d.ts.map +1 -1
  108. package/dist/entity/entity.js +153 -54
  109. package/dist/exceptions/error-handler.d.ts +1 -1
  110. package/dist/exceptions/error-handler.d.ts.map +1 -1
  111. package/dist/exceptions/error-handler.js +1 -1
  112. package/dist/exceptions/so-exceptions.d.ts +1 -1
  113. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  114. package/dist/exceptions/so-exceptions.js +1 -1
  115. package/dist/file-storage/driver.d.ts +1 -1
  116. package/dist/file-storage/driver.d.ts.map +1 -1
  117. package/dist/file-storage/driver.js +1 -1
  118. package/dist/file-storage/file-storage.js +2 -2
  119. package/dist/index.d.ts +18 -11
  120. package/dist/index.d.ts.map +1 -1
  121. package/dist/index.js +19 -13
  122. package/dist/migration/code-generation.d.ts +1 -1
  123. package/dist/migration/code-generation.d.ts.map +1 -1
  124. package/dist/migration/code-generation.js +123 -67
  125. package/dist/migration/migration-set.d.ts +2 -10
  126. package/dist/migration/migration-set.d.ts.map +1 -1
  127. package/dist/migration/migration-set.js +67 -218
  128. package/dist/migration/migrator.d.ts +24 -73
  129. package/dist/migration/migrator.d.ts.map +1 -1
  130. package/dist/migration/migrator.js +121 -301
  131. package/dist/migration/postgresql-schema-reader.d.ts +51 -0
  132. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -0
  133. package/dist/migration/postgresql-schema-reader.js +245 -0
  134. package/dist/migration/types.d.ts +6 -38
  135. package/dist/migration/types.d.ts.map +1 -1
  136. package/dist/migration/types.js +1 -1
  137. package/dist/naite/messaging-types.d.ts +43 -0
  138. package/dist/naite/messaging-types.d.ts.map +1 -0
  139. package/dist/naite/messaging-types.js +7 -0
  140. package/dist/naite/naite-reporter.d.ts +41 -0
  141. package/dist/naite/naite-reporter.d.ts.map +1 -0
  142. package/dist/naite/naite-reporter.js +102 -0
  143. package/dist/naite/naite.d.ts +91 -8
  144. package/dist/naite/naite.d.ts.map +1 -1
  145. package/dist/naite/naite.js +285 -41
  146. package/dist/stream/sse.d.ts +2 -2
  147. package/dist/stream/sse.d.ts.map +1 -1
  148. package/dist/stream/sse.js +1 -1
  149. package/dist/syncer/api-parser.d.ts +3 -13
  150. package/dist/syncer/api-parser.d.ts.map +1 -1
  151. package/dist/syncer/api-parser.js +67 -56
  152. package/dist/syncer/checksum.d.ts +2 -2
  153. package/dist/syncer/checksum.d.ts.map +1 -1
  154. package/dist/syncer/checksum.js +11 -11
  155. package/dist/syncer/code-generator.d.ts +3 -3
  156. package/dist/syncer/code-generator.d.ts.map +1 -1
  157. package/dist/syncer/code-generator.js +37 -17
  158. package/dist/syncer/entity-operations.d.ts +2 -2
  159. package/dist/syncer/entity-operations.d.ts.map +1 -1
  160. package/dist/syncer/entity-operations.js +9 -8
  161. package/dist/syncer/file-patterns.d.ts +1 -1
  162. package/dist/syncer/file-patterns.d.ts.map +1 -1
  163. package/dist/syncer/file-patterns.js +1 -1
  164. package/dist/syncer/index.d.ts +4 -4
  165. package/dist/syncer/index.d.ts.map +1 -1
  166. package/dist/syncer/index.js +5 -5
  167. package/dist/syncer/module-loader.d.ts +4 -4
  168. package/dist/syncer/module-loader.d.ts.map +1 -1
  169. package/dist/syncer/module-loader.js +17 -12
  170. package/dist/syncer/syncer.d.ts +31 -24
  171. package/dist/syncer/syncer.d.ts.map +1 -1
  172. package/dist/syncer/syncer.js +92 -45
  173. package/dist/template/entity-converter.d.ts +1 -1
  174. package/dist/template/entity-converter.d.ts.map +1 -1
  175. package/dist/template/entity-converter.js +15 -8
  176. package/dist/template/helpers.d.ts +2 -2
  177. package/dist/template/helpers.d.ts.map +1 -1
  178. package/dist/template/helpers.js +3 -3
  179. package/dist/template/implementations/entity.template.d.ts +2 -2
  180. package/dist/template/implementations/entity.template.d.ts.map +1 -1
  181. package/dist/template/implementations/entity.template.js +4 -5
  182. package/dist/template/implementations/generated.template.d.ts +2 -3
  183. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  184. package/dist/template/implementations/generated.template.js +46 -29
  185. package/dist/template/implementations/generated_http.template.d.ts +2 -3
  186. package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
  187. package/dist/template/implementations/generated_http.template.js +9 -9
  188. package/dist/template/implementations/generated_sso.template.d.ts +3 -4
  189. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  190. package/dist/template/implementations/generated_sso.template.js +54 -25
  191. package/dist/template/implementations/init_types.template.d.ts +2 -2
  192. package/dist/template/implementations/init_types.template.d.ts.map +1 -1
  193. package/dist/template/implementations/init_types.template.js +2 -2
  194. package/dist/template/implementations/model.template.d.ts +2 -2
  195. package/dist/template/implementations/model.template.d.ts.map +1 -1
  196. package/dist/template/implementations/model.template.js +47 -37
  197. package/dist/template/implementations/model_test.template.d.ts +2 -2
  198. package/dist/template/implementations/model_test.template.d.ts.map +1 -1
  199. package/dist/template/implementations/model_test.template.js +2 -2
  200. package/dist/template/implementations/service.template.d.ts +4 -4
  201. package/dist/template/implementations/service.template.d.ts.map +1 -1
  202. package/dist/template/implementations/service.template.js +24 -16
  203. package/dist/template/implementations/view_enums_buttonset.template.d.ts +2 -2
  204. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -1
  205. package/dist/template/implementations/view_enums_buttonset.template.js +1 -1
  206. package/dist/template/implementations/view_enums_dropdown.template.d.ts +2 -2
  207. package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -1
  208. package/dist/template/implementations/view_enums_dropdown.template.js +2 -2
  209. package/dist/template/implementations/view_enums_select.template.d.ts +2 -2
  210. package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -1
  211. package/dist/template/implementations/view_enums_select.template.js +2 -2
  212. package/dist/template/implementations/view_form.template.d.ts +2 -2
  213. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  214. package/dist/template/implementations/view_form.template.js +4 -4
  215. package/dist/template/implementations/view_id_all_select.template.d.ts +2 -2
  216. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -1
  217. package/dist/template/implementations/view_id_all_select.template.js +1 -1
  218. package/dist/template/implementations/view_id_async_select.template.d.ts +2 -2
  219. package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -1
  220. package/dist/template/implementations/view_id_async_select.template.js +1 -1
  221. package/dist/template/implementations/view_list.template.d.ts +2 -2
  222. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  223. package/dist/template/implementations/view_list.template.js +29 -19
  224. package/dist/template/implementations/view_list_columns.template.d.ts +3 -3
  225. package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -1
  226. package/dist/template/implementations/view_list_columns.template.js +1 -1
  227. package/dist/template/implementations/view_search_input.template.d.ts +2 -2
  228. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
  229. package/dist/template/implementations/view_search_input.template.js +1 -1
  230. package/dist/template/index.d.ts +4 -2
  231. package/dist/template/index.d.ts.map +1 -1
  232. package/dist/template/index.js +5 -3
  233. package/dist/template/template-manager.d.ts +56 -0
  234. package/dist/template/template-manager.d.ts.map +1 -0
  235. package/dist/template/template-manager.js +125 -0
  236. package/dist/template/template-types.d.ts +16 -0
  237. package/dist/template/template-types.d.ts.map +1 -0
  238. package/dist/template/template-types.js +7 -0
  239. package/dist/template/template.d.ts +12 -2
  240. package/dist/template/template.d.ts.map +1 -1
  241. package/dist/template/template.js +19 -6
  242. package/dist/template/zod-converter.d.ts +40 -7
  243. package/dist/template/zod-converter.d.ts.map +1 -1
  244. package/dist/template/zod-converter.js +341 -58
  245. package/dist/testing/_relation-graph.d.ts +1 -1
  246. package/dist/testing/_relation-graph.d.ts.map +1 -1
  247. package/dist/testing/_relation-graph.js +12 -3
  248. package/dist/testing/fixture-manager.d.ts +42 -11
  249. package/dist/testing/fixture-manager.d.ts.map +1 -1
  250. package/dist/testing/fixture-manager.js +338 -236
  251. package/dist/types/types.d.ts +709 -104
  252. package/dist/types/types.d.ts.map +1 -1
  253. package/dist/types/types.js +309 -52
  254. package/dist/typings/knex.d.js +2 -2
  255. package/dist/utils/async-utils.d.ts.map +1 -1
  256. package/dist/utils/async-utils.js +3 -3
  257. package/dist/utils/console-util.js +1 -1
  258. package/dist/utils/controller.d.ts +1 -0
  259. package/dist/utils/controller.d.ts.map +1 -1
  260. package/dist/utils/controller.js +4 -1
  261. package/dist/utils/esm-utils.d.ts +0 -6
  262. package/dist/utils/esm-utils.d.ts.map +1 -1
  263. package/dist/utils/esm-utils.js +2 -9
  264. package/dist/utils/formatter.d.ts +3 -0
  265. package/dist/utils/formatter.d.ts.map +1 -0
  266. package/dist/utils/formatter.js +110 -0
  267. package/dist/utils/fs-utils.d.ts +1 -1
  268. package/dist/utils/fs-utils.d.ts.map +1 -1
  269. package/dist/utils/fs-utils.js +1 -1
  270. package/dist/utils/lodash-able.d.ts.map +1 -1
  271. package/dist/utils/lodash-able.js +1 -1
  272. package/dist/utils/object-utils.d.ts +44 -0
  273. package/dist/utils/object-utils.d.ts.map +1 -0
  274. package/dist/utils/object-utils.js +191 -0
  275. package/dist/utils/path-utils.d.ts +1 -1
  276. package/dist/utils/path-utils.d.ts.map +1 -1
  277. package/dist/utils/path-utils.js +3 -3
  278. package/dist/utils/process-utils.js +1 -1
  279. package/dist/utils/sql-parser.d.ts +5 -1
  280. package/dist/utils/sql-parser.d.ts.map +1 -1
  281. package/dist/utils/sql-parser.js +14 -3
  282. package/dist/utils/type-utils.d.ts +23 -0
  283. package/dist/utils/type-utils.d.ts.map +1 -0
  284. package/dist/utils/type-utils.js +45 -0
  285. package/dist/utils/utils.d.ts +7 -1
  286. package/dist/utils/utils.d.ts.map +1 -1
  287. package/dist/utils/utils.js +44 -5
  288. package/dist/utils/zod-error.d.ts +1 -1
  289. package/dist/utils/zod-error.d.ts.map +1 -1
  290. package/dist/utils/zod-error.js +1 -1
  291. package/package.json +54 -29
  292. package/src/ai/agents/agent.ts +87 -0
  293. package/src/ai/agents/index.ts +2 -0
  294. package/src/ai/agents/types.ts +47 -0
  295. package/src/ai/index.ts +1 -0
  296. package/src/ai/providers/rtzr/api.ts +37 -0
  297. package/src/ai/providers/rtzr/error.ts +34 -0
  298. package/src/ai/providers/rtzr/index.ts +4 -0
  299. package/src/ai/providers/rtzr/model.ts +201 -0
  300. package/src/ai/providers/rtzr/options.ts +49 -0
  301. package/src/ai/providers/rtzr/provider.ts +91 -0
  302. package/src/ai/providers/rtzr/utils.ts +127 -0
  303. package/src/api/base-frame.ts +4 -2
  304. package/src/api/caster.ts +17 -23
  305. package/src/api/code-converters.ts +176 -533
  306. package/src/api/config.ts +39 -56
  307. package/src/api/context.ts +7 -18
  308. package/src/api/decorators.ts +175 -46
  309. package/src/api/index.ts +2 -2
  310. package/src/api/sonamu.ts +133 -124
  311. package/src/api/validator.ts +83 -0
  312. package/src/bin/build-config.ts +7 -1
  313. package/src/bin/cli.ts +192 -110
  314. package/src/bin/loader-register.ts +38 -0
  315. package/src/database/_batch_update.ts +46 -31
  316. package/src/database/base-model.ts +390 -182
  317. package/src/database/base-model.types.ts +155 -0
  318. package/src/database/code-generator.ts +13 -32
  319. package/src/database/db.ts +36 -50
  320. package/src/database/puri-subset.test-d.ts +471 -0
  321. package/src/database/puri-subset.types.ts +195 -0
  322. package/src/database/puri-wrapper.ts +58 -67
  323. package/src/database/puri.ts +182 -126
  324. package/src/database/puri.types.ts +64 -31
  325. package/src/database/transaction-context.ts +1 -1
  326. package/src/database/upsert-builder.ts +262 -132
  327. package/src/entity/entity-manager.ts +36 -28
  328. package/src/entity/entity.ts +330 -249
  329. package/src/exceptions/error-handler.ts +3 -3
  330. package/src/exceptions/so-exceptions.ts +11 -11
  331. package/src/file-storage/driver.ts +5 -5
  332. package/src/file-storage/file-storage.ts +2 -2
  333. package/src/index.ts +18 -12
  334. package/src/migration/code-generation.ts +185 -172
  335. package/src/migration/migration-set.ts +80 -293
  336. package/src/migration/migrator.ts +182 -425
  337. package/src/migration/mysql-schema-reader.ts.txt +272 -0
  338. package/src/migration/postgresql-schema-reader.ts +310 -0
  339. package/src/migration/types.ts +6 -39
  340. package/src/naite/messaging-types.ts +51 -0
  341. package/src/naite/naite-reporter.ts +128 -0
  342. package/src/naite/naite.ts +378 -33
  343. package/src/shared/web.shared.ts.txt +20 -24
  344. package/src/stream/sse.ts +5 -5
  345. package/src/syncer/api-parser.ts +52 -69
  346. package/src/syncer/checksum.ts +25 -37
  347. package/src/syncer/code-generator.ts +58 -62
  348. package/src/syncer/entity-operations.ts +12 -15
  349. package/src/syncer/file-patterns.ts +2 -2
  350. package/src/syncer/index.ts +4 -4
  351. package/src/syncer/module-loader.ts +28 -25
  352. package/src/syncer/syncer.ts +155 -162
  353. package/src/template/entity-converter.ts +18 -27
  354. package/src/template/helpers.ts +8 -11
  355. package/src/template/implementations/entity.template.ts +6 -6
  356. package/src/template/implementations/generated.template.ts +99 -99
  357. package/src/template/implementations/generated_http.template.ts +21 -54
  358. package/src/template/implementations/generated_sso.template.ts +78 -65
  359. package/src/template/implementations/init_types.template.ts +4 -6
  360. package/src/template/implementations/model.template.ts +47 -38
  361. package/src/template/implementations/model_test.template.ts +3 -3
  362. package/src/template/implementations/service.template.ts +56 -80
  363. package/src/template/implementations/view_enums_buttonset.template.ts +2 -2
  364. package/src/template/implementations/view_enums_dropdown.template.ts +4 -4
  365. package/src/template/implementations/view_enums_select.template.ts +3 -3
  366. package/src/template/implementations/view_form.template.ts +34 -75
  367. package/src/template/implementations/view_id_all_select.template.ts +2 -2
  368. package/src/template/implementations/view_id_async_select.template.ts +9 -23
  369. package/src/template/implementations/view_list.template.ts +54 -95
  370. package/src/template/implementations/view_list_columns.template.ts +4 -10
  371. package/src/template/implementations/view_search_input.template.ts +2 -2
  372. package/src/template/index.ts +4 -2
  373. package/src/template/template-manager.ts +166 -0
  374. package/src/template/template-types.ts +16 -0
  375. package/src/template/template.ts +29 -10
  376. package/src/template/zod-converter.ts +407 -101
  377. package/src/testing/_relation-graph.ts +18 -11
  378. package/src/testing/fixture-manager.ts +468 -362
  379. package/src/types/types.ts +516 -248
  380. package/src/typings/knex.d.ts +7 -9
  381. package/src/utils/async-utils.ts +8 -12
  382. package/src/utils/console-util.ts +1 -1
  383. package/src/utils/controller.ts +3 -0
  384. package/src/utils/esm-utils.ts +8 -18
  385. package/src/utils/formatter.ts +109 -0
  386. package/src/utils/fs-utils.ts +1 -1
  387. package/src/utils/lodash-able.ts +1 -4
  388. package/src/utils/object-utils.ts +217 -0
  389. package/src/utils/path-utils.ts +3 -6
  390. package/src/utils/process-utils.ts +1 -1
  391. package/src/utils/sql-parser.ts +23 -5
  392. package/src/utils/type-utils.ts +83 -0
  393. package/src/utils/utils.ts +58 -9
  394. package/src/utils/zod-error.ts +3 -3
  395. package/dist/bin/cli-wrapper.d.ts +0 -3
  396. package/dist/bin/cli-wrapper.d.ts.map +0 -1
  397. package/dist/bin/cli-wrapper.js +0 -72
  398. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +0 -2
  399. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +0 -1
  400. package/dist/database/knex-plugins/knex-on-duplicate-update.js +0 -39
  401. package/dist/entity/entity-utils.d.ts +0 -61
  402. package/dist/entity/entity-utils.d.ts.map +0 -1
  403. package/dist/entity/entity-utils.js +0 -210
  404. package/src/bin/cli-wrapper.ts +0 -82
  405. package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
  406. package/src/entity/entity-utils.ts +0 -291
@@ -1,37 +1,40 @@
1
- import { z } from "zod";
2
- import { ApiParamType, isBelongsToOneRelationProp, isBigIntegerProp, isBooleanProp, isDateProp, isDateTimeProp, isDecimalProp, isDoubleProp, isEnumProp, isFloatProp, isIntegerProp, isJsonProp, isOneToOneRelationProp, isRelationProp, isStringProp, isTextProp, isTimeProp, isTimestampProp, isUuidProp, isVirtualProp } from "../types/types.js";
3
- /*
4
- ExtendedApi 에서 ZodObject 리턴
5
- */ export function getZodObjectFromApi(api, references = {}) {
6
- if (api.typeParameters?.length > 0) {
7
- api.typeParameters.map((typeParam)=>{
8
- if (typeParam.constraint) {
9
- let zodType = getZodTypeFromApiParamType(typeParam.constraint, references);
10
- references[typeParam.id] = zodType;
11
- }
12
- });
1
+ /**
2
+ * code-converters는 API 타입 정의들을 Zod 객체나 TypeScript 코드로 변환하는 함수들을 제공합니다.
3
+ *
4
+ * 1. API 시리즈들:
5
+ * - ExtendedApi, ApiParam, ApiParamType
6
+ * - API 메타데이터를 표현하는 타입 정의들
7
+ *
8
+ * 2. ZodObject 변환
9
+ * - API 타입 정의 → Zod 타입 인스턴스 (런타임 밸리데이션용)
10
+ * - getZodTypeFromApiParamType → getZodObjectFromApiParams → getZodObjectFromApi
11
+ *
12
+ * 3. TsTypeDef 변환
13
+ * - API 타입 정의 → TypeScript 타입 코드 문자열 (코드 생성용)
14
+ * - apiParamTypeToTsType → apiParamToTsCode, apiParamToTsCodeAsObject
15
+ *
16
+ * 참고:
17
+ * - ZodTypeDef 생성 (Zod 코드 문자열): zod-converter.ts의 zodTypeToZodCode 사용
18
+ * - EntityProp 변환: zod-converter.ts 참조
19
+ */ import { z } from "zod";
20
+ import { ApiParamType } from "../types/types.js";
21
+ /**
22
+ * Promise 타입을 한 번 언래핑하여 내부 타입을 반환합니다.
23
+ * Promise가 아닌 경우 원본 타입을 그대로 반환합니다.
24
+ */ export function unwrapPromiseOnce(paramType) {
25
+ if (ApiParamType.isPromise(paramType)) {
26
+ return paramType.args?.[0];
27
+ } else {
28
+ return paramType;
13
29
  }
14
- const ReqType = getZodObjectFromApiParams(api.parameters.filter((param)=>!ApiParamType.isContext(param.type) && !ApiParamType.isRefKnex(param.type) && !(param.optional === true && param.name.startsWith("_") // _로 시작하는 파라미터는 제외
15
- )), references);
16
- return ReqType;
17
30
  }
18
31
  /*
19
- ZodObject통해 ApiParam 리턴
20
- */ export function getZodObjectFromApiParams(apiParams, references = {}) {
21
- return z.object(apiParams.reduce((r, param)=>{
22
- let zodType = getZodTypeFromApiParamType(param.type, references);
23
- if (param.optional) {
24
- zodType = zodType.optional();
25
- }
26
- return {
27
- ...r,
28
- [param.name]: zodType
29
- };
30
- }, {}));
31
- }
32
- /*
33
- ApiParamType으로 ZodType 컨버팅
34
- */ export function getZodTypeFromApiParamType(paramType, references) {
32
+ * API구성하는 요소들을 ZodObject로 변환하기 위한 함수들입니다.
33
+ */ /**
34
+ * ApiParamType을 Zod 타입 인스턴스로 변환합니다.
35
+ * string, number, array, union 등 모든 ApiParamType을 처리하며,
36
+ * 순환참조가 발생하는 경우 z.unknown()으로 fallback합니다.
37
+ */ export function getZodTypeFromApiParamType(paramType, references) {
35
38
  switch(paramType){
36
39
  case "string":
37
40
  return z.string();
@@ -40,268 +43,152 @@ import { ApiParamType, isBelongsToOneRelationProp, isBigIntegerProp, isBooleanPr
40
43
  case "boolean":
41
44
  return z.boolean();
42
45
  default:
43
- const advType = paramType;
44
- switch(advType.t){
45
- case "string-literal":
46
- case "numeric-literal":
47
- return z.literal(advType.value);
48
- case "object":
49
- const objType = paramType;
50
- return getZodObjectFromApiParams(objType.props);
51
- case "array":
52
- const arrType = paramType;
53
- return z.array(getZodTypeFromApiParamType(arrType.elementsType, references));
54
- case "ref":
55
- const refType = paramType;
56
- // Date 타입 처리
57
- if (refType.id === "Date") {
58
- return z.date();
59
- }
60
- // 객체 키 관리 유틸리티
61
- if ([
62
- "Pick",
63
- "Omit"
64
- ].includes(refType.id)) {
65
- if (refType.args?.length !== 2) {
66
- throw new Error(`잘못된 ${refType.id}`);
46
+ {
47
+ const advType = paramType;
48
+ switch(advType.t){
49
+ case "string-literal":
50
+ case "numeric-literal":
51
+ return z.literal(advType.value);
52
+ case "object":
53
+ {
54
+ const objType = paramType;
55
+ return getZodObjectFromApiParams(objType.props);
67
56
  }
68
- const [obj, literalOrUnion] = refType.args.map((arg)=>getZodTypeFromApiParamType(arg, references));
69
- let keys = [];
70
- if (literalOrUnion instanceof z.ZodUnion) {
71
- keys = literalOrUnion.def.options.map((option)=>option.def.value);
72
- } else {
73
- keys = literalOrUnion.def.values;
57
+ case "array":
58
+ {
59
+ const arrType = paramType;
60
+ return z.array(getZodTypeFromApiParamType(arrType.elementsType, references));
74
61
  }
75
- const keyRecord = keys.reduce((result, key)=>{
76
- return {
77
- ...result,
78
- [key]: true
79
- };
80
- }, {});
81
- if (refType.id === "Pick") {
82
- if (obj.pick) {
83
- return obj.pick(keyRecord);
62
+ case "ref":
63
+ {
64
+ const refType = paramType;
65
+ // Date 타입 처리
66
+ if (refType.id === "Date") {
67
+ return z.date();
84
68
  }
85
- } else {
86
- if (obj.omit) {
87
- return obj.omit(keyRecord);
69
+ // 객체 키 관리 유틸리티
70
+ if ([
71
+ "Pick",
72
+ "Omit"
73
+ ].includes(refType.id)) {
74
+ if (refType.args?.length !== 2) {
75
+ throw new Error(`잘못된 ${refType.id}`);
76
+ }
77
+ const [obj, literalOrUnion] = refType.args.map((arg)=>getZodTypeFromApiParamType(arg, references));
78
+ let keys = [];
79
+ if (literalOrUnion instanceof z.ZodUnion) {
80
+ keys = literalOrUnion.def.options.map((option)=>option.def.values[0]);
81
+ } else {
82
+ keys = literalOrUnion.def.values;
83
+ }
84
+ const keyRecord = Object.fromEntries(keys.map((key)=>[
85
+ key,
86
+ true
87
+ ]));
88
+ if (refType.id === "Pick") {
89
+ if (obj.pick) {
90
+ return obj.pick(keyRecord);
91
+ }
92
+ } else {
93
+ if (obj.omit) {
94
+ return obj.omit(keyRecord);
95
+ }
96
+ }
88
97
  }
98
+ if ([
99
+ "Partial"
100
+ ].includes(refType.id)) {
101
+ if (refType.args?.length !== 1) {
102
+ throw new Error(`잘못된 ${refType.id}`);
103
+ }
104
+ const obj = getZodTypeFromApiParamType(refType.args[0], references);
105
+ // biome-ignore lint/suspicious/noExplicitAny: Partial 인수 타입 캐스팅
106
+ return obj.partial();
107
+ }
108
+ const reference = references[refType.id];
109
+ if (reference === undefined) {
110
+ return z.unknown();
111
+ // throw new Error(`ref 참조 불가 ${refType.id}`);
112
+ }
113
+ return reference;
89
114
  }
90
- }
91
- if ([
92
- "Partial"
93
- ].includes(refType.id)) {
94
- if (refType.args?.length !== 1) {
95
- throw new Error(`잘못된 ${refType.id}`);
115
+ case "union":
116
+ {
117
+ const unionType = paramType;
118
+ // nullable 유니온
119
+ if (unionType.types.length === 2 && unionType.types.some((type)=>type === "null")) {
120
+ if (unionType.types[0] === "null") {
121
+ return getZodTypeFromApiParamType(unionType.types[1], references).nullable();
122
+ } else {
123
+ return getZodTypeFromApiParamType(unionType.types[0], references).nullable();
124
+ }
125
+ }
126
+ // 일반 유니온
127
+ return z.union(unionType.types.map((type)=>getZodTypeFromApiParamType(type, references)));
96
128
  }
97
- const obj = getZodTypeFromApiParamType(refType.args[0], references);
98
- return obj.partial();
99
- }
100
- const reference = references[refType.id];
101
- if (reference === undefined) {
102
- return z.string();
103
- // throw new Error(`ref 참조 불가 ${refType.id}`);
104
- }
105
- return reference;
106
- case "union":
107
- const unionType = paramType;
108
- // nullable 유니온
109
- if (unionType.types.length === 2 && unionType.types.some((type)=>type === "null")) {
110
- if (unionType.types[0] === "null") {
111
- return getZodTypeFromApiParamType(unionType.types[1], references).nullable();
112
- } else {
113
- return getZodTypeFromApiParamType(unionType.types[0], references).nullable();
129
+ case "intersection":
130
+ {
131
+ const intersectionType = paramType;
132
+ return intersectionType.types.reduce((result, type, index)=>{
133
+ const resolvedType = getZodTypeFromApiParamType(type, references);
134
+ if (index === 0) {
135
+ return resolvedType;
136
+ } else {
137
+ return z.intersection(result, resolvedType);
138
+ }
139
+ }, z.unknown());
114
140
  }
115
- }
116
- // 일반 유니온
117
- return z.union(unionType.types.map((type)=>getZodTypeFromApiParamType(type, references)));
118
- case "intersection":
119
- const intersectionType = paramType;
120
- return intersectionType.types.reduce((result, type, index)=>{
121
- const resolvedType = getZodTypeFromApiParamType(type, references);
122
- if (index === 0) {
123
- return resolvedType;
124
- } else {
125
- return z.intersection(result, resolvedType);
141
+ case "tuple-type":
142
+ {
143
+ const tupleType = paramType;
144
+ return z.tuple(// biome-ignore lint/suspicious/noExplicitAny: 생성되는 ZodTuple의 타입을 추적하기 어려움
145
+ tupleType.elements.map((elem)=>getZodTypeFromApiParamType(elem, references)));
126
146
  }
127
- }, z.unknown());
128
- case "tuple-type":
129
- const tupleType = paramType;
130
- return z.tuple(tupleType.elements.map((elem)=>getZodTypeFromApiParamType(elem, references)));
147
+ }
148
+ return z.unknown();
131
149
  }
132
- return z.unknown();
133
150
  }
134
151
  }
135
- export function propNodeToZodTypeDef(propNode, injectImportKeys) {
136
- if (propNode.nodeType === "plain") {
137
- return propToZodTypeDef(propNode.prop, injectImportKeys);
138
- } else if (propNode.nodeType === "array") {
139
- return [
140
- propNode.prop ? `${propNode.prop.name}: ` : "",
141
- "z.array(z.object({",
142
- propNode.children.map((childPropNode)=>propNodeToZodTypeDef(childPropNode, injectImportKeys)).join("\n"),
143
- "",
144
- "})),"
145
- ].join("\n");
146
- } else if (propNode.nodeType === "object") {
147
- return [
148
- propNode.prop ? `${propNode.prop.name}: ` : "",
149
- "z.object({",
150
- propNode.children.map((childPropNode)=>propNodeToZodTypeDef(childPropNode, injectImportKeys)).join("\n"),
151
- "",
152
- `})${propNode.prop && propNode.prop.nullable ? ".nullable()" : ""},`
153
- ].join("\n");
154
- } else {
155
- throw Error;
156
- }
157
- }
158
- export function getTextTypeLength(textType) {
159
- switch(textType){
160
- case "text":
161
- return 1024 * 64 - 1;
162
- case "mediumtext":
163
- return 1024 * 1024 * 16 - 1;
164
- case "longtext":
165
- return 1024 * 1024 * 1024 * 4 - 1;
166
- }
167
- }
168
- export function propToZodTypeDef(prop, injectImportKeys) {
169
- let stmt;
170
- if (isIntegerProp(prop)) {
171
- stmt = `${prop.name}: z.int()`;
172
- } else if (isBigIntegerProp(prop)) {
173
- stmt = `${prop.name}: z.bigint()`;
174
- } else if (isTextProp(prop)) {
175
- stmt = `${prop.name}: z.string().max(${getTextTypeLength(prop.textType)})`;
176
- } else if (isEnumProp(prop)) {
177
- stmt = `${prop.name}: ${prop.id}`;
178
- injectImportKeys.push(prop.id);
179
- } else if (isStringProp(prop)) {
180
- stmt = `${prop.name}: z.string().max(${prop.length})`;
181
- } else if (isDecimalProp(prop)) {
182
- stmt = `${prop.name}: z.string()`;
183
- } else if (isFloatProp(prop) || isDoubleProp(prop)) {
184
- stmt = `${prop.name}: z.number()`;
185
- } else if (isBooleanProp(prop)) {
186
- stmt = `${prop.name}: z.boolean()`;
187
- } else if (isDateProp(prop)) {
188
- stmt = `${prop.name}: z.string().length(10)`;
189
- } else if (isTimeProp(prop)) {
190
- stmt = `${prop.name}: z.string().length(8)`;
191
- } else if (isDateTimeProp(prop)) {
192
- stmt = `${prop.name}: z.date()`;
193
- } else if (isTimestampProp(prop)) {
194
- stmt = `${prop.name}: z.date()`;
195
- } else if (isJsonProp(prop)) {
196
- stmt = `${prop.name}: ${prop.id}`;
197
- injectImportKeys.push(prop.id);
198
- } else if (isUuidProp(prop)) {
199
- stmt = `${prop.name}: z.uuid()`;
200
- } else if (isVirtualProp(prop)) {
201
- stmt = `${prop.name}: ${prop.id}`;
202
- injectImportKeys.push(prop.id);
203
- } else if (isRelationProp(prop)) {
204
- if (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop) && prop.hasJoinColumn) {
205
- stmt = `${prop.name}_id: z.int()`;
206
- } else {
207
- // 그외 relation 케이스 제외
208
- return `// ${prop.name}: ${prop.relationType} ${prop.with}`;
152
+ /**
153
+ * ApiParam 배열을 ZodObject로 변환합니다.
154
+ * 각 파라미터의 optional 여부를 반영하여 Zod 스키마를 생성합니다.
155
+ */ export function getZodObjectFromApiParams(apiParams, references = {}) {
156
+ return z.object(Object.fromEntries(apiParams.map((param)=>{
157
+ let zodType = getZodTypeFromApiParamType(param.type, references);
158
+ if (param.optional) {
159
+ zodType = zodType.optional();
209
160
  }
210
- } else {
211
- return "// unable to resolve";
212
- }
213
- if (prop.unsigned) {
214
- stmt += ".nonnegative()";
215
- }
216
- if (prop.nullable) {
217
- stmt += ".nullable()";
218
- }
219
- return stmt + ",";
161
+ return [
162
+ param.name,
163
+ zodType
164
+ ];
165
+ })));
220
166
  }
221
- // TODO(Haze, 251031): "template_literal", "file"에 대한 지원이 필요함.
222
- export function zodTypeToZodCode(zt) {
223
- switch(zt.def.type){
224
- case "string":
225
- return "z.string()";
226
- case "number":
227
- return "z.number()";
228
- case "bigint":
229
- return "z.bigint()";
230
- case "boolean":
231
- return "z.boolean()";
232
- case "date":
233
- return "z.date()";
234
- case "null":
235
- return "z.null()";
236
- case "undefined":
237
- return "z.undefined()";
238
- case "any":
239
- return "z.any()";
240
- case "unknown":
241
- return "z.unknown()";
242
- case "never":
243
- return "z.never()";
244
- case "nullable":
245
- return zodTypeToZodCode(zt.def.innerType) + ".nullable()";
246
- case "default":
247
- const zDefaultDef = zt.def;
248
- return zodTypeToZodCode(zDefaultDef.innerType) + `.default(${zDefaultDef.defaultValue})`;
249
- case "record":
250
- const zRecordDef = zt.def;
251
- return `z.record(${zodTypeToZodCode(zRecordDef.keyType)}, ${zodTypeToZodCode(zRecordDef.valueType)})`;
252
- case "literal":
253
- const items = Array.from(zt.values).map((value)=>{
254
- if (typeof value === "string") {
255
- return `"${value}"`;
256
- }
257
- if (value === null) {
258
- return `null`;
259
- }
260
- if (value === undefined) {
261
- return `undefined`;
262
- }
263
- return `${value}`;
264
- });
265
- if (items.length === 1) {
266
- return `z.literal(${items[0]})`;
167
+ /**
168
+ * ExtendedApi를 ZodObject로 변환합니다.
169
+ * TypeParameter와 일반 파라미터를 처리하며,
170
+ * Context, RefKnex, _로 시작하는 optional 파라미터는 제외합니다.
171
+ */ export function getZodObjectFromApi(api, references = {}) {
172
+ if (api.typeParameters?.length > 0) {
173
+ for (const typeParam of api.typeParameters){
174
+ if (typeParam.constraint) {
175
+ const zodType = getZodTypeFromApiParamType(typeParam.constraint, references);
176
+ // biome-ignore lint/suspicious/noExplicitAny: 레퍼런스 타입 캐스팅
177
+ references[typeParam.id] = zodType;
267
178
  }
268
- return `z.literal([${items.join(", ")}])`;
269
- case "union":
270
- return `z.union([${zt.def.options.map((option)=>zodTypeToZodCode(option)).join(",")}])`;
271
- case "enum":
272
- // NOTE: z.enum(["A", "B"])도 z.enum({ A: "A", B: "B" })로 처리됨.
273
- return `z.enum({${Object.entries(zt.def.entries).map(([key, val])=>typeof val === "string" ? `${key}: "${val}"` : `${key}: ${val}`).join(", ")}})`;
274
- case "array":
275
- return `z.array(${zodTypeToZodCode(zt.def.element)})`;
276
- case "object":
277
- const shape = zt.shape;
278
- return [
279
- "z.object({",
280
- ...Object.keys(shape).map((key)=>`${key}: ${zodTypeToZodCode(shape[key])},`),
281
- "})"
282
- ].join("\n");
283
- case "optional":
284
- return zodTypeToZodCode(zt.def.innerType) + ".optional()";
285
- case "file":
286
- return `z.file()`;
287
- case "intersection":
288
- const zIntersectionDef = zt.def;
289
- return `z.intersection(${zodTypeToZodCode(zIntersectionDef.left)}, ${zodTypeToZodCode(zIntersectionDef.right)})`;
290
- case "file":
291
- return `z.file()`;
292
- default:
293
- throw new Error(`처리되지 않은 ZodType ${zt.def.type}`);
179
+ }
294
180
  }
181
+ const ReqType = getZodObjectFromApiParams(// api parsing한 결과가 api params
182
+ api.parameters.filter((param)=>!ApiParamType.isContext(param.type) && !ApiParamType.isRefKnex(param.type) && !(param.optional === true && param.name.startsWith("_"))), references);
183
+ return ReqType;
295
184
  }
296
- export function apiParamToTsCode(params, injectImportKeys) {
297
- return params.map((param)=>{
298
- return `${param.name}${param.optional && !param.defaultDef ? "?" : ""}: ${apiParamTypeToTsType(param.type, injectImportKeys)}${param.defaultDef ? `= ${param.defaultDef}` : ""}`;
299
- }).join(", ");
300
- }
301
- export function apiParamToTsCodeAsObject(params, injectImportKeys) {
302
- return `{ ${params.map((param)=>`${param.name}${param.optional ? "?" : ""}: ${apiParamTypeToTsType(param.type, injectImportKeys)}${param.defaultDef ? `= ${param.defaultDef}` : ""}`).join(", ")} }`;
303
- }
304
- export function apiParamTypeToTsType(paramType, injectImportKeys) {
185
+ /*
186
+ * API 타입 정의를 TypeScript 코드 문자열로 변환하기 위한 함수들입니다.
187
+ */ /**
188
+ * ApiParamType을 TypeScript 타입 문자열로 변환합니다.
189
+ * union, intersection, array, ref 등 모든 타입을 TS 문법으로 표현하며,
190
+ * import가 필요한 타입 ID는 injectImportKeys 수집합니다.
191
+ */ export function apiParamTypeToTsType(paramType, injectImportKeys) {
305
192
  if ([
306
193
  "string",
307
194
  "number",
@@ -326,7 +213,7 @@ export function apiParamTypeToTsType(paramType, injectImportKeys) {
326
213
  } else if (ApiParamType.isIntersection(paramType)) {
327
214
  return paramType.types.map((type)=>apiParamTypeToTsType(type, injectImportKeys)).join(" & ");
328
215
  } else if (ApiParamType.isArray(paramType)) {
329
- return apiParamTypeToTsType(paramType.elementsType, injectImportKeys) + "[]";
216
+ return `${apiParamTypeToTsType(paramType.elementsType, injectImportKeys)}[]`;
330
217
  } else if (ApiParamType.isRef(paramType)) {
331
218
  if ([
332
219
  "Pick",
@@ -353,137 +240,19 @@ export function apiParamTypeToTsType(paramType, injectImportKeys) {
353
240
  throw new Error(`resolve 불가 ApiParamType ${paramType}`);
354
241
  }
355
242
  }
356
- export function unwrapPromiseOnce(paramType) {
357
- if (ApiParamType.isPromise(paramType)) {
358
- return paramType.args[0];
359
- } else {
360
- return paramType;
361
- }
362
- }
363
- // TODO(Haze, 251031): "template_literal", "file"에 대한 지원이 필요함.
364
- export function serializeZodType(zt) {
365
- switch(zt.def.type){
366
- case "object":
367
- return {
368
- type: "object",
369
- shape: Object.keys(zt.shape).reduce((result, key)=>{
370
- return {
371
- ...result,
372
- [key]: serializeZodType(zt.shape[key])
373
- };
374
- }, {})
375
- };
376
- case "array":
377
- return {
378
- type: "array",
379
- element: serializeZodType(zt.def.element)
380
- };
381
- case "enum":
382
- return {
383
- type: "enum",
384
- values: zt.def.entries
385
- };
386
- case "string":
387
- return {
388
- type: "string",
389
- checks: zt.def.checks
390
- };
391
- case "number":
392
- return {
393
- type: "number",
394
- checks: zt.def.checks
395
- };
396
- case "boolean":
397
- return {
398
- type: "boolean"
399
- };
400
- case "nullable":
401
- return {
402
- ...serializeZodType(zt.def.innerType),
403
- nullable: true
404
- };
405
- case "optional":
406
- return {
407
- ...serializeZodType(zt.def.innerType),
408
- optional: true
409
- };
410
- case "any":
411
- return {
412
- type: "any"
413
- };
414
- case "record":
415
- return {
416
- type: "record",
417
- keyType: serializeZodType(zt.def.keyType),
418
- valueType: serializeZodType(zt.def.valueType)
419
- };
420
- case "union":
421
- return {
422
- type: "union",
423
- options: zt.def.options.map((option)=>serializeZodType(option))
424
- };
425
- default:
426
- throw new Error(`Serialize 로직이 정의되지 않은 ZodType: ${zt.def.type}`);
427
- }
243
+ /**
244
+ * ApiParam 배열을 TypeScript 함수 파라미터 코드로 변환합니다.
245
+ * 예: "name: string, age?: number, active: boolean = true"
246
+ */ export function apiParamToTsCode(params, injectImportKeys) {
247
+ return params.map((param)=>{
248
+ return `${param.name}${param.optional && !param.defaultDef ? "?" : ""}: ${apiParamTypeToTsType(param.type, injectImportKeys)}${param.defaultDef ? `= ${param.defaultDef}` : ""}`;
249
+ }).join(", ");
428
250
  }
429
- // TODO(Haze, 251031): "template_literal", "file"에 대한 지원이 필요함.
430
- export function zodTypeToTsTypeDef(zt) {
431
- switch(zt.def.type){
432
- case "string":
433
- case "number":
434
- case "boolean":
435
- case "bigint":
436
- case "date":
437
- case "null":
438
- case "undefined":
439
- case "any":
440
- case "unknown":
441
- case "never":
442
- return zt.def.type;
443
- case "nullable":
444
- return zodTypeToTsTypeDef(zt.def.innerType) + " | null";
445
- case "default":
446
- return zodTypeToTsTypeDef(zt.def.innerType);
447
- case "record":
448
- const recordType = zt;
449
- return `{ [ key: ${zodTypeToTsTypeDef(recordType.def.keyType)} ]: ${zodTypeToTsTypeDef(recordType.def.valueType)}}`;
450
- case "literal":
451
- return Array.from(zt.values).map((value)=>{
452
- if (typeof value === "string") {
453
- return `"${value}"`;
454
- }
455
- if (value === null) {
456
- return `null`;
457
- }
458
- if (value === undefined) {
459
- return `undefined`;
460
- }
461
- return `${value}`;
462
- }).join(" | ");
463
- case "union":
464
- return `${zt.options.map((option)=>zodTypeToTsTypeDef(option)).join(" | ")}`;
465
- case "enum":
466
- return `${zt.options.map((val)=>`"${val}"`).join(" | ")}`;
467
- case "array":
468
- return `${zodTypeToTsTypeDef(zt.element)}[]`;
469
- case "object":
470
- const shape = zt.shape;
471
- return [
472
- "{",
473
- ...Object.keys(shape).map((key)=>{
474
- if (shape[key].def.type === "optional") {
475
- return `${key}?: ${zodTypeToTsTypeDef(shape[key].def.innerType)},`;
476
- } else {
477
- return `${key}: ${zodTypeToTsTypeDef(shape[key])},`;
478
- }
479
- }),
480
- "}"
481
- ].join("\n");
482
- case "optional":
483
- return zodTypeToTsTypeDef(zt.def.innerType) + " | undefined";
484
- default:
485
- throw new Error(`처리되지 않은 ZodType ${zt.def.type}`);
486
- }
251
+ /**
252
+ * ApiParam 배열을 TypeScript 객체 타입 코드로 변환합니다.
253
+ * 예: "{ name: string, age?: number, active: boolean = true }"
254
+ */ export function apiParamToTsCodeAsObject(params, injectImportKeys) {
255
+ return `{ ${params.map((param)=>`${param.name}${param.optional ? "?" : ""}: ${apiParamTypeToTsType(param.type, injectImportKeys)}${param.defaultDef ? `= ${param.defaultDef}` : ""}`).join(", ")} }`;
487
256
  }
488
257
 
489
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvY29kZS1jb252ZXJ0ZXJzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgdHlwZSB7ICRab2RMb29zZVNoYXBlIH0gZnJvbSBcInpvZC92NC9jb3JlXCJcbmltcG9ydCB7XG4gIEFwaVBhcmFtLFxuICBBcGlQYXJhbVR5cGUsXG4gIEVudGl0eVByb3AsXG4gIEVudGl0eVByb3BOb2RlLFxuICBUZXh0UHJvcCxcbiAgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AsXG4gIGlzQmlnSW50ZWdlclByb3AsXG4gIGlzQm9vbGVhblByb3AsXG4gIGlzRGF0ZVByb3AsXG4gIGlzRGF0ZVRpbWVQcm9wLFxuICBpc0RlY2ltYWxQcm9wLFxuICBpc0RvdWJsZVByb3AsXG4gIGlzRW51bVByb3AsXG4gIGlzRmxvYXRQcm9wLFxuICBpc0ludGVnZXJQcm9wLFxuICBpc0pzb25Qcm9wLFxuICBpc09uZVRvT25lUmVsYXRpb25Qcm9wLFxuICBpc1JlbGF0aW9uUHJvcCxcbiAgaXNTdHJpbmdQcm9wLFxuICBpc1RleHRQcm9wLFxuICBpc1RpbWVQcm9wLFxuICBpc1RpbWVzdGFtcFByb3AsXG4gIGlzVXVpZFByb3AsXG4gIGlzVmlydHVhbFByb3AsXG59IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgRXh0ZW5kZWRBcGkgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgdHlwZSB7IGNvcmUgfSBmcm9tIFwiem9kL3Y0XCI7XG5cbi8vIDxhbnk+66W8IOyekOygnO2VmOqzoCwgWm9k7JeQ7IScIOygnOyVve2VmOuKlCDquLDrs7jsoIHsnbggR2VuZXJpYyBUeXBlIFBhcmFtZXRlcuulvCDsgqzsmqntlaguXG50eXBlIEFueVpvZFJlY29yZCA9IHouWm9kUmVjb3JkPHouWm9kU3RyaW5nIHwgei5ab2ROdW1iZXIgfCB6LlpvZFN5bWJvbCwgei5ab2RUeXBlPjtcbnR5cGUgQW55Wm9kT2JqZWN0ID0gei5ab2RPYmplY3Q8JFpvZExvb3NlU2hhcGU+O1xudHlwZSBBbnlab2RBcnJheSA9IHouWm9kQXJyYXk8ei5ab2RUeXBlPjtcbnR5cGUgQW55Wm9kTnVsbGFibGUgPSB6LlpvZE51bGxhYmxlPHouWm9kVHlwZT47XG50eXBlIEFueVpvZE9wdGlvbmFsID0gei5ab2RPcHRpb25hbDx6LlpvZFR5cGU+O1xudHlwZSBBbnlab2REZWZhdWx0ID0gei5ab2REZWZhdWx0PHouWm9kVHlwZT47XG50eXBlIEFueVpvZExpdGVyYWwgPSB6LlpvZExpdGVyYWw8Y29yZS51dGlsLkxpdGVyYWw+O1xudHlwZSBBbnlab2RVbmlvbiA9IHouWm9kVW5pb248ei5ab2RUeXBlW10+O1xuXG4vKlxuICBFeHRlbmRlZEFwaSDsl5DshJwgWm9kT2JqZWN0IOumrO2EtFxuKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRab2RPYmplY3RGcm9tQXBpKFxuICBhcGk6IEV4dGVuZGVkQXBpLFxuICByZWZlcmVuY2VzOiB7XG4gICAgW2lkOiBzdHJpbmddOiBBbnlab2RPYmplY3Q7XG4gIH0gPSB7fVxuKSB7XG4gIGlmIChhcGkudHlwZVBhcmFtZXRlcnM/Lmxlbmd0aCA+IDApIHtcbiAgICBhcGkudHlwZVBhcmFtZXRlcnMubWFwKCh0eXBlUGFyYW0pID0+IHtcbiAgICAgIGlmICh0eXBlUGFyYW0uY29uc3RyYWludCkge1xuICAgICAgICBsZXQgem9kVHlwZSA9IGdldFpvZFR5cGVGcm9tQXBpUGFyYW1UeXBlKFxuICAgICAgICAgIHR5cGVQYXJhbS5jb25zdHJhaW50LFxuICAgICAgICAgIHJlZmVyZW5jZXNcbiAgICAgICAgKTtcbiAgICAgICAgKHJlZmVyZW5jZXNbdHlwZVBhcmFtLmlkXSBhcyBhbnkpID0gem9kVHlwZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IFJlcVR5cGUgPSBnZXRab2RPYmplY3RGcm9tQXBpUGFyYW1zKFxuICAgIGFwaS5wYXJhbWV0ZXJzLmZpbHRlcihcbiAgICAgIChwYXJhbSkgPT5cbiAgICAgICAgIUFwaVBhcmFtVHlwZS5pc0NvbnRleHQocGFyYW0udHlwZSkgJiZcbiAgICAgICAgIUFwaVBhcmFtVHlwZS5pc1JlZktuZXgocGFyYW0udHlwZSkgJiZcbiAgICAgICAgIShwYXJhbS5vcHRpb25hbCA9PT0gdHJ1ZSAmJiBwYXJhbS5uYW1lLnN0YXJ0c1dpdGgoXCJfXCIpKSAvLyBf66GcIOyLnOyeke2VmOuKlCDtjIzrnbzrr7jthLDripQg7KCc7Jm4XG4gICAgKSxcbiAgICByZWZlcmVuY2VzXG4gICk7XG4gIHJldHVybiBSZXFUeXBlO1xufVxuXG4vKlxuICBab2RPYmplY3Trpbwg7Ya17ZW0IEFwaVBhcmFtIOumrO2EtFxuKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRab2RPYmplY3RGcm9tQXBpUGFyYW1zKFxuICBhcGlQYXJhbXM6IEFwaVBhcmFtW10sXG4gIHJlZmVyZW5jZXM6IHtcbiAgICBbaWQ6IHN0cmluZ106IEFueVpvZE9iamVjdDtcbiAgfSA9IHt9XG4pOiB6LlpvZE9iamVjdCB7XG4gIHJldHVybiB6Lm9iamVjdChcbiAgICBhcGlQYXJhbXMucmVkdWNlKChyLCBwYXJhbSkgPT4ge1xuICAgICAgbGV0IHpvZFR5cGUgPSBnZXRab2RUeXBlRnJvbUFwaVBhcmFtVHlwZShwYXJhbS50eXBlLCByZWZlcmVuY2VzKTtcbiAgICAgIGlmIChwYXJhbS5vcHRpb25hbCkge1xuICAgICAgICB6b2RUeXBlID0gem9kVHlwZS5vcHRpb25hbCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ucixcbiAgICAgICAgW3BhcmFtLm5hbWVdOiB6b2RUeXBlLFxuICAgICAgfTtcbiAgICB9LCB7fSlcbiAgKTtcbn1cblxuLypcbiAgQXBpUGFyYW1UeXBl7Jy866GcIFpvZFR5cGUg7Luo67KE7YyFXG4qL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFpvZFR5cGVGcm9tQXBpUGFyYW1UeXBlKFxuICBwYXJhbVR5cGU6IEFwaVBhcmFtVHlwZSxcbiAgcmVmZXJlbmNlczoge1xuICAgIFtpZDogc3RyaW5nXTogQW55Wm9kT2JqZWN0O1xuICB9XG4pOiB6LlpvZFR5cGU8dW5rbm93bj4ge1xuICBzd2l0Y2ggKHBhcmFtVHlwZSkge1xuICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICAgIHJldHVybiB6LnN0cmluZygpO1xuICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgIHJldHVybiB6Lm51bWJlcigpO1xuICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICByZXR1cm4gei5ib29sZWFuKCk7XG4gICAgZGVmYXVsdDpcbiAgICAgIGNvbnN0IGFkdlR5cGUgPSBwYXJhbVR5cGUgYXMgeyB0OiBzdHJpbmcgfTtcbiAgICAgIHN3aXRjaCAoYWR2VHlwZS50KSB7XG4gICAgICAgIGNhc2UgXCJzdHJpbmctbGl0ZXJhbFwiOlxuICAgICAgICBjYXNlIFwibnVtZXJpYy1saXRlcmFsXCI6XG4gICAgICAgICAgcmV0dXJuIHoubGl0ZXJhbCgoYWR2VHlwZSBhcyBhbnkpLnZhbHVlKTtcbiAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgIGNvbnN0IG9ialR5cGUgPSBwYXJhbVR5cGUgYXMgeyB0OiBzdHJpbmc7IHByb3BzOiBBcGlQYXJhbVtdIH07XG4gICAgICAgICAgcmV0dXJuIGdldFpvZE9iamVjdEZyb21BcGlQYXJhbXMob2JqVHlwZS5wcm9wcyk7XG4gICAgICAgIGNhc2UgXCJhcnJheVwiOlxuICAgICAgICAgIGNvbnN0IGFyclR5cGUgPSBwYXJhbVR5cGUgYXMge1xuICAgICAgICAgICAgdDogc3RyaW5nO1xuICAgICAgICAgICAgZWxlbWVudHNUeXBlOiBBcGlQYXJhbVR5cGU7XG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXR1cm4gei5hcnJheShcbiAgICAgICAgICAgIGdldFpvZFR5cGVGcm9tQXBpUGFyYW1UeXBlKGFyclR5cGUuZWxlbWVudHNUeXBlLCByZWZlcmVuY2VzKVxuICAgICAgICAgICk7XG4gICAgICAgIGNhc2UgXCJyZWZcIjpcbiAgICAgICAgICBjb25zdCByZWZUeXBlID0gcGFyYW1UeXBlIGFzIHtcbiAgICAgICAgICAgIHQ6IHN0cmluZztcbiAgICAgICAgICAgIGlkOiBzdHJpbmc7XG4gICAgICAgICAgICBhcmdzPzogQXBpUGFyYW1UeXBlW107XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8vIERhdGUg7YOA7J6FIOyymOumrFxuICAgICAgICAgIGlmIChyZWZUeXBlLmlkID09PSBcIkRhdGVcIikge1xuICAgICAgICAgICAgcmV0dXJuIHouZGF0ZSgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIOqwneyytCDtgqQg6rSA66asIOycoO2LuOumrO2LsFxuICAgICAgICAgIGlmIChbXCJQaWNrXCIsIFwiT21pdFwiXS5pbmNsdWRlcyhyZWZUeXBlLmlkKSkge1xuICAgICAgICAgICAgaWYgKHJlZlR5cGUuYXJncz8ubGVuZ3RoICE9PSAyKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7J6Y66q765CcICR7cmVmVHlwZS5pZH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IFtvYmosIGxpdGVyYWxPclVuaW9uXSA9IHJlZlR5cGUuYXJncyEubWFwKChhcmcpID0+XG4gICAgICAgICAgICAgIGdldFpvZFR5cGVGcm9tQXBpUGFyYW1UeXBlKGFyZywgcmVmZXJlbmNlcylcbiAgICAgICAgICAgICkgYXMgW0FueVpvZE9iamVjdCwgei5ab2RVbmlvbjxhbnk+IHwgQW55Wm9kTGl0ZXJhbF07XG4gICAgICAgICAgICBsZXQga2V5czogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgICAgIGlmIChsaXRlcmFsT3JVbmlvbiBpbnN0YW5jZW9mIHouWm9kVW5pb24pIHtcbiAgICAgICAgICAgICAga2V5cyA9IGxpdGVyYWxPclVuaW9uLmRlZi5vcHRpb25zLm1hcChcbiAgICAgICAgICAgICAgICAob3B0aW9uOiB7IGRlZjogeyB2YWx1ZTogc3RyaW5nIH0gfSkgPT4gb3B0aW9uLmRlZi52YWx1ZVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAga2V5cyA9IChsaXRlcmFsT3JVbmlvbiBhcyB6LlpvZExpdGVyYWw8c3RyaW5nPikuZGVmLnZhbHVlcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGtleVJlY29yZCA9IGtleXMucmVkdWNlKChyZXN1bHQsIGtleSkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAgICAgICAgICAgICBba2V5XTogdHJ1ZSxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0sIHt9IGFzIGFueSk7XG5cbiAgICAgICAgICAgIGlmIChyZWZUeXBlLmlkID09PSBcIlBpY2tcIikge1xuICAgICAgICAgICAgICBpZiAob2JqLnBpY2spIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqLnBpY2soa2V5UmVjb3JkKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKG9iai5vbWl0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iai5vbWl0KGtleVJlY29yZCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKFtcIlBhcnRpYWxcIl0uaW5jbHVkZXMocmVmVHlwZS5pZCkpIHtcbiAgICAgICAgICAgIGlmIChyZWZUeXBlLmFyZ3M/Lmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOyemOuqu+uQnCAke3JlZlR5cGUuaWR9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBvYmogPSBnZXRab2RUeXBlRnJvbUFwaVBhcmFtVHlwZShyZWZUeXBlLmFyZ3NbMF0sIHJlZmVyZW5jZXMpO1xuICAgICAgICAgICAgcmV0dXJuIChvYmogYXMgYW55KS5wYXJ0aWFsKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcmVmZXJlbmNlID0gcmVmZXJlbmNlc1tyZWZUeXBlLmlkXTtcbiAgICAgICAgICBpZiAocmVmZXJlbmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB6LnN0cmluZygpO1xuICAgICAgICAgICAgLy8gdGhyb3cgbmV3IEVycm9yKGByZWYg7LC47KGwIOu2iOqwgCAke3JlZlR5cGUuaWR9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiByZWZlcmVuY2U7XG4gICAgICAgIGNhc2UgXCJ1bmlvblwiOlxuICAgICAgICAgIGNvbnN0IHVuaW9uVHlwZSA9IHBhcmFtVHlwZSBhcyB7XG4gICAgICAgICAgICB0OiBzdHJpbmc7XG4gICAgICAgICAgICB0eXBlczogQXBpUGFyYW1UeXBlW107XG4gICAgICAgICAgfTtcbiAgICAgICAgICAvLyBudWxsYWJsZSDsnKDri4jsmKhcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB1bmlvblR5cGUudHlwZXMubGVuZ3RoID09PSAyICYmXG4gICAgICAgICAgICB1bmlvblR5cGUudHlwZXMuc29tZSgodHlwZSkgPT4gdHlwZSA9PT0gXCJudWxsXCIpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBpZiAodW5pb25UeXBlLnR5cGVzWzBdID09PSBcIm51bGxcIikge1xuICAgICAgICAgICAgICByZXR1cm4gZ2V0Wm9kVHlwZUZyb21BcGlQYXJhbVR5cGUoXG4gICAgICAgICAgICAgICAgdW5pb25UeXBlLnR5cGVzWzFdLFxuICAgICAgICAgICAgICAgIHJlZmVyZW5jZXNcbiAgICAgICAgICAgICAgKS5udWxsYWJsZSgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGdldFpvZFR5cGVGcm9tQXBpUGFyYW1UeXBlKFxuICAgICAgICAgICAgICAgIHVuaW9uVHlwZS50eXBlc1swXSxcbiAgICAgICAgICAgICAgICByZWZlcmVuY2VzXG4gICAgICAgICAgICAgICkubnVsbGFibGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyDsnbzrsJgg7Jyg64uI7JioXG4gICAgICAgICAgcmV0dXJuIHoudW5pb24oXG4gICAgICAgICAgICB1bmlvblR5cGUudHlwZXMubWFwKCh0eXBlKSA9PlxuICAgICAgICAgICAgICBnZXRab2RUeXBlRnJvbUFwaVBhcmFtVHlwZSh0eXBlLCByZWZlcmVuY2VzKVxuICAgICAgICAgICAgKSBhcyBhbnlcbiAgICAgICAgICApO1xuICAgICAgICBjYXNlIFwiaW50ZXJzZWN0aW9uXCI6XG4gICAgICAgICAgY29uc3QgaW50ZXJzZWN0aW9uVHlwZSA9IHBhcmFtVHlwZSBhcyB7XG4gICAgICAgICAgICB0OiBzdHJpbmc7XG4gICAgICAgICAgICB0eXBlczogQXBpUGFyYW1UeXBlW107XG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXR1cm4gaW50ZXJzZWN0aW9uVHlwZS50eXBlcy5yZWR1Y2UoKHJlc3VsdCwgdHlwZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc29sdmVkVHlwZSA9IGdldFpvZFR5cGVGcm9tQXBpUGFyYW1UeXBlKHR5cGUsIHJlZmVyZW5jZXMpO1xuICAgICAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlZFR5cGU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gei5pbnRlcnNlY3Rpb24ocmVzdWx0IGFzIGFueSwgcmVzb2x2ZWRUeXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LCB6LnVua25vd24oKSBhcyBhbnkpIGFzIGFueTtcbiAgICAgICAgY2FzZSBcInR1cGxlLXR5cGVcIjpcbiAgICAgICAgICBjb25zdCB0dXBsZVR5cGUgPSBwYXJhbVR5cGUgYXMgQXBpUGFyYW1UeXBlLlR1cGxlVHlwZTtcbiAgICAgICAgICByZXR1cm4gei50dXBsZShcbiAgICAgICAgICAgIHR1cGxlVHlwZS5lbGVtZW50cy5tYXAoKGVsZW0pID0+XG4gICAgICAgICAgICAgIGdldFpvZFR5cGVGcm9tQXBpUGFyYW1UeXBlKGVsZW0sIHJlZmVyZW5jZXMpXG4gICAgICAgICAgICApIGFzIGFueVxuICAgICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gei51bmtub3duKCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByb3BOb2RlVG9ab2RUeXBlRGVmKFxuICBwcm9wTm9kZTogRW50aXR5UHJvcE5vZGUsXG4gIGluamVjdEltcG9ydEtleXM6IHN0cmluZ1tdXG4pOiBzdHJpbmcge1xuICBpZiAocHJvcE5vZGUubm9kZVR5cGUgPT09IFwicGxhaW5cIikge1xuICAgIHJldHVybiBwcm9wVG9ab2RUeXBlRGVmKHByb3BOb2RlLnByb3AsIGluamVjdEltcG9ydEtleXMpO1xuICB9IGVsc2UgaWYgKHByb3BOb2RlLm5vZGVUeXBlID09PSBcImFycmF5XCIpIHtcbiAgICByZXR1cm4gW1xuICAgICAgcHJvcE5vZGUucHJvcCA/IGAke3Byb3BOb2RlLnByb3AubmFtZX06IGAgOiBcIlwiLFxuICAgICAgXCJ6LmFycmF5KHoub2JqZWN0KHtcIixcbiAgICAgIHByb3BOb2RlLmNoaWxkcmVuXG4gICAgICAgIC5tYXAoKGNoaWxkUHJvcE5vZGUpID0+XG4gICAgICAgICAgcHJvcE5vZGVUb1pvZFR5cGVEZWYoY2hpbGRQcm9wTm9kZSwgaW5qZWN0SW1wb3J0S2V5cylcbiAgICAgICAgKVxuICAgICAgICAuam9pbihcIlxcblwiKSxcbiAgICAgIFwiXCIsXG4gICAgICBcIn0pKSxcIixcbiAgICBdLmpvaW4oXCJcXG5cIik7XG4gIH0gZWxzZSBpZiAocHJvcE5vZGUubm9kZVR5cGUgPT09IFwib2JqZWN0XCIpIHtcbiAgICByZXR1cm4gW1xuICAgICAgcHJvcE5vZGUucHJvcCA/IGAke3Byb3BOb2RlLnByb3AubmFtZX06IGAgOiBcIlwiLFxuICAgICAgXCJ6Lm9iamVjdCh7XCIsXG4gICAgICBwcm9wTm9kZS5jaGlsZHJlblxuICAgICAgICAubWFwKChjaGlsZFByb3BOb2RlKSA9PlxuICAgICAgICAgIHByb3BOb2RlVG9ab2RUeXBlRGVmKGNoaWxkUHJvcE5vZGUsIGluamVjdEltcG9ydEtleXMpXG4gICAgICAgIClcbiAgICAgICAgLmpvaW4oXCJcXG5cIiksXG4gICAgICBcIlwiLFxuICAgICAgYH0pJHtwcm9wTm9kZS5wcm9wICYmIHByb3BOb2RlLnByb3AubnVsbGFibGUgPyBcIi5udWxsYWJsZSgpXCIgOiBcIlwifSxgLFxuICAgIF0uam9pbihcIlxcblwiKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBFcnJvcjtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGV4dFR5cGVMZW5ndGgodGV4dFR5cGU6IFRleHRQcm9wW1widGV4dFR5cGVcIl0pOiBudW1iZXIge1xuICBzd2l0Y2ggKHRleHRUeXBlKSB7XG4gICAgY2FzZSBcInRleHRcIjpcbiAgICAgIHJldHVybiAxMDI0ICogNjQgLSAxO1xuICAgIGNhc2UgXCJtZWRpdW10ZXh0XCI6XG4gICAgICByZXR1cm4gMTAyNCAqIDEwMjQgKiAxNiAtIDE7XG4gICAgY2FzZSBcImxvbmd0ZXh0XCI6XG4gICAgICByZXR1cm4gMTAyNCAqIDEwMjQgKiAxMDI0ICogNCAtIDE7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByb3BUb1pvZFR5cGVEZWYoXG4gIHByb3A6IEVudGl0eVByb3AsXG4gIGluamVjdEltcG9ydEtleXM6IHN0cmluZ1tdXG4pOiBzdHJpbmcge1xuICBsZXQgc3RtdDogc3RyaW5nO1xuICBpZiAoaXNJbnRlZ2VyUHJvcChwcm9wKSkge1xuICAgIHN0bXQgPSBgJHtwcm9wLm5hbWV9OiB6LmludCgpYDtcbiAgfSBlbHNlIGlmIChpc0JpZ0ludGVnZXJQcm9wKHByb3ApKSB7XG4gICAgc3RtdCA9IGAke3Byb3AubmFtZX06IHouYmlnaW50KClgO1xuICB9IGVsc2UgaWYgKGlzVGV4dFByb3AocHJvcCkpIHtcbiAgICBzdG10ID0gYCR7cHJvcC5uYW1lfTogei5zdHJpbmcoKS5tYXgoJHtnZXRUZXh0VHlwZUxlbmd0aChwcm9wLnRleHRUeXBlKX0pYDtcbiAgfSBlbHNlIGlmIChpc0VudW1Qcm9wKHByb3ApKSB7XG4gICAgc3RtdCA9IGAke3Byb3AubmFtZX06ICR7cHJvcC5pZH1gO1xuICAgIGluamVjdEltcG9ydEtleXMucHVzaChwcm9wLmlkKTtcbiAgfSBlbHNlIGlmIChpc1N0cmluZ1Byb3AocHJvcCkpIHtcbiAgICBzdG10ID0gYCR7cHJvcC5uYW1lfTogei5zdHJpbmcoKS5tYXgoJHtwcm9wLmxlbmd0aH0pYDtcbiAgfSBlbHNlIGlmIChpc0RlY2ltYWxQcm9wKHByb3ApKSB7XG4gICAgc3RtdCA9IGAke3Byb3AubmFtZX06IHouc3RyaW5nKClgO1xuICB9IGVsc2UgaWYgKGlzRmxvYXRQcm9wKHByb3ApIHx8IGlzRG91YmxlUHJvcChwcm9wKSkge1xuICAgIHN0bXQgPSBgJHtwcm9wLm5hbWV9OiB6Lm51bWJlcigpYDtcbiAgfSBlbHNlIGlmIChpc0Jvb2xlYW5Qcm9wKHByb3ApKSB7XG4gICAgc3RtdCA9IGAke3Byb3AubmFtZX06IHouYm9vbGVhbigpYDtcbiAgfSBlbHNlIGlmIChpc0RhdGVQcm9wKHByb3ApKSB7XG4gICAgc3RtdCA9IGAke3Byb3AubmFtZX06IHouc3RyaW5nKCkubGVuZ3RoKDEwKWA7XG4gIH0gZWxzZSBpZiAoaXNUaW1lUHJvcChwcm9wKSkge1xuICAgIHN0bXQgPSBgJHtwcm9wLm5hbWV9OiB6LnN0cmluZygpLmxlbmd0aCg4KWA7XG4gIH0gZWxzZSBpZiAoaXNEYXRlVGltZVByb3AocHJvcCkpIHtcbiAgICBzdG10ID0gYCR7cHJvcC5uYW1lfTogei5kYXRlKClgO1xuICB9IGVsc2UgaWYgKGlzVGltZXN0YW1wUHJvcChwcm9wKSkge1xuICAgIHN0bXQgPSBgJHtwcm9wLm5hbWV9OiB6LmRhdGUoKWA7XG4gIH0gZWxzZSBpZiAoaXNKc29uUHJvcChwcm9wKSkge1xuICAgIHN0bXQgPSBgJHtwcm9wLm5hbWV9OiAke3Byb3AuaWR9YDtcbiAgICBpbmplY3RJbXBvcnRLZXlzLnB1c2gocHJvcC5pZCk7XG4gIH0gZWxzZSBpZiAoaXNVdWlkUHJvcChwcm9wKSkge1xuICAgIHN0bXQgPSBgJHtwcm9wLm5hbWV9OiB6LnV1aWQoKWA7XG4gIH0gZWxzZSBpZiAoaXNWaXJ0dWFsUHJvcChwcm9wKSkge1xuICAgIHN0bXQgPSBgJHtwcm9wLm5hbWV9OiAke3Byb3AuaWR9YDtcbiAgICBpbmplY3RJbXBvcnRLZXlzLnB1c2gocHJvcC5pZCk7XG4gIH0gZWxzZSBpZiAoaXNSZWxhdGlvblByb3AocHJvcCkpIHtcbiAgICBpZiAoXG4gICAgICBpc0JlbG9uZ3NUb09uZVJlbGF0aW9uUHJvcChwcm9wKSB8fFxuICAgICAgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocHJvcCkgJiYgcHJvcC5oYXNKb2luQ29sdW1uKVxuICAgICkge1xuICAgICAgc3RtdCA9IGAke3Byb3AubmFtZX1faWQ6IHouaW50KClgO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyDqt7jsmbggcmVsYXRpb24g7LyA7J207IqkIOygnOyZuFxuICAgICAgcmV0dXJuIGAvLyAke3Byb3AubmFtZX06ICR7cHJvcC5yZWxhdGlvblR5cGV9ICR7cHJvcC53aXRofWA7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBcIi8vIHVuYWJsZSB0byByZXNvbHZlXCI7XG4gIH1cblxuICBpZiAoKHByb3AgYXMgeyB1bnNpZ25lZD86IGJvb2xlYW4gfSkudW5zaWduZWQpIHtcbiAgICBzdG10ICs9IFwiLm5vbm5lZ2F0aXZlKClcIjtcbiAgfVxuICBpZiAocHJvcC5udWxsYWJsZSkge1xuICAgIHN0bXQgKz0gXCIubnVsbGFibGUoKVwiO1xuICB9XG5cbiAgcmV0dXJuIHN0bXQgKyBcIixcIjtcbn1cblxuLy8gVE9ETyhIYXplLCAyNTEwMzEpOiBcInRlbXBsYXRlX2xpdGVyYWxcIiwgXCJmaWxlXCLsl5Ag64yA7ZWcIOyngOybkOydtCDtlYTsmpTtlaguXG5leHBvcnQgZnVuY3Rpb24gem9kVHlwZVRvWm9kQ29kZSh6dDogei5ab2RUeXBlKTogc3RyaW5nIHtcbiAgc3dpdGNoICh6dC5kZWYudHlwZSkge1xuICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICAgIHJldHVybiBcInouc3RyaW5nKClcIjtcbiAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICByZXR1cm4gXCJ6Lm51bWJlcigpXCI7XG4gICAgY2FzZSBcImJpZ2ludFwiOlxuICAgICAgcmV0dXJuIFwiei5iaWdpbnQoKVwiO1xuICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICByZXR1cm4gXCJ6LmJvb2xlYW4oKVwiO1xuICAgIGNhc2UgXCJkYXRlXCI6XG4gICAgICByZXR1cm4gXCJ6LmRhdGUoKVwiO1xuICAgIGNhc2UgXCJudWxsXCI6XG4gICAgICByZXR1cm4gXCJ6Lm51bGwoKVwiO1xuICAgIGNhc2UgXCJ1bmRlZmluZWRcIjpcbiAgICAgIHJldHVybiBcInoudW5kZWZpbmVkKClcIjtcbiAgICBjYXNlIFwiYW55XCI6XG4gICAgICByZXR1cm4gXCJ6LmFueSgpXCI7XG4gICAgY2FzZSBcInVua25vd25cIjpcbiAgICAgIHJldHVybiBcInoudW5rbm93bigpXCI7XG4gICAgY2FzZSBcIm5ldmVyXCI6XG4gICAgICByZXR1cm4gXCJ6Lm5ldmVyKClcIjtcbiAgICBjYXNlIFwibnVsbGFibGVcIjpcbiAgICAgIHJldHVybiB6b2RUeXBlVG9ab2RDb2RlKCh6dCBhcyBBbnlab2ROdWxsYWJsZSkuZGVmLmlubmVyVHlwZSkgKyBcIi5udWxsYWJsZSgpXCI7XG4gICAgY2FzZSBcImRlZmF1bHRcIjpcbiAgICAgIGNvbnN0IHpEZWZhdWx0RGVmID0gKHp0IGFzIEFueVpvZERlZmF1bHQpLmRlZjtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIHpvZFR5cGVUb1pvZENvZGUoekRlZmF1bHREZWYuaW5uZXJUeXBlKSArXG4gICAgICAgIGAuZGVmYXVsdCgke3pEZWZhdWx0RGVmLmRlZmF1bHRWYWx1ZX0pYFxuICAgICAgKTtcbiAgICBjYXNlIFwicmVjb3JkXCI6XG4gICAgICBjb25zdCB6UmVjb3JkRGVmID0gKHp0IGFzIEFueVpvZFJlY29yZCkuZGVmO1xuICAgICAgcmV0dXJuIGB6LnJlY29yZCgke3pvZFR5cGVUb1pvZENvZGUoelJlY29yZERlZi5rZXlUeXBlKX0sICR7em9kVHlwZVRvWm9kQ29kZShcbiAgICAgICAgelJlY29yZERlZi52YWx1ZVR5cGVcbiAgICAgICl9KWA7XG4gICAgY2FzZSBcImxpdGVyYWxcIjpcbiAgICAgIGNvbnN0IGl0ZW1zID0gQXJyYXkuZnJvbSgoenQgYXMgei5ab2RMaXRlcmFsPGFueT4pLnZhbHVlcykubWFwKHZhbHVlID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIHJldHVybiBgXCIke3ZhbHVlfVwiYDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBgbnVsbGA7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiBgdW5kZWZpbmVkYDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBgJHt2YWx1ZX1gO1xuICAgICAgfSk7XG5cbiAgICAgIGlmIChpdGVtcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIGB6LmxpdGVyYWwoJHtpdGVtc1swXX0pYDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBgei5saXRlcmFsKFske2l0ZW1zLmpvaW4oXCIsIFwiKX1dKWA7XG4gICAgY2FzZSBcInVuaW9uXCI6XG4gICAgICByZXR1cm4gYHoudW5pb24oWyR7KHp0IGFzIEFueVpvZFVuaW9uKS5kZWYub3B0aW9uc1xuICAgICAgICAubWFwKChvcHRpb246IHouWm9kVHlwZSkgPT4gem9kVHlwZVRvWm9kQ29kZShvcHRpb24pKVxuICAgICAgICAuam9pbihcIixcIil9XSlgO1xuICAgIGNhc2UgXCJlbnVtXCI6XG4gICAgICAvLyBOT1RFOiB6LmVudW0oW1wiQVwiLCBcIkJcIl0p64+EIHouZW51bSh7IEE6IFwiQVwiLCBCOiBcIkJcIiB9KeuhnCDsspjrpqzrkKguXG4gICAgICByZXR1cm4gYHouZW51bSh7JHtPYmplY3QuZW50cmllcygoenQgYXMgei5ab2RFbnVtKS5kZWYuZW50cmllcylcbiAgICAgICAgLm1hcCgoW2tleSwgdmFsXSkgPT5cbiAgICAgICAgICB0eXBlb2YgdmFsID09PSBcInN0cmluZ1wiID8gYCR7a2V5fTogXCIke3ZhbH1cImAgOiBgJHtrZXl9OiAke3ZhbH1gKVxuICAgICAgICAuam9pbihcIiwgXCIpfX0pYDtcbiAgICBjYXNlIFwiYXJyYXlcIjpcbiAgICAgIHJldHVybiBgei5hcnJheSgke3pvZFR5cGVUb1pvZENvZGUoKHp0IGFzIHouWm9kQXJyYXk8ei5ab2RUeXBlPikuZGVmLmVsZW1lbnQpfSlgO1xuICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgIGNvbnN0IHNoYXBlID0gKHp0IGFzIGFueSkuc2hhcGU7XG4gICAgICByZXR1cm4gW1xuICAgICAgICBcInoub2JqZWN0KHtcIixcbiAgICAgICAgLi4uT2JqZWN0LmtleXMoc2hhcGUpLm1hcChcbiAgICAgICAgICAoa2V5KSA9PiBgJHtrZXl9OiAke3pvZFR5cGVUb1pvZENvZGUoc2hhcGVba2V5XSl9LGBcbiAgICAgICAgKSxcbiAgICAgICAgXCJ9KVwiLFxuICAgICAgXS5qb2luKFwiXFxuXCIpO1xuICAgIGNhc2UgXCJvcHRpb25hbFwiOlxuICAgICAgcmV0dXJuIHpvZFR5cGVUb1pvZENvZGUoKHp0IGFzIHouWm9kT3B0aW9uYWw8ei5ab2RUeXBlPikuZGVmLmlubmVyVHlwZSkgKyBcIi5vcHRpb25hbCgpXCI7XG4gICAgY2FzZSBcImZpbGVcIjpcbiAgICAgIHJldHVybiBgei5maWxlKClgO1xuICAgIGNhc2UgXCJpbnRlcnNlY3Rpb25cIjpcbiAgICAgIGNvbnN0IHpJbnRlcnNlY3Rpb25EZWYgPSAoenQgYXMgei5ab2RJbnRlcnNlY3Rpb248ei5ab2RUeXBlLCB6LlpvZFR5cGU+KS5kZWY7XG4gICAgICByZXR1cm4gYHouaW50ZXJzZWN0aW9uKCR7em9kVHlwZVRvWm9kQ29kZSh6SW50ZXJzZWN0aW9uRGVmLmxlZnQpfSwgJHt6b2RUeXBlVG9ab2RDb2RlKHpJbnRlcnNlY3Rpb25EZWYucmlnaHQpfSlgO1xuICAgIGNhc2UgXCJmaWxlXCI6XG4gICAgICByZXR1cm4gYHouZmlsZSgpYDtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGDsspjrpqzrkJjsp4Ag7JWK7J2AIFpvZFR5cGUgJHt6dC5kZWYudHlwZX1gKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYXBpUGFyYW1Ub1RzQ29kZShcbiAgcGFyYW1zOiBBcGlQYXJhbVtdLFxuICBpbmplY3RJbXBvcnRLZXlzOiBzdHJpbmdbXVxuKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhcmFtc1xuICAgIC5tYXAoKHBhcmFtKSA9PiB7XG4gICAgICByZXR1cm4gYCR7cGFyYW0ubmFtZX0ke1xuICAgICAgICBwYXJhbS5vcHRpb25hbCAmJiAhcGFyYW0uZGVmYXVsdERlZiA/IFwiP1wiIDogXCJcIlxuICAgICAgfTogJHthcGlQYXJhbVR5cGVUb1RzVHlwZShwYXJhbS50eXBlLCBpbmplY3RJbXBvcnRLZXlzKX0ke1xuICAgICAgICBwYXJhbS5kZWZhdWx0RGVmID8gYD0gJHtwYXJhbS5kZWZhdWx0RGVmfWAgOiBcIlwiXG4gICAgICB9YDtcbiAgICB9KVxuICAgIC5qb2luKFwiLCBcIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhcGlQYXJhbVRvVHNDb2RlQXNPYmplY3QoXG4gIHBhcmFtczogQXBpUGFyYW1bXSxcbiAgaW5qZWN0SW1wb3J0S2V5czogc3RyaW5nW11cbik6IHN0cmluZyB7XG4gIHJldHVybiBgeyAke3BhcmFtc1xuICAgIC5tYXAoXG4gICAgICAocGFyYW0pID0+XG4gICAgICAgIGAke3BhcmFtLm5hbWV9JHtwYXJhbS5vcHRpb25hbCA/IFwiP1wiIDogXCJcIn06ICR7YXBpUGFyYW1UeXBlVG9Uc1R5cGUoXG4gICAgICAgICAgcGFyYW0udHlwZSxcbiAgICAgICAgICBpbmplY3RJbXBvcnRLZXlzXG4gICAgICAgICl9JHtwYXJhbS5kZWZhdWx0RGVmID8gYD0gJHtwYXJhbS5kZWZhdWx0RGVmfWAgOiBcIlwifWBcbiAgICApXG4gICAgLmpvaW4oXCIsIFwiKX0gfWA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhcGlQYXJhbVR5cGVUb1RzVHlwZShcbiAgcGFyYW1UeXBlOiBBcGlQYXJhbVR5cGUsXG4gIGluamVjdEltcG9ydEtleXM6IHN0cmluZ1tdXG4pOiBzdHJpbmcge1xuICBpZiAoXG4gICAgW1xuICAgICAgXCJzdHJpbmdcIixcbiAgICAgIFwibnVtYmVyXCIsXG4gICAgICBcImJvb2xlYW5cIixcbiAgICAgIFwidHJ1ZVwiLFxuICAgICAgXCJmYWxzZVwiLFxuICAgICAgXCJudWxsXCIsXG4gICAgICBcInVuZGVmaW5lZFwiLFxuICAgICAgXCJ2b2lkXCIsXG4gICAgICBcImFueVwiLFxuICAgICAgXCJ1bmtub3duXCIsXG4gICAgXS5pbmNsdWRlcyhwYXJhbVR5cGUgYXMgc3RyaW5nKVxuICApIHtcbiAgICByZXR1cm4gcGFyYW1UeXBlIGFzIHN0cmluZztcbiAgfSBlbHNlIGlmIChBcGlQYXJhbVR5cGUuaXNPYmplY3QocGFyYW1UeXBlKSkge1xuICAgIHJldHVybiBgeyAke2FwaVBhcmFtVG9Uc0NvZGUocGFyYW1UeXBlLnByb3BzLCBpbmplY3RJbXBvcnRLZXlzKX0gfWA7XG4gIH0gZWxzZSBpZiAoQXBpUGFyYW1UeXBlLmlzU3RyaW5nTGl0ZXJhbChwYXJhbVR5cGUpKSB7XG4gICAgcmV0dXJuIGBcIiR7cGFyYW1UeXBlLnZhbHVlfVwiYDtcbiAgfSBlbHNlIGlmIChBcGlQYXJhbVR5cGUuaXNOdW1lcmljTGl0ZXJhbChwYXJhbVR5cGUpKSB7XG4gICAgcmV0dXJuIFN0cmluZyhwYXJhbVR5cGUudmFsdWUpO1xuICB9IGVsc2UgaWYgKEFwaVBhcmFtVHlwZS5pc1VuaW9uKHBhcmFtVHlwZSkpIHtcbiAgICByZXR1cm4gcGFyYW1UeXBlLnR5cGVzXG4gICAgICAubWFwKCh0eXBlKSA9PiBhcGlQYXJhbVR5cGVUb1RzVHlwZSh0eXBlLCBpbmplY3RJbXBvcnRLZXlzKSlcbiAgICAgIC5qb2luKFwiIHwgXCIpO1xuICB9IGVsc2UgaWYgKEFwaVBhcmFtVHlwZS5pc0ludGVyc2VjdGlvbihwYXJhbVR5cGUpKSB7XG4gICAgcmV0dXJuIHBhcmFtVHlwZS50eXBlc1xuICAgICAgLm1hcCgodHlwZSkgPT4gYXBpUGFyYW1UeXBlVG9Uc1R5cGUodHlwZSwgaW5qZWN0SW1wb3J0S2V5cykpXG4gICAgICAuam9pbihcIiAmIFwiKTtcbiAgfSBlbHNlIGlmIChBcGlQYXJhbVR5cGUuaXNBcnJheShwYXJhbVR5cGUpKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGFwaVBhcmFtVHlwZVRvVHNUeXBlKHBhcmFtVHlwZS5lbGVtZW50c1R5cGUsIGluamVjdEltcG9ydEtleXMpICsgXCJbXVwiXG4gICAgKTtcbiAgfSBlbHNlIGlmIChBcGlQYXJhbVR5cGUuaXNSZWYocGFyYW1UeXBlKSkge1xuICAgIGlmIChcbiAgICAgIFtcIlBpY2tcIiwgXCJPbWl0XCIsIFwiUHJvbWlzZVwiLCBcIlBhcnRpYWxcIiwgXCJEYXRlXCJdLmluY2x1ZGVzKHBhcmFtVHlwZS5pZCkgPT09XG4gICAgICBmYWxzZVxuICAgICkge1xuICAgICAgLy8gaW1wb3J0S2V5cyDsnbjsoJ3shZhcbiAgICAgIGluamVjdEltcG9ydEtleXMucHVzaChwYXJhbVR5cGUuaWQpO1xuICAgIH1cbiAgICBpZiAocGFyYW1UeXBlLmFyZ3MgPT09IHVuZGVmaW5lZCB8fCBwYXJhbVR5cGUuYXJncy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBwYXJhbVR5cGUuaWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBgJHtwYXJhbVR5cGUuaWR9PCR7cGFyYW1UeXBlLmFyZ3NcbiAgICAgICAgLm1hcCgoYXJnKSA9PiBhcGlQYXJhbVR5cGVUb1RzVHlwZShhcmcsIGluamVjdEltcG9ydEtleXMpKVxuICAgICAgICAuam9pbihcIixcIil9PmA7XG4gICAgfVxuICB9IGVsc2UgaWYgKEFwaVBhcmFtVHlwZS5pc0luZGV4ZWRBY2Nlc3MocGFyYW1UeXBlKSkge1xuICAgIHJldHVybiBgJHthcGlQYXJhbVR5cGVUb1RzVHlwZShcbiAgICAgIHBhcmFtVHlwZS5vYmplY3QsXG4gICAgICBpbmplY3RJbXBvcnRLZXlzXG4gICAgKX1bJHthcGlQYXJhbVR5cGVUb1RzVHlwZShwYXJhbVR5cGUuaW5kZXgsIGluamVjdEltcG9ydEtleXMpfV1gO1xuICB9IGVsc2UgaWYgKEFwaVBhcmFtVHlwZS5pc1R1cGxlVHlwZShwYXJhbVR5cGUpKSB7XG4gICAgcmV0dXJuIGBbICR7cGFyYW1UeXBlLmVsZW1lbnRzLm1hcCgoZWxlbSkgPT5cbiAgICAgIGFwaVBhcmFtVHlwZVRvVHNUeXBlKGVsZW0sIGluamVjdEltcG9ydEtleXMpXG4gICAgKX0gXWA7XG4gIH0gZWxzZSBpZiAoQXBpUGFyYW1UeXBlLmlzVHlwZVBhcmFtKHBhcmFtVHlwZSkpIHtcbiAgICByZXR1cm4gYDwke3BhcmFtVHlwZS5pZH0ke1xuICAgICAgcGFyYW1UeXBlLmNvbnN0cmFpbnRcbiAgICAgICAgPyBgIGV4dGVuZHMgJHthcGlQYXJhbVR5cGVUb1RzVHlwZShcbiAgICAgICAgICAgIHBhcmFtVHlwZS5jb25zdHJhaW50LFxuICAgICAgICAgICAgaW5qZWN0SW1wb3J0S2V5c1xuICAgICAgICAgICl9YFxuICAgICAgICA6IFwiXCJcbiAgICB9PmA7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGByZXNvbHZlIOu2iOqwgCBBcGlQYXJhbVR5cGUgJHtwYXJhbVR5cGV9YCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVud3JhcFByb21pc2VPbmNlKHBhcmFtVHlwZTogQXBpUGFyYW1UeXBlKSB7XG4gIGlmIChBcGlQYXJhbVR5cGUuaXNQcm9taXNlKHBhcmFtVHlwZSkpIHtcbiAgICByZXR1cm4gcGFyYW1UeXBlLmFyZ3MhWzBdO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBwYXJhbVR5cGU7XG4gIH1cbn1cblxuLy8gVE9ETyhIYXplLCAyNTEwMzEpOiBcInRlbXBsYXRlX2xpdGVyYWxcIiwgXCJmaWxlXCLsl5Ag64yA7ZWcIOyngOybkOydtCDtlYTsmpTtlaguXG5leHBvcnQgZnVuY3Rpb24gc2VyaWFsaXplWm9kVHlwZSh6dDogei5ab2RUeXBlKTogYW55IHtcbiAgc3dpdGNoICh6dC5kZWYudHlwZSkge1xuICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgIHNoYXBlOiBPYmplY3Qua2V5cygoenQgYXMgQW55Wm9kT2JqZWN0KS5zaGFwZSkucmVkdWNlKFxuICAgICAgICAgIChyZXN1bHQsIGtleSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgLi4ucmVzdWx0LFxuICAgICAgICAgICAgICBba2V5XTogc2VyaWFsaXplWm9kVHlwZSgoenQgYXMgQW55Wm9kT2JqZWN0KS5zaGFwZVtrZXldKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7fVxuICAgICAgICApLFxuICAgICAgfTtcbiAgICBjYXNlIFwiYXJyYXlcIjpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgICAgZWxlbWVudDogc2VyaWFsaXplWm9kVHlwZSgoenQgYXMgQW55Wm9kQXJyYXkpLmRlZi5lbGVtZW50KSxcbiAgICAgIH07XG4gICAgY2FzZSBcImVudW1cIjpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IFwiZW51bVwiLFxuICAgICAgICB2YWx1ZXM6ICh6dCBhcyB6LlpvZEVudW0pLmRlZi5lbnRyaWVzLFxuICAgICAgfTtcbiAgICBjYXNlIFwic3RyaW5nXCI6XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBjaGVja3M6IHp0LmRlZi5jaGVja3MsXG4gICAgICB9O1xuICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgIGNoZWNrczogenQuZGVmLmNoZWNrcyxcbiAgICAgIH07XG4gICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgICAgfTtcbiAgICBjYXNlIFwibnVsbGFibGVcIjpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnNlcmlhbGl6ZVpvZFR5cGUoKHp0IGFzIEFueVpvZE51bGxhYmxlKS5kZWYuaW5uZXJUeXBlKSxcbiAgICAgICAgbnVsbGFibGU6IHRydWUsXG4gICAgICB9O1xuICAgIGNhc2UgXCJvcHRpb25hbFwiOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uc2VyaWFsaXplWm9kVHlwZSgoenQgYXMgQW55Wm9kT3B0aW9uYWwpLmRlZi5pbm5lclR5cGUpLFxuICAgICAgICBvcHRpb25hbDogdHJ1ZSxcbiAgICAgIH07XG4gICAgY2FzZSBcImFueVwiOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogXCJhbnlcIixcbiAgICAgIH07XG4gICAgY2FzZSBcInJlY29yZFwiOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogXCJyZWNvcmRcIixcbiAgICAgICAga2V5VHlwZTogc2VyaWFsaXplWm9kVHlwZSgoenQgYXMgQW55Wm9kUmVjb3JkKS5kZWYua2V5VHlwZSksXG4gICAgICAgIHZhbHVlVHlwZTogc2VyaWFsaXplWm9kVHlwZSgoenQgYXMgQW55Wm9kUmVjb3JkKS5kZWYudmFsdWVUeXBlKSxcbiAgICAgIH07XG4gICAgY2FzZSBcInVuaW9uXCI6XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBcInVuaW9uXCIsXG4gICAgICAgIG9wdGlvbnM6ICh6dC5kZWYgYXMgQW55Wm9kVW5pb24pLm9wdGlvbnMubWFwKChvcHRpb24pID0+XG4gICAgICAgICAgc2VyaWFsaXplWm9kVHlwZShvcHRpb24pXG4gICAgICAgICksXG4gICAgICB9O1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBTZXJpYWxpemUg66Gc7KeB7J20IOygleydmOuQmOyngCDslYrsnYAgWm9kVHlwZTogJHt6dC5kZWYudHlwZX1gXG4gICAgICApO1xuICB9XG59XG5cbi8vIFRPRE8oSGF6ZSwgMjUxMDMxKTogXCJ0ZW1wbGF0ZV9saXRlcmFsXCIsIFwiZmlsZVwi7JeQIOuMgO2VnCDsp4Dsm5DsnbQg7ZWE7JqU7ZWoLlxuZXhwb3J0IGZ1bmN0aW9uIHpvZFR5cGVUb1RzVHlwZURlZih6dDogei5ab2RUeXBlKTogc3RyaW5nIHtcbiAgc3dpdGNoICh6dC5kZWYudHlwZSkge1xuICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICBjYXNlIFwiYmlnaW50XCI6XG4gICAgY2FzZSBcImRhdGVcIjpcbiAgICBjYXNlIFwibnVsbFwiOlxuICAgIGNhc2UgXCJ1bmRlZmluZWRcIjpcbiAgICBjYXNlIFwiYW55XCI6XG4gICAgY2FzZSBcInVua25vd25cIjpcbiAgICBjYXNlIFwibmV2ZXJcIjpcbiAgICAgIHJldHVybiB6dC5kZWYudHlwZTtcbiAgICBjYXNlIFwibnVsbGFibGVcIjpcbiAgICAgIHJldHVybiB6b2RUeXBlVG9Uc1R5cGVEZWYoKHp0IGFzIEFueVpvZE51bGxhYmxlKS5kZWYuaW5uZXJUeXBlKSArIFwiIHwgbnVsbFwiO1xuICAgIGNhc2UgXCJkZWZhdWx0XCI6XG4gICAgICByZXR1cm4gem9kVHlwZVRvVHNUeXBlRGVmKCh6dCBhcyBBbnlab2REZWZhdWx0KS5kZWYuaW5uZXJUeXBlKTtcbiAgICBjYXNlIFwicmVjb3JkXCI6XG4gICAgICBjb25zdCByZWNvcmRUeXBlID0genQgYXMgQW55Wm9kUmVjb3JkO1xuICAgICAgcmV0dXJuIGB7IFsga2V5OiAke3pvZFR5cGVUb1RzVHlwZURlZihyZWNvcmRUeXBlLmRlZi5rZXlUeXBlKX0gXTogJHt6b2RUeXBlVG9Uc1R5cGVEZWYocmVjb3JkVHlwZS5kZWYudmFsdWVUeXBlKX19YDtcbiAgICBjYXNlIFwibGl0ZXJhbFwiOlxuICAgICAgcmV0dXJuIEFycmF5LmZyb20oKHp0IGFzIHouWm9kTGl0ZXJhbCkudmFsdWVzKS5tYXAodmFsdWUgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgcmV0dXJuIGBcIiR7dmFsdWV9XCJgO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIGBudWxsYDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmV0dXJuIGB1bmRlZmluZWRgO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGAke3ZhbHVlfWA7XG4gICAgICB9KS5qb2luKFwiIHwgXCIpXG4gICAgY2FzZSBcInVuaW9uXCI6XG4gICAgICByZXR1cm4gYCR7KHp0IGFzIEFueVpvZFVuaW9uKS5vcHRpb25zXG4gICAgICAgIC5tYXAoKG9wdGlvbikgPT4gem9kVHlwZVRvVHNUeXBlRGVmKG9wdGlvbikpXG4gICAgICAgIC5qb2luKFwiIHwgXCIpfWA7XG4gICAgY2FzZSBcImVudW1cIjpcbiAgICAgIHJldHVybiBgJHsoenQgYXMgei5ab2RFbnVtKS5vcHRpb25zLm1hcCgodmFsKSA9PiBgXCIke3ZhbH1cImApLmpvaW4oXCIgfCBcIil9YDtcbiAgICBjYXNlIFwiYXJyYXlcIjpcbiAgICAgIHJldHVybiBgJHt6b2RUeXBlVG9Uc1R5cGVEZWYoKHp0IGFzIEFueVpvZEFycmF5KS5lbGVtZW50KX1bXWA7XG4gICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgY29uc3Qgc2hhcGUgPSAoenQgYXMgQW55Wm9kT2JqZWN0KS5zaGFwZTtcbiAgICAgIHJldHVybiBbXG4gICAgICAgIFwie1wiLFxuICAgICAgICAuLi5PYmplY3Qua2V5cyhzaGFwZSkubWFwKChrZXkpID0+IHtcbiAgICAgICAgICBpZiAoc2hhcGVba2V5XS5kZWYudHlwZSA9PT0gXCJvcHRpb25hbFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gYCR7a2V5fT86ICR7em9kVHlwZVRvVHNUeXBlRGVmKHNoYXBlW2tleV0uZGVmLmlubmVyVHlwZSl9LGA7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBgJHtrZXl9OiAke3pvZFR5cGVUb1RzVHlwZURlZihzaGFwZVtrZXldKX0sYDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLFxuICAgICAgICBcIn1cIixcbiAgICAgIF0uam9pbihcIlxcblwiKTtcbiAgICBjYXNlIFwib3B0aW9uYWxcIjpcbiAgICAgIHJldHVybiB6b2RUeXBlVG9Uc1R5cGVEZWYoKHp0IGFzIEFueVpvZE9wdGlvbmFsKS5kZWYuaW5uZXJUeXBlKSArIFwiIHwgdW5kZWZpbmVkXCI7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihg7LKY66as65CY7KeAIOyViuydgCBab2RUeXBlICR7enQuZGVmLnR5cGV9YCk7XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJ6IiwiQXBpUGFyYW1UeXBlIiwiaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AiLCJpc0JpZ0ludGVnZXJQcm9wIiwiaXNCb29sZWFuUHJvcCIsImlzRGF0ZVByb3AiLCJpc0RhdGVUaW1lUHJvcCIsImlzRGVjaW1hbFByb3AiLCJpc0RvdWJsZVByb3AiLCJpc0VudW1Qcm9wIiwiaXNGbG9hdFByb3AiLCJpc0ludGVnZXJQcm9wIiwiaXNKc29uUHJvcCIsImlzT25lVG9PbmVSZWxhdGlvblByb3AiLCJpc1JlbGF0aW9uUHJvcCIsImlzU3RyaW5nUHJvcCIsImlzVGV4dFByb3AiLCJpc1RpbWVQcm9wIiwiaXNUaW1lc3RhbXBQcm9wIiwiaXNVdWlkUHJvcCIsImlzVmlydHVhbFByb3AiLCJnZXRab2RPYmplY3RGcm9tQXBpIiwiYXBpIiwicmVmZXJlbmNlcyIsInR5cGVQYXJhbWV0ZXJzIiwibGVuZ3RoIiwibWFwIiwidHlwZVBhcmFtIiwiY29uc3RyYWludCIsInpvZFR5cGUiLCJnZXRab2RUeXBlRnJvbUFwaVBhcmFtVHlwZSIsImlkIiwiUmVxVHlwZSIsImdldFpvZE9iamVjdEZyb21BcGlQYXJhbXMiLCJwYXJhbWV0ZXJzIiwiZmlsdGVyIiwicGFyYW0iLCJpc0NvbnRleHQiLCJ0eXBlIiwiaXNSZWZLbmV4Iiwib3B0aW9uYWwiLCJuYW1lIiwic3RhcnRzV2l0aCIsImFwaVBhcmFtcyIsIm9iamVjdCIsInJlZHVjZSIsInIiLCJwYXJhbVR5cGUiLCJzdHJpbmciLCJudW1iZXIiLCJib29sZWFuIiwiYWR2VHlwZSIsInQiLCJsaXRlcmFsIiwidmFsdWUiLCJvYmpUeXBlIiwicHJvcHMiLCJhcnJUeXBlIiwiYXJyYXkiLCJlbGVtZW50c1R5cGUiLCJyZWZUeXBlIiwiZGF0ZSIsImluY2x1ZGVzIiwiYXJncyIsIkVycm9yIiwib2JqIiwibGl0ZXJhbE9yVW5pb24iLCJhcmciLCJrZXlzIiwiWm9kVW5pb24iLCJkZWYiLCJvcHRpb25zIiwib3B0aW9uIiwidmFsdWVzIiwia2V5UmVjb3JkIiwicmVzdWx0Iiwia2V5IiwicGljayIsIm9taXQiLCJwYXJ0aWFsIiwicmVmZXJlbmNlIiwidW5kZWZpbmVkIiwidW5pb25UeXBlIiwidHlwZXMiLCJzb21lIiwibnVsbGFibGUiLCJ1bmlvbiIsImludGVyc2VjdGlvblR5cGUiLCJpbmRleCIsInJlc29sdmVkVHlwZSIsImludGVyc2VjdGlvbiIsInVua25vd24iLCJ0dXBsZVR5cGUiLCJ0dXBsZSIsImVsZW1lbnRzIiwiZWxlbSIsInByb3BOb2RlVG9ab2RUeXBlRGVmIiwicHJvcE5vZGUiLCJpbmplY3RJbXBvcnRLZXlzIiwibm9kZVR5cGUiLCJwcm9wVG9ab2RUeXBlRGVmIiwicHJvcCIsImNoaWxkcmVuIiwiY2hpbGRQcm9wTm9kZSIsImpvaW4iLCJnZXRUZXh0VHlwZUxlbmd0aCIsInRleHRUeXBlIiwic3RtdCIsInB1c2giLCJoYXNKb2luQ29sdW1uIiwicmVsYXRpb25UeXBlIiwid2l0aCIsInVuc2lnbmVkIiwiem9kVHlwZVRvWm9kQ29kZSIsInp0IiwiaW5uZXJUeXBlIiwiekRlZmF1bHREZWYiLCJkZWZhdWx0VmFsdWUiLCJ6UmVjb3JkRGVmIiwia2V5VHlwZSIsInZhbHVlVHlwZSIsIml0ZW1zIiwiQXJyYXkiLCJmcm9tIiwiT2JqZWN0IiwiZW50cmllcyIsInZhbCIsImVsZW1lbnQiLCJzaGFwZSIsInpJbnRlcnNlY3Rpb25EZWYiLCJsZWZ0IiwicmlnaHQiLCJhcGlQYXJhbVRvVHNDb2RlIiwicGFyYW1zIiwiZGVmYXVsdERlZiIsImFwaVBhcmFtVHlwZVRvVHNUeXBlIiwiYXBpUGFyYW1Ub1RzQ29kZUFzT2JqZWN0IiwiaXNPYmplY3QiLCJpc1N0cmluZ0xpdGVyYWwiLCJpc051bWVyaWNMaXRlcmFsIiwiU3RyaW5nIiwiaXNVbmlvbiIsImlzSW50ZXJzZWN0aW9uIiwiaXNBcnJheSIsImlzUmVmIiwiaXNJbmRleGVkQWNjZXNzIiwiaXNUdXBsZVR5cGUiLCJpc1R5cGVQYXJhbSIsInVud3JhcFByb21pc2VPbmNlIiwiaXNQcm9taXNlIiwic2VyaWFsaXplWm9kVHlwZSIsImNoZWNrcyIsInpvZFR5cGVUb1RzVHlwZURlZiIsInJlY29yZFR5cGUiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLENBQUMsUUFBUSxNQUFNO0FBRXhCLFNBRUVDLFlBQVksRUFJWkMsMEJBQTBCLEVBQzFCQyxn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
258
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvY29kZS1jb252ZXJ0ZXJzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogY29kZS1jb252ZXJ0ZXJz64qUIEFQSSDtg4DsnoUg7KCV7J2Y65Ok7J2EIFpvZCDqsJ3ssrTrgpggVHlwZVNjcmlwdCDsvZTrk5zroZwg67OA7ZmY7ZWY64qUIO2VqOyImOuTpOydhCDsoJzqs7Xtlanri4jri6QuXG4gKlxuICogMS4gQVBJIOyLnOumrOymiOuTpDpcbiAqIC0gRXh0ZW5kZWRBcGksIEFwaVBhcmFtLCBBcGlQYXJhbVR5cGVcbiAqIC0gQVBJIOuplO2DgOuNsOydtO2EsOulvCDtkZztmITtlZjripQg7YOA7J6FIOygleydmOuTpFxuICpcbiAqIDIuIFpvZE9iamVjdCDrs4DtmZhcbiAqIC0gQVBJIO2DgOyehSDsoJXsnZgg4oaSIFpvZCDtg4DsnoUg7J247Iqk7YS07IqkICjrn7Dtg4DsnoQg67C466as642w7J207IWY7JqpKVxuICogLSBnZXRab2RUeXBlRnJvbUFwaVBhcmFtVHlwZSDihpIgZ2V0Wm9kT2JqZWN0RnJvbUFwaVBhcmFtcyDihpIgZ2V0Wm9kT2JqZWN0RnJvbUFwaVxuICpcbiAqIDMuIFRzVHlwZURlZiDrs4DtmZhcbiAqIC0gQVBJIO2DgOyehSDsoJXsnZgg4oaSIFR5cGVTY3JpcHQg7YOA7J6FIOy9lOuTnCDrrLjsnpDsl7QgKOy9lOuTnCDsg53shLHsmqkpXG4gKiAtIGFwaVBhcmFtVHlwZVRvVHNUeXBlIOKGkiBhcGlQYXJhbVRvVHNDb2RlLCBhcGlQYXJhbVRvVHNDb2RlQXNPYmplY3RcbiAqXG4gKiDssLjqs6A6XG4gKiAtIFpvZFR5cGVEZWYg7IOd7ISxIChab2Qg7L2U65OcIOusuOyekOyXtCk6IHpvZC1jb252ZXJ0ZXIudHPsnZggem9kVHlwZVRvWm9kQ29kZSDsgqzsmqlcbiAqIC0gRW50aXR5UHJvcCDrs4DtmZg6IHpvZC1jb252ZXJ0ZXIudHMg7LC47KGwXG4gKi9cblxuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB0eXBlIHsgY29yZSB9IGZyb20gXCJ6b2QvdjRcIjtcbmltcG9ydCB0eXBlIHsgJFpvZExvb3NlU2hhcGUgfSBmcm9tIFwiem9kL3Y0L2NvcmVcIjtcbmltcG9ydCB7IHR5cGUgQXBpUGFyYW0sIEFwaVBhcmFtVHlwZSB9IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHR5cGUgeyBFeHRlbmRlZEFwaSB9IGZyb20gXCIuL2RlY29yYXRvcnNcIjtcblxuLy8gPGFueT7rpbwg7J6Q7KCc7ZWY6rOgLCBab2Tsl5DshJwg7KCc7JW97ZWY64qUIOq4sOuzuOyggeyduCBHZW5lcmljIFR5cGUgUGFyYW1ldGVy66W8IOyCrOyaqe2VqC5cbnR5cGUgQW55Wm9kT2JqZWN0ID0gei5ab2RPYmplY3Q8JFpvZExvb3NlU2hhcGU+O1xudHlwZSBBbnlab2RMaXRlcmFsID0gei5ab2RMaXRlcmFsPGNvcmUudXRpbC5MaXRlcmFsPjtcblxuLyoqXG4gKiBQcm9taXNlIO2DgOyeheydhCDtlZwg67KIIOyWuOuemO2Vke2VmOyXrCDrgrTrtoAg7YOA7J6F7J2EIOuwmO2ZmO2VqeuLiOuLpC5cbiAqIFByb21pc2XqsIAg7JWE64uMIOqyveyasCDsm5Drs7gg7YOA7J6F7J2EIOq3uOuMgOuhnCDrsJjtmZjtlanri4jri6QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bndyYXBQcm9taXNlT25jZShwYXJhbVR5cGU6IEFwaVBhcmFtVHlwZSkge1xuICBpZiAoQXBpUGFyYW1UeXBlLmlzUHJvbWlzZShwYXJhbVR5cGUpKSB7XG4gICAgcmV0dXJuIHBhcmFtVHlwZS5hcmdzPy5bMF07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHBhcmFtVHlwZTtcbiAgfVxufVxuXG4vKlxuICogQVBJ66W8IOq1rOyEse2VmOuKlCDsmpTshozrk6TsnYQgWm9kT2JqZWN066GcIOuzgO2ZmO2VmOq4sCDsnITtlZwg7ZWo7IiY65Ok7J6F64uI64ukLlxuICovXG5cbi8qKlxuICogQXBpUGFyYW1UeXBl7J2EIFpvZCDtg4DsnoUg7J247Iqk7YS07Iqk66GcIOuzgO2ZmO2VqeuLiOuLpC5cbiAqIHN0cmluZywgbnVtYmVyLCBhcnJheSwgdW5pb24g65OxIOuqqOuToCBBcGlQYXJhbVR5cGXsnYQg7LKY66as7ZWY66mwLFxuICog7Iic7ZmY7LC47KGw6rCAIOuwnOyDne2VmOuKlCDqsr3smrAgei51bmtub3duKCnsnLzroZwgZmFsbGJhY2vtlanri4jri6QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRab2RUeXBlRnJvbUFwaVBhcmFtVHlwZShcbiAgcGFyYW1UeXBlOiBBcGlQYXJhbVR5cGUsXG4gIHJlZmVyZW5jZXM6IHtcbiAgICBbaWQ6IHN0cmluZ106IEFueVpvZE9iamVjdDtcbiAgfSxcbik6IHouWm9kVHlwZTx1bmtub3duPiB7XG4gIHN3aXRjaCAocGFyYW1UeXBlKSB7XG4gICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgcmV0dXJuIHouc3RyaW5nKCk7XG4gICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgcmV0dXJuIHoubnVtYmVyKCk7XG4gICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgIHJldHVybiB6LmJvb2xlYW4oKTtcbiAgICBkZWZhdWx0OiB7XG4gICAgICBjb25zdCBhZHZUeXBlID0gcGFyYW1UeXBlIGFzIHsgdDogc3RyaW5nOyB2YWx1ZT86IHN0cmluZyB8IG51bWJlciB9O1xuICAgICAgc3dpdGNoIChhZHZUeXBlLnQpIHtcbiAgICAgICAgY2FzZSBcInN0cmluZy1saXRlcmFsXCI6XG4gICAgICAgIGNhc2UgXCJudW1lcmljLWxpdGVyYWxcIjpcbiAgICAgICAgICByZXR1cm4gei5saXRlcmFsKGFkdlR5cGUudmFsdWUpO1xuICAgICAgICBjYXNlIFwib2JqZWN0XCI6IHtcbiAgICAgICAgICBjb25zdCBvYmpUeXBlID0gcGFyYW1UeXBlIGFzIHsgdDogc3RyaW5nOyBwcm9wczogQXBpUGFyYW1bXSB9O1xuICAgICAgICAgIHJldHVybiBnZXRab2RPYmplY3RGcm9tQXBpUGFyYW1zKG9ialR5cGUucHJvcHMpO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJhcnJheVwiOiB7XG4gICAgICAgICAgY29uc3QgYXJyVHlwZSA9IHBhcmFtVHlwZSBhcyB7XG4gICAgICAgICAgICB0OiBzdHJpbmc7XG4gICAgICAgICAgICBlbGVtZW50c1R5cGU6IEFwaVBhcmFtVHlwZTtcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJldHVybiB6LmFycmF5KGdldFpvZFR5cGVGcm9tQXBpUGFyYW1UeXBlKGFyclR5cGUuZWxlbWVudHNUeXBlLCByZWZlcmVuY2VzKSk7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBcInJlZlwiOiB7XG4gICAgICAgICAgY29uc3QgcmVmVHlwZSA9IHBhcmFtVHlwZSBhcyB7XG4gICAgICAgICAgICB0OiBzdHJpbmc7XG4gICAgICAgICAgICBpZDogc3RyaW5nO1xuICAgICAgICAgICAgYXJncz86IEFwaVBhcmFtVHlwZVtdO1xuICAgICAgICAgIH07XG4gICAgICAgICAgLy8gRGF0ZSDtg4DsnoUg7LKY66asXG4gICAgICAgICAgaWYgKHJlZlR5cGUuaWQgPT09IFwiRGF0ZVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gei5kYXRlKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIOqwneyytCDtgqQg6rSA66asIOycoO2LuOumrO2LsFxuICAgICAgICAgIGlmIChbXCJQaWNrXCIsIFwiT21pdFwiXS5pbmNsdWRlcyhyZWZUeXBlLmlkKSkge1xuICAgICAgICAgICAgaWYgKHJlZlR5cGUuYXJncz8ubGVuZ3RoICE9PSAyKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7J6Y66q765CcICR7cmVmVHlwZS5pZH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IFtvYmosIGxpdGVyYWxPclVuaW9uXSA9IHJlZlR5cGUuYXJncy5tYXAoXG4gICAgICAgICAgICAgIChhcmcpID0+IGdldFpvZFR5cGVGcm9tQXBpUGFyYW1UeXBlKGFyZywgcmVmZXJlbmNlcyksXG4gICAgICAgICAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTog7IOd7ISx65CY64qUIFpvZFVuaW9u7J2YIO2DgOyeheydhCDstpTsoIHtlZjquLAg7Ja066Ck7JuAXG4gICAgICAgICAgICApIGFzIFtBbnlab2RPYmplY3QsIHouWm9kVW5pb248YW55PiB8IEFueVpvZExpdGVyYWxdO1xuXG4gICAgICAgICAgICBsZXQga2V5czogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgICAgIGlmIChsaXRlcmFsT3JVbmlvbiBpbnN0YW5jZW9mIHouWm9kVW5pb24pIHtcbiAgICAgICAgICAgICAga2V5cyA9IGxpdGVyYWxPclVuaW9uLmRlZi5vcHRpb25zLm1hcChcbiAgICAgICAgICAgICAgICAob3B0aW9uOiB7IGRlZjogeyB2YWx1ZXM6IHN0cmluZ1tdIH0gfSkgPT4gb3B0aW9uLmRlZi52YWx1ZXNbMF0sXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBrZXlzID0gKGxpdGVyYWxPclVuaW9uIGFzIHouWm9kTGl0ZXJhbDxzdHJpbmc+KS5kZWYudmFsdWVzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qga2V5UmVjb3JkID0gT2JqZWN0LmZyb21FbnRyaWVzKGtleXMubWFwKChrZXkpID0+IFtrZXksIHRydWUgYXMgY29uc3RdKSk7XG4gICAgICAgICAgICBpZiAocmVmVHlwZS5pZCA9PT0gXCJQaWNrXCIpIHtcbiAgICAgICAgICAgICAgaWYgKG9iai5waWNrKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iai5waWNrKGtleVJlY29yZCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmIChvYmoub21pdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvYmoub21pdChrZXlSZWNvcmQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChbXCJQYXJ0aWFsXCJdLmluY2x1ZGVzKHJlZlR5cGUuaWQpKSB7XG4gICAgICAgICAgICBpZiAocmVmVHlwZS5hcmdzPy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDsnpjrqrvrkJwgJHtyZWZUeXBlLmlkfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgb2JqID0gZ2V0Wm9kVHlwZUZyb21BcGlQYXJhbVR5cGUocmVmVHlwZS5hcmdzWzBdLCByZWZlcmVuY2VzKTtcbiAgICAgICAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogUGFydGlhbCDsnbjsiJgg7YOA7J6FIOy6kOyKpO2MhVxuICAgICAgICAgICAgcmV0dXJuIChvYmogYXMgei5ab2RPYmplY3Q8YW55PikucGFydGlhbCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCByZWZlcmVuY2UgPSByZWZlcmVuY2VzW3JlZlR5cGUuaWRdO1xuICAgICAgICAgIGlmIChyZWZlcmVuY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHoudW5rbm93bigpO1xuICAgICAgICAgICAgLy8gdGhyb3cgbmV3IEVycm9yKGByZWYg7LC47KGwIOu2iOqwgCAke3JlZlR5cGUuaWR9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiByZWZlcmVuY2U7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBcInVuaW9uXCI6IHtcbiAgICAgICAgICBjb25zdCB1bmlvblR5cGUgPSBwYXJhbVR5cGUgYXMge1xuICAgICAgICAgICAgdDogc3RyaW5nO1xuICAgICAgICAgICAgdHlwZXM6IEFwaVBhcmFtVHlwZVtdO1xuICAgICAgICAgIH07XG4gICAgICAgICAgLy8gbnVsbGFibGUg7Jyg64uI7JioXG4gICAgICAgICAgaWYgKHVuaW9uVHlwZS50eXBlcy5sZW5ndGggPT09IDIgJiYgdW5pb25UeXBlLnR5cGVzLnNvbWUoKHR5cGUpID0+IHR5cGUgPT09IFwibnVsbFwiKSkge1xuICAgICAgICAgICAgaWYgKHVuaW9uVHlwZS50eXBlc1swXSA9PT0gXCJudWxsXCIpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGdldFpvZFR5cGVGcm9tQXBpUGFyYW1UeXBlKHVuaW9uVHlwZS50eXBlc1sxXSwgcmVmZXJlbmNlcykubnVsbGFibGUoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBnZXRab2RUeXBlRnJvbUFwaVBhcmFtVHlwZSh1bmlvblR5cGUudHlwZXNbMF0sIHJlZmVyZW5jZXMpLm51bGxhYmxlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIOydvOuwmCDsnKDri4jsmKhcbiAgICAgICAgICByZXR1cm4gei51bmlvbihcbiAgICAgICAgICAgIHVuaW9uVHlwZS50eXBlcy5tYXAoKHR5cGUpID0+IGdldFpvZFR5cGVGcm9tQXBpUGFyYW1UeXBlKHR5cGUsIHJlZmVyZW5jZXMpKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJpbnRlcnNlY3Rpb25cIjoge1xuICAgICAgICAgIGNvbnN0IGludGVyc2VjdGlvblR5cGUgPSBwYXJhbVR5cGUgYXMge1xuICAgICAgICAgICAgdDogc3RyaW5nO1xuICAgICAgICAgICAgdHlwZXM6IEFwaVBhcmFtVHlwZVtdO1xuICAgICAgICAgIH07XG4gICAgICAgICAgcmV0dXJuIGludGVyc2VjdGlvblR5cGUudHlwZXMucmVkdWNlKFxuICAgICAgICAgICAgKHJlc3VsdCwgdHlwZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgcmVzb2x2ZWRUeXBlID0gZ2V0Wm9kVHlwZUZyb21BcGlQYXJhbVR5cGUodHlwZSwgcmVmZXJlbmNlcyk7XG4gICAgICAgICAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlZFR5cGU7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHouaW50ZXJzZWN0aW9uKHJlc3VsdCwgcmVzb2x2ZWRUeXBlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHoudW5rbm93bigpIGFzIHouWm9kVHlwZTx1bmtub3duPixcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJ0dXBsZS10eXBlXCI6IHtcbiAgICAgICAgICBjb25zdCB0dXBsZVR5cGUgPSBwYXJhbVR5cGUgYXMgQXBpUGFyYW1UeXBlLlR1cGxlVHlwZTtcbiAgICAgICAgICByZXR1cm4gei50dXBsZShcbiAgICAgICAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTog7IOd7ISx65CY64qUIFpvZFR1cGxl7J2YIO2DgOyeheydhCDstpTsoIHtlZjquLAg7Ja066Ck7JuAXG4gICAgICAgICAgICB0dXBsZVR5cGUuZWxlbWVudHMubWFwKChlbGVtKSA9PiBnZXRab2RUeXBlRnJvbUFwaVBhcmFtVHlwZShlbGVtLCByZWZlcmVuY2VzKSkgYXMgYW55LFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB6LnVua25vd24oKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBBcGlQYXJhbSDrsLDsl7TsnYQgWm9kT2JqZWN066GcIOuzgO2ZmO2VqeuLiOuLpC5cbiAqIOqwgSDtjIzrnbzrr7jthLDsnZggb3B0aW9uYWwg7Jes67aA66W8IOuwmOyYge2VmOyXrCBab2Qg7Iqk7YKk66eI66W8IOyDneyEse2VqeuLiOuLpC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFpvZE9iamVjdEZyb21BcGlQYXJhbXMoXG4gIGFwaVBhcmFtczogQXBpUGFyYW1bXSxcbiAgcmVmZXJlbmNlczoge1xuICAgIFtpZDogc3RyaW5nXTogQW55Wm9kT2JqZWN0O1xuICB9ID0ge30sXG4pOiB6LlpvZE9iamVjdCB7XG4gIHJldHVybiB6Lm9iamVjdChcbiAgICBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBhcGlQYXJhbXMubWFwKChwYXJhbSkgPT4ge1xuICAgICAgICBsZXQgem9kVHlwZSA9IGdldFpvZFR5cGVGcm9tQXBpUGFyYW1UeXBlKHBhcmFtLnR5cGUsIHJlZmVyZW5jZXMpO1xuICAgICAgICBpZiAocGFyYW0ub3B0aW9uYWwpIHtcbiAgICAgICAgICB6b2RUeXBlID0gem9kVHlwZS5vcHRpb25hbCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbcGFyYW0ubmFtZSwgem9kVHlwZV07XG4gICAgICB9KSxcbiAgICApLFxuICApO1xufVxuXG4vKipcbiAqIEV4dGVuZGVkQXBp66W8IFpvZE9iamVjdOuhnCDrs4DtmZjtlanri4jri6QuXG4gKiBUeXBlUGFyYW1ldGVy7JmAIOydvOuwmCDtjIzrnbzrr7jthLDrpbwg7LKY66as7ZWY66mwLFxuICogQ29udGV4dCwgUmVmS25leCwgX+uhnCDsi5zsnpHtlZjripQgb3B0aW9uYWwg7YyM652866+47YSw64qUIOygnOyZuO2VqeuLiOuLpC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFpvZE9iamVjdEZyb21BcGkoXG4gIGFwaTogRXh0ZW5kZWRBcGksXG4gIHJlZmVyZW5jZXM6IHtcbiAgICBbaWQ6IHN0cmluZ106IEFueVpvZE9iamVjdDtcbiAgfSA9IHt9LFxuKSB7XG4gIGlmIChhcGkudHlwZVBhcmFtZXRlcnM/Lmxlbmd0aCA+IDApIHtcbiAgICBmb3IgKGNvbnN0IHR5cGVQYXJhbSBvZiBhcGkudHlwZVBhcmFtZXRlcnMpIHtcbiAgICAgIGlmICh0eXBlUGFyYW0uY29uc3RyYWludCkge1xuICAgICAgICBjb25zdCB6b2RUeXBlID0gZ2V0Wm9kVHlwZUZyb21BcGlQYXJhbVR5cGUodHlwZVBhcmFtLmNvbnN0cmFpbnQsIHJlZmVyZW5jZXMpO1xuICAgICAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IOugiO2NvOufsOyKpCDtg4DsnoUg7LqQ7Iqk7YyFXG4gICAgICAgIChyZWZlcmVuY2VzW3R5cGVQYXJhbS5pZF0gYXMgei5ab2RUeXBlPGFueT4pID0gem9kVHlwZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgY29uc3QgUmVxVHlwZSA9IGdldFpvZE9iamVjdEZyb21BcGlQYXJhbXMoXG4gICAgLy8gYXBpIHBhcnNpbmftlZwg6rKw6rO86rCAIGFwaSBwYXJhbXNcbiAgICBhcGkucGFyYW1ldGVycy5maWx0ZXIoXG4gICAgICAocGFyYW0pID0+XG4gICAgICAgICFBcGlQYXJhbVR5cGUuaXNDb250ZXh0KHBhcmFtLnR5cGUpICYmXG4gICAgICAgICFBcGlQYXJhbVR5cGUuaXNSZWZLbmV4KHBhcmFtLnR5cGUpICYmXG4gICAgICAgICEocGFyYW0ub3B0aW9uYWwgPT09IHRydWUgJiYgcGFyYW0ubmFtZS5zdGFydHNXaXRoKFwiX1wiKSksIC8vIF/roZwg7Iuc7J6R7ZWY64qUIO2MjOudvOuvuO2EsOuKlCDsoJzsmbhcbiAgICApLFxuICAgIHJlZmVyZW5jZXMsXG4gICk7XG4gIHJldHVybiBSZXFUeXBlO1xufVxuXG4vKlxuICogQVBJIO2DgOyehSDsoJXsnZjrpbwgVHlwZVNjcmlwdCDsvZTrk5wg66y47J6Q7Je066GcIOuzgO2ZmO2VmOq4sCDsnITtlZwg7ZWo7IiY65Ok7J6F64uI64ukLlxuICovXG5cbi8qKlxuICogQXBpUGFyYW1UeXBl7J2EIFR5cGVTY3JpcHQg7YOA7J6FIOusuOyekOyXtOuhnCDrs4DtmZjtlanri4jri6QuXG4gKiB1bmlvbiwgaW50ZXJzZWN0aW9uLCBhcnJheSwgcmVmIOuTsSDrqqjrk6Ag7YOA7J6F7J2EIFRTIOusuOuyleycvOuhnCDtkZztmITtlZjrqbAsXG4gKiBpbXBvcnTqsIAg7ZWE7JqU7ZWcIO2DgOyehSBJROuKlCBpbmplY3RJbXBvcnRLZXlz7JeQIOyImOynke2VqeuLiOuLpC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwaVBhcmFtVHlwZVRvVHNUeXBlKHBhcmFtVHlwZTogQXBpUGFyYW1UeXBlLCBpbmplY3RJbXBvcnRLZXlzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIGlmIChcbiAgICBbXG4gICAgICBcInN0cmluZ1wiLFxuICAgICAgXCJudW1iZXJcIixcbiAgICAgIFwiYm9vbGVhblwiLFxuICAgICAgXCJ0cnVlXCIsXG4gICAgICBcImZhbHNlXCIsXG4gICAgICBcIm51bGxcIixcbiAgICAgIFwidW5kZWZpbmVkXCIsXG4gICAgICBcInZvaWRcIixcbiAgICAgIFwiYW55XCIsXG4gICAgICBcInVua25vd25cIixcbiAgICBdLmluY2x1ZGVzKHBhcmFtVHlwZSBhcyBzdHJpbmcpXG4gICkge1xuICAgIHJldHVybiBwYXJhbVR5cGUgYXMgc3RyaW5nO1xuICB9IGVsc2UgaWYgKEFwaVBhcmFtVHlwZS5pc09iamVjdChwYXJhbVR5cGUpKSB7XG4gICAgcmV0dXJuIGB7ICR7YXBpUGFyYW1Ub1RzQ29kZShwYXJhbVR5cGUucHJvcHMsIGluamVjdEltcG9ydEtleXMpfSB9YDtcbiAgfSBlbHNlIGlmIChBcGlQYXJhbVR5cGUuaXNTdHJpbmdMaXRlcmFsKHBhcmFtVHlwZSkpIHtcbiAgICByZXR1cm4gYFwiJHtwYXJhbVR5cGUudmFsdWV9XCJgO1xuICB9IGVsc2UgaWYgKEFwaVBhcmFtVHlwZS5pc051bWVyaWNMaXRlcmFsKHBhcmFtVHlwZSkpIHtcbiAgICByZXR1cm4gU3RyaW5nKHBhcmFtVHlwZS52YWx1ZSk7XG4gIH0gZWxzZSBpZiAoQXBpUGFyYW1UeXBlLmlzVW5pb24ocGFyYW1UeXBlKSkge1xuICAgIHJldHVybiBwYXJhbVR5cGUudHlwZXMubWFwKCh0eXBlKSA9PiBhcGlQYXJhbVR5cGVUb1RzVHlwZSh0eXBlLCBpbmplY3RJbXBvcnRLZXlzKSkuam9pbihcIiB8IFwiKTtcbiAgfSBlbHNlIGlmIChBcGlQYXJhbVR5cGUuaXNJbnRlcnNlY3Rpb24ocGFyYW1UeXBlKSkge1xuICAgIHJldHVybiBwYXJhbVR5cGUudHlwZXMubWFwKCh0eXBlKSA9PiBhcGlQYXJhbVR5cGVUb1RzVHlwZSh0eXBlLCBpbmplY3RJbXBvcnRLZXlzKSkuam9pbihcIiAmIFwiKTtcbiAgfSBlbHNlIGlmIChBcGlQYXJhbVR5cGUuaXNBcnJheShwYXJhbVR5cGUpKSB7XG4gICAgcmV0dXJuIGAke2FwaVBhcmFtVHlwZVRvVHNUeXBlKHBhcmFtVHlwZS5lbGVtZW50c1R5cGUsIGluamVjdEltcG9ydEtleXMpfVtdYDtcbiAgfSBlbHNlIGlmIChBcGlQYXJhbVR5cGUuaXNSZWYocGFyYW1UeXBlKSkge1xuICAgIGlmIChbXCJQaWNrXCIsIFwiT21pdFwiLCBcIlByb21pc2VcIiwgXCJQYXJ0aWFsXCIsIFwiRGF0ZVwiXS5pbmNsdWRlcyhwYXJhbVR5cGUuaWQpID09PSBmYWxzZSkge1xuICAgICAgLy8gaW1wb3J0S2V5cyDsnbjsoJ3shZhcbiAgICAgIGluamVjdEltcG9ydEtleXMucHVzaChwYXJhbVR5cGUuaWQpO1xuICAgIH1cbiAgICBpZiAocGFyYW1UeXBlLmFyZ3MgPT09IHVuZGVmaW5lZCB8fCBwYXJhbVR5cGUuYXJncy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBwYXJhbVR5cGUuaWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBgJHtwYXJhbVR5cGUuaWR9PCR7cGFyYW1UeXBlLmFyZ3NcbiAgICAgICAgLm1hcCgoYXJnKSA9PiBhcGlQYXJhbVR5cGVUb1RzVHlwZShhcmcsIGluamVjdEltcG9ydEtleXMpKVxuICAgICAgICAuam9pbihcIixcIil9PmA7XG4gICAgfVxuICB9IGVsc2UgaWYgKEFwaVBhcmFtVHlwZS5pc0luZGV4ZWRBY2Nlc3MocGFyYW1UeXBlKSkge1xuICAgIHJldHVybiBgJHthcGlQYXJhbVR5cGVUb1RzVHlwZShcbiAgICAgIHBhcmFtVHlwZS5vYmplY3QsXG4gICAgICBpbmplY3RJbXBvcnRLZXlzLFxuICAgICl9WyR7YXBpUGFyYW1UeXBlVG9Uc1R5cGUocGFyYW1UeXBlLmluZGV4LCBpbmplY3RJbXBvcnRLZXlzKX1dYDtcbiAgfSBlbHNlIGlmIChBcGlQYXJhbVR5cGUuaXNUdXBsZVR5cGUocGFyYW1UeXBlKSkge1xuICAgIHJldHVybiBgWyAke3BhcmFtVHlwZS5lbGVtZW50cy5tYXAoKGVsZW0pID0+IGFwaVBhcmFtVHlwZVRvVHNUeXBlKGVsZW0sIGluamVjdEltcG9ydEtleXMpKX0gXWA7XG4gIH0gZWxzZSBpZiAoQXBpUGFyYW1UeXBlLmlzVHlwZVBhcmFtKHBhcmFtVHlwZSkpIHtcbiAgICByZXR1cm4gYDwke3BhcmFtVHlwZS5pZH0ke1xuICAgICAgcGFyYW1UeXBlLmNvbnN0cmFpbnRcbiAgICAgICAgPyBgIGV4dGVuZHMgJHthcGlQYXJhbVR5cGVUb1RzVHlwZShwYXJhbVR5cGUuY29uc3RyYWludCwgaW5qZWN0SW1wb3J0S2V5cyl9YFxuICAgICAgICA6IFwiXCJcbiAgICB9PmA7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGByZXNvbHZlIOu2iOqwgCBBcGlQYXJhbVR5cGUgJHtwYXJhbVR5cGV9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBcGlQYXJhbSDrsLDsl7TsnYQgVHlwZVNjcmlwdCDtlajsiJgg7YyM652866+47YSwIOy9lOuTnOuhnCDrs4DtmZjtlanri4jri6QuXG4gKiDsmIg6IFwibmFtZTogc3RyaW5nLCBhZ2U/OiBudW1iZXIsIGFjdGl2ZTogYm9vbGVhbiA9IHRydWVcIlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBpUGFyYW1Ub1RzQ29kZShwYXJhbXM6IEFwaVBhcmFtW10sIGluamVjdEltcG9ydEtleXM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhcmFtc1xuICAgIC5tYXAoKHBhcmFtKSA9PiB7XG4gICAgICByZXR1cm4gYCR7cGFyYW0ubmFtZX0ke1xuICAgICAgICBwYXJhbS5vcHRpb25hbCAmJiAhcGFyYW0uZGVmYXVsdERlZiA/IFwiP1wiIDogXCJcIlxuICAgICAgfTogJHthcGlQYXJhbVR5cGVUb1RzVHlwZShwYXJhbS50eXBlLCBpbmplY3RJbXBvcnRLZXlzKX0ke1xuICAgICAgICBwYXJhbS5kZWZhdWx0RGVmID8gYD0gJHtwYXJhbS5kZWZhdWx0RGVmfWAgOiBcIlwiXG4gICAgICB9YDtcbiAgICB9KVxuICAgIC5qb2luKFwiLCBcIik7XG59XG5cbi8qKlxuICogQXBpUGFyYW0g67Cw7Je07J2EIFR5cGVTY3JpcHQg6rCd7LK0IO2DgOyehSDsvZTrk5zroZwg67OA7ZmY7ZWp64uI64ukLlxuICog7JiIOiBcInsgbmFtZTogc3RyaW5nLCBhZ2U/OiBudW1iZXIsIGFjdGl2ZTogYm9vbGVhbiA9IHRydWUgfVwiXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcGlQYXJhbVRvVHNDb2RlQXNPYmplY3QocGFyYW1zOiBBcGlQYXJhbVtdLCBpbmplY3RJbXBvcnRLZXlzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIHJldHVybiBgeyAke3BhcmFtc1xuICAgIC5tYXAoXG4gICAgICAocGFyYW0pID0+XG4gICAgICAgIGAke3BhcmFtLm5hbWV9JHtwYXJhbS5vcHRpb25hbCA/IFwiP1wiIDogXCJcIn06ICR7YXBpUGFyYW1UeXBlVG9Uc1R5cGUoXG4gICAgICAgICAgcGFyYW0udHlwZSxcbiAgICAgICAgICBpbmplY3RJbXBvcnRLZXlzLFxuICAgICAgICApfSR7cGFyYW0uZGVmYXVsdERlZiA/IGA9ICR7cGFyYW0uZGVmYXVsdERlZn1gIDogXCJcIn1gLFxuICAgIClcbiAgICAuam9pbihcIiwgXCIpfSB9YDtcbn1cbiJdLCJuYW1lcyI6WyJ6IiwiQXBpUGFyYW1UeXBlIiwidW53cmFwUHJvbWlzZU9uY2UiLCJwYXJhbVR5cGUiLCJpc1Byb21pc2UiLCJhcmdzIiwiZ2V0Wm9kVHlwZUZyb21BcGlQYXJhbVR5cGUiLCJyZWZlcmVuY2VzIiwic3RyaW5nIiwibnVtYmVyIiwiYm9vbGVhbiIsImFkdlR5cGUiLCJ0IiwibGl0ZXJhbCIsInZhbHVlIiwib2JqVHlwZSIsImdldFpvZE9iamVjdEZyb21BcGlQYXJhbXMiLCJwcm9wcyIsImFyclR5cGUiLCJhcnJheSIsImVsZW1lbnRzVHlwZSIsInJlZlR5cGUiLCJpZCIsImRhdGUiLCJpbmNsdWRlcyIsImxlbmd0aCIsIkVycm9yIiwib2JqIiwibGl0ZXJhbE9yVW5pb24iLCJtYXAiLCJhcmciLCJrZXlzIiwiWm9kVW5pb24iLCJkZWYiLCJvcHRpb25zIiwib3B0aW9uIiwidmFsdWVzIiwia2V5UmVjb3JkIiwiT2JqZWN0IiwiZnJvbUVudHJpZXMiLCJrZXkiLCJwaWNrIiwib21pdCIsInBhcnRpYWwiLCJyZWZlcmVuY2UiLCJ1bmRlZmluZWQiLCJ1bmtub3duIiwidW5pb25UeXBlIiwidHlwZXMiLCJzb21lIiwidHlwZSIsIm51bGxhYmxlIiwidW5pb24iLCJpbnRlcnNlY3Rpb25UeXBlIiwicmVkdWNlIiwicmVzdWx0IiwiaW5kZXgiLCJyZXNvbHZlZFR5cGUiLCJpbnRlcnNlY3Rpb24iLCJ0dXBsZVR5cGUiLCJ0dXBsZSIsImVsZW1lbnRzIiwiZWxlbSIsImFwaVBhcmFtcyIsIm9iamVjdCIsInBhcmFtIiwiem9kVHlwZSIsIm9wdGlvbmFsIiwibmFtZSIsImdldFpvZE9iamVjdEZyb21BcGkiLCJhcGkiLCJ0eXBlUGFyYW1ldGVycyIsInR5cGVQYXJhbSIsImNvbnN0cmFpbnQiLCJSZXFUeXBlIiwicGFyYW1ldGVycyIsImZpbHRlciIsImlzQ29udGV4dCIsImlzUmVmS25leCIsInN0YXJ0c1dpdGgiLCJhcGlQYXJhbVR5cGVUb1RzVHlwZSIsImluamVjdEltcG9ydEtleXMiLCJpc09iamVjdCIsImFwaVBhcmFtVG9Uc0NvZGUiLCJpc1N0cmluZ0xpdGVyYWwiLCJpc051bWVyaWNMaXRlcmFsIiwiU3RyaW5nIiwiaXNVbmlvbiIsImpvaW4iLCJpc0ludGVyc2VjdGlvbiIsImlzQXJyYXkiLCJpc1JlZiIsInB1c2giLCJpc0luZGV4ZWRBY2Nlc3MiLCJpc1R1cGxlVHlwZSIsImlzVHlw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