sonamu 0.5.6 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (365) hide show
  1. package/dist/api/base-frame.js +12 -2
  2. package/dist/api/caster.js +66 -2
  3. package/dist/api/code-converters.js +489 -2
  4. package/dist/api/config.d.ts +76 -0
  5. package/dist/api/config.d.ts.map +1 -0
  6. package/dist/api/config.js +32 -0
  7. package/dist/api/context.d.ts +1 -0
  8. package/dist/api/context.d.ts.map +1 -1
  9. package/dist/api/context.js +3 -2
  10. package/dist/api/decorators.d.ts +1 -0
  11. package/dist/api/decorators.d.ts.map +1 -1
  12. package/dist/api/decorators.js +142 -2
  13. package/dist/api/index.js +9 -2
  14. package/dist/api/sonamu.d.ts +8 -22
  15. package/dist/api/sonamu.d.ts.map +1 -1
  16. package/dist/api/sonamu.js +482 -2
  17. package/dist/bin/build-config.d.ts +2 -1
  18. package/dist/bin/build-config.d.ts.map +1 -1
  19. package/dist/bin/build-config.js +12 -2
  20. package/dist/bin/cli-wrapper.js +71 -2
  21. package/dist/bin/cli.js +418 -2
  22. package/dist/bin/hot-hook-register.d.ts +11 -0
  23. package/dist/bin/hot-hook-register.d.ts.map +1 -0
  24. package/dist/bin/hot-hook-register.js +21 -0
  25. package/dist/database/_batch_update.js +78 -2
  26. package/dist/database/base-model.js +247 -2
  27. package/dist/database/code-generator.js +53 -2
  28. package/dist/database/db.d.ts +5 -16
  29. package/dist/database/db.d.ts.map +1 -1
  30. package/dist/database/db.js +132 -2
  31. package/dist/database/knex-plugins/knex-on-duplicate-update.js +39 -2
  32. package/dist/database/puri-wrapper.d.ts +22 -10
  33. package/dist/database/puri-wrapper.d.ts.map +1 -1
  34. package/dist/database/puri-wrapper.js +109 -2
  35. package/dist/database/puri.d.ts +105 -73
  36. package/dist/database/puri.d.ts.map +1 -1
  37. package/dist/database/puri.js +539 -2
  38. package/dist/database/puri.types.d.ts +33 -42
  39. package/dist/database/puri.types.d.ts.map +1 -1
  40. package/dist/database/puri.types.js +3 -2
  41. package/dist/database/transaction-context.d.ts +3 -3
  42. package/dist/database/transaction-context.d.ts.map +1 -1
  43. package/dist/database/transaction-context.js +14 -2
  44. package/dist/database/upsert-builder.js +215 -2
  45. package/dist/entity/entity-manager.d.ts +3 -1
  46. package/dist/entity/entity-manager.d.ts.map +1 -1
  47. package/dist/entity/entity-manager.js +114 -2
  48. package/dist/entity/entity-utils.js +210 -2
  49. package/dist/entity/entity.d.ts.map +1 -1
  50. package/dist/entity/entity.js +651 -2
  51. package/dist/exceptions/error-handler.js +29 -2
  52. package/dist/exceptions/so-exceptions.js +85 -2
  53. package/dist/file-storage/driver.js +79 -2
  54. package/dist/file-storage/file-storage.js +75 -2
  55. package/dist/index.d.ts +2 -0
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +28 -2
  58. package/dist/migration/code-generation.js +558 -2
  59. package/dist/migration/migration-set.js +364 -2
  60. package/dist/migration/migrator.d.ts +0 -9
  61. package/dist/migration/migrator.d.ts.map +1 -1
  62. package/dist/migration/migrator.js +510 -2
  63. package/dist/migration/types.js +3 -2
  64. package/dist/naite/naite.d.ts +12 -0
  65. package/dist/naite/naite.d.ts.map +1 -0
  66. package/dist/naite/naite.js +72 -0
  67. package/dist/stream/index.js +3 -2
  68. package/dist/stream/sse.js +38 -2
  69. package/dist/syncer/api-parser.d.ts +20 -0
  70. package/dist/syncer/api-parser.d.ts.map +1 -0
  71. package/dist/syncer/api-parser.js +229 -0
  72. package/dist/syncer/checksum.d.ts +21 -0
  73. package/dist/syncer/checksum.d.ts.map +1 -0
  74. package/dist/syncer/checksum.js +98 -0
  75. package/dist/syncer/code-generator.d.ts +20 -0
  76. package/dist/syncer/code-generator.d.ts.map +1 -0
  77. package/dist/syncer/code-generator.js +141 -0
  78. package/dist/syncer/entity-operations.d.ts +17 -0
  79. package/dist/syncer/entity-operations.d.ts.map +1 -0
  80. package/dist/syncer/entity-operations.js +58 -0
  81. package/dist/syncer/file-patterns.d.ts +29 -0
  82. package/dist/syncer/file-patterns.d.ts.map +1 -0
  83. package/dist/syncer/file-patterns.js +38 -0
  84. package/dist/syncer/index.d.ts +6 -0
  85. package/dist/syncer/index.d.ts.map +1 -1
  86. package/dist/syncer/index.js +9 -2
  87. package/dist/syncer/module-loader.d.ts +35 -0
  88. package/dist/syncer/module-loader.d.ts.map +1 -0
  89. package/dist/syncer/module-loader.js +82 -0
  90. package/dist/syncer/syncer.d.ts +93 -108
  91. package/dist/syncer/syncer.d.ts.map +1 -1
  92. package/dist/syncer/syncer.js +375 -2
  93. package/dist/template/entity-converter.d.ts +14 -0
  94. package/dist/template/entity-converter.d.ts.map +1 -0
  95. package/dist/template/entity-converter.js +101 -0
  96. package/dist/template/helpers.d.ts +23 -0
  97. package/dist/template/helpers.d.ts.map +1 -0
  98. package/dist/template/helpers.js +64 -0
  99. package/dist/{templates → template/implementations}/entity.template.d.ts +3 -3
  100. package/dist/template/implementations/entity.template.d.ts.map +1 -0
  101. package/dist/template/implementations/entity.template.js +87 -0
  102. package/dist/{templates → template/implementations}/generated.template.d.ts +3 -3
  103. package/dist/template/implementations/generated.template.d.ts.map +1 -0
  104. package/dist/template/implementations/generated.template.js +232 -0
  105. package/dist/{templates → template/implementations}/generated_http.template.d.ts +3 -3
  106. package/dist/template/implementations/generated_http.template.d.ts.map +1 -0
  107. package/dist/template/implementations/generated_http.template.js +131 -0
  108. package/dist/{templates → template/implementations}/generated_sso.template.d.ts +3 -3
  109. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -0
  110. package/dist/template/implementations/generated_sso.template.js +105 -0
  111. package/dist/{templates → template/implementations}/init_types.template.d.ts +3 -3
  112. package/dist/template/implementations/init_types.template.d.ts.map +1 -0
  113. package/dist/template/implementations/init_types.template.js +38 -0
  114. package/dist/template/implementations/model.template.d.ts +17 -0
  115. package/dist/template/implementations/model.template.d.ts.map +1 -0
  116. package/dist/template/implementations/model.template.js +171 -0
  117. package/dist/{templates → template/implementations}/model_test.template.d.ts +3 -3
  118. package/dist/template/implementations/model_test.template.d.ts.map +1 -0
  119. package/dist/template/implementations/model_test.template.js +35 -0
  120. package/dist/{templates → template/implementations}/service.template.d.ts +6 -6
  121. package/dist/template/implementations/service.template.d.ts.map +1 -0
  122. package/dist/template/implementations/service.template.js +193 -0
  123. package/dist/{templates → template/implementations}/view_enums_buttonset.template.d.ts +3 -3
  124. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -0
  125. package/dist/template/implementations/view_enums_buttonset.template.js +31 -0
  126. package/dist/{templates → template/implementations}/view_enums_dropdown.template.d.ts +3 -4
  127. package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -0
  128. package/dist/template/implementations/view_enums_dropdown.template.js +50 -0
  129. package/dist/{templates → template/implementations}/view_enums_select.template.d.ts +3 -3
  130. package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -0
  131. package/dist/template/implementations/view_enums_select.template.js +55 -0
  132. package/dist/{templates → template/implementations}/view_form.template.d.ts +5 -5
  133. package/dist/template/implementations/view_form.template.d.ts.map +1 -0
  134. package/dist/template/implementations/view_form.template.js +337 -0
  135. package/dist/{templates → template/implementations}/view_id_all_select.template.d.ts +3 -3
  136. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -0
  137. package/dist/template/implementations/view_id_all_select.template.js +31 -0
  138. package/dist/{templates → template/implementations}/view_id_async_select.template.d.ts +3 -3
  139. package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -0
  140. package/dist/template/implementations/view_id_async_select.template.js +105 -0
  141. package/dist/{templates → template/implementations}/view_list.template.d.ts +5 -13
  142. package/dist/template/implementations/view_list.template.d.ts.map +1 -0
  143. package/dist/template/implementations/view_list.template.js +465 -0
  144. package/dist/{templates → template/implementations}/view_list_columns.template.d.ts +3 -3
  145. package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -0
  146. package/dist/template/implementations/view_list_columns.template.js +49 -0
  147. package/dist/{templates → template/implementations}/view_search_input.template.d.ts +3 -3
  148. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -0
  149. package/dist/template/implementations/view_search_input.template.js +64 -0
  150. package/dist/template/index.d.ts +5 -0
  151. package/dist/template/index.d.ts.map +1 -0
  152. package/dist/template/index.js +6 -0
  153. package/dist/template/template.d.ts +39 -0
  154. package/dist/template/template.d.ts.map +1 -0
  155. package/dist/template/template.js +47 -0
  156. package/dist/template/zod-converter.d.ts +18 -0
  157. package/dist/template/zod-converter.d.ts.map +1 -0
  158. package/dist/template/zod-converter.js +166 -0
  159. package/dist/testing/_relation-graph.js +80 -2
  160. package/dist/testing/fixture-manager.d.ts.map +1 -1
  161. package/dist/testing/fixture-manager.js +521 -2
  162. package/dist/types/types.d.ts +39 -40
  163. package/dist/types/types.d.ts.map +1 -1
  164. package/dist/types/types.js +289 -2
  165. package/dist/typings/knex.d.js +3 -2
  166. package/dist/utils/async-utils.d.ts +7 -0
  167. package/dist/utils/async-utils.d.ts.map +1 -1
  168. package/dist/utils/async-utils.js +57 -2
  169. package/dist/utils/console-util.d.ts +2 -0
  170. package/dist/utils/console-util.d.ts.map +1 -0
  171. package/dist/utils/console-util.js +6 -0
  172. package/dist/utils/controller.js +26 -2
  173. package/dist/utils/esm-utils.d.ts +45 -0
  174. package/dist/utils/esm-utils.d.ts.map +1 -0
  175. package/dist/utils/esm-utils.js +56 -0
  176. package/dist/utils/fs-utils.js +17 -2
  177. package/dist/utils/lodash-able.js +6 -2
  178. package/dist/utils/model.js +22 -2
  179. package/dist/utils/path-utils.d.ts +89 -0
  180. package/dist/utils/path-utils.d.ts.map +1 -0
  181. package/dist/utils/path-utils.js +60 -0
  182. package/dist/utils/process-utils.d.ts +13 -0
  183. package/dist/utils/process-utils.d.ts.map +1 -0
  184. package/dist/utils/process-utils.js +36 -0
  185. package/dist/utils/sql-parser.js +35 -2
  186. package/dist/utils/utils.d.ts +4 -7
  187. package/dist/utils/utils.d.ts.map +1 -1
  188. package/dist/utils/utils.js +33 -2
  189. package/dist/utils/zod-error.d.ts.map +1 -1
  190. package/dist/utils/zod-error.js +19 -2
  191. package/package.json +21 -9
  192. package/src/api/code-converters.ts +2 -2
  193. package/src/api/config.ts +142 -0
  194. package/src/api/context.ts +1 -0
  195. package/src/api/decorators.ts +15 -5
  196. package/src/api/sonamu.ts +102 -87
  197. package/src/bin/build-config.ts +2 -1
  198. package/src/bin/cli-wrapper.ts +10 -3
  199. package/src/bin/cli.ts +108 -56
  200. package/src/bin/hot-hook-register.ts +22 -0
  201. package/src/database/base-model.ts +1 -1
  202. package/src/database/code-generator.ts +1 -1
  203. package/src/database/db.ts +53 -60
  204. package/src/database/puri-wrapper.ts +104 -26
  205. package/src/database/puri.ts +477 -580
  206. package/src/database/puri.types.ts +111 -201
  207. package/src/database/transaction-context.ts +4 -4
  208. package/src/database/upsert-builder.ts +1 -1
  209. package/src/entity/entity-manager.ts +19 -15
  210. package/src/entity/entity.ts +4 -3
  211. package/src/index.ts +2 -0
  212. package/src/migration/code-generation.ts +1 -1
  213. package/src/migration/migration-set.ts +1 -1
  214. package/src/migration/migrator.ts +23 -152
  215. package/src/naite/naite.ts +70 -0
  216. package/src/syncer/api-parser.ts +299 -0
  217. package/src/syncer/checksum.ts +152 -0
  218. package/src/syncer/code-generator.ts +202 -0
  219. package/src/syncer/entity-operations.ts +68 -0
  220. package/src/syncer/file-patterns.ts +56 -0
  221. package/src/syncer/index.ts +6 -0
  222. package/src/syncer/module-loader.ts +125 -0
  223. package/src/syncer/syncer.ts +363 -1420
  224. package/src/template/entity-converter.ts +123 -0
  225. package/src/template/helpers.ts +84 -0
  226. package/src/{templates → template/implementations}/entity.template.ts +4 -4
  227. package/src/{templates → template/implementations}/generated.template.ts +9 -9
  228. package/src/{templates → template/implementations}/generated_http.template.ts +9 -6
  229. package/src/{templates → template/implementations}/generated_sso.template.ts +7 -7
  230. package/src/{templates → template/implementations}/init_types.template.ts +4 -4
  231. package/src/{templates → template/implementations}/model.template.ts +9 -9
  232. package/src/{templates → template/implementations}/model_test.template.ts +5 -5
  233. package/src/{templates → template/implementations}/service.template.ts +29 -12
  234. package/src/{templates → template/implementations}/view_enums_buttonset.template.ts +3 -3
  235. package/src/{templates → template/implementations}/view_enums_dropdown.template.ts +5 -21
  236. package/src/{templates → template/implementations}/view_enums_select.template.ts +4 -4
  237. package/src/{templates → template/implementations}/view_form.template.ts +11 -13
  238. package/src/{templates → template/implementations}/view_id_all_select.template.ts +3 -3
  239. package/src/{templates → template/implementations}/view_id_async_select.template.ts +3 -3
  240. package/src/{templates → template/implementations}/view_list.template.ts +13 -64
  241. package/src/{templates → template/implementations}/view_list_columns.template.ts +3 -3
  242. package/src/{templates → template/implementations}/view_search_input.template.ts +3 -3
  243. package/src/template/index.ts +4 -0
  244. package/src/template/template.ts +86 -0
  245. package/src/template/zod-converter.ts +219 -0
  246. package/src/testing/fixture-manager.ts +8 -1
  247. package/src/types/types.ts +39 -62
  248. package/src/utils/async-utils.ts +17 -0
  249. package/src/utils/console-util.ts +4 -0
  250. package/src/utils/esm-utils.ts +69 -0
  251. package/src/utils/path-utils.ts +102 -0
  252. package/src/utils/process-utils.ts +46 -0
  253. package/src/utils/sql-parser.ts +1 -1
  254. package/src/utils/utils.ts +14 -40
  255. package/src/utils/zod-error.ts +0 -1
  256. package/dist/api/base-frame.js.map +0 -1
  257. package/dist/api/caster.js.map +0 -1
  258. package/dist/api/code-converters.js.map +0 -1
  259. package/dist/api/context.js.map +0 -1
  260. package/dist/api/decorators.js.map +0 -1
  261. package/dist/api/index.js.map +0 -1
  262. package/dist/api/sonamu.js.map +0 -1
  263. package/dist/bin/build-config.js.map +0 -1
  264. package/dist/bin/cli-wrapper.js.map +0 -1
  265. package/dist/bin/cli.js.map +0 -1
  266. package/dist/database/_batch_update.js.map +0 -1
  267. package/dist/database/base-model.js.map +0 -1
  268. package/dist/database/code-generator.js.map +0 -1
  269. package/dist/database/db.js.map +0 -1
  270. package/dist/database/knex-plugins/knex-on-duplicate-update.js.map +0 -1
  271. package/dist/database/puri-wrapper.js.map +0 -1
  272. package/dist/database/puri.js.map +0 -1
  273. package/dist/database/puri.types.js.map +0 -1
  274. package/dist/database/transaction-context.js.map +0 -1
  275. package/dist/database/upsert-builder.js.map +0 -1
  276. package/dist/entity/entity-manager.js.map +0 -1
  277. package/dist/entity/entity-utils.js.map +0 -1
  278. package/dist/entity/entity.js.map +0 -1
  279. package/dist/exceptions/error-handler.js.map +0 -1
  280. package/dist/exceptions/so-exceptions.js.map +0 -1
  281. package/dist/file-storage/driver.js.map +0 -1
  282. package/dist/file-storage/file-storage.js.map +0 -1
  283. package/dist/index.js.map +0 -1
  284. package/dist/migration/code-generation.js.map +0 -1
  285. package/dist/migration/migration-set.js.map +0 -1
  286. package/dist/migration/migrator.js.map +0 -1
  287. package/dist/migration/types.js.map +0 -1
  288. package/dist/stream/index.js.map +0 -1
  289. package/dist/stream/sse.js.map +0 -1
  290. package/dist/syncer/index.js.map +0 -1
  291. package/dist/syncer/syncer.js.map +0 -1
  292. package/dist/templates/base-template.d.ts +0 -13
  293. package/dist/templates/base-template.d.ts.map +0 -1
  294. package/dist/templates/base-template.js +0 -2
  295. package/dist/templates/base-template.js.map +0 -1
  296. package/dist/templates/entity.template.d.ts.map +0 -1
  297. package/dist/templates/entity.template.js +0 -2
  298. package/dist/templates/entity.template.js.map +0 -1
  299. package/dist/templates/generated.template.d.ts.map +0 -1
  300. package/dist/templates/generated.template.js +0 -2
  301. package/dist/templates/generated.template.js.map +0 -1
  302. package/dist/templates/generated_http.template.d.ts.map +0 -1
  303. package/dist/templates/generated_http.template.js +0 -2
  304. package/dist/templates/generated_http.template.js.map +0 -1
  305. package/dist/templates/generated_sso.template.d.ts.map +0 -1
  306. package/dist/templates/generated_sso.template.js +0 -2
  307. package/dist/templates/generated_sso.template.js.map +0 -1
  308. package/dist/templates/index.d.ts +0 -2
  309. package/dist/templates/index.d.ts.map +0 -1
  310. package/dist/templates/index.js +0 -2
  311. package/dist/templates/index.js.map +0 -1
  312. package/dist/templates/init_types.template.d.ts.map +0 -1
  313. package/dist/templates/init_types.template.js +0 -2
  314. package/dist/templates/init_types.template.js.map +0 -1
  315. package/dist/templates/model.template.d.ts +0 -17
  316. package/dist/templates/model.template.d.ts.map +0 -1
  317. package/dist/templates/model.template.js +0 -2
  318. package/dist/templates/model.template.js.map +0 -1
  319. package/dist/templates/model_test.template.d.ts.map +0 -1
  320. package/dist/templates/model_test.template.js +0 -2
  321. package/dist/templates/model_test.template.js.map +0 -1
  322. package/dist/templates/service.template.d.ts.map +0 -1
  323. package/dist/templates/service.template.js +0 -2
  324. package/dist/templates/service.template.js.map +0 -1
  325. package/dist/templates/view_enums_buttonset.template.d.ts.map +0 -1
  326. package/dist/templates/view_enums_buttonset.template.js +0 -2
  327. package/dist/templates/view_enums_buttonset.template.js.map +0 -1
  328. package/dist/templates/view_enums_dropdown.template.d.ts.map +0 -1
  329. package/dist/templates/view_enums_dropdown.template.js +0 -2
  330. package/dist/templates/view_enums_dropdown.template.js.map +0 -1
  331. package/dist/templates/view_enums_select.template.d.ts.map +0 -1
  332. package/dist/templates/view_enums_select.template.js +0 -2
  333. package/dist/templates/view_enums_select.template.js.map +0 -1
  334. package/dist/templates/view_form.template.d.ts.map +0 -1
  335. package/dist/templates/view_form.template.js +0 -2
  336. package/dist/templates/view_form.template.js.map +0 -1
  337. package/dist/templates/view_id_all_select.template.d.ts.map +0 -1
  338. package/dist/templates/view_id_all_select.template.js +0 -2
  339. package/dist/templates/view_id_all_select.template.js.map +0 -1
  340. package/dist/templates/view_id_async_select.template.d.ts.map +0 -1
  341. package/dist/templates/view_id_async_select.template.js +0 -2
  342. package/dist/templates/view_id_async_select.template.js.map +0 -1
  343. package/dist/templates/view_list.template.d.ts.map +0 -1
  344. package/dist/templates/view_list.template.js +0 -2
  345. package/dist/templates/view_list.template.js.map +0 -1
  346. package/dist/templates/view_list_columns.template.d.ts.map +0 -1
  347. package/dist/templates/view_list_columns.template.js +0 -2
  348. package/dist/templates/view_list_columns.template.js.map +0 -1
  349. package/dist/templates/view_search_input.template.d.ts.map +0 -1
  350. package/dist/templates/view_search_input.template.js +0 -2
  351. package/dist/templates/view_search_input.template.js.map +0 -1
  352. package/dist/testing/_relation-graph.js.map +0 -1
  353. package/dist/testing/fixture-manager.js.map +0 -1
  354. package/dist/types/types.js.map +0 -1
  355. package/dist/typings/knex.d.js.map +0 -1
  356. package/dist/utils/async-utils.js.map +0 -1
  357. package/dist/utils/controller.js.map +0 -1
  358. package/dist/utils/fs-utils.js.map +0 -1
  359. package/dist/utils/lodash-able.js.map +0 -1
  360. package/dist/utils/model.js.map +0 -1
  361. package/dist/utils/sql-parser.js.map +0 -1
  362. package/dist/utils/utils.js.map +0 -1
  363. package/dist/utils/zod-error.js.map +0 -1
  364. package/src/templates/base-template.ts +0 -19
  365. package/src/templates/index.ts +0 -1
@@ -1,2 +1,539 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});function _export(target,all){for(var name in all)Object.defineProperty(target,name,{enumerable:true,get:Object.getOwnPropertyDescriptor(all,name).get})}_export(exports,{get JoinClauseGroup(){return JoinClauseGroup},get Puri(){return Puri}});var _chalk=/*#__PURE__*/_interop_require_default(require("chalk"));function _array_like_to_array(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}function _array_with_holes(arr){if(Array.isArray(arr))return arr}function _array_without_holes(arr){if(Array.isArray(arr))return _array_like_to_array(arr)}function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{Promise.resolve(value).then(_next,_throw)}}function _async_to_generator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(undefined)})}}function _class_call_check(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _create_class(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor}function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _instanceof(left,right){if(right!=null&&typeof Symbol!=="undefined"&&right[Symbol.hasInstance]){return!!right[Symbol.hasInstance](left)}else{return left instanceof right}}function _interop_require_default(obj){return obj&&obj.__esModule?obj:{default:obj}}function _iterable_to_array(iter){if(typeof Symbol!=="undefined"&&iter[Symbol.iterator]!=null||iter["@@iterator"]!=null)return Array.from(iter)}function _iterable_to_array_limit(arr,i){var _i=arr==null?null:typeof Symbol!=="undefined"&&arr[Symbol.iterator]||arr["@@iterator"];if(_i==null)return;var _arr=[];var _n=true;var _d=false;var _s,_e;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"]!=null)_i["return"]()}finally{if(_d)throw _e}}return _arr}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _non_iterable_spread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _sliced_to_array(arr,i){return _array_with_holes(arr)||_iterable_to_array_limit(arr,i)||_unsupported_iterable_to_array(arr,i)||_non_iterable_rest()}function _to_consumable_array(arr){return _array_without_holes(arr)||_iterable_to_array(arr)||_unsupported_iterable_to_array(arr)||_non_iterable_spread()}function _type_of(obj){"@swc/helpers - typeof";return obj&&typeof Symbol!=="undefined"&&obj.constructor===Symbol?"symbol":typeof obj}function _unsupported_iterable_to_array(o,minLen){if(!o)return;if(typeof o==="string")return _array_like_to_array(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(n);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _array_like_to_array(o,minLen)}function _ts_generator(thisArg,body){var f,y,t,_={label:0,sent:function(){if(t[0]&1)throw t[1];return t[1]},trys:[],ops:[]},g=Object.create((typeof Iterator==="function"?Iterator:Object).prototype);return g.next=verb(0),g["throw"]=verb(1),g["return"]=verb(2),typeof Symbol==="function"&&(g[Symbol.iterator]=function(){return this}),g;function verb(n){return function(v){return step([n,v])}}function step(op){if(f)throw new TypeError("Generator is already executing.");while(g&&(g=0,op[0]&&(_=0)),_)try{if(f=1,y&&(t=op[0]&2?y["return"]:op[0]?y["throw"]||((t=y["return"])&&t.call(y),0):y.next)&&!(t=t.call(y,op[1])).done)return t;if(y=0,t)op=[op[0]&2,t.value];switch(op[0]){case 0:case 1:t=op;break;case 4:_.label++;return{value:op[1],done:false};case 5:_.label++;y=op[1];op=[0];continue;case 7:op=_.ops.pop();_.trys.pop();continue;default:if(!(t=_.trys,t=t.length>0&&t[t.length-1])&&(op[0]===6||op[0]===2)){_=0;continue}if(op[0]===3&&(!t||op[1]>t[0]&&op[1]<t[3])){_.label=op[1];break}if(op[0]===6&&_.label<t[1]){_.label=t[1];t=op;break}if(t&&_.label<t[2]){_.label=t[2];_.ops.push(op);break}if(t[2])_.ops.pop();_.trys.pop();continue}op=body.call(thisArg,_)}catch(e){op=[6,e];y=0}finally{f=t=0}if(op[0]&5)throw op[1];return{value:op[0]?op[1]:void 0,done:true}}}var Puri=/*#__PURE__*/function(){"use strict";function Puri(knex,tableNameOrSubquery,alias){_class_call_check(this,Puri);_define_property(this,"knex",void 0);_define_property(this,"knexQuery",void 0);this.knex=knex;if(typeof tableNameOrSubquery==="string"){this.knexQuery=knex(tableNameOrSubquery).from(tableNameOrSubquery)}else{this.knexQuery=knex.from(tableNameOrSubquery.raw().as(alias))}}_create_class(Puri,[{key:"select",value:function select(selectObj){var selectClauses=[];var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=Object.entries(selectObj)[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var _step_value=_sliced_to_array(_step.value,2),alias=_step_value[0],columnOrFunction=_step_value[1];if((typeof columnOrFunction==="undefined"?"undefined":_type_of(columnOrFunction))==="object"&&columnOrFunction._type==="sql_function"){selectClauses.push(this.knex.raw("".concat(columnOrFunction._sql," as ").concat(alias)))}else{var columnPath=columnOrFunction;if(alias===columnPath){selectClauses.push(columnPath)}else{selectClauses.push("".concat(columnPath," as ").concat(alias))}}}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}this.knexQuery.select(selectClauses);return this}},{key:"selectAll",value:function selectAll(){this.knexQuery.select("*");return this}},{key:"where",value:function where(columnOrConditions,operatorOrValue,value){if((typeof columnOrConditions==="undefined"?"undefined":_type_of(columnOrConditions))==="object"){this.knexQuery.where(columnOrConditions)}else if(arguments.length===2){if(operatorOrValue===null){this.knexQuery.whereNull(columnOrConditions);return this}this.knexQuery.where(columnOrConditions,operatorOrValue)}else if(arguments.length===3){if(value===null){if(operatorOrValue==="!="){this.knexQuery.whereNotNull(columnOrConditions);return this}else if(operatorOrValue==="="){this.knexQuery.whereNull(columnOrConditions);return this}}this.knexQuery.where(columnOrConditions,operatorOrValue,value)}else{this.knexQuery.where(columnOrConditions)}return this}},{key:"whereIn",value:function whereIn(column,values){this.knexQuery.whereIn(column,values);return this}},{key:"whereNotIn",value:function whereNotIn(column,values){this.knexQuery.whereNotIn(column,values);return this}},{key:"whereMatch",value:function whereMatch(column,value){this.knexQuery.whereRaw("MATCH (".concat(String(column),") AGAINST (?)"),[value]);return this}},{key:"whereGroup",value:function whereGroup(callback){this.knexQuery.where(function(builder){var group=new WhereGroup(builder);callback(group)});return this}},{key:"orWhereGroup",value:function orWhereGroup(callback){this.knexQuery.orWhere(function(builder){var group=new WhereGroup(builder);callback(group)});return this}},{key:"join",value:function join(tableOrSubquery){for(var _len=arguments.length,args=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){args[_key-1]=arguments[_key]}if(_instanceof(tableOrSubquery,Puri)){var _args=_sliced_to_array(args,3),alias=_args[0],left=_args[1],right=_args[2];this.knexQuery.join(tableOrSubquery.raw().as(alias),left,right)}else if(args.length===2&&typeof args[0]==="string"&&typeof args[1]==="string"){var _args1=_sliced_to_array(args,2),left1=_args1[0],right1=_args1[1];this.knexQuery.join(tableOrSubquery,left1,right1)}else if(args.length===1&&typeof args[0]==="function"){var joinCallback=args[0];this.knexQuery.join(tableOrSubquery,function(joinClause){joinCallback(new JoinClauseGroup(joinClause))})}else{throw new Error("Invalid arguments")}return this}},{key:"leftJoin",value:function leftJoin(tableOrSubquery){for(var _len=arguments.length,args=new Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){args[_key-1]=arguments[_key]}if(_instanceof(tableOrSubquery,Puri)){var _args=_sliced_to_array(args,3),alias=_args[0],left=_args[1],right=_args[2];this.knexQuery.leftJoin(tableOrSubquery.raw().as(alias),left,right)}else{var _args1=_sliced_to_array(args,2),left1=_args1[0],right1=_args1[1];this.knexQuery.leftJoin(tableOrSubquery,left1,right1)}return this}},{key:"orderBy",value:function orderBy(column){var direction=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"asc";this.knexQuery.orderBy(column,direction);return this}},{key:"limit",value:function limit(count){this.knexQuery.limit(count);return this}},{key:"offset",value:function offset(count){this.knexQuery.offset(count);return this}},{key:"groupBy",value:function groupBy(){for(var _len=arguments.length,columns=new Array(_len),_key=0;_key<_len;_key++){columns[_key]=arguments[_key]}var _this_knexQuery;(_this_knexQuery=this.knexQuery).groupBy.apply(_this_knexQuery,_to_consumable_array(columns));return this}},{key:"having",value:function having(){for(var _len=arguments.length,conditions=new Array(_len),_key=0;_key<_len;_key++){conditions[_key]=arguments[_key]}var _this_knexQuery;(_this_knexQuery=this.knexQuery).having.apply(_this_knexQuery,_to_consumable_array(conditions));return this}},{key:"then",value:function then(onfulfilled,onrejected){return this.knexQuery.then(onfulfilled,onrejected)}},{key:"catch",value:function _catch(onrejected){return this.knexQuery.catch(onrejected)}},{key:"finally",value:function _finally(onfinally){return this.knexQuery.finally(onfinally)}},{key:"first",value:function first(){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,this.knexQuery.first()]})}).call(this)}},{key:"firstOrFail",value:function firstOrFail(){return _async_to_generator(function(){var result;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this.knexQuery.first()];case 1:result=_state.sent();if(!result){throw new Error("No results found")}return[2,result]}})}).call(this)}},{key:"at",value:function at(index){return _async_to_generator(function(){var results;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this];case 1:results=_state.sent();return[2,results[index]]}})}).call(this)}},{key:"assertAt",value:function assertAt(index){return _async_to_generator(function(){var results,result;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this];case 1:results=_state.sent();result=results[index];if(result===undefined){throw new Error("No result found at index ".concat(index))}return[2,result]}})}).call(this)}},{key:"pluck",value:function pluck(column){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,this.knexQuery.pluck(column)]})}).call(this)}},{key:"insert",value:function insert(data){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,this.knexQuery.insert(data)]})}).call(this)}},{key:"update",value:function update(data){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,this.knexQuery.update(data)]})}).call(this)}},{key:"delete",value:function _delete(){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,this.knexQuery.delete()]})}).call(this)}},{key:"toQuery",value:function toQuery(){return this.knexQuery.toQuery()}},{key:"debug",value:function debug(){console.log("".concat(_chalk.default.cyan("[Puri Debug]")," ").concat(_chalk.default.yellow(this.formatSQL(this.toQuery()))));return this}},{key:"formatSQL",value:function formatSQL(unformatted){var keywords=["SELECT","FROM","WHERE","INSERT","INTO","VALUES","UPDATE","DELETE","CREATE","TABLE","ALTER","DROP","JOIN","ON","INNER","LEFT","RIGHT","FULL","OUTER","GROUP","BY","ORDER","HAVING","DISTINCT","LIMIT","OFFSET","AS","AND","OR","NOT","IN","LIKE","IS","NULL","CASE","WHEN","THEN","ELSE","END","UNION","ALL","EXISTS","BETWEEN"];var formatted=unformatted;keywords.forEach(function(keyword){var regex=new RegExp("\\b".concat(keyword,"\\b"),"gi");formatted=formatted.replace(regex,keyword.toUpperCase())});var majorClauses=["SELECT","FROM","WHERE","GROUP BY","ORDER BY","HAVING","LIMIT","UNION"];majorClauses.forEach(function(clause){var regex=new RegExp("\\s+(".concat(clause,")\\s+"),"gi");formatted=formatted.replace(regex,"\n".concat(clause.toUpperCase()," "))});formatted=formatted.replace(/\s+((?:INNER|LEFT|RIGHT|FULL OUTER)\s+)?JOIN\s+/gi,"\n$1JOIN ");formatted=formatted.replace(/\s+(AND|OR)\s+/gi,"\n $1 ");var lines=formatted.split("\n");var indentedLines=[];var indentLevel=0;var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=lines[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var line=_step.value;var trimmedLine=line.trim();if(!trimmedLine)continue;var closingParens=(trimmedLine.match(/\)/g)||[]).length;var openingParens=(trimmedLine.match(/\(/g)||[]).length;if(closingParens>0&&openingParens===0){indentLevel=Math.max(0,indentLevel-closingParens)}var indent=" ".repeat(indentLevel);indentedLines.push(indent+trimmedLine);if(openingParens>closingParens){indentLevel+=openingParens-closingParens}}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}return indentedLines.join("\n").trim()}},{key:"raw",value:function raw(){return this.knexQuery}},{key:"increment",value:function increment(column,value){if(value<=0){throw new Error("Increment value must be greater than 0")}this.knexQuery.increment(column,value);return this}},{key:"decrement",value:function decrement(column,value){if(value<=0){throw new Error("Decrement value must be greater than 0")}this.knexQuery.decrement(column,value);return this}}],[{key:"count",value:function count(){var column=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"*";return{_type:"sql_function",_return:"number",_sql:"COUNT(".concat(column,")")}}},{key:"sum",value:function sum(column){return{_type:"sql_function",_return:"number",_sql:"SUM(".concat(column,")")}}},{key:"avg",value:function avg(column){return{_type:"sql_function",_return:"number",_sql:"AVG(".concat(column,")")}}},{key:"max",value:function max(column){return{_type:"sql_function",_return:"number",_sql:"MAX(".concat(column,")")}}},{key:"min",value:function min(column){return{_type:"sql_function",_return:"number",_sql:"MIN(".concat(column,")")}}},{key:"concat",value:function concat(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}return{_type:"sql_function",_return:"string",_sql:"CONCAT(".concat(args.join(", "),")")}}},{key:"upper",value:function upper(column){return{_type:"sql_function",_return:"string",_sql:"UPPER(".concat(column,")")}}},{key:"lower",value:function lower(column){return{_type:"sql_function",_return:"string",_sql:"LOWER(".concat(column,")")}}},{key:"rawString",value:function rawString(sql){return{_type:"sql_function",_return:"string",_sql:sql}}},{key:"rawNumber",value:function rawNumber(sql){return{_type:"sql_function",_return:"number",_sql:sql}}},{key:"rawBoolean",value:function rawBoolean(sql){return{_type:"sql_function",_return:"boolean",_sql:sql}}},{key:"rawDate",value:function rawDate(sql){return{_type:"sql_function",_return:"date",_sql:sql}}}]);return Puri}();var WhereGroup=/*#__PURE__*/function(){"use strict";function WhereGroup(builder){_class_call_check(this,WhereGroup);_define_property(this,"builder",void 0);this.builder=builder}_create_class(WhereGroup,[{key:"where",value:function where(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}var _this_builder;(_this_builder=this.builder).where.apply(_this_builder,[args[0]].concat(_to_consumable_array(args.slice(1))));return this}},{key:"orWhere",value:function orWhere(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}var _this_builder;(_this_builder=this.builder).orWhere.apply(_this_builder,[args[0]].concat(_to_consumable_array(args.slice(1))));return this}},{key:"whereIn",value:function whereIn(column,values){this.builder.whereIn(column,values);return this}},{key:"orWhereIn",value:function orWhereIn(column,values){this.builder.orWhereIn(column,values);return this}},{key:"whereGroup",value:function whereGroup(callback){this.builder.where(function(subBuilder){var subGroup=new WhereGroup(subBuilder);callback(subGroup)});return this}},{key:"orWhereGroup",value:function orWhereGroup(callback){this.builder.orWhere(function(subBuilder){var subGroup=new WhereGroup(subBuilder);callback(subGroup)});return this}}]);return WhereGroup}();var JoinClauseGroup=/*#__PURE__*/function(){"use strict";function JoinClauseGroup(callback){_class_call_check(this,JoinClauseGroup);_define_property(this,"callback",void 0);this.callback=callback}_create_class(JoinClauseGroup,[{key:"on",value:function on(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}var _this_callback;(_this_callback=this.callback).on.apply(_this_callback,_to_consumable_array(args));return this}},{key:"orOn",value:function orOn(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}var _this_callback;(_this_callback=this.callback).orOn.apply(_this_callback,_to_consumable_array(args));return this}}]);return JoinClauseGroup}();
2
- //# sourceMappingURL=puri.js.map
1
+ import chalk from "chalk";
2
+ import assert from "assert";
3
+ import { Naite } from "../naite/naite.js";
4
+ export class Puri {
5
+ knex;
6
+ knexQuery;
7
+ constructor(knex, tableNameOrSpec){
8
+ this.knex = knex;
9
+ if (typeof tableNameOrSpec === "string") {
10
+ // Case: new Puri(knex, "users")
11
+ this.knexQuery = this.knex(tableNameOrSpec).from(tableNameOrSpec);
12
+ } else if (typeof tableNameOrSpec === "object") {
13
+ const entries = Object.entries(tableNameOrSpec);
14
+ if (entries.length !== 1) {
15
+ throw new Error("Table spec must have exactly one entry");
16
+ }
17
+ assert(entries[0]);
18
+ const [alias, spec] = entries[0];
19
+ if (typeof spec === "string") {
20
+ this.knexQuery = this.knex(spec).from({
21
+ [alias]: spec
22
+ });
23
+ } else if (spec instanceof Puri) {
24
+ const subqueryBuilder = spec.raw();
25
+ this.knexQuery = this.knex.from(subqueryBuilder.as(alias));
26
+ } else {
27
+ throw new Error("Invalid table specification");
28
+ }
29
+ } else {
30
+ throw new Error("Invalid table specification");
31
+ }
32
+ }
33
+ // Static SQL helper functions for SELECT
34
+ static count(column = "*") {
35
+ return {
36
+ _type: "sql_expression",
37
+ _return: "number",
38
+ _sql: `COUNT(${column})`
39
+ };
40
+ }
41
+ static sum(column) {
42
+ return {
43
+ _type: "sql_expression",
44
+ _return: "number",
45
+ _sql: `SUM(${column})`
46
+ };
47
+ }
48
+ static avg(column) {
49
+ return {
50
+ _type: "sql_expression",
51
+ _return: "number",
52
+ _sql: `AVG(${column})`
53
+ };
54
+ }
55
+ static max(column) {
56
+ return {
57
+ _type: "sql_expression",
58
+ _return: "number",
59
+ _sql: `MAX(${column})`
60
+ };
61
+ }
62
+ static min(column) {
63
+ return {
64
+ _type: "sql_expression",
65
+ _return: "number",
66
+ _sql: `MIN(${column})`
67
+ };
68
+ }
69
+ static concat(...args) {
70
+ return {
71
+ _type: "sql_expression",
72
+ _return: "string",
73
+ _sql: `CONCAT(${args.join(", ")})`
74
+ };
75
+ }
76
+ static upper(column) {
77
+ return {
78
+ _type: "sql_expression",
79
+ _return: "string",
80
+ _sql: `UPPER(${column})`
81
+ };
82
+ }
83
+ static lower(column) {
84
+ return {
85
+ _type: "sql_expression",
86
+ _return: "string",
87
+ _sql: `LOWER(${column})`
88
+ };
89
+ }
90
+ // Raw functions for SELECT
91
+ static rawString(sql) {
92
+ return {
93
+ _type: "sql_expression",
94
+ _return: "string",
95
+ _sql: sql
96
+ };
97
+ }
98
+ static rawNumber(sql) {
99
+ return {
100
+ _type: "sql_expression",
101
+ _return: "number",
102
+ _sql: sql
103
+ };
104
+ }
105
+ static rawBoolean(sql) {
106
+ return {
107
+ _type: "sql_expression",
108
+ _return: "boolean",
109
+ _sql: sql
110
+ };
111
+ }
112
+ static rawDate(sql) {
113
+ return {
114
+ _type: "sql_expression",
115
+ _return: "date",
116
+ _sql: sql
117
+ };
118
+ }
119
+ // SELECT (overwrite)
120
+ select(selectObj) {
121
+ const selectClauses = [];
122
+ for (const [alias, columnOrFunction] of Object.entries(selectObj)){
123
+ if (typeof columnOrFunction === "object" && columnOrFunction._type === "sql_expression") {
124
+ // SQL 함수인 경우
125
+ selectClauses.push(this.knex.raw(`${columnOrFunction._sql} as ${alias}`));
126
+ } else {
127
+ // 일반 컬럼인 경우
128
+ const columnPath = columnOrFunction;
129
+ if (alias === columnPath) {
130
+ // alias와 컬럼명이 같으면 alias 생략
131
+ selectClauses.push(columnPath);
132
+ } else {
133
+ // alias 지정
134
+ selectClauses.push(`${columnPath} as ${alias}`);
135
+ }
136
+ }
137
+ }
138
+ this.knexQuery.select(selectClauses);
139
+ return this;
140
+ }
141
+ // SELECT (select는 overwrite, appendSelect는 append)
142
+ appendSelect(selectObj) {
143
+ return this.select(selectObj);
144
+ }
145
+ // SELECT *
146
+ selectAll() {
147
+ this.knexQuery.select("*");
148
+ return this;
149
+ }
150
+ // JOIN 실제 구현
151
+ join(tableNameOrSpec, ...args) {
152
+ return this.__commonJoin("join", tableNameOrSpec, ...args);
153
+ }
154
+ // LEFT JOIN 실제 구현
155
+ leftJoin(tableNameOrSpec, ...args) {
156
+ return this.__commonJoin("leftJoin", tableNameOrSpec, ...args);
157
+ }
158
+ __commonJoin(joinType, tableNameOrSpec, ...args) {
159
+ if (typeof tableNameOrSpec === "string") {
160
+ // Case 1: join("posts", ...)
161
+ const tableName = tableNameOrSpec;
162
+ if (args.length === 1 && typeof args[0] === "function") {
163
+ // join("posts", callback)
164
+ const callback = args[0];
165
+ this.knexQuery[joinType](tableName, (joinClause)=>{
166
+ callback(new JoinClauseGroup(joinClause));
167
+ });
168
+ } else {
169
+ // join("posts", left, right)
170
+ const [left, right] = args;
171
+ this.knexQuery[joinType](tableName, left, right);
172
+ }
173
+ } else if (typeof tableNameOrSpec === "object") {
174
+ // Case 2: join({ alias: "table" }, ...) or join({ alias: subquery }, ...)
175
+ const entries = Object.entries(tableNameOrSpec);
176
+ if (entries.length !== 1) {
177
+ throw new Error("Table spec must have exactly one entry");
178
+ }
179
+ assert(entries[0]);
180
+ const [[alias, spec]] = entries;
181
+ if (typeof spec === "string") {
182
+ // 테이블: join({ p: "posts" }, ...)
183
+ if (args.length === 1 && typeof args[0] === "function") {
184
+ // Callback
185
+ const callback = args[0];
186
+ this.knexQuery[joinType]({
187
+ [alias]: spec
188
+ }, (joinClause)=>{
189
+ callback(new JoinClauseGroup(joinClause));
190
+ });
191
+ } else {
192
+ // Simple
193
+ const [left, right] = args;
194
+ this.knexQuery[joinType]({
195
+ [alias]: spec
196
+ }, left, right);
197
+ }
198
+ } else if (spec instanceof Puri) {
199
+ // 서브쿼리: join({ sq: subquery }, ...)
200
+ if (args.length === 1 && typeof args[0] === "function") {
201
+ // Callback
202
+ const callback = args[0];
203
+ this.knexQuery[joinType](spec.raw().as(alias), (joinClause)=>{
204
+ callback(new JoinClauseGroup(joinClause));
205
+ });
206
+ } else {
207
+ // Simple
208
+ const [left, right] = args;
209
+ this.knexQuery[joinType](spec.raw().as(alias), left, right);
210
+ }
211
+ } else {
212
+ throw new Error("Invalid table specification");
213
+ }
214
+ } else {
215
+ throw new Error("Invalid arguments");
216
+ }
217
+ return this;
218
+ }
219
+ // WHERE: 컬럼 - 사용: .where("u.id", "like", "%test%")
220
+ where(columnOrConditions, operatorOrValue, value) {
221
+ if (typeof columnOrConditions === "object") {
222
+ this.knexQuery.where(columnOrConditions);
223
+ } else if (arguments.length === 2) {
224
+ if (operatorOrValue === null) {
225
+ this.knexQuery.whereNull(columnOrConditions);
226
+ return this;
227
+ }
228
+ this.knexQuery.where(columnOrConditions, operatorOrValue);
229
+ } else if (arguments.length === 3) {
230
+ if (value === null) {
231
+ if (operatorOrValue === "!=") {
232
+ this.knexQuery.whereNotNull(columnOrConditions);
233
+ return this;
234
+ } else if (operatorOrValue === "=") {
235
+ this.knexQuery.whereNull(columnOrConditions);
236
+ return this;
237
+ }
238
+ }
239
+ this.knexQuery.where(columnOrConditions, operatorOrValue, value);
240
+ } else {
241
+ this.knexQuery.where(columnOrConditions);
242
+ }
243
+ return this;
244
+ }
245
+ // WHERE IN
246
+ whereIn(column, values) {
247
+ this.knexQuery.whereIn(column, values);
248
+ return this;
249
+ }
250
+ // WHERE NOT IN
251
+ whereNotIn(column, values) {
252
+ this.knexQuery.whereIn(column, values);
253
+ return this;
254
+ }
255
+ // WHERE MATCH
256
+ whereMatch(column, value) {
257
+ this.knexQuery.whereRaw(`MATCH (${String(column)}) AGAINST (?)`, [
258
+ value
259
+ ]);
260
+ return this;
261
+ }
262
+ // WHERE 괄호 그룹핑
263
+ whereGroup(callback) {
264
+ this.knexQuery.where((builder)=>{
265
+ const group = new WhereGroup(builder);
266
+ callback(group);
267
+ });
268
+ return this;
269
+ }
270
+ orWhereGroup(callback) {
271
+ this.knexQuery.orWhere((builder)=>{
272
+ const group = new WhereGroup(builder);
273
+ callback(group);
274
+ });
275
+ return this;
276
+ }
277
+ orderBy(column, direction = "asc") {
278
+ this.knexQuery.orderBy(column, direction);
279
+ return this;
280
+ }
281
+ // 기본 쿼리 메서드들
282
+ limit(count) {
283
+ this.knexQuery.limit(count);
284
+ return this;
285
+ }
286
+ offset(count) {
287
+ this.knexQuery.offset(count);
288
+ return this;
289
+ }
290
+ groupBy(...columns) {
291
+ this.knexQuery.groupBy(...columns);
292
+ return this;
293
+ }
294
+ // HAVING 구현
295
+ having(...conditions) {
296
+ if (conditions.length === 1) {
297
+ // having("COUNT(*) > 10")
298
+ this.knexQuery.having(conditions[0]);
299
+ } else if (conditions.length === 3) {
300
+ // having("count", ">", 10)
301
+ this.knexQuery.having(conditions[0], conditions[1], conditions[2]);
302
+ } else {
303
+ throw new Error("Invalid having arguments");
304
+ }
305
+ return this;
306
+ }
307
+ // 실행 메서드들 - thenable 구현
308
+ then(onfulfilled, onrejected) {
309
+ Naite.t("puri-query", this.toQuery());
310
+ return this.knexQuery.then(onfulfilled, onrejected);
311
+ }
312
+ catch(onrejected) {
313
+ return this.knexQuery.catch(onrejected);
314
+ }
315
+ finally(onfinally) {
316
+ return this.knexQuery.finally(onfinally);
317
+ }
318
+ // 하나만 쿼리
319
+ first() {
320
+ this.knexQuery.first();
321
+ return new ResolvedPuri(this.knexQuery);
322
+ }
323
+ // 쿼리한 레코드에서 특정 컬럼만 추출한 배열 리턴
324
+ pluck(column) {
325
+ this.knexQuery.pluck(column);
326
+ return new ResolvedPuri(this.knexQuery);
327
+ }
328
+ // INSERT
329
+ insert(data) {
330
+ this.knexQuery.insert(data);
331
+ return new ResolvedPuri(this.knexQuery);
332
+ }
333
+ // UPDATE
334
+ update(data) {
335
+ this.knexQuery.update(data);
336
+ return new ResolvedPuri(this.knexQuery);
337
+ }
338
+ // Increment
339
+ increment(column, value) {
340
+ if (value <= 0) {
341
+ throw new Error("Increment value must be greater than 0");
342
+ }
343
+ this.knexQuery.increment(column, value);
344
+ return new ResolvedPuri(this.knexQuery);
345
+ }
346
+ // Decrement
347
+ decrement(column, value) {
348
+ if (value <= 0) {
349
+ throw new Error("Decrement value must be greater than 0");
350
+ }
351
+ this.knexQuery.decrement(column, value);
352
+ return new ResolvedPuri(this.knexQuery);
353
+ }
354
+ // DELETE
355
+ delete() {
356
+ this.knexQuery.delete();
357
+ return new ResolvedPuri(this.knexQuery);
358
+ }
359
+ // 확인 쿼리 리턴
360
+ toQuery() {
361
+ return this.knexQuery.toQuery();
362
+ }
363
+ // 쿼리 디버깅 로그 출력
364
+ debug() {
365
+ console.log(`${chalk.cyan("[Puri Debug]")} ${chalk.yellow(this.toQuery())}`);
366
+ return this;
367
+ }
368
+ formatSQL(unformatted) {
369
+ // SQL 예약어 목록
370
+ const keywords = [
371
+ "SELECT",
372
+ "FROM",
373
+ "WHERE",
374
+ "INSERT",
375
+ "INTO",
376
+ "VALUES",
377
+ "UPDATE",
378
+ "DELETE",
379
+ "CREATE",
380
+ "TABLE",
381
+ "ALTER",
382
+ "DROP",
383
+ "JOIN",
384
+ "ON",
385
+ "INNER",
386
+ "LEFT",
387
+ "RIGHT",
388
+ "FULL",
389
+ "OUTER",
390
+ "GROUP",
391
+ "BY",
392
+ "ORDER",
393
+ "HAVING",
394
+ "DISTINCT",
395
+ "LIMIT",
396
+ "OFFSET",
397
+ "AS",
398
+ "AND",
399
+ "OR",
400
+ "NOT",
401
+ "IN",
402
+ "LIKE",
403
+ "IS",
404
+ "NULL",
405
+ "CASE",
406
+ "WHEN",
407
+ "THEN",
408
+ "ELSE",
409
+ "END",
410
+ "UNION",
411
+ "ALL",
412
+ "EXISTS",
413
+ "BETWEEN"
414
+ ];
415
+ let formatted = unformatted;
416
+ // 예약어를 대문자로 변환
417
+ keywords.forEach((keyword)=>{
418
+ const regex = new RegExp(`\\b${keyword}\\b`, "gi");
419
+ formatted = formatted.replace(regex, keyword.toUpperCase());
420
+ });
421
+ // 주요 절 앞에 줄바꿈 추가
422
+ const majorClauses = [
423
+ "SELECT",
424
+ "FROM",
425
+ "WHERE",
426
+ "GROUP BY",
427
+ "ORDER BY",
428
+ "HAVING",
429
+ "LIMIT",
430
+ "UNION"
431
+ ];
432
+ majorClauses.forEach((clause)=>{
433
+ const regex = new RegExp(`\\s+(${clause})\\s+`, "gi");
434
+ formatted = formatted.replace(regex, `\n${clause.toUpperCase()} `);
435
+ });
436
+ // JOIN 절 처리
437
+ formatted = formatted.replace(/\s+((?:INNER|LEFT|RIGHT|FULL OUTER)\s+)?JOIN\s+/gi, "\n$1JOIN ");
438
+ // AND, OR 조건 처리
439
+ formatted = formatted.replace(/\s+(AND|OR)\s+/gi, "\n $1 ");
440
+ // 괄호 처리 및 들여쓰기
441
+ const lines = formatted.split("\n");
442
+ const indentedLines = [];
443
+ let indentLevel = 0;
444
+ for (let line of lines){
445
+ const trimmedLine = line.trim();
446
+ if (!trimmedLine) continue;
447
+ // 닫는 괄호가 있으면 들여쓰기 레벨 감소
448
+ const closingParens = (trimmedLine.match(/\)/g) || []).length;
449
+ const openingParens = (trimmedLine.match(/\(/g) || []).length;
450
+ if (closingParens > 0 && openingParens === 0) {
451
+ indentLevel = Math.max(0, indentLevel - closingParens);
452
+ }
453
+ // 현재 들여쓰기 적용
454
+ const indent = " ".repeat(indentLevel);
455
+ indentedLines.push(indent + trimmedLine);
456
+ // 여는 괄호가 있으면 들여쓰기 레벨 증가
457
+ if (openingParens > closingParens) {
458
+ indentLevel += openingParens - closingParens;
459
+ }
460
+ }
461
+ return indentedLines.join("\n").trim();
462
+ }
463
+ // Knex 쿼리 빌더 직접 접근
464
+ raw() {
465
+ return this.knexQuery;
466
+ }
467
+ }
468
+ export class WhereGroup {
469
+ builder;
470
+ constructor(builder){
471
+ this.builder = builder;
472
+ }
473
+ where(...args) {
474
+ this.builder.where(args[0], ...args.slice(1));
475
+ return this;
476
+ }
477
+ orWhere(...args) {
478
+ this.builder.orWhere(args[0], ...args.slice(1));
479
+ return this;
480
+ }
481
+ whereGroup(callback) {
482
+ this.builder.where((subBuilder)=>{
483
+ const subGroup = new WhereGroup(subBuilder);
484
+ callback(subGroup);
485
+ });
486
+ return this;
487
+ }
488
+ orWhereGroup(callback) {
489
+ this.builder.orWhere((subBuilder)=>{
490
+ const subGroup = new WhereGroup(subBuilder);
491
+ callback(subGroup);
492
+ });
493
+ return this;
494
+ }
495
+ }
496
+ export class JoinClauseGroup {
497
+ callback;
498
+ constructor(callback){
499
+ this.callback = callback;
500
+ }
501
+ // ON(AND) 구현
502
+ on(...args) {
503
+ this.callback.on(...args);
504
+ return this;
505
+ }
506
+ // ON(OR) 구현
507
+ orOn(...args) {
508
+ this.callback.orOn(...args);
509
+ return this;
510
+ }
511
+ }
512
+ /*
513
+ TResolved: 쿼리 실행 후 반환될 결과 타입
514
+ _TReturning: 추후 RETURNING 절에 사용될 타입
515
+ */ export class ResolvedPuri {
516
+ knexQuery;
517
+ constructor(knexQuery){
518
+ this.knexQuery = knexQuery;
519
+ }
520
+ toQuery() {
521
+ return this.knexQuery.toQuery();
522
+ }
523
+ debug() {
524
+ console.log(`${chalk.cyan("[Puri Debug]")} ${chalk.yellow(this.toQuery())}`);
525
+ return this;
526
+ }
527
+ then(onfulfilled, onrejected) {
528
+ Naite.t("puri-query", this.toQuery());
529
+ return this.knexQuery.then(onfulfilled, onrejected);
530
+ }
531
+ catch(onrejected) {
532
+ return this.knexQuery.catch(onrejected);
533
+ }
534
+ finally(onfinally) {
535
+ return this.knexQuery.finally(onfinally);
536
+ }
537
+ }
538
+
539
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYXRhYmFzZS9wdXJpLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgS25leCB9IGZyb20gXCJrbmV4XCI7XG5pbXBvcnQgdHlwZSB7XG4gIEF2YWlsYWJsZUNvbHVtbnMsXG4gIFNlbGVjdE9iamVjdCxcbiAgUGFyc2VTZWxlY3RPYmplY3QsXG4gIFdoZXJlQ29uZGl0aW9uLFxuICBDb21wYXJpc29uT3BlcmF0b3IsXG4gIEV4dHJhY3RDb2x1bW5UeXBlLFxuICBTcWxFeHByZXNzaW9uLFxuICBFeHBhbmQsXG4gIEZ1bGx0ZXh0Q29sdW1ucyxcbiAgUmVzdWx0QXZhaWxhYmxlQ29sdW1ucyxcbiAgSW5zZXJ0RGF0YSxcbiAgU2luZ2xlVGFibGVWYWx1ZSxcbn0gZnJvbSBcIi4vcHVyaS50eXBlc1wiO1xuaW1wb3J0IGNoYWxrIGZyb20gXCJjaGFsa1wiO1xuaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCI7XG5pbXBvcnQgeyBOYWl0ZSB9IGZyb20gXCIuLi9uYWl0ZS9uYWl0ZVwiO1xuXG5leHBvcnQgY2xhc3MgUHVyaTxUU2NoZW1hLCBUVGFibGVzIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PiwgVFJlc3VsdD4ge1xuICBwcml2YXRlIGtuZXhRdWVyeTogS25leC5RdWVyeUJ1aWxkZXI7XG5cbiAgLy8g7IOd7ISx7J6QIOyLnOq3uOuLiOyymOuTpFxuICBjb25zdHJ1Y3RvcihrbmV4OiBLbmV4LCB0YWJsZU5hbWU6IHN0cmluZyk7XG4gIGNvbnN0cnVjdG9yKFxuICAgIGtuZXg6IEtuZXgsXG4gICAgdGFibGVTcGVjOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBQdXJpPFRTY2hlbWEsIGFueSwgYW55Pj5cbiAgKTtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGtuZXg6IEtuZXgsXG4gICAgdGFibGVOYW1lT3JTcGVjOiBhbnlcbiAgKSB7XG4gICAgaWYgKHR5cGVvZiB0YWJsZU5hbWVPclNwZWMgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIC8vIENhc2U6IG5ldyBQdXJpKGtuZXgsIFwidXNlcnNcIilcbiAgICAgIHRoaXMua25leFF1ZXJ5ID0gdGhpcy5rbmV4KHRhYmxlTmFtZU9yU3BlYykuZnJvbSh0YWJsZU5hbWVPclNwZWMpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHRhYmxlTmFtZU9yU3BlYyA9PT0gXCJvYmplY3RcIikge1xuICAgICAgY29uc3QgZW50cmllcyA9IE9iamVjdC5lbnRyaWVzKHRhYmxlTmFtZU9yU3BlYyk7XG4gICAgICBpZiAoZW50cmllcy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGFibGUgc3BlYyBtdXN0IGhhdmUgZXhhY3RseSBvbmUgZW50cnlcIik7XG4gICAgICB9XG4gICAgICBhc3NlcnQoZW50cmllc1swXSk7XG4gICAgICBjb25zdCBbYWxpYXMsIHNwZWNdID0gZW50cmllc1swXTtcbiAgICAgIGlmICh0eXBlb2Ygc3BlYyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICB0aGlzLmtuZXhRdWVyeSA9IHRoaXMua25leChzcGVjKS5mcm9tKHsgW2FsaWFzXTogc3BlYyB9KTtcbiAgICAgIH0gZWxzZSBpZiAoc3BlYyBpbnN0YW5jZW9mIFB1cmkpIHtcbiAgICAgICAgY29uc3Qgc3VicXVlcnlCdWlsZGVyID0gc3BlYy5yYXcoKTtcbiAgICAgICAgdGhpcy5rbmV4UXVlcnkgPSB0aGlzLmtuZXguZnJvbShzdWJxdWVyeUJ1aWxkZXIuYXMoYWxpYXMpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdGFibGUgc3BlY2lmaWNhdGlvblwiKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCB0YWJsZSBzcGVjaWZpY2F0aW9uXCIpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFN0YXRpYyBTUUwgaGVscGVyIGZ1bmN0aW9ucyBmb3IgU0VMRUNUXG4gIHN0YXRpYyBjb3VudChjb2x1bW46IHN0cmluZyA9IFwiKlwiKTogU3FsRXhwcmVzc2lvbjxcIm51bWJlclwiPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsXG4gICAgICBfcmV0dXJuOiBcIm51bWJlclwiLFxuICAgICAgX3NxbDogYENPVU5UKCR7Y29sdW1ufSlgLFxuICAgIH07XG4gIH1cbiAgc3RhdGljIHN1bShjb2x1bW46IHN0cmluZyk6IFNxbEV4cHJlc3Npb248XCJudW1iZXJcIj4ge1xuICAgIHJldHVybiB7XG4gICAgICBfdHlwZTogXCJzcWxfZXhwcmVzc2lvblwiLFxuICAgICAgX3JldHVybjogXCJudW1iZXJcIixcbiAgICAgIF9zcWw6IGBTVU0oJHtjb2x1bW59KWAsXG4gICAgfTtcbiAgfVxuICBzdGF0aWMgYXZnKGNvbHVtbjogc3RyaW5nKTogU3FsRXhwcmVzc2lvbjxcIm51bWJlclwiPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsXG4gICAgICBfcmV0dXJuOiBcIm51bWJlclwiLFxuICAgICAgX3NxbDogYEFWRygke2NvbHVtbn0pYCxcbiAgICB9O1xuICB9XG4gIHN0YXRpYyBtYXgoY29sdW1uOiBzdHJpbmcpOiBTcWxFeHByZXNzaW9uPFwibnVtYmVyXCI+IHtcbiAgICByZXR1cm4ge1xuICAgICAgX3R5cGU6IFwic3FsX2V4cHJlc3Npb25cIixcbiAgICAgIF9yZXR1cm46IFwibnVtYmVyXCIsXG4gICAgICBfc3FsOiBgTUFYKCR7Y29sdW1ufSlgLFxuICAgIH07XG4gIH1cbiAgc3RhdGljIG1pbihjb2x1bW46IHN0cmluZyk6IFNxbEV4cHJlc3Npb248XCJudW1iZXJcIj4ge1xuICAgIHJldHVybiB7XG4gICAgICBfdHlwZTogXCJzcWxfZXhwcmVzc2lvblwiLFxuICAgICAgX3JldHVybjogXCJudW1iZXJcIixcbiAgICAgIF9zcWw6IGBNSU4oJHtjb2x1bW59KWAsXG4gICAgfTtcbiAgfVxuICBzdGF0aWMgY29uY2F0KC4uLmFyZ3M6IHN0cmluZ1tdKTogU3FsRXhwcmVzc2lvbjxcInN0cmluZ1wiPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsXG4gICAgICBfcmV0dXJuOiBcInN0cmluZ1wiLFxuICAgICAgX3NxbDogYENPTkNBVCgke2FyZ3Muam9pbihcIiwgXCIpfSlgLFxuICAgIH07XG4gIH1cbiAgc3RhdGljIHVwcGVyKGNvbHVtbjogc3RyaW5nKTogU3FsRXhwcmVzc2lvbjxcInN0cmluZ1wiPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsXG4gICAgICBfcmV0dXJuOiBcInN0cmluZ1wiLFxuICAgICAgX3NxbDogYFVQUEVSKCR7Y29sdW1ufSlgLFxuICAgIH07XG4gIH1cbiAgc3RhdGljIGxvd2VyKGNvbHVtbjogc3RyaW5nKTogU3FsRXhwcmVzc2lvbjxcInN0cmluZ1wiPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsXG4gICAgICBfcmV0dXJuOiBcInN0cmluZ1wiLFxuICAgICAgX3NxbDogYExPV0VSKCR7Y29sdW1ufSlgLFxuICAgIH07XG4gIH1cblxuICAvLyBSYXcgZnVuY3Rpb25zIGZvciBTRUxFQ1RcbiAgc3RhdGljIHJhd1N0cmluZyhzcWw6IHN0cmluZyk6IFNxbEV4cHJlc3Npb248XCJzdHJpbmdcIj4ge1xuICAgIHJldHVybiB7IF90eXBlOiBcInNxbF9leHByZXNzaW9uXCIsIF9yZXR1cm46IFwic3RyaW5nXCIsIF9zcWw6IHNxbCB9O1xuICB9XG4gIHN0YXRpYyByYXdOdW1iZXIoc3FsOiBzdHJpbmcpOiBTcWxFeHByZXNzaW9uPFwibnVtYmVyXCI+IHtcbiAgICByZXR1cm4geyBfdHlwZTogXCJzcWxfZXhwcmVzc2lvblwiLCBfcmV0dXJuOiBcIm51bWJlclwiLCBfc3FsOiBzcWwgfTtcbiAgfVxuICBzdGF0aWMgcmF3Qm9vbGVhbihzcWw6IHN0cmluZyk6IFNxbEV4cHJlc3Npb248XCJib29sZWFuXCI+IHtcbiAgICByZXR1cm4geyBfdHlwZTogXCJzcWxfZXhwcmVzc2lvblwiLCBfcmV0dXJuOiBcImJvb2xlYW5cIiwgX3NxbDogc3FsIH07XG4gIH1cbiAgc3RhdGljIHJhd0RhdGUoc3FsOiBzdHJpbmcpOiBTcWxFeHByZXNzaW9uPFwiZGF0ZVwiPiB7XG4gICAgcmV0dXJuIHsgX3R5cGU6IFwic3FsX2V4cHJlc3Npb25cIiwgX3JldHVybjogXCJkYXRlXCIsIF9zcWw6IHNxbCB9O1xuICB9XG5cbiAgLy8gU0VMRUNUIChvdmVyd3JpdGUpXG4gIHNlbGVjdDxUU2VsZWN0IGV4dGVuZHMgU2VsZWN0T2JqZWN0PFRUYWJsZXM+PihcbiAgICBzZWxlY3RPYmo6IFRTZWxlY3RcbiAgKTogUHVyaTxUU2NoZW1hLCBUVGFibGVzLCBQYXJzZVNlbGVjdE9iamVjdDxUVGFibGVzLCBUU2VsZWN0Pj4ge1xuICAgIGNvbnN0IHNlbGVjdENsYXVzZXM6IChzdHJpbmcgfCBLbmV4LlJhdylbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBbYWxpYXMsIGNvbHVtbk9yRnVuY3Rpb25dIG9mIE9iamVjdC5lbnRyaWVzKHNlbGVjdE9iaikpIHtcbiAgICAgIGlmIChcbiAgICAgICAgdHlwZW9mIGNvbHVtbk9yRnVuY3Rpb24gPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgY29sdW1uT3JGdW5jdGlvbi5fdHlwZSA9PT0gXCJzcWxfZXhwcmVzc2lvblwiXG4gICAgICApIHtcbiAgICAgICAgLy8gU1FMIO2VqOyImOyduCDqsr3smrBcbiAgICAgICAgc2VsZWN0Q2xhdXNlcy5wdXNoKFxuICAgICAgICAgIHRoaXMua25leC5yYXcoYCR7Y29sdW1uT3JGdW5jdGlvbi5fc3FsfSBhcyAke2FsaWFzfWApXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyDsnbzrsJgg7Lus65+87J24IOqyveyasFxuICAgICAgICBjb25zdCBjb2x1bW5QYXRoID0gY29sdW1uT3JGdW5jdGlvbiBhcyBzdHJpbmc7XG4gICAgICAgIGlmIChhbGlhcyA9PT0gY29sdW1uUGF0aCkge1xuICAgICAgICAgIC8vIGFsaWFz7JmAIOy7rOufvOuqheydtCDqsJnsnLzrqbQgYWxpYXMg7IOd6561XG4gICAgICAgICAgc2VsZWN0Q2xhdXNlcy5wdXNoKGNvbHVtblBhdGgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGFsaWFzIOyngOyglVxuICAgICAgICAgIHNlbGVjdENsYXVzZXMucHVzaChgJHtjb2x1bW5QYXRofSBhcyAke2FsaWFzfWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5rbmV4UXVlcnkuc2VsZWN0KHNlbGVjdENsYXVzZXMpO1xuICAgIHJldHVybiB0aGlzIGFzIGFueTtcbiAgfVxuXG4gIC8vIFNFTEVDVCAoc2VsZWN064qUIG92ZXJ3cml0ZSwgYXBwZW5kU2VsZWN064qUIGFwcGVuZClcbiAgYXBwZW5kU2VsZWN0PFRTZWxlY3QgZXh0ZW5kcyBTZWxlY3RPYmplY3Q8VFRhYmxlcz4+KFxuICAgIHNlbGVjdE9iajogVFNlbGVjdFxuICApOiBQdXJpPFRTY2hlbWEsIFRUYWJsZXMsIFRSZXN1bHQgJiBQYXJzZVNlbGVjdE9iamVjdDxUVGFibGVzLCBUU2VsZWN0Pj4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdChzZWxlY3RPYmopIGFzIGFueTtcbiAgfVxuXG4gIC8vIFNFTEVDVCAqXG4gIHNlbGVjdEFsbCgpOiB0aGlzIHtcbiAgICB0aGlzLmtuZXhRdWVyeS5zZWxlY3QoXCIqXCIpO1xuICAgIHJldHVybiB0aGlzIGFzIGFueTtcbiAgfVxuXG4gIC8vIEpPSU46IOyEnOu4jOy/vOumrCArIEFsaWFzXG4gIGpvaW48VEpvaW5BbGlhcyBleHRlbmRzIHN0cmluZywgVFN1YlJlc3VsdD4oXG4gICAgdGFibGVTcGVjOiB7IFtLIGluIFRKb2luQWxpYXNdOiBQdXJpPFRTY2hlbWEsIGFueSwgVFN1YlJlc3VsdD4gfSxcbiAgICBsZWZ0OiBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+LFxuICAgIHJpZ2h0OiBgJHtUSm9pbkFsaWFzfS4ke2tleW9mIFRTdWJSZXN1bHQgJiBzdHJpbmd9YFxuICApOiBQdXJpPFxuICAgIFRTY2hlbWEsXG4gICAgVFRhYmxlcyAmIFJlY29yZDxUSm9pbkFsaWFzLCBUU3ViUmVzdWx0PiwgLy8g7ISc67iM7L+866as7J2YIFRSZXN1bHRcbiAgICBUUmVzdWx0XG4gID47XG4gIC8vIEpPSU46IO2FjOydtOu4lCArIEFsaWFzXG4gIGpvaW48VEpvaW5UYWJsZSBleHRlbmRzIGtleW9mIFRTY2hlbWEsIFRKb2luQWxpYXMgZXh0ZW5kcyBzdHJpbmc+KFxuICAgIHRhYmxlU3BlYzogeyBbSyBpbiBUSm9pbkFsaWFzXTogVEpvaW5UYWJsZSB9LFxuICAgIGxlZnQ6IEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4sXG4gICAgcmlnaHQ6IGAke1RKb2luQWxpYXN9LiR7a2V5b2YgVFNjaGVtYVtUSm9pblRhYmxlXSAmIHN0cmluZ31gXG4gICk6IFB1cmk8XG4gICAgVFNjaGVtYSxcbiAgICBUVGFibGVzICYgUmVjb3JkPFRKb2luQWxpYXMsIFRTY2hlbWFbVEpvaW5UYWJsZV0+LCAvLyBUVGFibGVzIO2ZleyepSFcbiAgICBUUmVzdWx0XG4gID47XG4gIC8vIEpPSU46IO2FjOydtOu4lOuqhVxuICBqb2luPFRKb2luVGFibGUgZXh0ZW5kcyBrZXlvZiBUU2NoZW1hPihcbiAgICB0YWJsZU5hbWU6IFRKb2luVGFibGUsXG4gICAgbGVmdDogQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPixcbiAgICByaWdodDogYCR7VEpvaW5UYWJsZSAmIHN0cmluZ30uJHtrZXlvZiBUU2NoZW1hW1RKb2luVGFibGVdICYgc3RyaW5nfWBcbiAgKTogUHVyaTxcbiAgICBUU2NoZW1hLFxuICAgIFRUYWJsZXMgJiBSZWNvcmQ8VEpvaW5UYWJsZSwgVFNjaGVtYVtUSm9pblRhYmxlXT4sIC8vIO2FjOydtOu4lOuqheydtCDtgqRcbiAgICBUUmVzdWx0XG4gID47XG4gIC8vIEpPSU46IOyEnOu4jOy/vOumrCArIEFsaWFzICsg7L2c67CxXG4gIGpvaW48VEpvaW5BbGlhcyBleHRlbmRzIHN0cmluZywgVFN1YlJlc3VsdD4oXG4gICAgdGFibGVTcGVjOiB7IFtLIGluIFRKb2luQWxpYXNdOiBQdXJpPFRTY2hlbWEsIGFueSwgVFN1YlJlc3VsdD4gfSxcbiAgICBjYWxsYmFjazogKFxuICAgICAgajogSm9pbkNsYXVzZUdyb3VwPFRUYWJsZXMsIFJlY29yZDxUSm9pbkFsaWFzLCBUU3ViUmVzdWx0Pj5cbiAgICApID0+IHZvaWRcbiAgKTogUHVyaTxUU2NoZW1hLCBUVGFibGVzICYgUmVjb3JkPFRKb2luQWxpYXMsIFRTdWJSZXN1bHQ+LCBUUmVzdWx0PjtcbiAgLy8gSk9JTjog7YWM7J2067iUICsgQWxpYXMgKyDsvZzrsLFcbiAgam9pbjxUSm9pblRhYmxlIGV4dGVuZHMga2V5b2YgVFNjaGVtYSwgVEpvaW5BbGlhcyBleHRlbmRzIHN0cmluZz4oXG4gICAgdGFibGVTcGVjOiB7IFtLIGluIFRKb2luQWxpYXNdOiBUSm9pblRhYmxlIH0sXG4gICAgY2FsbGJhY2s6IChcbiAgICAgIGo6IEpvaW5DbGF1c2VHcm91cDxUVGFibGVzLCBSZWNvcmQ8VEpvaW5BbGlhcywgVFNjaGVtYVtUSm9pblRhYmxlXT4+XG4gICAgKSA9PiB2b2lkXG4gICk6IFB1cmk8VFNjaGVtYSwgVFRhYmxlcyAmIFJlY29yZDxUSm9pbkFsaWFzLCBUU2NoZW1hW1RKb2luVGFibGVdPiwgVFJlc3VsdD47XG4gIC8vIEpPSU46IO2FjOydtOu4lOuqhSArIOy9nOuwsVxuICBqb2luPFRKb2luVGFibGUgZXh0ZW5kcyBrZXlvZiBUU2NoZW1hPihcbiAgICB0YWJsZU5hbWU6IFRKb2luVGFibGUsXG4gICAgY2FsbGJhY2s6IChcbiAgICAgIGo6IEpvaW5DbGF1c2VHcm91cDxUVGFibGVzLCBSZWNvcmQ8VEpvaW5UYWJsZSwgVFNjaGVtYVtUSm9pblRhYmxlXT4+XG4gICAgKSA9PiB2b2lkXG4gICk6IFB1cmk8VFNjaGVtYSwgVFRhYmxlcyAmIFJlY29yZDxUSm9pblRhYmxlLCBUU2NoZW1hW1RKb2luVGFibGVdPiwgVFJlc3VsdD47XG4gIC8vIEpPSU4g7Iuk7KCcIOq1rO2YhFxuICBqb2luKHRhYmxlTmFtZU9yU3BlYzogYW55LCAuLi5hcmdzOiBhbnlbXSk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMuX19jb21tb25Kb2luKFwiam9pblwiLCB0YWJsZU5hbWVPclNwZWMsIC4uLmFyZ3MpO1xuICB9XG5cbiAgLy8gTEVGVCBKT0lOOiDshJzruIzsv7zrpqwgKyBBbGlhc1xuICBsZWZ0Sm9pbjxUSm9pbkFsaWFzIGV4dGVuZHMgc3RyaW5nLCBUU3ViUmVzdWx0PihcbiAgICB0YWJsZVNwZWM6IHsgW0sgaW4gVEpvaW5BbGlhc106IFB1cmk8VFNjaGVtYSwgYW55LCBUU3ViUmVzdWx0PiB9LFxuICAgIGxlZnQ6IEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4sXG4gICAgcmlnaHQ6IGAke1RKb2luQWxpYXN9LiR7a2V5b2YgVFN1YlJlc3VsdCAmIHN0cmluZ31gXG4gICk6IFB1cmk8XG4gICAgVFNjaGVtYSxcbiAgICBUVGFibGVzICYgUmVjb3JkPFRKb2luQWxpYXMsIFRTdWJSZXN1bHQ+LCAvLyDshJzruIzsv7zrpqzsnZggVFJlc3VsdFxuICAgIFRSZXN1bHRcbiAgPjtcbiAgLy8gTEVGVCBKT0lOOiDthYzsnbTruJQgKyBBbGlhc1xuICBsZWZ0Sm9pbjxUSm9pblRhYmxlIGV4dGVuZHMga2V5b2YgVFNjaGVtYSwgVEpvaW5BbGlhcyBleHRlbmRzIHN0cmluZz4oXG4gICAgdGFibGVTcGVjOiB7IFtLIGluIFRKb2luQWxpYXNdOiBUSm9pblRhYmxlIH0sXG4gICAgbGVmdDogQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPixcbiAgICByaWdodDogYCR7VEpvaW5BbGlhc30uJHtrZXlvZiBUU2NoZW1hW1RKb2luVGFibGVdICYgc3RyaW5nfWBcbiAgKTogUHVyaTxcbiAgICBUU2NoZW1hLFxuICAgIFRUYWJsZXMgJiBSZWNvcmQ8VEpvaW5BbGlhcywgVFNjaGVtYVtUSm9pblRhYmxlXT4sIC8vIFRUYWJsZXMg7ZmV7J6lIVxuICAgIFRSZXN1bHRcbiAgPjtcbiAgLy8gTEVGVCBKT0lOOiDthYzsnbTruJTrqoVcbiAgbGVmdEpvaW48VEpvaW5UYWJsZSBleHRlbmRzIGtleW9mIFRTY2hlbWE+KFxuICAgIHRhYmxlTmFtZTogVEpvaW5UYWJsZSxcbiAgICBsZWZ0OiBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+LFxuICAgIHJpZ2h0OiBgJHtUSm9pblRhYmxlICYgc3RyaW5nfS4ke2tleW9mIFRTY2hlbWFbVEpvaW5UYWJsZV0gJiBzdHJpbmd9YFxuICApOiBQdXJpPFxuICAgIFRTY2hlbWEsXG4gICAgVFRhYmxlcyAmIFJlY29yZDxUSm9pblRhYmxlLCBUU2NoZW1hW1RKb2luVGFibGVdPiwgLy8g7YWM7J2067iU66qF7J20IO2CpFxuICAgIFRSZXN1bHRcbiAgPjtcbiAgLy8gTEVGVCBKT0lOOiDshJzruIzsv7zrpqwgKyBBbGlhcyArIOy9nOuwsVxuICBsZWZ0Sm9pbjxUSm9pbkFsaWFzIGV4dGVuZHMgc3RyaW5nLCBUU3ViUmVzdWx0PihcbiAgICB0YWJsZVNwZWM6IHsgW0sgaW4gVEpvaW5BbGlhc106IFB1cmk8VFNjaGVtYSwgYW55LCBUU3ViUmVzdWx0PiB9LFxuICAgIGNhbGxiYWNrOiAoXG4gICAgICBqOiBKb2luQ2xhdXNlR3JvdXA8VFRhYmxlcywgUmVjb3JkPFRKb2luQWxpYXMsIFRTdWJSZXN1bHQ+PlxuICAgICkgPT4gdm9pZFxuICApOiBQdXJpPFRTY2hlbWEsIFRUYWJsZXMgJiBSZWNvcmQ8VEpvaW5BbGlhcywgVFN1YlJlc3VsdD4sIFRSZXN1bHQ+O1xuICAvLyBMRUZUIEpPSU46IO2FjOydtOu4lCArIEFsaWFzICsg7L2c67CxXG4gIGxlZnRKb2luPFRKb2luVGFibGUgZXh0ZW5kcyBrZXlvZiBUU2NoZW1hLCBUSm9pbkFsaWFzIGV4dGVuZHMgc3RyaW5nPihcbiAgICB0YWJsZVNwZWM6IHsgW0sgaW4gVEpvaW5BbGlhc106IFRKb2luVGFibGUgfSxcbiAgICBjYWxsYmFjazogKFxuICAgICAgajogSm9pbkNsYXVzZUdyb3VwPFRUYWJsZXMsIFJlY29yZDxUSm9pbkFsaWFzLCBUU2NoZW1hW1RKb2luVGFibGVdPj5cbiAgICApID0+IHZvaWRcbiAgKTogUHVyaTxUU2NoZW1hLCBUVGFibGVzICYgUmVjb3JkPFRKb2luQWxpYXMsIFRTY2hlbWFbVEpvaW5UYWJsZV0+LCBUUmVzdWx0PjtcbiAgLy8gTEVGVCBKT0lOOiDthYzsnbTruJTrqoUgKyDsvZzrsLFcbiAgbGVmdEpvaW48VEpvaW5UYWJsZSBleHRlbmRzIGtleW9mIFRTY2hlbWE+KFxuICAgIHRhYmxlTmFtZTogVEpvaW5UYWJsZSxcbiAgICBjYWxsYmFjazogKFxuICAgICAgajogSm9pbkNsYXVzZUdyb3VwPFRUYWJsZXMsIFJlY29yZDxUSm9pblRhYmxlLCBUU2NoZW1hW1RKb2luVGFibGVdPj5cbiAgICApID0+IHZvaWRcbiAgKTogUHVyaTxUU2NoZW1hLCBUVGFibGVzICYgUmVjb3JkPFRKb2luVGFibGUsIFRTY2hlbWFbVEpvaW5UYWJsZV0+LCBUUmVzdWx0PjtcbiAgLy8gTEVGVCBKT0lOIOyLpOygnCDqtaztmIRcbiAgbGVmdEpvaW4odGFibGVOYW1lT3JTcGVjOiBhbnksIC4uLmFyZ3M6IGFueVtdKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5fX2NvbW1vbkpvaW4oXCJsZWZ0Sm9pblwiLCB0YWJsZU5hbWVPclNwZWMsIC4uLmFyZ3MpO1xuICB9XG5cbiAgX19jb21tb25Kb2luKFxuICAgIGpvaW5UeXBlOiBcImpvaW5cIiB8IFwibGVmdEpvaW5cIixcbiAgICB0YWJsZU5hbWVPclNwZWM6IGFueSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiB0aGlzIHtcbiAgICBpZiAodHlwZW9mIHRhYmxlTmFtZU9yU3BlYyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgLy8gQ2FzZSAxOiBqb2luKFwicG9zdHNcIiwgLi4uKVxuICAgICAgY29uc3QgdGFibGVOYW1lID0gdGFibGVOYW1lT3JTcGVjO1xuXG4gICAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3NbMF0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAvLyBqb2luKFwicG9zdHNcIiwgY2FsbGJhY2spXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gYXJnc1swXTtcbiAgICAgICAgdGhpcy5rbmV4UXVlcnlbam9pblR5cGVdKHRhYmxlTmFtZSwgKGpvaW5DbGF1c2UpID0+IHtcbiAgICAgICAgICBjYWxsYmFjayhuZXcgSm9pbkNsYXVzZUdyb3VwKGpvaW5DbGF1c2UpKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBqb2luKFwicG9zdHNcIiwgbGVmdCwgcmlnaHQpXG4gICAgICAgIGNvbnN0IFtsZWZ0LCByaWdodF0gPSBhcmdzO1xuICAgICAgICB0aGlzLmtuZXhRdWVyeVtqb2luVHlwZV0odGFibGVOYW1lLCBsZWZ0LCByaWdodCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdGFibGVOYW1lT3JTcGVjID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAvLyBDYXNlIDI6IGpvaW4oeyBhbGlhczogXCJ0YWJsZVwiIH0sIC4uLikgb3Igam9pbih7IGFsaWFzOiBzdWJxdWVyeSB9LCAuLi4pXG4gICAgICBjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXModGFibGVOYW1lT3JTcGVjKTtcbiAgICAgIGlmIChlbnRyaWVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUYWJsZSBzcGVjIG11c3QgaGF2ZSBleGFjdGx5IG9uZSBlbnRyeVwiKTtcbiAgICAgIH1cbiAgICAgIGFzc2VydChlbnRyaWVzWzBdKTtcbiAgICAgIGNvbnN0IFtbYWxpYXMsIHNwZWNdXSA9IGVudHJpZXM7XG5cbiAgICAgIGlmICh0eXBlb2Ygc3BlYyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAvLyDthYzsnbTruJQ6IGpvaW4oeyBwOiBcInBvc3RzXCIgfSwgLi4uKVxuICAgICAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3NbMF0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgIC8vIENhbGxiYWNrXG4gICAgICAgICAgY29uc3QgY2FsbGJhY2sgPSBhcmdzWzBdO1xuICAgICAgICAgIHRoaXMua25leFF1ZXJ5W2pvaW5UeXBlXSh7IFthbGlhc106IHNwZWMgfSwgKGpvaW5DbGF1c2UpID0+IHtcbiAgICAgICAgICAgIGNhbGxiYWNrKG5ldyBKb2luQ2xhdXNlR3JvdXAoam9pbkNsYXVzZSkpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFNpbXBsZVxuICAgICAgICAgIGNvbnN0IFtsZWZ0LCByaWdodF0gPSBhcmdzO1xuICAgICAgICAgIHRoaXMua25leFF1ZXJ5W2pvaW5UeXBlXSh7IFthbGlhc106IHNwZWMgfSwgbGVmdCwgcmlnaHQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNwZWMgaW5zdGFuY2VvZiBQdXJpKSB7XG4gICAgICAgIC8vIOyEnOu4jOy/vOumrDogam9pbih7IHNxOiBzdWJxdWVyeSB9LCAuLi4pXG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMSAmJiB0eXBlb2YgYXJnc1swXSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgLy8gQ2FsbGJhY2tcbiAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IGFyZ3NbMF07XG4gICAgICAgICAgdGhpcy5rbmV4UXVlcnlbam9pblR5cGVdKHNwZWMucmF3KCkuYXMoYWxpYXMpLCAoam9pbkNsYXVzZSkgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2sobmV3IEpvaW5DbGF1c2VHcm91cChqb2luQ2xhdXNlKSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gU2ltcGxlXG4gICAgICAgICAgY29uc3QgW2xlZnQsIHJpZ2h0XSA9IGFyZ3M7XG4gICAgICAgICAgdGhpcy5rbmV4UXVlcnlbam9pblR5cGVdKHNwZWMucmF3KCkuYXMoYWxpYXMpLCBsZWZ0LCByaWdodCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdGFibGUgc3BlY2lmaWNhdGlvblwiKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBhcmd1bWVudHNcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBXSEVSRTog6rCd7LK0IC0g7IKs7JqpOiAud2hlcmUoeyBcInUuaWRcIjogMSwgXCJ1LnN0YXR1c1wiOiBcImFjdGl2ZVwiIH0pXG4gIHdoZXJlKGNvbmRpdGlvbnM6IFdoZXJlQ29uZGl0aW9uPFRUYWJsZXM+KTogdGhpcztcbiAgLy8gV0hFUkU6IOy7rOufvCAtIOyCrOyaqTogLndoZXJlKFwidS5pZFwiLCAxKVxuICB3aGVyZTxUQ29sdW1uIGV4dGVuZHMgQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPj4oXG4gICAgY29sdW1uOiBUQ29sdW1uLFxuICAgIHZhbHVlOiBFeHRyYWN0Q29sdW1uVHlwZTxUVGFibGVzLCBUQ29sdW1uICYgc3RyaW5nPlxuICApOiB0aGlzO1xuICAvLyBXSEVSRTog7Lus65+8IC0g7IKs7JqpOiAud2hlcmUoXCJ1LmlkXCIsIFwiPlwiLCAxMClcbiAgd2hlcmU8VENvbHVtbiBleHRlbmRzIEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICBvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yIHwgXCJsaWtlXCIgfCBcIm5vdCBsaWtlXCIsXG4gICAgdmFsdWU6IEV4dHJhY3RDb2x1bW5UeXBlPFRUYWJsZXMsIFRDb2x1bW4gJiBzdHJpbmc+XG4gICk6IHRoaXM7XG4gIC8vIFdIRVJFOiDsu6zrn7wgLSDsgqzsmqk6IC53aGVyZShcInUuaWRcIiwgXCJsaWtlXCIsIFwiJXRlc3QlXCIpXG4gIHdoZXJlKGNvbHVtbk9yQ29uZGl0aW9uczogYW55LCBvcGVyYXRvck9yVmFsdWU/OiBhbnksIHZhbHVlPzogYW55KTogdGhpcyB7XG4gICAgaWYgKHR5cGVvZiBjb2x1bW5PckNvbmRpdGlvbnMgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRoaXMua25leFF1ZXJ5LndoZXJlKGNvbHVtbk9yQ29uZGl0aW9ucyk7XG4gICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7XG4gICAgICBpZiAob3BlcmF0b3JPclZhbHVlID09PSBudWxsKSB7XG4gICAgICAgIHRoaXMua25leFF1ZXJ5LndoZXJlTnVsbChjb2x1bW5PckNvbmRpdGlvbnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIHRoaXMua25leFF1ZXJ5LndoZXJlKGNvbHVtbk9yQ29uZGl0aW9ucywgb3BlcmF0b3JPclZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpIHtcbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICBpZiAob3BlcmF0b3JPclZhbHVlID09PSBcIiE9XCIpIHtcbiAgICAgICAgICB0aGlzLmtuZXhRdWVyeS53aGVyZU5vdE51bGwoY29sdW1uT3JDb25kaXRpb25zKTtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRvck9yVmFsdWUgPT09IFwiPVwiKSB7XG4gICAgICAgICAgdGhpcy5rbmV4UXVlcnkud2hlcmVOdWxsKGNvbHVtbk9yQ29uZGl0aW9ucyk7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMua25leFF1ZXJ5LndoZXJlKGNvbHVtbk9yQ29uZGl0aW9ucywgb3BlcmF0b3JPclZhbHVlLCB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMua25leFF1ZXJ5LndoZXJlKGNvbHVtbk9yQ29uZGl0aW9ucyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gV0hFUkUgSU5cbiAgd2hlcmVJbjxUQ29sdW1uIGV4dGVuZHMgQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPj4oXG4gICAgY29sdW1uOiBUQ29sdW1uLFxuICAgIHZhbHVlczogRXh0cmFjdENvbHVtblR5cGU8VFRhYmxlcywgVENvbHVtbiAmIHN0cmluZz5bXVxuICApOiBQdXJpPFRTY2hlbWEsIFRUYWJsZXMsIFRSZXN1bHQ+IHtcbiAgICB0aGlzLmtuZXhRdWVyeS53aGVyZUluKGNvbHVtbiwgdmFsdWVzKTtcbiAgICByZXR1cm4gdGhpcyBhcyBhbnk7XG4gIH1cblxuICAvLyBXSEVSRSBOT1QgSU5cbiAgd2hlcmVOb3RJbjxUQ29sdW1uIGV4dGVuZHMgQXZhaWxhYmxlQ29sdW1uczxUVGFibGVzPj4oXG4gICAgY29sdW1uOiBUQ29sdW1uLFxuICAgIHZhbHVlczogRXh0cmFjdENvbHVtblR5cGU8VFRhYmxlcywgVENvbHVtbiAmIHN0cmluZz5bXVxuICApOiBQdXJpPFRTY2hlbWEsIFRUYWJsZXMsIFRSZXN1bHQ+IHtcbiAgICB0aGlzLmtuZXhRdWVyeS53aGVyZUluKGNvbHVtbiwgdmFsdWVzKTtcbiAgICByZXR1cm4gdGhpcyBhcyBhbnk7XG4gIH1cblxuICAvLyBXSEVSRSBNQVRDSFxuICB3aGVyZU1hdGNoPFRDb2x1bW4gZXh0ZW5kcyBGdWxsdGV4dENvbHVtbnM8VFRhYmxlcz4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICB2YWx1ZTogc3RyaW5nXG4gICk6IHRoaXMge1xuICAgIHRoaXMua25leFF1ZXJ5LndoZXJlUmF3KGBNQVRDSCAoJHtTdHJpbmcoY29sdW1uKX0pIEFHQUlOU1QgKD8pYCwgW3ZhbHVlXSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBXSEVSRSDqtITtmLgg6re466O57ZWRXG4gIHdoZXJlR3JvdXAoY2FsbGJhY2s6IChnOiBXaGVyZUdyb3VwPFRUYWJsZXM+KSA9PiB2b2lkKTogdGhpcyB7XG4gICAgdGhpcy5rbmV4UXVlcnkud2hlcmUoKGJ1aWxkZXIpID0+IHtcbiAgICAgIGNvbnN0IGdyb3VwID0gbmV3IFdoZXJlR3JvdXA8VFRhYmxlcz4oYnVpbGRlcik7XG4gICAgICBjYWxsYmFjayhncm91cCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgb3JXaGVyZUdyb3VwKGNhbGxiYWNrOiAoZzogV2hlcmVHcm91cDxUVGFibGVzPikgPT4gdm9pZCk6IHRoaXMge1xuICAgIHRoaXMua25leFF1ZXJ5Lm9yV2hlcmUoKGJ1aWxkZXIpID0+IHtcbiAgICAgIGNvbnN0IGdyb3VwID0gbmV3IFdoZXJlR3JvdXA8VFRhYmxlcz4oYnVpbGRlcik7XG4gICAgICBjYWxsYmFjayhncm91cCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBPUkRFUiBCWVxuICBvcmRlckJ5PFRDb2x1bW4gZXh0ZW5kcyBSZXN1bHRBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXMsIFRSZXN1bHQ+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICAgZGlyZWN0aW9uOiBcImFzY1wiIHwgXCJkZXNjXCJcbiAgKTogdGhpcztcbiAgb3JkZXJCeShjb2x1bW46IHN0cmluZywgZGlyZWN0aW9uOiBcImFzY1wiIHwgXCJkZXNjXCIgPSBcImFzY1wiKTogdGhpcyB7XG4gICAgdGhpcy5rbmV4UXVlcnkub3JkZXJCeShjb2x1bW4sIGRpcmVjdGlvbik7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyDquLDrs7gg7L+866asIOuplOyEnOuTnOuTpFxuICBsaW1pdChjb3VudDogbnVtYmVyKTogdGhpcyB7XG4gICAgdGhpcy5rbmV4UXVlcnkubGltaXQoY291bnQpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgb2Zmc2V0KGNvdW50OiBudW1iZXIpOiB0aGlzIHtcbiAgICB0aGlzLmtuZXhRdWVyeS5vZmZzZXQoY291bnQpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gR1JPVVAgQllcbiAgZ3JvdXBCeTxUQ29sdW1ucyBleHRlbmRzIFJlc3VsdEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcywgVFJlc3VsdD4+KFxuICAgIC4uLmNvbHVtbnM6IFRDb2x1bW5zW11cbiAgKTogdGhpcztcbiAgZ3JvdXBCeSguLi5jb2x1bW5zOiBzdHJpbmdbXSk6IHRoaXMge1xuICAgIHRoaXMua25leFF1ZXJ5Lmdyb3VwQnkoLi4uKGNvbHVtbnMgYXMgc3RyaW5nW10pKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIEhBVklOR1xuICBoYXZpbmcoY29uZGl0aW9uOiBzdHJpbmcpOiB0aGlzO1xuICBoYXZpbmc8VENvbHVtbiBleHRlbmRzIFJlc3VsdEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcywgVFJlc3VsdD4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICBvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLFxuICAgIHZhbHVlOiBhbnlcbiAgKTogdGhpcztcbiAgLy8gSEFWSU5HIOq1rO2YhFxuICBoYXZpbmcoLi4uY29uZGl0aW9uczogYW55W10pOiB0aGlzIHtcbiAgICBpZiAoY29uZGl0aW9ucy5sZW5ndGggPT09IDEpIHtcbiAgICAgIC8vIGhhdmluZyhcIkNPVU5UKCopID4gMTBcIilcbiAgICAgIHRoaXMua25leFF1ZXJ5LmhhdmluZyhjb25kaXRpb25zWzBdKTtcbiAgICB9IGVsc2UgaWYgKGNvbmRpdGlvbnMubGVuZ3RoID09PSAzKSB7XG4gICAgICAvLyBoYXZpbmcoXCJjb3VudFwiLCBcIj5cIiwgMTApXG4gICAgICB0aGlzLmtuZXhRdWVyeS5oYXZpbmcoY29uZGl0aW9uc1swXSwgY29uZGl0aW9uc1sxXSwgY29uZGl0aW9uc1syXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgaGF2aW5nIGFyZ3VtZW50c1wiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyDsi6Ttlokg66mU7ISc65Oc65OkIC0gdGhlbmFibGUg6rWs7ZiEXG4gIHRoZW48VFJlc3VsdDEgPSBFeHBhbmQ8VFJlc3VsdD5bXSwgVFJlc3VsdDIgPSBuZXZlcj4oXG4gICAgb25mdWxmaWxsZWQ/OlxuICAgICAgfCAoKHZhbHVlOiBFeHBhbmQ8VFJlc3VsdD5bXSkgPT4gVFJlc3VsdDEgfCBQcm9taXNlTGlrZTxUUmVzdWx0MT4pXG4gICAgICB8IG51bGwsXG4gICAgb25yZWplY3RlZD86ICgocmVhc29uOiBhbnkpID0+IFRSZXN1bHQyIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDI+KSB8IG51bGxcbiAgKTogUHJvbWlzZTxUUmVzdWx0MSB8IFRSZXN1bHQyPiB7XG4gICAgTmFpdGUudChcInB1cmktcXVlcnlcIiwgdGhpcy50b1F1ZXJ5KCkpO1xuICAgIHJldHVybiB0aGlzLmtuZXhRdWVyeS50aGVuKG9uZnVsZmlsbGVkIGFzIGFueSwgb25yZWplY3RlZCk7XG4gIH1cbiAgY2F0Y2g8VFJlc3VsdDIgPSBuZXZlcj4oXG4gICAgb25yZWplY3RlZD86ICgocmVhc29uOiBhbnkpID0+IFRSZXN1bHQyIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDI+KSB8IG51bGxcbiAgKTogUHJvbWlzZTxUUmVzdWx0IHwgVFJlc3VsdDI+IHtcbiAgICByZXR1cm4gdGhpcy5rbmV4UXVlcnkuY2F0Y2gob25yZWplY3RlZCk7XG4gIH1cbiAgZmluYWxseShvbmZpbmFsbHk/OiAoKCkgPT4gdm9pZCkgfCBudWxsKTogUHJvbWlzZTxUUmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMua25leFF1ZXJ5LmZpbmFsbHkob25maW5hbGx5KTtcbiAgfVxuXG4gIC8vIO2VmOuCmOunjCDsv7zrpqxcbiAgZmlyc3QoKTogUmVzb2x2ZWRQdXJpPEV4cGFuZDxUUmVzdWx0PiwgbmV2ZXI+IHtcbiAgICB0aGlzLmtuZXhRdWVyeS5maXJzdCgpO1xuICAgIHJldHVybiBuZXcgUmVzb2x2ZWRQdXJpKHRoaXMua25leFF1ZXJ5KTtcbiAgfVxuXG4gIC8vIOy/vOumrO2VnCDroIjsvZTrk5zsl5DshJwg7Yq57KCVIOy7rOufvOunjCDstpTstpztlZwg67Cw7Je0IOumrO2EtFxuICBwbHVjazxcbiAgICBUQ29sdW1uIGV4dGVuZHMga2V5b2YgVFJlc3VsdCB8IFJlc3VsdEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcywgVFJlc3VsdD4sXG4gID4oXG4gICAgY29sdW1uOiBUQ29sdW1uXG4gICk6IFJlc29sdmVkUHVyaTxcbiAgICBUQ29sdW1uIGV4dGVuZHMga2V5b2YgVFJlc3VsdFxuICAgICAgPyBUUmVzdWx0W1RDb2x1bW5dW11cbiAgICAgIDogRXh0cmFjdENvbHVtblR5cGU8VFRhYmxlcywgVENvbHVtbiAmIHN0cmluZz5bXSxcbiAgICBuZXZlclxuICA+IHtcbiAgICB0aGlzLmtuZXhRdWVyeS5wbHVjayhjb2x1bW4gYXMgc3RyaW5nKTtcbiAgICByZXR1cm4gbmV3IFJlc29sdmVkUHVyaSh0aGlzLmtuZXhRdWVyeSk7XG4gIH1cblxuICAvLyBJTlNFUlRcbiAgaW5zZXJ0KFxuICAgIGRhdGE6IEluc2VydERhdGE8U2luZ2xlVGFibGVWYWx1ZTxUVGFibGVzPj5cbiAgKTogUmVzb2x2ZWRQdXJpPFtudW1iZXJdLCBuZXZlcj4ge1xuICAgIHRoaXMua25leFF1ZXJ5Lmluc2VydChkYXRhKTtcbiAgICByZXR1cm4gbmV3IFJlc29sdmVkUHVyaSh0aGlzLmtuZXhRdWVyeSk7XG4gIH1cblxuICAvLyBVUERBVEVcbiAgdXBkYXRlKGRhdGE6IFdoZXJlQ29uZGl0aW9uPFRUYWJsZXM+KTogUmVzb2x2ZWRQdXJpPFRSZXN1bHQsIG51bWJlcj4ge1xuICAgIHRoaXMua25leFF1ZXJ5LnVwZGF0ZShkYXRhKTtcbiAgICByZXR1cm4gbmV3IFJlc29sdmVkUHVyaSh0aGlzLmtuZXhRdWVyeSk7XG4gIH1cblxuICAvLyBJbmNyZW1lbnRcbiAgaW5jcmVtZW50PFRDb2x1bW4gZXh0ZW5kcyBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICAgdmFsdWU6IG51bWJlclxuICApOiBSZXNvbHZlZFB1cmk8bnVtYmVyLCBuZXZlcj4ge1xuICAgIGlmICh2YWx1ZSA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbmNyZW1lbnQgdmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gMFwiKTtcbiAgICB9XG4gICAgdGhpcy5rbmV4UXVlcnkuaW5jcmVtZW50KGNvbHVtbiwgdmFsdWUpO1xuICAgIHJldHVybiBuZXcgUmVzb2x2ZWRQdXJpKHRoaXMua25leFF1ZXJ5KTtcbiAgfVxuICAvLyBEZWNyZW1lbnRcbiAgZGVjcmVtZW50PFRDb2x1bW4gZXh0ZW5kcyBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICAgdmFsdWU6IG51bWJlclxuICApOiBSZXNvbHZlZFB1cmk8bnVtYmVyLCBuZXZlcj4ge1xuICAgIGlmICh2YWx1ZSA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEZWNyZW1lbnQgdmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gMFwiKTtcbiAgICB9XG4gICAgdGhpcy5rbmV4UXVlcnkuZGVjcmVtZW50KGNvbHVtbiwgdmFsdWUpO1xuICAgIHJldHVybiBuZXcgUmVzb2x2ZWRQdXJpKHRoaXMua25leFF1ZXJ5KTtcbiAgfVxuXG4gIC8vIERFTEVURVxuICBkZWxldGUoKTogUmVzb2x2ZWRQdXJpPG51bWJlciwgbmV2ZXI+IHtcbiAgICB0aGlzLmtuZXhRdWVyeS5kZWxldGUoKTtcbiAgICByZXR1cm4gbmV3IFJlc29sdmVkUHVyaSh0aGlzLmtuZXhRdWVyeSk7XG4gIH1cblxuICAvLyDtmZXsnbgg7L+866asIOumrO2EtFxuICB0b1F1ZXJ5KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMua25leFF1ZXJ5LnRvUXVlcnkoKTtcbiAgfVxuXG4gIC8vIOy/vOumrCDrlJTrsoTquYUg66Gc6re4IOy2nOugpVxuICBkZWJ1ZygpOiB0aGlzIHtcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGAke2NoYWxrLmN5YW4oXCJbUHVyaSBEZWJ1Z11cIil9ICR7Y2hhbGsueWVsbG93KHRoaXMudG9RdWVyeSgpKX1gXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGZvcm1hdFNRTCh1bmZvcm1hdHRlZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAvLyBTUUwg7JiI7JW97Ja0IOuqqeuhnVxuICAgIGNvbnN0IGtleXdvcmRzID0gW1xuICAgICAgXCJTRUxFQ1RcIixcbiAgICAgIFwiRlJPTVwiLFxuICAgICAgXCJXSEVSRVwiLFxuICAgICAgXCJJTlNFUlRcIixcbiAgICAgIFwiSU5UT1wiLFxuICAgICAgXCJWQUxVRVNcIixcbiAgICAgIFwiVVBEQVRFXCIsXG4gICAgICBcIkRFTEVURVwiLFxuICAgICAgXCJDUkVBVEVcIixcbiAgICAgIFwiVEFCTEVcIixcbiAgICAgIFwiQUxURVJcIixcbiAgICAgIFwiRFJPUFwiLFxuICAgICAgXCJKT0lOXCIsXG4gICAgICBcIk9OXCIsXG4gICAgICBcIklOTkVSXCIsXG4gICAgICBcIkxFRlRcIixcbiAgICAgIFwiUklHSFRcIixcbiAgICAgIFwiRlVMTFwiLFxuICAgICAgXCJPVVRFUlwiLFxuICAgICAgXCJHUk9VUFwiLFxuICAgICAgXCJCWVwiLFxuICAgICAgXCJPUkRFUlwiLFxuICAgICAgXCJIQVZJTkdcIixcbiAgICAgIFwiRElTVElOQ1RcIixcbiAgICAgIFwiTElNSVRcIixcbiAgICAgIFwiT0ZGU0VUXCIsXG4gICAgICBcIkFTXCIsXG4gICAgICBcIkFORFwiLFxuICAgICAgXCJPUlwiLFxuICAgICAgXCJOT1RcIixcbiAgICAgIFwiSU5cIixcbiAgICAgIFwiTElLRVwiLFxuICAgICAgXCJJU1wiLFxuICAgICAgXCJOVUxMXCIsXG4gICAgICBcIkNBU0VcIixcbiAgICAgIFwiV0hFTlwiLFxuICAgICAgXCJUSEVOXCIsXG4gICAgICBcIkVMU0VcIixcbiAgICAgIFwiRU5EXCIsXG4gICAgICBcIlVOSU9OXCIsXG4gICAgICBcIkFMTFwiLFxuICAgICAgXCJFWElTVFNcIixcbiAgICAgIFwiQkVUV0VFTlwiLFxuICAgIF07XG5cbiAgICBsZXQgZm9ybWF0dGVkID0gdW5mb3JtYXR0ZWQ7XG5cbiAgICAvLyDsmIjslb3slrTrpbwg64yA66y47J6Q66GcIOuzgO2ZmFxuICAgIGtleXdvcmRzLmZvckVhY2goKGtleXdvcmQpID0+IHtcbiAgICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChgXFxcXGIke2tleXdvcmR9XFxcXGJgLCBcImdpXCIpO1xuICAgICAgZm9ybWF0dGVkID0gZm9ybWF0dGVkLnJlcGxhY2UocmVnZXgsIGtleXdvcmQudG9VcHBlckNhc2UoKSk7XG4gICAgfSk7XG5cbiAgICAvLyDso7zsmpQg7KCIIOyVnuyXkCDspITrsJTqv4gg7LaU6rCAXG4gICAgY29uc3QgbWFqb3JDbGF1c2VzID0gW1xuICAgICAgXCJTRUxFQ1RcIixcbiAgICAgIFwiRlJPTVwiLFxuICAgICAgXCJXSEVSRVwiLFxuICAgICAgXCJHUk9VUCBCWVwiLFxuICAgICAgXCJPUkRFUiBCWVwiLFxuICAgICAgXCJIQVZJTkdcIixcbiAgICAgIFwiTElNSVRcIixcbiAgICAgIFwiVU5JT05cIixcbiAgICBdO1xuICAgIG1ham9yQ2xhdXNlcy5mb3JFYWNoKChjbGF1c2UpID0+IHtcbiAgICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChgXFxcXHMrKCR7Y2xhdXNlfSlcXFxccytgLCBcImdpXCIpO1xuICAgICAgZm9ybWF0dGVkID0gZm9ybWF0dGVkLnJlcGxhY2UocmVnZXgsIGBcXG4ke2NsYXVzZS50b1VwcGVyQ2FzZSgpfSBgKTtcbiAgICB9KTtcblxuICAgIC8vIEpPSU4g7KCIIOyymOumrFxuICAgIGZvcm1hdHRlZCA9IGZvcm1hdHRlZC5yZXBsYWNlKFxuICAgICAgL1xccysoKD86SU5ORVJ8TEVGVHxSSUdIVHxGVUxMIE9VVEVSKVxccyspP0pPSU5cXHMrL2dpLFxuICAgICAgXCJcXG4kMUpPSU4gXCJcbiAgICApO1xuXG4gICAgLy8gQU5ELCBPUiDsobDqsbQg7LKY66asXG4gICAgZm9ybWF0dGVkID0gZm9ybWF0dGVkLnJlcGxhY2UoL1xccysoQU5EfE9SKVxccysvZ2ksIFwiXFxuICAkMSBcIik7XG5cbiAgICAvLyDqtITtmLgg7LKY66asIOuwjyDrk6Tsl6zsk7DquLBcbiAgICBjb25zdCBsaW5lcyA9IGZvcm1hdHRlZC5zcGxpdChcIlxcblwiKTtcbiAgICBjb25zdCBpbmRlbnRlZExpbmVzID0gW107XG4gICAgbGV0IGluZGVudExldmVsID0gMDtcblxuICAgIGZvciAobGV0IGxpbmUgb2YgbGluZXMpIHtcbiAgICAgIGNvbnN0IHRyaW1tZWRMaW5lID0gbGluZS50cmltKCk7XG4gICAgICBpZiAoIXRyaW1tZWRMaW5lKSBjb250aW51ZTtcblxuICAgICAgLy8g64ur64qUIOq0hO2YuOqwgCDsnojsnLzrqbQg65Ok7Jes7JOw6riwIOugiOuyqCDqsJDshoxcbiAgICAgIGNvbnN0IGNsb3NpbmdQYXJlbnMgPSAodHJpbW1lZExpbmUubWF0Y2goL1xcKS9nKSB8fCBbXSkubGVuZ3RoO1xuICAgICAgY29uc3Qgb3BlbmluZ1BhcmVucyA9ICh0cmltbWVkTGluZS5tYXRjaCgvXFwoL2cpIHx8IFtdKS5sZW5ndGg7XG5cbiAgICAgIGlmIChjbG9zaW5nUGFyZW5zID4gMCAmJiBvcGVuaW5nUGFyZW5zID09PSAwKSB7XG4gICAgICAgIGluZGVudExldmVsID0gTWF0aC5tYXgoMCwgaW5kZW50TGV2ZWwgLSBjbG9zaW5nUGFyZW5zKTtcbiAgICAgIH1cblxuICAgICAgLy8g7ZiE7J6sIOuTpOyXrOyTsOq4sCDsoIHsmqlcbiAgICAgIGNvbnN0IGluZGVudCA9IFwiICBcIi5yZXBlYXQoaW5kZW50TGV2ZWwpO1xuICAgICAgaW5kZW50ZWRMaW5lcy5wdXNoKGluZGVudCArIHRyaW1tZWRMaW5lKTtcblxuICAgICAgLy8g7Jes64qUIOq0hO2YuOqwgCDsnojsnLzrqbQg65Ok7Jes7JOw6riwIOugiOuyqCDspp3qsIBcbiAgICAgIGlmIChvcGVuaW5nUGFyZW5zID4gY2xvc2luZ1BhcmVucykge1xuICAgICAgICBpbmRlbnRMZXZlbCArPSBvcGVuaW5nUGFyZW5zIC0gY2xvc2luZ1BhcmVucztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaW5kZW50ZWRMaW5lcy5qb2luKFwiXFxuXCIpLnRyaW0oKTtcbiAgfVxuXG4gIC8vIEtuZXgg7L+866asIOu5jOuNlCDsp4HsoJEg7KCR6re8XG4gIHJhdygpOiBLbmV4LlF1ZXJ5QnVpbGRlciB7XG4gICAgcmV0dXJuIHRoaXMua25leFF1ZXJ5O1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXaGVyZUdyb3VwPFRUYWJsZXMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgYnVpbGRlcjogS25leC5RdWVyeUJ1aWxkZXIpIHt9XG5cbiAgLy8gd2hlcmUg66mU7ISc65Oc65OkXG4gIHdoZXJlKGNvbmRpdGlvbnM6IFdoZXJlQ29uZGl0aW9uPFRUYWJsZXM+KTogdGhpcztcbiAgd2hlcmU8VENvbHVtbiBleHRlbmRzIEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICB2YWx1ZTogRXh0cmFjdENvbHVtblR5cGU8VFRhYmxlcywgVENvbHVtbiAmIHN0cmluZz5cbiAgKTogdGhpcztcbiAgd2hlcmU8VENvbHVtbiBleHRlbmRzIEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICBvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLFxuICAgIHZhbHVlOiBFeHRyYWN0Q29sdW1uVHlwZTxUVGFibGVzLCBUQ29sdW1uICYgc3RyaW5nPlxuICApOiB0aGlzO1xuICB3aGVyZSguLi5hcmdzOiBhbnlbXSk6IFdoZXJlR3JvdXA8VFRhYmxlcz4ge1xuICAgIHRoaXMuYnVpbGRlci53aGVyZShhcmdzWzBdLCAuLi5hcmdzLnNsaWNlKDEpKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIG9yV2hlcmUg66mU7ISc65Oc65OkXG4gIG9yV2hlcmUoY29uZGl0aW9uczogV2hlcmVDb25kaXRpb248VFRhYmxlcz4pOiB0aGlzO1xuICBvcldoZXJlPFRDb2x1bW4gZXh0ZW5kcyBBdmFpbGFibGVDb2x1bW5zPFRUYWJsZXM+PihcbiAgICBjb2x1bW46IFRDb2x1bW4sXG4gICAgdmFsdWU6IEV4dHJhY3RDb2x1bW5UeXBlPFRUYWJsZXMsIFRDb2x1bW4gJiBzdHJpbmc+XG4gICk6IHRoaXM7XG4gIG9yV2hlcmU8VENvbHVtbiBleHRlbmRzIEF2YWlsYWJsZUNvbHVtbnM8VFRhYmxlcz4+KFxuICAgIGNvbHVtbjogVENvbHVtbixcbiAgICBvcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLFxuICAgIHZhbHVlOiBFeHRyYWN0Q29sdW1uVHlwZTxUVGFibGVzLCBUQ29sdW1uICYgc3RyaW5nPlxuICApOiB0aGlzO1xuICBvcldoZXJlKC4uLmFyZ3M6IGFueVtdKTogV2hlcmVHcm91cDxUVGFibGVzPiB7XG4gICAgdGhpcy5idWlsZGVyLm9yV2hlcmUoYXJnc1swXSwgLi4uYXJncy5zbGljZSgxKSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyDspJHssqkg6re466O5XG4gIHdoZXJlR3JvdXAoY2FsbGJhY2s6IChnOiBXaGVyZUdyb3VwPFRUYWJsZXM+KSA9PiB2b2lkKTogdGhpcztcbiAgd2hlcmVHcm91cChjYWxsYmFjazogKGc6IFdoZXJlR3JvdXA8VFRhYmxlcz4pID0+IHZvaWQpOiBXaGVyZUdyb3VwPFRUYWJsZXM+IHtcbiAgICB0aGlzLmJ1aWxkZXIud2hlcmUoKHN1YkJ1aWxkZXIpID0+IHtcbiAgICAgIGNvbnN0IHN1Ykdyb3VwID0gbmV3IFdoZXJlR3JvdXA8VFRhYmxlcz4oc3ViQnVpbGRlcik7XG4gICAgICBjYWxsYmFjayhzdWJHcm91cCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgb3JXaGVyZUdyb3VwKGNhbGxiYWNrOiAoZzogV2hlcmVHcm91cDxUVGFibGVzPikgPT4gdm9pZCk6IHRoaXM7XG4gIG9yV2hlcmVHcm91cChcbiAgICBjYWxsYmFjazogKGc6IFdoZXJlR3JvdXA8VFRhYmxlcz4pID0+IHZvaWRcbiAgKTogV2hlcmVHcm91cDxUVGFibGVzPiB7XG4gICAgdGhpcy5idWlsZGVyLm9yV2hlcmUoKHN1YkJ1aWxkZXIpID0+IHtcbiAgICAgIGNvbnN0IHN1Ykdyb3VwID0gbmV3IFdoZXJlR3JvdXA8VFRhYmxlcz4oc3ViQnVpbGRlcik7XG4gICAgICBjYWxsYmFjayhzdWJHcm91cCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEpvaW5DbGF1c2VHcm91cDxcbiAgVExlZnQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBUUmlnaHQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuPiB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgY2FsbGJhY2s6IEtuZXguSm9pbkNsYXVzZSkge31cblxuICAvLyBPTihBTkQpOiDsu6zrn7wgPSDsu6zrn7xcbiAgb24obGVmdDogQXZhaWxhYmxlQ29sdW1uczxUTGVmdD4sIHJpZ2h0OiBBdmFpbGFibGVDb2x1bW5zPFRSaWdodD4pOiB0aGlzO1xuICAvLyBPTihBTkQpOiDsu6zrn7wgKOyXsOyCsOyekCkg7Lus65+8XG4gIG9uKFxuICAgIGxlZnQ6IEF2YWlsYWJsZUNvbHVtbnM8VExlZnQ+LFxuICAgIG9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IsXG4gICAgcmlnaHQ6IEF2YWlsYWJsZUNvbHVtbnM8VFJpZ2h0PlxuICApOiB0aGlzO1xuICAvLyBPTihBTkQpOiDsvZzrsLFcbiAgb24oY2FsbGJhY2s6IChuZXN0ZWQ6IEpvaW5DbGF1c2VHcm91cDxUTGVmdCwgVFJpZ2h0PikgPT4gdm9pZCk6IHRoaXM7XG4gIC8vIE9OKEFORCkg6rWs7ZiEXG4gIG9uKC4uLmFyZ3M6IGFueVtdKTogdGhpcyB7XG4gICAgdGhpcy5jYWxsYmFjay5vbiguLi4oYXJncyBhcyBbc3RyaW5nLCBzdHJpbmddKSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBPTihPUik6IOy7rOufvCA9IOy7rOufvFxuICBvck9uKGxlZnQ6IEF2YWlsYWJsZUNvbHVtbnM8VExlZnQ+LCByaWdodDogQXZhaWxhYmxlQ29sdW1uczxUUmlnaHQ+KTogdGhpcztcbiAgLy8gT04oT1IpOiDsu6zrn7wgKOyXsOyCsOyekCkg7Lus65+8XG4gIG9yT24oXG4gICAgbGVmdDogQXZhaWxhYmxlQ29sdW1uczxUTGVmdD4sXG4gICAgb3BlcmF0b3I6IENvbXBhcmlzb25PcGVyYXRvcixcbiAgICByaWdodDogQXZhaWxhYmxlQ29sdW1uczxUUmlnaHQ+XG4gICk6IHRoaXM7XG4gIC8vIE9OKE9SKTog7L2c67CxXG4gIG9yT24oY2FsbGJhY2s6IChuZXN0ZWQ6IEpvaW5DbGF1c2VHcm91cDxUTGVmdCwgVFJpZ2h0PikgPT4gdm9pZCk6IHRoaXM7XG4gIC8vIE9OKE9SKSDqtaztmIRcbiAgb3JPbiguLi5hcmdzOiBhbnlbXSk6IHRoaXMge1xuICAgIHRoaXMuY2FsbGJhY2sub3JPbiguLi4oYXJncyBhcyBbc3RyaW5nLCBzdHJpbmddKSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn1cblxuLypcbiAgVFJlc29sdmVkOiDsv7zrpqwg7Iuk7ZaJIO2bhCDrsJjtmZjrkKAg6rKw6rO8IO2DgOyehVxuICBfVFJldHVybmluZzog7LaU7ZuEIFJFVFVSTklORyDsoIjsl5Ag7IKs7Jqp65CgIO2DgOyehVxuKi9cbmV4cG9ydCBjbGFzcyBSZXNvbHZlZFB1cmk8VFJlc29sdmVkLCBfVFJldHVybmluZz4ge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMga25leFF1ZXJ5OiBLbmV4LlF1ZXJ5QnVpbGRlcikge31cblxuICB0b1F1ZXJ5KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMua25leFF1ZXJ5LnRvUXVlcnkoKTtcbiAgfVxuXG4gIGRlYnVnKCk6IHRoaXMge1xuICAgIGNvbnNvbGUubG9nKFxuICAgICAgYCR7Y2hhbGsuY3lhbihcIltQdXJpIERlYnVnXVwiKX0gJHtjaGFsay55ZWxsb3codGhpcy50b1F1ZXJ5KCkpfWBcbiAgICApO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdGhlbjxUUmVzdWx0MSA9IFRSZXNvbHZlZCwgVFJlc3VsdDIgPSBuZXZlcj4oXG4gICAgb25mdWxmaWxsZWQ/OlxuICAgICAgfCAoKHZhbHVlOiBUUmVzb2x2ZWQpID0+IFRSZXN1bHQxIHwgUHJvbWlzZUxpa2U8VFJlc3VsdDE+KVxuICAgICAgfCBudWxsLFxuICAgIG9ucmVqZWN0ZWQ/OiAoKHJlYXNvbjogYW55KSA9PiBUUmVzdWx0MiB8IFByb21pc2VMaWtlPFRSZXN1bHQyPikgfCBudWxsXG4gICk6IFByb21pc2U8VFJlc3VsdDEgfCBUUmVzdWx0Mj4ge1xuICAgIE5haXRlLnQoXCJwdXJpLXF1ZXJ5XCIsIHRoaXMudG9RdWVyeSgpKTtcbiAgICByZXR1cm4gdGhpcy5rbmV4UXVlcnkudGhlbihvbmZ1bGZpbGxlZCBhcyBhbnksIG9ucmVqZWN0ZWQpO1xuICB9XG4gIGNhdGNoPFRSZXN1bHQyID0gbmV2ZXI+KFxuICAgIG9ucmVqZWN0ZWQ/OiAoKHJlYXNvbjogYW55KSA9PiBUUmVzdWx0MiB8IFByb21pc2VMaWtlPFRSZXN1bHQyPikgfCBudWxsXG4gICk6IFByb21pc2U8VFJlc29sdmVkIHwgVFJlc3VsdDI+IHtcbiAgICByZXR1cm4gdGhpcy5rbmV4UXVlcnkuY2F0Y2gob25yZWplY3RlZCk7XG4gIH1cbiAgZmluYWxseShvbmZpbmFsbHk/OiAoKCkgPT4gdm9pZCkgfCBudWxsKTogUHJvbWlzZTxUUmVzb2x2ZWQ+IHtcbiAgICByZXR1cm4gdGhpcy5rbmV4UXVlcnkuZmluYWxseShvbmZpbmFsbHkpO1xuICB9XG59XG4iXSwibmFtZXMiOlsiY2hhbGsiLCJhc3NlcnQiLCJOYWl0ZSIsIlB1cmkiLCJrbmV4UXVlcnkiLCJrbmV4IiwidGFibGVOYW1lT3JTcGVjIiwiZnJvbSIsImVudHJpZXMiLCJPYmplY3QiLCJsZW5ndGgiLCJFcnJvciIsImFsaWFzIiwic3BlYyIsInN1YnF1ZXJ5QnVpbGRlciIsInJhdyIsImFzIiwiY291bnQiLCJjb2x1bW4iLCJfdHlwZSIsIl9yZXR1cm4iLCJfc3FsIiwic3VtIiwiYXZnIiwibWF4IiwibWluIiwiY29uY2F0IiwiYXJncyIsImpvaW4iLCJ1cHBlciIsImxvd2VyIiwicmF3U3RyaW5nIiwic3FsIiwicmF3TnVtYmVyIiwicmF3Qm9vbGVhbiIsInJhd0RhdGUiLCJzZWxlY3QiLCJzZWxlY3RPYmoiLCJzZWxlY3RDbGF1c2VzIiwiY29sdW1uT3JGdW5jdGlvbiIsInB1c2giLCJjb2x1bW5QYXRoIiwiYXBwZW5kU2VsZWN0Iiwic2VsZWN0QWxsIiwiX19jb21tb25Kb2luIiwibGVmdEpvaW4iLCJqb2luVHlwZSIsInRhYmxlTmFtZSIsImNhbGxiYWNrIiwiam9pbkNsYXVzZSIsIkpvaW5DbGF1c2VHcm91cCIsImxlZnQiLCJyaWdodCIsIndoZXJlIiwiY29sdW1uT3JDb25kaXRpb25zIiwib3BlcmF0b3JPclZhbHVlIiwidmFsdWUiLCJhcmd1bWVudHMiLCJ3aGVyZU51bGwiLCJ3aGVyZU5vdE51bGwiLCJ3aGVyZUluIiwidmFsdWVzIiwid2hlcmVOb3RJbiIsIndoZXJlTWF0Y2giLCJ3aGVyZVJhdyIsIlN0cmluZyIsIndoZXJlR3JvdXAiLCJidWlsZGVyIiwiZ3JvdXAiLCJXaGVyZUdyb3VwIiwib3JXaGVyZUdyb3VwIiwib3JXaGVyZSIsIm9yZGVyQnkiLCJkaXJlY3Rpb24iLCJsaW1pdCIsIm9mZnNldCIsImdyb3VwQnkiLCJjb2x1bW5zIiwiaGF2aW5nIiwiY29uZGl0aW9ucyIsInRoZW4iLCJvbmZ1bGZpbGxlZCIsIm9ucmVqZWN0ZWQiLCJ0IiwidG9RdWVyeSIsImNhdGNoIiwiZmluYWxseSIsIm9uZmluYWxseSIsImZpcnN0IiwiUmVzb2x2ZWRQdXJpIiwicGx1Y2siLCJpbnNlcnQiLCJkYXRhIiwidXBkYXRlIiwiaW5jcmVtZW50IiwiZGVjcmVtZW50IiwiZGVsZXRlIiwiZGVidWciLCJjb25zb2xlIiwibG9nIiwiY3lhbiIsInllbGxvdyIsImZvcm1hdFNRTCIsInVuZm9ybWF0dGVkIiwia2V5d29yZHMiLCJmb3JtYXR0ZWQiLCJmb3JFYWNoIiwia2V5d29yZCIsInJlZ2V4IiwiUmVnRXhwIiwicmVwbGFjZSIsInRvVXBwZXJDYXNlIiwibWFqb3JDbGF1c2VzIiwiY2xhdXNlIiwibGluZXMiLCJzcGxpdCIsImluZGVudGVkTGluZXMiLCJpbmRlbnRMZXZlbCIsImxpbmUiLCJ0cmltbWVkTGluZSIsInRyaW0iLCJjbG9zaW5nUGFyZW5zIiwibWF0Y2giLCJvcGVuaW5nUGFyZW5zIiwiTWF0aCIsImluZGVudCIsInJlcGVhdCIsInNsaWNlIiwic3ViQnVpbGRlciIsInN1Ykdyb3VwIiwib24iLCJvck9uIl0sIm1hcHBpbmdzIjoiQUFlQSxPQUFPQSxXQUFXLFFBQVE7QUFDMUIsT0FBT0MsWUFBWSxTQUFTO0FBQzVCLFNBQVNDLEtBQUssUUFBUSxvQkFBaUI7QUFFdkMsT0FBTyxNQUFNQzs7SUFDSEMsVUFBNkI7SUFRckMsWUFDRSxBQUFPQyxJQUFVLEVBQ2pCQyxlQUFvQixDQUNwQjthQUZPRCxPQUFBQTtRQUdQLElBQUksT0FBT0Msb0JBQW9CLFVBQVU7WUFDdkMsZ0NBQWdDO1lBQ2hDLElBQUksQ0FBQ0YsU0FBUyxHQUFHLElBQUksQ0FBQ0MsSUFBSSxDQUFDQyxpQkFBaUJDLElBQUksQ0FBQ0Q7UUFDbkQsT0FBTyxJQUFJLE9BQU9BLG9CQUFvQixVQUFVO1lBQzlDLE1BQU1FLFVBQVVDLE9BQU9ELE9BQU8sQ0FBQ0Y7WUFDL0IsSUFBSUUsUUFBUUUsTUFBTSxLQUFLLEdBQUc7Z0JBQ3hCLE1BQU0sSUFBSUMs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