@nlabs/reaktor 0.10.2 → 0.10.6

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 (472) hide show
  1. package/coverage/block-navigation.js +1 -1
  2. package/coverage/index.html +23 -23
  3. package/coverage/sorter.js +21 -7
  4. package/lib/actions/apps.d.ts +1 -0
  5. package/lib/actions/apps.d.ts.map +1 -0
  6. package/lib/actions/apps.js +218 -17
  7. package/lib/actions/connections.d.ts +1 -0
  8. package/lib/actions/connections.d.ts.map +1 -0
  9. package/lib/actions/connections.js +61 -6
  10. package/lib/actions/content.d.ts +1 -0
  11. package/lib/actions/content.d.ts.map +1 -0
  12. package/lib/actions/content.js +232 -9
  13. package/lib/actions/conversations.d.ts +1 -0
  14. package/lib/actions/conversations.d.ts.map +1 -0
  15. package/lib/actions/conversations.js +321 -19
  16. package/lib/actions/dynamodb.d.ts +1 -0
  17. package/lib/actions/dynamodb.d.ts.map +1 -0
  18. package/lib/actions/dynamodb.js +119 -2
  19. package/lib/actions/email.d.ts +1 -0
  20. package/lib/actions/email.d.ts.map +1 -0
  21. package/lib/actions/email.js +56 -2
  22. package/lib/actions/files.d.ts +1 -0
  23. package/lib/actions/files.d.ts.map +1 -0
  24. package/lib/actions/files.js +226 -5
  25. package/lib/actions/groups.d.ts +1 -0
  26. package/lib/actions/groups.d.ts.map +1 -0
  27. package/lib/actions/groups.js +234 -19
  28. package/lib/actions/images.d.ts +1 -0
  29. package/lib/actions/images.d.ts.map +1 -0
  30. package/lib/actions/images.js +688 -31
  31. package/lib/actions/index.d.ts +2 -0
  32. package/lib/actions/index.d.ts.map +1 -0
  33. package/lib/actions/index.js +29 -2
  34. package/lib/actions/ios.d.ts +1 -0
  35. package/lib/actions/ios.d.ts.map +1 -0
  36. package/lib/actions/ios.js +228 -9
  37. package/lib/actions/locations.d.ts +1 -0
  38. package/lib/actions/locations.d.ts.map +1 -0
  39. package/lib/actions/locations.js +111 -7
  40. package/lib/actions/messages.d.ts +1 -0
  41. package/lib/actions/messages.d.ts.map +1 -0
  42. package/lib/actions/messages.js +155 -21
  43. package/lib/actions/notifications.d.ts +1 -0
  44. package/lib/actions/notifications.d.ts.map +1 -0
  45. package/lib/actions/notifications.js +37 -2
  46. package/lib/actions/payments.d.ts +1 -0
  47. package/lib/actions/payments.d.ts.map +1 -0
  48. package/lib/actions/payments.js +428 -11
  49. package/lib/actions/posts.d.ts +1 -0
  50. package/lib/actions/posts.d.ts.map +1 -0
  51. package/lib/actions/posts.js +540 -75
  52. package/lib/actions/profiles.d.ts +1 -0
  53. package/lib/actions/profiles.d.ts.map +1 -0
  54. package/lib/actions/profiles.js +58 -8
  55. package/lib/actions/reactions.d.ts +1 -0
  56. package/lib/actions/reactions.d.ts.map +1 -0
  57. package/lib/actions/reactions.js +276 -25
  58. package/lib/actions/s3.d.ts +1 -0
  59. package/lib/actions/s3.d.ts.map +1 -0
  60. package/lib/actions/s3.js +102 -2
  61. package/lib/actions/search.d.ts +1 -0
  62. package/lib/actions/search.d.ts.map +1 -0
  63. package/lib/actions/search.js +81 -5
  64. package/lib/actions/sms.d.ts +1 -0
  65. package/lib/actions/sms.d.ts.map +1 -0
  66. package/lib/actions/sms.js +52 -2
  67. package/lib/actions/statistics.d.ts +1 -0
  68. package/lib/actions/statistics.d.ts.map +1 -0
  69. package/lib/actions/statistics.js +41 -6
  70. package/lib/actions/subscriptions.d.ts +1 -0
  71. package/lib/actions/subscriptions.d.ts.map +1 -0
  72. package/lib/actions/subscriptions.js +196 -6
  73. package/lib/actions/tags.d.ts +1 -0
  74. package/lib/actions/tags.d.ts.map +1 -0
  75. package/lib/actions/tags.js +258 -19
  76. package/lib/actions/users.d.ts +1 -0
  77. package/lib/actions/users.d.ts.map +1 -0
  78. package/lib/actions/users.js +781 -66
  79. package/lib/actions/videos.d.ts +26 -0
  80. package/lib/actions/videos.d.ts.map +1 -0
  81. package/lib/actions/videos.js +423 -0
  82. package/lib/actions/websockets.d.ts +1 -0
  83. package/lib/actions/websockets.d.ts.map +1 -0
  84. package/lib/actions/websockets.js +148 -14
  85. package/lib/adapters/arangoAdapter.d.ts +1 -0
  86. package/lib/adapters/arangoAdapter.d.ts.map +1 -0
  87. package/lib/adapters/arangoAdapter.js +70 -2
  88. package/lib/adapters/contentAdapter.d.ts +1 -0
  89. package/lib/adapters/contentAdapter.d.ts.map +1 -0
  90. package/lib/adapters/contentAdapter.js +108 -2
  91. package/lib/adapters/fileAdapter.d.ts +1 -0
  92. package/lib/adapters/fileAdapter.d.ts.map +1 -0
  93. package/lib/adapters/fileAdapter.js +119 -2
  94. package/lib/adapters/imageAdapter.d.ts +1 -0
  95. package/lib/adapters/imageAdapter.d.ts.map +1 -0
  96. package/lib/adapters/imageAdapter.js +112 -2
  97. package/lib/adapters/index.d.ts +1 -0
  98. package/lib/adapters/index.d.ts.map +1 -0
  99. package/lib/adapters/index.js +11 -2
  100. package/lib/adapters/messageAdapter.d.ts +1 -0
  101. package/lib/adapters/messageAdapter.d.ts.map +1 -0
  102. package/lib/adapters/messageAdapter.js +82 -2
  103. package/lib/adapters/postAdapter.d.ts +1 -0
  104. package/lib/adapters/postAdapter.d.ts.map +1 -0
  105. package/lib/adapters/postAdapter.js +117 -2
  106. package/lib/adapters/reaktorAdapter.d.ts +1 -0
  107. package/lib/adapters/reaktorAdapter.d.ts.map +1 -0
  108. package/lib/adapters/reaktorAdapter.js +59 -2
  109. package/lib/adapters/tagAdapter.d.ts +1 -0
  110. package/lib/adapters/tagAdapter.d.ts.map +1 -0
  111. package/lib/adapters/tagAdapter.js +99 -2
  112. package/lib/adapters/userAdapter.d.ts +1 -0
  113. package/lib/adapters/userAdapter.d.ts.map +1 -0
  114. package/lib/adapters/userAdapter.js +264 -2
  115. package/lib/config.d.ts +1 -0
  116. package/lib/config.d.ts.map +1 -0
  117. package/lib/config.js +161 -2
  118. package/lib/handlers/graphqlHandler.d.ts +1 -0
  119. package/lib/handlers/graphqlHandler.d.ts.map +1 -0
  120. package/lib/handlers/graphqlHandler.js +118 -2
  121. package/lib/index.d.ts +1 -0
  122. package/lib/index.d.ts.map +1 -0
  123. package/lib/index.js +18 -2
  124. package/lib/lambdas/actions/websockets.d.ts +1 -0
  125. package/lib/lambdas/actions/websockets.d.ts.map +1 -0
  126. package/lib/lambdas/actions/websockets.js +89 -14
  127. package/lib/lambdas/authorizer.d.ts +1 -0
  128. package/lib/lambdas/authorizer.d.ts.map +1 -0
  129. package/lib/lambdas/authorizer.js +41 -2
  130. package/lib/lambdas/connection.d.ts +1 -0
  131. package/lib/lambdas/connection.d.ts.map +1 -0
  132. package/lib/lambdas/connection.js +85 -2
  133. package/lib/lambdas/utils/message.d.ts +1 -0
  134. package/lib/lambdas/utils/message.d.ts.map +1 -0
  135. package/lib/lambdas/utils/message.js +20 -2
  136. package/lib/lambdas/utils/websocket.d.ts +1 -0
  137. package/lib/lambdas/utils/websocket.d.ts.map +1 -0
  138. package/lib/lambdas/utils/websocket.js +78 -2
  139. package/lib/mocks/conversation.d.ts +1 -0
  140. package/lib/mocks/conversation.d.ts.map +1 -0
  141. package/lib/mocks/conversation.js +10 -2
  142. package/lib/mocks/file.d.ts +1 -0
  143. package/lib/mocks/file.d.ts.map +1 -0
  144. package/lib/mocks/file.js +13 -2
  145. package/lib/mocks/group.d.ts +1 -0
  146. package/lib/mocks/group.d.ts.map +1 -0
  147. package/lib/mocks/group.js +20 -2
  148. package/lib/mocks/image.d.ts +1 -0
  149. package/lib/mocks/image.d.ts.map +1 -0
  150. package/lib/mocks/image.js +17 -2
  151. package/lib/mocks/post.d.ts +1 -0
  152. package/lib/mocks/post.d.ts.map +1 -0
  153. package/lib/mocks/post.js +28 -2
  154. package/lib/mocks/tag.d.ts +1 -0
  155. package/lib/mocks/tag.d.ts.map +1 -0
  156. package/lib/mocks/tag.js +12 -2
  157. package/lib/mocks/user.d.ts +1 -0
  158. package/lib/mocks/user.d.ts.map +1 -0
  159. package/lib/mocks/user.js +61 -2
  160. package/lib/mocks/video.d.ts +4 -0
  161. package/lib/mocks/video.d.ts.map +1 -0
  162. package/lib/mocks/video.js +17 -0
  163. package/lib/mutations/content.d.ts +1 -0
  164. package/lib/mutations/content.d.ts.map +1 -0
  165. package/lib/mutations/content.js +27 -2
  166. package/lib/mutations/index.d.ts +1 -0
  167. package/lib/mutations/index.d.ts.map +1 -0
  168. package/lib/mutations/index.js +29 -2
  169. package/lib/mutations/locations.d.ts +1 -0
  170. package/lib/mutations/locations.d.ts.map +1 -0
  171. package/lib/mutations/locations.js +22 -2
  172. package/lib/mutations/messages.d.ts +1 -0
  173. package/lib/mutations/messages.d.ts.map +1 -0
  174. package/lib/mutations/messages.js +75 -2
  175. package/lib/mutations/posts.d.ts +1 -0
  176. package/lib/mutations/posts.d.ts.map +1 -0
  177. package/lib/mutations/posts.js +31 -2
  178. package/lib/mutations/profiles.d.ts +1 -0
  179. package/lib/mutations/profiles.d.ts.map +1 -0
  180. package/lib/mutations/profiles.js +78 -2
  181. package/lib/mutations/reactions.d.ts +1 -0
  182. package/lib/mutations/reactions.d.ts.map +1 -0
  183. package/lib/mutations/reactions.js +29 -2
  184. package/lib/mutations/statistics.d.ts +1 -0
  185. package/lib/mutations/statistics.d.ts.map +1 -0
  186. package/lib/mutations/statistics.js +17 -2
  187. package/lib/mutations/subscriptions.d.ts +1 -0
  188. package/lib/mutations/subscriptions.d.ts.map +1 -0
  189. package/lib/mutations/subscriptions.js +38 -2
  190. package/lib/mutations/tags.d.ts +1 -0
  191. package/lib/mutations/tags.d.ts.map +1 -0
  192. package/lib/mutations/tags.js +109 -2
  193. package/lib/mutations/users.d.ts +1 -0
  194. package/lib/mutations/users.d.ts.map +1 -0
  195. package/lib/mutations/users.js +129 -2
  196. package/lib/objectTypes/app.d.ts +1 -0
  197. package/lib/objectTypes/app.d.ts.map +1 -0
  198. package/lib/objectTypes/app.js +147 -2
  199. package/lib/objectTypes/bankAccount.d.ts +1 -0
  200. package/lib/objectTypes/bankAccount.d.ts.map +1 -0
  201. package/lib/objectTypes/bankAccount.js +54 -2
  202. package/lib/objectTypes/connection.d.ts +1 -0
  203. package/lib/objectTypes/connection.d.ts.map +1 -0
  204. package/lib/objectTypes/connection.js +26 -2
  205. package/lib/objectTypes/content.d.ts +1 -0
  206. package/lib/objectTypes/content.d.ts.map +1 -0
  207. package/lib/objectTypes/content.js +79 -2
  208. package/lib/objectTypes/conversation.d.ts +1 -0
  209. package/lib/objectTypes/conversation.d.ts.map +1 -0
  210. package/lib/objectTypes/conversation.js +53 -2
  211. package/lib/objectTypes/creditCard.d.ts +1 -0
  212. package/lib/objectTypes/creditCard.d.ts.map +1 -0
  213. package/lib/objectTypes/creditCard.js +64 -2
  214. package/lib/objectTypes/document.d.ts +1 -0
  215. package/lib/objectTypes/document.d.ts.map +1 -0
  216. package/lib/objectTypes/document.js +21 -2
  217. package/lib/objectTypes/error.d.ts +1 -0
  218. package/lib/objectTypes/error.d.ts.map +1 -0
  219. package/lib/objectTypes/error.js +24 -2
  220. package/lib/objectTypes/external.d.ts +1 -0
  221. package/lib/objectTypes/external.d.ts.map +1 -0
  222. package/lib/objectTypes/external.js +52 -2
  223. package/lib/objectTypes/file.d.ts +1 -0
  224. package/lib/objectTypes/file.d.ts.map +1 -0
  225. package/lib/objectTypes/file.js +76 -2
  226. package/lib/objectTypes/filter.d.ts +1 -0
  227. package/lib/objectTypes/filter.d.ts.map +1 -0
  228. package/lib/objectTypes/filter.js +21 -2
  229. package/lib/objectTypes/group.d.ts +1 -0
  230. package/lib/objectTypes/group.d.ts.map +1 -0
  231. package/lib/objectTypes/group.js +97 -2
  232. package/lib/objectTypes/iapSubscription.d.ts +1 -0
  233. package/lib/objectTypes/iapSubscription.d.ts.map +1 -0
  234. package/lib/objectTypes/iapSubscription.js +18 -2
  235. package/lib/objectTypes/image.d.ts +1 -0
  236. package/lib/objectTypes/image.d.ts.map +1 -0
  237. package/lib/objectTypes/image.js +105 -2
  238. package/lib/objectTypes/index.d.ts +1 -0
  239. package/lib/objectTypes/index.d.ts.map +1 -0
  240. package/lib/objectTypes/index.js +28 -2
  241. package/lib/objectTypes/location.d.ts +1 -0
  242. package/lib/objectTypes/location.d.ts.map +1 -0
  243. package/lib/objectTypes/location.js +85 -2
  244. package/lib/objectTypes/message.d.ts +1 -0
  245. package/lib/objectTypes/message.d.ts.map +1 -0
  246. package/lib/objectTypes/message.js +72 -2
  247. package/lib/objectTypes/passcode.d.ts +1 -0
  248. package/lib/objectTypes/passcode.d.ts.map +1 -0
  249. package/lib/objectTypes/passcode.js +20 -2
  250. package/lib/objectTypes/plan.d.ts +1 -0
  251. package/lib/objectTypes/plan.d.ts.map +1 -0
  252. package/lib/objectTypes/plan.js +71 -2
  253. package/lib/objectTypes/post.d.ts +1 -0
  254. package/lib/objectTypes/post.d.ts.map +1 -0
  255. package/lib/objectTypes/post.js +101 -2
  256. package/lib/objectTypes/profile.d.ts +1 -0
  257. package/lib/objectTypes/profile.d.ts.map +1 -0
  258. package/lib/objectTypes/profile.js +68 -2
  259. package/lib/objectTypes/reaction.d.ts +1 -0
  260. package/lib/objectTypes/reaction.d.ts.map +1 -0
  261. package/lib/objectTypes/reaction.js +37 -2
  262. package/lib/objectTypes/relation.d.ts +1 -0
  263. package/lib/objectTypes/relation.d.ts.map +1 -0
  264. package/lib/objectTypes/relation.js +27 -2
  265. package/lib/objectTypes/search.d.ts +1 -0
  266. package/lib/objectTypes/search.d.ts.map +1 -0
  267. package/lib/objectTypes/search.js +50 -2
  268. package/lib/objectTypes/statistics.d.ts +1 -0
  269. package/lib/objectTypes/statistics.d.ts.map +1 -0
  270. package/lib/objectTypes/statistics.js +17 -2
  271. package/lib/objectTypes/subscription.d.ts +1 -0
  272. package/lib/objectTypes/subscription.d.ts.map +1 -0
  273. package/lib/objectTypes/subscription.js +102 -2
  274. package/lib/objectTypes/tag.d.ts +1 -0
  275. package/lib/objectTypes/tag.d.ts.map +1 -0
  276. package/lib/objectTypes/tag.js +41 -2
  277. package/lib/objectTypes/user.d.ts +1 -0
  278. package/lib/objectTypes/user.d.ts.map +1 -0
  279. package/lib/objectTypes/user.js +111 -2
  280. package/lib/queries/content.d.ts +1 -0
  281. package/lib/queries/content.d.ts.map +1 -0
  282. package/lib/queries/content.js +50 -2
  283. package/lib/queries/index.d.ts +1 -0
  284. package/lib/queries/index.d.ts.map +1 -0
  285. package/lib/queries/index.js +27 -2
  286. package/lib/queries/locations.d.ts +1 -0
  287. package/lib/queries/locations.d.ts.map +1 -0
  288. package/lib/queries/locations.js +23 -2
  289. package/lib/queries/messages.d.ts +1 -0
  290. package/lib/queries/messages.d.ts.map +1 -0
  291. package/lib/queries/messages.js +35 -2
  292. package/lib/queries/posts.d.ts +1 -0
  293. package/lib/queries/posts.d.ts.map +1 -0
  294. package/lib/queries/posts.js +154 -2
  295. package/lib/queries/reactions.d.ts +1 -0
  296. package/lib/queries/reactions.d.ts.map +1 -0
  297. package/lib/queries/reactions.js +34 -2
  298. package/lib/queries/statistics.d.ts +1 -0
  299. package/lib/queries/statistics.d.ts.map +1 -0
  300. package/lib/queries/statistics.js +17 -2
  301. package/lib/queries/subscriptions.d.ts +1 -0
  302. package/lib/queries/subscriptions.d.ts.map +1 -0
  303. package/lib/queries/subscriptions.js +21 -2
  304. package/lib/queries/tags.d.ts +1 -0
  305. package/lib/queries/tags.d.ts.map +1 -0
  306. package/lib/queries/tags.js +56 -2
  307. package/lib/queries/users.d.ts +1 -0
  308. package/lib/queries/users.d.ts.map +1 -0
  309. package/lib/queries/users.js +39 -2
  310. package/lib/templates/email/layout.d.ts +1 -0
  311. package/lib/templates/email/layout.d.ts.map +1 -0
  312. package/lib/templates/email/layout.js +4 -3
  313. package/lib/templates/email/passwordForgot.d.ts +1 -0
  314. package/lib/templates/email/passwordForgot.d.ts.map +1 -0
  315. package/lib/templates/email/passwordForgot.js +4 -3
  316. package/lib/templates/email/passwordRecovery.d.ts +1 -0
  317. package/lib/templates/email/passwordRecovery.d.ts.map +1 -0
  318. package/lib/templates/email/passwordRecovery.js +4 -3
  319. package/lib/templates/email/verifyEmail.d.ts +1 -0
  320. package/lib/templates/email/verifyEmail.d.ts.map +1 -0
  321. package/lib/templates/email/verifyEmail.js +4 -3
  322. package/lib/templates/email/welcome.d.ts +1 -0
  323. package/lib/templates/email/welcome.d.ts.map +1 -0
  324. package/lib/templates/email/welcome.js +4 -3
  325. package/lib/templates/sms/passwordForgot.d.ts +1 -0
  326. package/lib/templates/sms/passwordForgot.d.ts.map +1 -0
  327. package/lib/templates/sms/passwordForgot.js +3 -2
  328. package/lib/templates/sms/passwordRecovery.d.ts +1 -0
  329. package/lib/templates/sms/passwordRecovery.d.ts.map +1 -0
  330. package/lib/templates/sms/passwordRecovery.js +3 -2
  331. package/lib/templates/sms/verifyEmail.d.ts +1 -0
  332. package/lib/templates/sms/verifyEmail.d.ts.map +1 -0
  333. package/lib/templates/sms/verifyEmail.js +3 -2
  334. package/lib/templates/sms/verifyPhone.d.ts +1 -0
  335. package/lib/templates/sms/verifyPhone.d.ts.map +1 -0
  336. package/lib/templates/sms/verifyPhone.js +3 -2
  337. package/lib/templates/sms/welcome.d.ts +1 -0
  338. package/lib/templates/sms/welcome.d.ts.map +1 -0
  339. package/lib/templates/sms/welcome.js +3 -2
  340. package/lib/types/apps.types.d.ts +1 -0
  341. package/lib/types/apps.types.d.ts.map +1 -0
  342. package/lib/types/apps.types.js +10 -2
  343. package/lib/types/arangodb.types.d.ts +2 -1
  344. package/lib/types/arangodb.types.d.ts.map +1 -0
  345. package/lib/types/arangodb.types.js +6 -1
  346. package/lib/types/auth.types.d.ts +1 -0
  347. package/lib/types/auth.types.d.ts.map +1 -0
  348. package/lib/types/auth.types.js +6 -1
  349. package/lib/types/connections.types.d.ts +1 -0
  350. package/lib/types/connections.types.d.ts.map +1 -0
  351. package/lib/types/connections.types.js +6 -1
  352. package/lib/types/content.types.d.ts +1 -0
  353. package/lib/types/content.types.d.ts.map +1 -0
  354. package/lib/types/content.types.js +6 -1
  355. package/lib/types/conversations.types.d.ts +1 -0
  356. package/lib/types/conversations.types.d.ts.map +1 -0
  357. package/lib/types/conversations.types.js +6 -1
  358. package/lib/types/email.types.d.ts +1 -0
  359. package/lib/types/email.types.d.ts.map +1 -0
  360. package/lib/types/email.types.js +6 -1
  361. package/lib/types/error.types.d.ts +1 -0
  362. package/lib/types/error.types.d.ts.map +1 -0
  363. package/lib/types/error.types.js +20 -2
  364. package/lib/types/files.types.d.ts +1 -0
  365. package/lib/types/files.types.d.ts.map +1 -0
  366. package/lib/types/files.types.js +6 -1
  367. package/lib/types/google.types.d.ts +1 -0
  368. package/lib/types/google.types.d.ts.map +1 -0
  369. package/lib/types/google.types.js +6 -1
  370. package/lib/types/groups.types.d.ts +1 -0
  371. package/lib/types/groups.types.d.ts.map +1 -0
  372. package/lib/types/groups.types.js +6 -1
  373. package/lib/types/images.types.d.ts +1 -0
  374. package/lib/types/images.types.d.ts.map +1 -0
  375. package/lib/types/images.types.js +6 -1
  376. package/lib/types/index.d.ts +2 -0
  377. package/lib/types/index.d.ts.map +1 -0
  378. package/lib/types/index.js +28 -2
  379. package/lib/types/locations.types.d.ts +1 -0
  380. package/lib/types/locations.types.d.ts.map +1 -0
  381. package/lib/types/locations.types.js +6 -1
  382. package/lib/types/messages.types.d.ts +1 -0
  383. package/lib/types/messages.types.d.ts.map +1 -0
  384. package/lib/types/messages.types.js +6 -1
  385. package/lib/types/notifications.types.d.ts +1 -0
  386. package/lib/types/notifications.types.d.ts.map +1 -0
  387. package/lib/types/notifications.types.js +6 -1
  388. package/lib/types/payments.types.d.ts +1 -0
  389. package/lib/types/payments.types.d.ts.map +1 -0
  390. package/lib/types/payments.types.js +6 -1
  391. package/lib/types/posts.types.d.ts +1 -0
  392. package/lib/types/posts.types.d.ts.map +1 -0
  393. package/lib/types/posts.types.js +6 -1
  394. package/lib/types/profiles.types.d.ts +1 -0
  395. package/lib/types/profiles.types.d.ts.map +1 -0
  396. package/lib/types/profiles.types.js +3 -1
  397. package/lib/types/statistics.types.d.ts +1 -0
  398. package/lib/types/statistics.types.d.ts.map +1 -0
  399. package/lib/types/statistics.types.js +3 -1
  400. package/lib/types/tags.types.d.ts +1 -0
  401. package/lib/types/tags.types.d.ts.map +1 -0
  402. package/lib/types/tags.types.js +6 -1
  403. package/lib/types/users.types.d.ts +1 -0
  404. package/lib/types/users.types.d.ts.map +1 -0
  405. package/lib/types/users.types.js +6 -1
  406. package/lib/types/videos.types.d.ts +47 -0
  407. package/lib/types/videos.types.d.ts.map +1 -0
  408. package/lib/types/videos.types.js +6 -0
  409. package/lib/types/websockets.types.d.ts +1 -0
  410. package/lib/types/websockets.types.d.ts.map +1 -0
  411. package/lib/types/websockets.types.js +6 -1
  412. package/lib/utils/adapterUtils.d.ts +1 -0
  413. package/lib/utils/adapterUtils.d.ts.map +1 -0
  414. package/lib/utils/adapterUtils.js +23 -2
  415. package/lib/utils/analyticsUtils.d.ts +1 -0
  416. package/lib/utils/analyticsUtils.d.ts.map +1 -0
  417. package/lib/utils/analyticsUtils.js +45 -2
  418. package/lib/utils/arangodbUtils.d.ts +1 -0
  419. package/lib/utils/arangodbUtils.d.ts.map +1 -0
  420. package/lib/utils/arangodbUtils.js +128 -5
  421. package/lib/utils/authUtils.d.ts +1 -0
  422. package/lib/utils/authUtils.d.ts.map +1 -0
  423. package/lib/utils/authUtils.js +54 -2
  424. package/lib/utils/contextUtils.d.ts +1 -0
  425. package/lib/utils/contextUtils.d.ts.map +1 -0
  426. package/lib/utils/contextUtils.js +10 -2
  427. package/lib/utils/dbI18n.d.ts +1 -0
  428. package/lib/utils/dbI18n.d.ts.map +1 -0
  429. package/lib/utils/dbI18n.example.d.ts +1 -0
  430. package/lib/utils/dbI18n.example.d.ts.map +1 -0
  431. package/lib/utils/dbI18n.example.js +92 -5
  432. package/lib/utils/dbI18n.js +28 -2
  433. package/lib/utils/googleTranslate.d.ts +1 -0
  434. package/lib/utils/googleTranslate.d.ts.map +1 -0
  435. package/lib/utils/googleTranslate.js +70 -2
  436. package/lib/utils/graphqlUtils.d.ts +1 -0
  437. package/lib/utils/graphqlUtils.d.ts.map +1 -0
  438. package/lib/utils/graphqlUtils.js +11 -2
  439. package/lib/utils/index.d.ts +1 -0
  440. package/lib/utils/index.d.ts.map +1 -0
  441. package/lib/utils/index.js +19 -2
  442. package/lib/utils/languageDetection.d.ts +1 -0
  443. package/lib/utils/languageDetection.d.ts.map +1 -0
  444. package/lib/utils/languageDetection.js +120 -2
  445. package/lib/utils/localeUtils.d.ts +1 -0
  446. package/lib/utils/localeUtils.d.ts.map +1 -0
  447. package/lib/utils/localeUtils.example.d.ts +1 -0
  448. package/lib/utils/localeUtils.example.d.ts.map +1 -0
  449. package/lib/utils/localeUtils.example.js +124 -2
  450. package/lib/utils/localeUtils.js +71 -2
  451. package/lib/utils/middlewareUtils.d.ts +1 -0
  452. package/lib/utils/middlewareUtils.d.ts.map +1 -0
  453. package/lib/utils/middlewareUtils.js +10 -2
  454. package/lib/utils/sessionUtils.d.ts +1 -0
  455. package/lib/utils/sessionUtils.d.ts.map +1 -0
  456. package/lib/utils/sessionUtils.js +26 -2
  457. package/lib/utils/stripeUtils.d.ts +2 -1
  458. package/lib/utils/stripeUtils.d.ts.map +1 -0
  459. package/lib/utils/stripeUtils.js +12 -2
  460. package/lib/utils/templateUtils.d.ts +1 -0
  461. package/lib/utils/templateUtils.d.ts.map +1 -0
  462. package/lib/utils/templateUtils.js +11 -2
  463. package/lib/utils/testUtils.d.ts +1 -0
  464. package/lib/utils/testUtils.d.ts.map +1 -0
  465. package/lib/utils/testUtils.js +292 -2
  466. package/lib/utils/translationQueue.d.ts +1 -0
  467. package/lib/utils/translationQueue.d.ts.map +1 -0
  468. package/lib/utils/translationQueue.example.d.ts +1 -0
  469. package/lib/utils/translationQueue.example.d.ts.map +1 -0
  470. package/lib/utils/translationQueue.example.js +340 -2
  471. package/lib/utils/translationQueue.js +113 -2
  472. package/package.json +47 -29
@@ -1,37 +1,176 @@
1
- import{get as J}from"@nlabs/rip-hunter";import{parseNum as Z}from"@nlabs/utils/parsers/numbers";import{createHash as z,parseArangoId as K,parseChar as w,parseId as j}from"@nlabs/utils/parsers/strings";import{aql as v}from"arangojs";import L from"gm";import{DateTime as X}from"luxon";import{Config as O}from"../config.js";import{ErrorTypes as E}from"../types/error.types.js";import{logError as R,logException as Y}from"../utils/analyticsUtils.js";import{getDocId as ee,getLimit as _,selectReactionCountByType as te,useDb as N}from"../utils/arangodbUtils.js";import{getGroupDetails as re,isGrouped as ae}from"./groups.js";import{s3DeleteList as se,s3GetSignedUrl as ne,s3Put as G}from"./s3.js";import{lowerCaseKeys as oe}from"@nlabs/utils/parsers/objects";const f="images";L.subClass({imageMagick:"7+"});const H=(e={})=>{const{from:t=0,to:s=30,type:r="default"}=e;return{limit:_(t,s),type:w(r,32)}},W=(e=[])=>e.reduce((t,s)=>{if(s.includes("Count"))return te("images","i",s,t);switch(s){case"reactions":return t.queries.push(`LET reactions = (
1
+ /**
2
+ * Copyright (c) 2019-Present, Nitrogen Labs, Inc.
3
+ * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
+ */ import { get as httpGet } from '@nlabs/rip-hunter';
5
+ import { parseNum } from '@nlabs/utils/parsers/numbers';
6
+ import { createHash, parseArangoId, parseChar, parseId } from '@nlabs/utils/parsers/strings';
7
+ import { aql } from 'arangojs';
8
+ import gm from 'gm';
9
+ import { DateTime } from 'luxon';
10
+ import { Config } from '../config.js';
11
+ import { ErrorTypes } from '../types/error.types.js';
12
+ import { logError, logException } from '../utils/analyticsUtils.js';
13
+ import { getDocId, getLimit, selectReactionCountByType, useDb } from '../utils/arangodbUtils.js';
14
+ import { getGroupDetails, isGrouped } from './groups.js';
15
+ import { s3DeleteList, s3GetSignedUrl, s3Put } from './s3.js';
16
+ import { lowerCaseKeys } from '@nlabs/utils/parsers/objects';
17
+ const eventCategory = 'images';
18
+ gm.subClass({
19
+ imageMagick: '7+'
20
+ });
21
+ export const parseImageOptions = (options = {})=>{
22
+ const { from = 0, to = 30, type = 'default' } = options;
23
+ return {
24
+ limit: getLimit(from, to),
25
+ type: parseChar(type, 32)
26
+ };
27
+ };
28
+ export const getImageOptional = (fields = [])=>fields.reduce((selects, field)=>{
29
+ if (field.includes('Count')) {
30
+ return selectReactionCountByType('images', 'i', field, selects);
31
+ }
32
+ switch(field){
33
+ case 'reactions':
34
+ {
35
+ selects.queries.push(`LET reactions = (
2
36
  FOR image, r IN INBOUND i._id reactions
3
37
  COLLECT reactionName = r.value INTO reactionItems
4
38
  RETURN {name: reactionName, count: LENGTH(reactionItems[*].r.value)}
5
- )`),t.objects.push("reactions:reactions"),t;case"tags":return t.queries.push(`LET tags = (
39
+ )`);
40
+ selects.objects.push('reactions:reactions');
41
+ return selects;
42
+ }
43
+ case 'tags':
44
+ {
45
+ selects.queries.push(`LET tags = (
6
46
  FOR t, pl IN INBOUND i._id isTagged
7
47
  RETURN t
8
- )`),t.objects.push("tags:tags"),t;case"users":return t.queries.push(`LET users = FIRST(
48
+ )`);
49
+ selects.objects.push('tags:tags');
50
+ return selects;
51
+ }
52
+ case 'users':
53
+ {
54
+ selects.queries.push(`LET users = FIRST(
9
55
  FOR u IN users
10
56
  FILTER i.userId == u._key
11
57
  LIMIT 1
12
58
  RETURN u
13
- )`),t.objects.push("users:users"),t;default:return t}},{objects:[],queries:[]}),be=(e,t,s=0,r=30)=>{const i="getImagesByUser",{databaseName:n}=e,a=j(t),m=_(s,r),g=`FOR i IN images
14
- FILTER i.userId == "${a}"
59
+ )`);
60
+ selects.objects.push('users:users');
61
+ return selects;
62
+ }
63
+ default:
64
+ {
65
+ return selects;
66
+ }
67
+ }
68
+ }, {
69
+ objects: [],
70
+ queries: []
71
+ });
72
+ export const getImagesByUser = (context, userId, from = 0, to = 30)=>{
73
+ const action = 'getImagesByUser';
74
+ const { databaseName } = context;
75
+ const formatUserId = parseId(userId);
76
+ const limit = getLimit(from, to);
77
+ const aqlQry = `FOR i IN images
78
+ FILTER i.userId == "${formatUserId}"
15
79
  LET user = FIRST(
16
80
  FOR u IN users
17
81
  FILTER u._key == i.userId
18
82
  LIMIT 1
19
83
  RETURN u
20
84
  )
21
- ${m.aql}
85
+ ${limit.aql}
22
86
  SORT i.added
23
- RETURN MERGE(i, {user:user})`;return N(n).query(g).then(o=>o.all()).catch(o=>(R({action:i,category:f,params:{from:s,to:r,userId:t},value:E.DATABASE_ERROR},o,e),[]))},Ae=(e,t)=>{const s="getImageCountByItem",{databaseName:r}=e,i=K(t),n=v`FOR i IN hasImage
24
- FILTER i._to == ${i}
25
- RETURN {count: COUNT(i)}`;return N(r).query(n).then(a=>a.next()).then(({count:a})=>a).catch(a=>R({action:s,category:f,params:{itemId:t},value:E.DATABASE_ERROR},a,e))},Ne=async(e,t,s={})=>{const r="getImagesByItem",{databaseName:i,fields:n=[]}=e,a=K(t),{limit:m}=H(s),{objects:g,queries:o}=W(n),l=`FOR i, l IN 1..1 OUTBOUND "${a}" hasImage
87
+ RETURN MERGE(i, {user:user})`;
88
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.all()).catch((error)=>{
89
+ logError({
90
+ action,
91
+ category: eventCategory,
92
+ params: {
93
+ from,
94
+ to,
95
+ userId
96
+ },
97
+ value: ErrorTypes.DATABASE_ERROR
98
+ }, error, context);
99
+ return [];
100
+ });
101
+ };
102
+ export const getImageCountByItem = (context, itemId)=>{
103
+ const action = 'getImageCountByItem';
104
+ const { databaseName } = context;
105
+ const formatItemId = parseArangoId(itemId);
106
+ const aqlQry = aql`FOR i IN hasImage
107
+ FILTER i._to == ${formatItemId}
108
+ RETURN {count: COUNT(i)}`;
109
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.next()).then(({ count })=>count).catch((error)=>logError({
110
+ action,
111
+ category: eventCategory,
112
+ params: {
113
+ itemId
114
+ },
115
+ value: ErrorTypes.DATABASE_ERROR
116
+ }, error, context));
117
+ };
118
+ export const getImagesByItem = async (context, itemId, options = {})=>{
119
+ const action = 'getImagesByItem';
120
+ const { databaseName, fields = [] } = context;
121
+ const formatItemId = parseArangoId(itemId);
122
+ const { limit } = parseImageOptions(options);
123
+ const { objects: selectObjects, queries: selectQueries } = getImageOptional(fields);
124
+ const aqlQry = `FOR i, l IN 1..1 OUTBOUND "${formatItemId}" hasImage
26
125
  FILTER NOT IS_NULL(i)
27
- ${o.join(`
28
- `)}
126
+ ${selectQueries.join('\n')}
29
127
  SORT i.added
30
- ${m.aql}
31
- RETURN MERGE(i, {${g.join(", ")}})`;return N(i).query(l).then(y=>y.all()).catch(y=>(R({action:r,category:f,params:{itemId:t,options:s},value:E.DATABASE_ERROR},y,e),[]))},Oe=(e,t)=>{const s="getImagesByGroup",{databaseName:r,session:{userId:i}}=e,{filters:n,groupId:a,from:m,to:g}=t,o=j(a),l=_(m,g);return n.map(y=>{const{conditional:I,name:c,value:u}=y;let p=I;switch(I!==">="&&I!=="<="&&I!==">"&&I!=="<"&&(p="=="),c){case"added":return`p.added ${p} ${Z(u)}`;default:return""}}),re(e,o).then(y=>{if(y.privacy==="public"){n.push({conditional:"==",name:"groupId",value:o});const c=`FOR i IN
128
+ ${limit.aql}
129
+ RETURN MERGE(i, {${selectObjects.join(', ')}})`;
130
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.all()).catch((error)=>{
131
+ logError({
132
+ action,
133
+ category: eventCategory,
134
+ params: {
135
+ itemId,
136
+ options
137
+ },
138
+ value: ErrorTypes.DATABASE_ERROR
139
+ }, error, context);
140
+ return [];
141
+ });
142
+ };
143
+ export const getImagesByGroup = (context, params)=>{
144
+ const action = 'getImagesByGroup';
145
+ const { databaseName, session: { userId: sessionId } } = context;
146
+ const { filters, groupId, from, to } = params;
147
+ const formatGroupId = parseId(groupId);
148
+ const limit = getLimit(from, to);
149
+ filters.map((filter)=>{
150
+ const { conditional, name, value } = filter;
151
+ let formatCond = conditional;
152
+ if (conditional !== '>=' && conditional !== '<=' && conditional !== '>' && conditional !== '<') {
153
+ formatCond = '==';
154
+ }
155
+ switch(name){
156
+ case 'added':
157
+ return `p.added ${formatCond} ${parseNum(value)}`;
158
+ default:
159
+ return '';
160
+ }
161
+ });
162
+ return getGroupDetails(context, formatGroupId).then((group)=>{
163
+ if (group.privacy === 'public') {
164
+ filters.push({
165
+ conditional: '==',
166
+ name: 'groupId',
167
+ value: formatGroupId
168
+ });
169
+ const filterStr = filters.join(' && ');
170
+ const aqlQry = `FOR i IN
32
171
  FLATTEN(
33
172
  FOR p IN posts
34
- FILTER ${n.join(" && ")}
173
+ FILTER ${filterStr}
35
174
  LET images = (
36
175
  FOR i, e IN INBOUND p._id hasImage
37
176
  RETURN i
@@ -40,27 +179,545 @@ import{get as J}from"@nlabs/rip-hunter";import{parseNum as Z}from"@nlabs/utils/p
40
179
  RETURN images
41
180
  )
42
181
  SORT i.added DESC
43
- ${l.aql}
44
- RETURN i`;return N(r).query(c).then(u=>u.all()).catch(u=>(R({action:s,category:f,params:{filters:n,from:m,groupId:a,to:g},value:E.DATABASE_ERROR},u,e),[]))}return ae(e,i,a).then(I=>{if(I.isValid){n.push({conditional:"==",name:"groupId",value:I.groupId});const u=`FOR p IN post
45
- FILTER ${n.join(" && ")}
182
+ ${limit.aql}
183
+ RETURN i`;
184
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.all()).catch((error)=>{
185
+ logError({
186
+ action,
187
+ category: eventCategory,
188
+ params: {
189
+ filters,
190
+ from,
191
+ groupId,
192
+ to
193
+ },
194
+ value: ErrorTypes.DATABASE_ERROR
195
+ }, error, context);
196
+ return [];
197
+ });
198
+ }
199
+ return isGrouped(context, sessionId, groupId).then((grouped)=>{
200
+ if (grouped.isValid) {
201
+ filters.push({
202
+ conditional: '==',
203
+ name: 'groupId',
204
+ value: grouped.groupId
205
+ });
206
+ const filterList = filters.join(' && ');
207
+ const aqlQry = `FOR p IN post
208
+ FILTER ${filterList}
46
209
  FOR f IN p.files
47
210
  FILTER f.type == "image/jpeg" || f.type == "image/png"
48
- ${l.aql}
211
+ ${limit.aql}
49
212
  SORT p.added DESC
50
- RETURN f`;return N(r).query(u).then(p=>p.all()).catch(p=>(R({action:s,category:f,params:{filters:n,from:m,groupId:a,to:g},value:E.DATABASE_ERROR},p,e),[]))}return[]})})},$e=(e,t=[],s)=>{const r="getUsersByImage",{databaseName:i,fields:n=[],session:{userId:a}}=e,{limit:m}=H(s),{objects:g,queries:o}=W(n),l=`users/${a}`,y=t.map(u=>w(u,32)),I=['r.type == "images"',`POSITION(${JSON.stringify(y)}, LOWER(r.name))`],c=`FOR i, r IN OUTBOUND "${l}" hasReaction
213
+ RETURN f`;
214
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.all()).catch((error)=>{
215
+ logError({
216
+ action,
217
+ category: eventCategory,
218
+ params: {
219
+ filters,
220
+ from,
221
+ groupId,
222
+ to
223
+ },
224
+ value: ErrorTypes.DATABASE_ERROR
225
+ }, error, context);
226
+ return [];
227
+ });
228
+ }
229
+ return [];
230
+ });
231
+ });
232
+ };
233
+ export const getImagesByReactions = (context, reactions = [], options)=>{
234
+ const action = 'getUsersByImage';
235
+ const { databaseName, fields = [], session: { userId: sessionId } } = context;
236
+ const { limit } = parseImageOptions(options);
237
+ const { objects: selectObjects, queries: selectQueries } = getImageOptional(fields);
238
+ const formatSessionId = `users/${sessionId}`;
239
+ const formatReactions = reactions.map((reactionName)=>parseChar(reactionName, 32));
240
+ const filterBy = [
241
+ 'r.type == "images"',
242
+ `POSITION(${JSON.stringify(formatReactions)}, LOWER(r.name))`
243
+ ];
244
+ // Get data from database
245
+ const aqlQry = `FOR i, r IN OUTBOUND "${formatSessionId}" hasReaction
51
246
  OPTIONS {vertexCollections: "images"}
52
- ${o.join(`
53
- `)}
54
- FILTER ${I.join(" && ")}
55
- ${m.aql}
56
- RETURN MERGE(i, {${g.join(", ")}})`;return N(i).query(c).then(u=>u.all()).catch(u=>(R({action:r,category:f,params:{options:s,reactions:t},value:E.DATABASE_ERROR},u,e),[]))},Be=(e,t)=>{const s="getItem",{databaseName:r}=e,i=j(t),n=v`FOR i IN images
57
- FILTER i._key==${i}
247
+ ${selectQueries.join('\n')}
248
+ FILTER ${filterBy.join(' && ')}
249
+ ${limit.aql}
250
+ RETURN MERGE(i, {${selectObjects.join(', ')}})`;
251
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.all()).catch((error)=>{
252
+ logError({
253
+ action,
254
+ category: eventCategory,
255
+ params: {
256
+ options,
257
+ reactions
258
+ },
259
+ value: ErrorTypes.DATABASE_ERROR
260
+ }, error, context);
261
+ return [];
262
+ });
263
+ };
264
+ export const getImage = (context, imageId)=>{
265
+ const action = 'getItem';
266
+ const { databaseName } = context;
267
+ const formatImageId = parseId(imageId);
268
+ const aqlQry = aql`FOR i IN images
269
+ FILTER i._key==${formatImageId}
58
270
  LIMIT 1
59
- RETURN i`;return N(r).query(n).then(a=>a.next()).catch(a=>R({action:s,category:f,params:{imageId:t},value:E.DATABASE_ERROR},a,e))},M=(e,t,s,r="images")=>{let i=t;switch(s){case"image/png":i=`${t}.png`;break;default:i=`${t}.jpg`;break}return`users/${e}/${r}/${i}`},Ce=({bucket:e,directory:t="images",imageId:s,imageType:r="jpg",isThumb:i=!1,type:n,typeId:a})=>{if(!n)return"";if(!s)return r==="profile"?`${O.get("image.defaultUrl")}/users_bk.jpg`:`${O.get("image.defaultUrl")}/users_wh.jpg`;const m=e||O.get("image.bucket")||"dev.reaktor.io",g=i?`${s}-th.${r}`:`${s}.${r==="profile"||r==="other"?"jpg":r}`,o=O.get("image.url")||`https://s3.amazonaws.com/${m}`;return n==="apps"?`${o}/${n}/${t}/${g}`:`${o}/${n}/${a}/${t}/${g}`},De=async({bucket:e,imageDir:t="images",imageId:s,imageType:r="jpg",isThumb:i=!1,type:n,typeId:a,urlType:m="public"})=>{if(!s)return"";i&&(m="signed");const o=`${n}/${a}/${t}/${s}${i?"-th":""}.${r}`;switch(m){case"signed":try{const l=O.get("image.bucket")||"dev.reaktor.io";return await ne({Bucket:e||l,Expires:900,Key:o})}catch(l){throw l}case"public":return`https://box.${O.get("app.url")}/${o}`;case"dev":return`https://s3.amazonaws.com/dev.${O.get("app.url")}/${o}`;default:return""}},ie=async(e,t,s,r="image/jpeg",i)=>{const n="resizeSaveImage",{session:{userId:a}}=e,m=O.get("image.imgSize"),g=O.get("image.imgQuality"),o=r.split("/")[1],l=await new Promise((c,u)=>{L(s,"img").setFormat(o).quality(g).autoOrient().resize(m,m,">").stream((p,T)=>{if(p){u(R({action:n,category:f,params:{fileType:r,imageId:t},value:E.IMAGE_SAVE},p,e));return}let A=Buffer.from("");T.on("data",C=>{A=Buffer.concat([A,C])}),T.on("end",()=>c(A))})});try{const c={ACL:"authenticated-read",Body:l,Bucket:null,ContentType:r,...i||{},Key:M(a,t,r,"images")};await G(c)}catch(c){return R({action:n,category:f,params:{fileType:r,imageId:t},value:E.IMAGE_SAVE},c,e)}const y=await new Promise(c=>{L(l,"img").identify({bufferStream:!0},(u,p={})=>{if(u)return R({action:n,category:f,value:E.IMAGE_SAVE},u,e);const T=oe(p),{make:A,model:C,datetimeoriginal:h}=T,d=T["channel statistics"];let $;if(d){let{red:D,green:U,blue:S,mean:B}=d;D?(B=D["standard deviation"]||D.mean,D=B?+B.split(" ")[0].substring(0,3):0):D=0,U?(B=U["standard deviation"]||U.mean,U=B?+B.split(" ")[0].substring(0,3):0):U=0,S?(B=S["standard deviation"]||S.mean,S=B?+B.split(" ")[0].substring(0,3):0):S=0;const Q=(S|U<<8|D<<16).toString(16);$=Q==="0"?"000000":Q}const{"JPEG-Quality":b,Orientation:q,Resolution:F,size:k}=p;let P;if(F){const[D,U]=F.split(" ");P=`${D.split("x")[0]} ${U==="pixels/inch"?"ppi":""}`}return c({color:$,fileSize:l.length,fileType:o,height:k?.height||0,imageId:t,make:A,model:C,orientation:q==="Unknown"?void 0:q?.toLowerCase(),quality:b?+b:void 0,resolution:P,taken:h?X.fromMillis(h).millisecond:void 0,width:k?.width||0})})}),I=await new Promise((c,u)=>{const p=O.get("image.thmSize"),T=O.get("image.thmQuality");L(l,"img").setFormat(o).gravity("Center").resize(p,p,"^").extent(p,p).quality(T).stream((A,C)=>{if(A){R({action:n,category:f,params:{fileType:r,imageId:t},value:E.IMAGE_SAVE},A,e);return}let h=Buffer.from("");C.on("data",d=>{h=Buffer.concat([h,d])}),C.on("end",()=>c(h))})});try{const c={ACL:"authenticated-read",Body:I,Bucket:null,ContentType:r,...i||{},Key:M(a,t,r,"thumbs")};await G(c)}catch(c){return R({action:n,category:f,value:E.IMAGE_SAVE},c,e)}return y},x=(e,t,s)=>{const r="addImage",{databaseName:i,session:{userId:n}}=e,{imageId:a,description:m,buffer:g,fileType:o}=t,l=Date.now();return ie(e,a,g,o,s).then(y=>{const I={...y,_key:a,added:l,description:m,fileType:o,modified:l,userId:n},c=v`INSERT ${I} IN images RETURN NEW`;return N(i).query(c).then(u=>u.next()).catch(u=>R({action:r,category:f,params:{image:t,s3Options:s},value:E.DATABASE_ERROR},u,e))}).catch(y=>R({action:r,category:f,value:E.IMAGE_RESIZE},y,e))},V=async(e,t)=>{const s="addImageEdge",{databaseName:r,session:{userId:i}}=e,{imageId:n,itemId:a,itemType:m}=t,g=Date.now(),o=z(`hasImage-${n}-${a}-${i}`),l=w(m).toLowerCase(),y=j(a),I=ee(l,{_key:y}),u=`images/${j(n)}`,p={_from:I,_key:o,_to:u,added:g,itemType:m};return I?N(r).collection("hasImage").save(p,{returnNew:!0}).then(T=>N(r).collection("hasImage").document(T)).catch(T=>R({action:s,category:f,params:{edge:p,fileDocId:u,imageId:n,itemDocId:I,itemId:a,itemType:m},value:E.DATABASE_ERROR},T,e)):null},Ue=async(e,t,s)=>{const r="updateImage",{databaseName:i,session:{userId:n}}=e,{base64:a="",buffer:m,description:g="",imageId:o,itemId:l,itemType:y,fileType:I,url:c=""}=t,u=Date.now(),p=o||z(`image-${n}`),T=j(l),A=w(y,16).toLowerCase(),C={description:g,imageId:p,userId:n};if(a||m){let h=m;if(a){const b=a.substr(a.indexOf(",")+1);h=Buffer.from(b,"base64")}let d=I;if(!I){const{fileTypeFromBuffer:b}=await import("file-type"),{mime:q}=await b(h);d=q}const $={...C,buffer:h,fileType:d};return x(e,$,s).then(b=>T&&A?V(e,{imageId:p,itemId:T,itemType:A}).then(()=>b):b).catch(b=>R({action:r,category:f,value:E.IMAGE_SAVE},b,e))}else if(c!==""){let h;return J(c).then(d=>d.status!==200?Y({action:r,category:f,value:E.IMAGE_REQUEST},e):(h=d.headers.get("content-type"),d)).then(d=>d.buffer()).then(d=>{const $={...C,buffer:d,fileType:h};return x(e,$,s).then(b=>T&&A?V(e,{imageId:p,itemId:T,itemType:A}).then(()=>b):b)}).catch(d=>R({action:r,category:f,value:"fetch_error"},d,e))}else if(o!==""){const h={description:g,modified:u},d=v`UPDATE {_key: ${p}} WITH ${h} IN images RETURN NEW`;return N(i).query(d).then($=>$.next()).catch($=>R({action:r,category:f,params:{aqlQry:d,formatImageId:p,update:h},value:E.DATABASE_ERROR},$,e))}return null},Se=async(e,t)=>{const s="delete",{databaseName:r,session:{userId:i}}=e,n=j(t);try{const a=v`FOR hi IN hasImage
60
- FILTER hi._from == ${n}
271
+ RETURN i`;
272
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.next()).catch((error)=>logError({
273
+ action,
274
+ category: eventCategory,
275
+ params: {
276
+ imageId
277
+ },
278
+ value: ErrorTypes.DATABASE_ERROR
279
+ }, error, context));
280
+ };
281
+ export const getPathUserImages = (userId, imageId, imageType, dir = 'images')=>{
282
+ let filename = imageId;
283
+ switch(imageType){
284
+ case 'image/png':
285
+ filename = `${imageId}.png`;
286
+ break;
287
+ default:
288
+ filename = `${imageId}.jpg`;
289
+ break;
290
+ }
291
+ return `users/${userId}/${dir}/${filename}`;
292
+ };
293
+ export const getAppImageUrl = ({ bucket, directory = 'images', imageId, imageType = 'jpg', isThumb = false, type, typeId })=>{
294
+ if (!type) {
295
+ return '';
296
+ }
297
+ if (!imageId) {
298
+ if (imageType === 'profile') {
299
+ return `${Config.get('image.defaultUrl')}/users_bk.jpg`;
300
+ }
301
+ return `${Config.get('image.defaultUrl')}/users_wh.jpg`;
302
+ }
303
+ const bucketName = bucket || Config.get('image.bucket') || 'dev.reaktor.io';
304
+ const imageName = isThumb ? `${imageId}-th.${imageType}` : `${imageId}.${imageType === 'profile' || imageType === 'other' ? 'jpg' : imageType}`;
305
+ const imageUrl = Config.get('image.url') || `https://s3.amazonaws.com/${bucketName}`;
306
+ if (type === 'apps') {
307
+ return `${imageUrl}/${type}/${directory}/${imageName}`;
308
+ }
309
+ return `${imageUrl}/${type}/${typeId}/${directory}/${imageName}`;
310
+ };
311
+ export const getImageUrl = async ({ bucket, imageDir = 'images', imageId, imageType = 'jpg', isThumb = false, type, typeId, urlType = 'public' })=>{
312
+ if (!imageId) {
313
+ return '';
314
+ }
315
+ // Always use signed URLs for thumbnails
316
+ if (isThumb) {
317
+ urlType = 'signed';
318
+ }
319
+ const thumbSuffix = isThumb ? '-th' : '';
320
+ const imageKey = `${type}/${typeId}/${imageDir}/${imageId}${thumbSuffix}.${imageType}`;
321
+ switch(urlType){
322
+ case 'signed':
323
+ {
324
+ try {
325
+ const defaultBucket = Config.get('image.bucket') || 'dev.reaktor.io';
326
+ return await s3GetSignedUrl({
327
+ Bucket: bucket || defaultBucket,
328
+ Expires: 900,
329
+ Key: imageKey
330
+ });
331
+ } catch (error) {
332
+ throw error;
333
+ }
334
+ }
335
+ case 'public':
336
+ {
337
+ return `https://box.${Config.get('app.url')}/${imageKey}`;
338
+ }
339
+ case 'dev':
340
+ {
341
+ return `https://s3.amazonaws.com/dev.${Config.get('app.url')}/${imageKey}`;
342
+ }
343
+ default:
344
+ {
345
+ return '';
346
+ }
347
+ }
348
+ };
349
+ export const resizeSaveImage = async (context, imageId, buffer, fileType = 'image/jpeg', s3Options)=>{
350
+ const action = 'resizeSaveImage';
351
+ const { session: { userId: sessionId } } = context;
352
+ const imgW = Config.get('image.imgSize');
353
+ const imgQ = Config.get('image.imgQuality');
354
+ const format = fileType.split('/')[1];
355
+ const imageOptimizedBuffer = await new Promise((resolve, reject)=>{
356
+ gm(buffer, 'img').setFormat(format).quality(imgQ).autoOrient().resize(imgW, imgW, '>').stream((streamError, stdout)=>{
357
+ if (streamError) {
358
+ reject(logError({
359
+ action,
360
+ category: eventCategory,
361
+ params: {
362
+ fileType,
363
+ imageId
364
+ },
365
+ value: ErrorTypes.IMAGE_SAVE
366
+ }, streamError, context));
367
+ return;
368
+ }
369
+ let imageBuffer = Buffer.from('');
370
+ stdout.on('data', (data)=>{
371
+ imageBuffer = Buffer.concat([
372
+ imageBuffer,
373
+ data
374
+ ]);
375
+ });
376
+ stdout.on('end', ()=>resolve(imageBuffer));
377
+ });
378
+ });
379
+ try {
380
+ const imageObj = {
381
+ ACL: 'authenticated-read',
382
+ Body: imageOptimizedBuffer,
383
+ Bucket: null,
384
+ ContentType: fileType,
385
+ ...s3Options || {},
386
+ Key: getPathUserImages(sessionId, imageId, fileType, 'images')
387
+ };
388
+ await s3Put(imageObj);
389
+ } catch (error) {
390
+ return logError({
391
+ action,
392
+ category: eventCategory,
393
+ params: {
394
+ fileType,
395
+ imageId
396
+ },
397
+ value: ErrorTypes.IMAGE_SAVE
398
+ }, error, context);
399
+ }
400
+ const imageIdentity = await new Promise((resolve)=>{
401
+ gm(imageOptimizedBuffer, 'img').identify({
402
+ bufferStream: true
403
+ }, (error, imageData = {})=>{
404
+ if (error) {
405
+ return logError({
406
+ action,
407
+ category: eventCategory,
408
+ value: ErrorTypes.IMAGE_SAVE
409
+ }, error, context);
410
+ }
411
+ const formatValues = lowerCaseKeys(imageData);
412
+ const { make: cameraMake, model: cameraModel, datetimeoriginal: taken } = formatValues;
413
+ const stats = formatValues['channel statistics'];
414
+ let color;
415
+ if (stats) {
416
+ let { red, green, blue, mean } = stats;
417
+ if (red) {
418
+ mean = red['standard deviation'] || red.mean;
419
+ red = mean ? +mean.split(' ')[0].substring(0, 3) : 0;
420
+ } else {
421
+ red = 0;
422
+ }
423
+ if (green) {
424
+ mean = green['standard deviation'] || green.mean;
425
+ green = mean ? +mean.split(' ')[0].substring(0, 3) : 0;
426
+ } else {
427
+ green = 0;
428
+ }
429
+ if (blue) {
430
+ mean = blue['standard deviation'] || blue.mean;
431
+ blue = mean ? +mean.split(' ')[0].substring(0, 3) : 0;
432
+ } else {
433
+ blue = 0;
434
+ }
435
+ const rgb = blue | green << 8 | red << 16;
436
+ const rgbColor = rgb.toString(16);
437
+ color = rgbColor === '0' ? '000000' : rgbColor;
438
+ }
439
+ const { 'JPEG-Quality': quality, Orientation: orientationData, Resolution: resolutionData, size } = imageData;
440
+ let resolution;
441
+ if (resolutionData) {
442
+ const [resolutionNumber, resolutionUnit] = resolutionData.split(' ');
443
+ const resolutionValue = resolutionNumber.split('x')[0];
444
+ const resolutionUnitValue = resolutionUnit === 'pixels/inch' ? 'ppi' : '';
445
+ resolution = `${resolutionValue} ${resolutionUnitValue}`;
446
+ }
447
+ return resolve({
448
+ color,
449
+ fileSize: imageOptimizedBuffer.length,
450
+ fileType: format,
451
+ height: size?.height || 0,
452
+ imageId,
453
+ make: cameraMake,
454
+ model: cameraModel,
455
+ orientation: orientationData === 'Unknown' ? undefined : orientationData?.toLowerCase(),
456
+ quality: quality ? +quality : undefined,
457
+ resolution,
458
+ taken: taken ? DateTime.fromMillis(taken).millisecond : undefined,
459
+ width: size?.width || 0
460
+ });
461
+ });
462
+ });
463
+ const thumbOptimizedBuffer = await new Promise((resolve, reject)=>{
464
+ const thmW = Config.get('image.thmSize');
465
+ const thmQ = Config.get('image.thmQuality');
466
+ gm(imageOptimizedBuffer, 'img').setFormat(format).gravity('Center').resize(thmW, thmW, '^').extent(thmW, thmW).quality(thmQ).stream((streamError, thumbStdout)=>{
467
+ if (streamError) {
468
+ logError({
469
+ action,
470
+ category: eventCategory,
471
+ params: {
472
+ fileType,
473
+ imageId
474
+ },
475
+ value: ErrorTypes.IMAGE_SAVE
476
+ }, streamError, context);
477
+ return;
478
+ }
479
+ let thumbBuffer = Buffer.from('');
480
+ thumbStdout.on('data', (data)=>{
481
+ thumbBuffer = Buffer.concat([
482
+ thumbBuffer,
483
+ data
484
+ ]);
485
+ });
486
+ thumbStdout.on('end', ()=>resolve(thumbBuffer));
487
+ });
488
+ });
489
+ try {
490
+ const thumbObj = {
491
+ ACL: 'authenticated-read',
492
+ Body: thumbOptimizedBuffer,
493
+ Bucket: null,
494
+ ContentType: fileType,
495
+ ...s3Options || {},
496
+ Key: getPathUserImages(sessionId, imageId, fileType, 'thumbs')
497
+ };
498
+ await s3Put(thumbObj);
499
+ } catch (error) {
500
+ return logError({
501
+ action,
502
+ category: eventCategory,
503
+ value: ErrorTypes.IMAGE_SAVE
504
+ }, error, context);
505
+ }
506
+ return imageIdentity;
507
+ };
508
+ export const addImage = (context, image, s3Options)=>{
509
+ const action = 'addImage';
510
+ const { databaseName, session: { userId: sessionId } } = context;
511
+ const { imageId, description, buffer, fileType } = image;
512
+ const now = Date.now();
513
+ return resizeSaveImage(context, imageId, buffer, fileType, s3Options).then((resizedImage)=>{
514
+ const insert = {
515
+ ...resizedImage,
516
+ _key: imageId,
517
+ added: now,
518
+ description,
519
+ fileType,
520
+ modified: now,
521
+ userId: sessionId
522
+ };
523
+ const aqlQry = aql`INSERT ${insert} IN images RETURN NEW`;
524
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.next()).catch((error)=>logError({
525
+ action,
526
+ category: eventCategory,
527
+ params: {
528
+ image,
529
+ s3Options
530
+ },
531
+ value: ErrorTypes.DATABASE_ERROR
532
+ }, error, context));
533
+ }).catch((error)=>logError({
534
+ action,
535
+ category: eventCategory,
536
+ value: ErrorTypes.IMAGE_RESIZE
537
+ }, error, context));
538
+ };
539
+ export const addImageEdge = async (context, imageEdge)=>{
540
+ const action = 'addImageEdge';
541
+ const { databaseName, session: { userId: sessionId } } = context;
542
+ const { imageId, itemId, itemType } = imageEdge;
543
+ const now = Date.now();
544
+ // const edgeCollection: EdgeCollection = useDb(databaseName).collection('hasImage');
545
+ const edgeId = createHash(`hasImage-${imageId}-${itemId}-${sessionId}`);
546
+ const formatItemType = parseChar(itemType).toLowerCase();
547
+ const formatItemId = parseId(itemId);
548
+ const itemDocId = getDocId(formatItemType, {
549
+ _key: formatItemId
550
+ });
551
+ const formatImageId = parseId(imageId);
552
+ const fileDocId = `images/${formatImageId}`;
553
+ const edge = {
554
+ _from: itemDocId,
555
+ _key: edgeId,
556
+ _to: fileDocId,
557
+ added: now,
558
+ itemType
559
+ };
560
+ if (itemDocId) {
561
+ return useDb(databaseName).collection('hasImage').save(edge, {
562
+ returnNew: true
563
+ }).then((fileEdge)=>useDb(databaseName).collection('hasImage').document(fileEdge)).catch((error)=>logError({
564
+ action,
565
+ category: eventCategory,
566
+ params: {
567
+ edge,
568
+ fileDocId,
569
+ imageId,
570
+ itemDocId,
571
+ itemId,
572
+ itemType
573
+ },
574
+ value: ErrorTypes.DATABASE_ERROR
575
+ }, error, context));
576
+ }
577
+ return null;
578
+ };
579
+ export const updateImage = async (context, image, s3Options)=>{
580
+ const action = 'updateImage';
581
+ const { databaseName, session: { userId: sessionId } } = context;
582
+ const { base64 = '', buffer: imageBuffer, description = '', imageId, itemId, itemType, fileType, url = '' } = image;
583
+ const now = Date.now();
584
+ const formatImageId = imageId || createHash(`image-${sessionId}`);
585
+ const formatItemId = parseId(itemId);
586
+ const formatItemType = parseChar(itemType, 16).toLowerCase();
587
+ const customParams = {
588
+ description,
589
+ imageId: formatImageId,
590
+ userId: sessionId
591
+ };
592
+ if (base64 || imageBuffer) {
593
+ let buffer = imageBuffer;
594
+ if (base64) {
595
+ const formatBase64 = base64.substr(base64.indexOf(',') + 1);
596
+ buffer = Buffer.from(formatBase64, 'base64');
597
+ }
598
+ let updatedFileType = fileType;
599
+ if (!fileType) {
600
+ const { fileTypeFromBuffer } = await import('file-type');
601
+ const { mime } = await fileTypeFromBuffer(buffer);
602
+ updatedFileType = mime;
603
+ }
604
+ const imgParams = {
605
+ ...customParams,
606
+ buffer,
607
+ fileType: updatedFileType
608
+ };
609
+ return addImage(context, imgParams, s3Options).then((image)=>{
610
+ if (formatItemId && formatItemType) {
611
+ const imageEdge = {
612
+ imageId: formatImageId,
613
+ itemId: formatItemId,
614
+ itemType: formatItemType
615
+ };
616
+ return addImageEdge(context, imageEdge).then(()=>image);
617
+ }
618
+ return image;
619
+ }).catch((error)=>logError({
620
+ action,
621
+ category: eventCategory,
622
+ value: ErrorTypes.IMAGE_SAVE
623
+ }, error, context));
624
+ } else if (url !== '') {
625
+ let contentType;
626
+ return httpGet(url).then((res)=>{
627
+ if (res.status !== 200) {
628
+ return logException({
629
+ action,
630
+ category: eventCategory,
631
+ value: ErrorTypes.IMAGE_REQUEST
632
+ }, context);
633
+ }
634
+ contentType = res.headers.get('content-type');
635
+ return res;
636
+ }).then((res)=>res.buffer()).then((buffer)=>{
637
+ const imgParams = {
638
+ ...customParams,
639
+ buffer,
640
+ fileType: contentType
641
+ };
642
+ return addImage(context, imgParams, s3Options).then((image)=>{
643
+ if (formatItemId && formatItemType) {
644
+ const imageEdge = {
645
+ imageId: formatImageId,
646
+ itemId: formatItemId,
647
+ itemType: formatItemType
648
+ };
649
+ return addImageEdge(context, imageEdge).then(()=>image);
650
+ }
651
+ return image;
652
+ });
653
+ }).catch((error)=>logError({
654
+ action,
655
+ category: eventCategory,
656
+ value: 'fetch_error'
657
+ }, error, context));
658
+ } else if (imageId !== '') {
659
+ const update = {
660
+ description,
661
+ modified: now
662
+ };
663
+ const aqlQry = aql`UPDATE {_key: ${formatImageId}} WITH ${update} IN images RETURN NEW`;
664
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.next()).catch((error)=>logError({
665
+ action,
666
+ category: eventCategory,
667
+ params: {
668
+ aqlQry,
669
+ formatImageId,
670
+ update
671
+ },
672
+ value: ErrorTypes.DATABASE_ERROR
673
+ }, error, context));
674
+ }
675
+ return null;
676
+ };
677
+ export const deleteImage = async (context, imageId)=>{
678
+ const action = 'delete';
679
+ const { databaseName, session: { userId: sessionId } } = context;
680
+ const formatImageId = parseId(imageId);
681
+ try {
682
+ const removeEdgeQuery = aql`FOR hi IN hasImage
683
+ FILTER hi._from == ${formatImageId}
61
684
  REMOVE hi IN hasImage
62
- RETURN OLD`;await N(r).query(a);const m=v`FOR i IN images
63
- FILTER i._key == ${n} && i.userId == ${i}
685
+ RETURN OLD`;
686
+ await useDb(databaseName).query(removeEdgeQuery);
687
+ const aqlQuery = aql`FOR i IN images
688
+ FILTER i._key == ${formatImageId} && i.userId == ${sessionId}
64
689
  REMOVE i IN images
65
- RETURN OLD`,g=await N(r).query(m).then(o=>o.next());if(g){const{_key:o}=g,l={Bucket:null,Delete:{Objects:[{Key:`users/${i}/images/${o}.jpg`},{Key:`users/${i}/thumbs/${o}.jpg`}],Quiet:!0}};return se(l).then(()=>g)}return null}catch(a){return R({action:s,category:f,params:{imageId:t},value:E.DATABASE_ERROR},a,e)}};export{x as addImage,V as addImageEdge,Se as deleteImage,Ce as getAppImageUrl,Be as getImage,Ae as getImageCountByItem,W as getImageOptional,De as getImageUrl,Oe as getImagesByGroup,Ne as getImagesByItem,$e as getImagesByReactions,be as getImagesByUser,M as getPathUserImages,H as parseImageOptions,ie as resizeSaveImage,Ue as updateImage};
66
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FjdGlvbnMvaW1hZ2VzLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxOS1QcmVzZW50LCBOaXRyb2dlbiBMYWJzLCBJbmMuXG4gKiBDb3B5cmlnaHRzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIHRoZSBhY2NvbXBhbnlpbmcgTElDRU5TRSBmaWxlIGZvciB0ZXJtcy5cbiAqL1xuaW1wb3J0IHtEZWxldGVPYmplY3RzQ29tbWFuZElucHV0LCBQdXRPYmplY3RDb21tYW5kSW5wdXR9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1zMyc7XG5pbXBvcnQge2dldCBhcyBodHRwR2V0fSBmcm9tICdAbmxhYnMvcmlwLWh1bnRlcic7XG5pbXBvcnQge3BhcnNlTnVtfSBmcm9tICdAbmxhYnMvdXRpbHMvcGFyc2Vycy9udW1iZXJzJztcbmltcG9ydCB7Y3JlYXRlSGFzaCwgcGFyc2VBcmFuZ29JZCwgcGFyc2VDaGFyLCBwYXJzZUlkfSBmcm9tICdAbmxhYnMvdXRpbHMvcGFyc2Vycy9zdHJpbmdzJztcbmltcG9ydCB7YXFsfSBmcm9tICdhcmFuZ29qcyc7XG5pbXBvcnQge0FxbFF1ZXJ5fSBmcm9tICdhcmFuZ29qcy9hcWwnO1xuaW1wb3J0IGdtIGZyb20gJ2dtJztcbmltcG9ydCB7RGF0ZVRpbWV9IGZyb20gJ2x1eG9uJztcblxuaW1wb3J0IHtDb25maWd9IGZyb20gJy4uL2NvbmZpZy5qcyc7XG5pbXBvcnQge0Vycm9yVHlwZXN9IGZyb20gJy4uL3R5cGVzL2Vycm9yLnR5cGVzLmpzJztcbmltcG9ydCB7bG9nRXJyb3IsIGxvZ0V4Y2VwdGlvbn0gZnJvbSAnLi4vdXRpbHMvYW5hbHl0aWNzVXRpbHMuanMnO1xuaW1wb3J0IHtnZXREb2NJZCwgZ2V0TGltaXQsIHNlbGVjdFJlYWN0aW9uQ291bnRCeVR5cGUsIHVzZURifSBmcm9tICcuLi91dGlscy9hcmFuZ29kYlV0aWxzLmpzJztcbmltcG9ydCB7Z2V0R3JvdXBEZXRhaWxzLCBpc0dyb3VwZWR9IGZyb20gJy4vZ3JvdXBzLmpzJztcbmltcG9ydCB7czNEZWxldGVMaXN0LCBzM0dldFNpZ25lZFVybCwgczNQdXR9IGZyb20gJy4vczMuanMnO1xuXG5pbXBvcnQge2xvd2VyQ2FzZUtleXN9IGZyb20gJ0BubGFicy91dGlscy9wYXJzZXJzL29iamVjdHMnO1xuaW1wb3J0IHR5cGUge1F1ZXJ5RmlsdGVyfSBmcm9tICcuLi90eXBlcy9hcHBzLnR5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtBcmFuZ29EYkNvbGxlY3Rpb24sIEFyYW5nb0RiTGltaXR9IGZyb20gJy4uL3R5cGVzL2FyYW5nb2RiLnR5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtBcGlDb250ZXh0fSBmcm9tICcuLi90eXBlcy9hdXRoLnR5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtHcm91cFR5cGUsIEdyb3VwVXNlcn0gZnJvbSAnLi4vdHlwZXMvZ3JvdXBzLnR5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtJbWFnZUVkZ2VUeXBlLCBJbWFnZUlkZW50aWZ5VHlwZSwgSW1hZ2VPcHRpb25zLCBJbWFnZVR5cGUsIEltYWdlVXJsRGF0YX0gZnJvbSAnLi4vdHlwZXMvaW1hZ2VzLnR5cGVzLmpzJztcblxuLy8gRGVmaW5lIGludGVyZmFjZSBmb3IgSFRUUCByZXNwb25zZSB3aXRoIGJ1ZmZlciBtZXRob2RcbmludGVyZmFjZSBIdHRwUmVzcG9uc2UgZXh0ZW5kcyBSZXNwb25zZSB7XG4gIGJ1ZmZlcigpOiBQcm9taXNlPEJ1ZmZlcj47XG59XG5cbmNvbnN0IGV2ZW50Q2F0ZWdvcnk6IHN0cmluZyA9ICdpbWFnZXMnO1xuZ20uc3ViQ2xhc3Moe2ltYWdlTWFnaWNrOiAnNysnfSk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZUltYWdlT3B0aW9ucyA9IChvcHRpb25zOiBJbWFnZU9wdGlvbnMgPSB7fSkgPT4ge1xuICBjb25zdCB7XG4gICAgZnJvbSA9IDAsXG4gICAgdG8gPSAzMCxcbiAgICB0eXBlID0gJ2RlZmF1bHQnXG4gIH0gPSBvcHRpb25zO1xuXG4gIHJldHVybiB7XG4gICAgbGltaXQ6IGdldExpbWl0KGZyb20sIHRvKSBhcyBBcmFuZ29EYkxpbWl0LFxuICAgIHR5cGU6IHBhcnNlQ2hhcih0eXBlLCAzMilcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRJbWFnZU9wdGlvbmFsID0gKGZpZWxkczogc3RyaW5nW10gPSBbXSkgPT5cbiAgZmllbGRzLnJlZHVjZSgoc2VsZWN0cywgZmllbGQ6IHN0cmluZykgPT4ge1xuICAgIGlmKGZpZWxkLmluY2x1ZGVzKCdDb3VudCcpKSB7XG4gICAgICByZXR1cm4gc2VsZWN0UmVhY3Rpb25Db3VudEJ5VHlwZSgnaW1hZ2VzJywgJ2knLCBmaWVsZCwgc2VsZWN0cyk7XG4gICAgfVxuXG4gICAgc3dpdGNoKGZpZWxkKSB7XG4gICAgICBjYXNlICdyZWFjdGlvbnMnOiB7XG4gICAgICAgIHNlbGVjdHMucXVlcmllcy5wdXNoKGBMRVQgcmVhY3Rpb25zID0gKFxuICAgICAgICAgIEZPUiBpbWFnZSwgciBJTiBJTkJPVU5EIGkuX2lkIHJlYWN0aW9uc1xuICAgICAgICAgIENPTExFQ1QgcmVhY3Rpb25OYW1lID0gci52YWx1ZSBJTlRPIHJlYWN0aW9uSXRlbXNcbiAgICAgICAgICBSRVRVUk4ge25hbWU6IHJlYWN0aW9uTmFtZSwgY291bnQ6IExFTkdUSChyZWFjdGlvbkl0ZW1zWypdLnIudmFsdWUpfVxuICAgICAgICApYCk7XG4gICAgICAgIHNlbGVjdHMub2JqZWN0cy5wdXNoKCdyZWFjdGlvbnM6cmVhY3Rpb25zJyk7XG4gICAgICAgIHJldHVybiBzZWxlY3RzO1xuICAgICAgfVxuICAgICAgY2FzZSAndGFncyc6IHtcbiAgICAgICAgc2VsZWN0cy5xdWVyaWVzLnB1c2goYExFVCB0YWdzID0gKFxuICAgICAgICAgIEZPUiB0LCBwbCBJTiBJTkJPVU5EIGkuX2lkIGlzVGFnZ2VkXG4gICAgICAgICAgUkVUVVJOIHRcbiAgICAgICAgKWApO1xuICAgICAgICBzZWxlY3RzLm9iamVjdHMucHVzaCgndGFnczp0YWdzJyk7XG4gICAgICAgIHJldHVybiBzZWxlY3RzO1xuICAgICAgfVxuICAgICAgY2FzZSAndXNlcnMnOiB7XG4gICAgICAgIHNlbGVjdHMucXVlcmllcy5wdXNoKGBMRVQgdXNlcnMgPSBGSVJTVChcbiAgICAgICAgICBGT1IgdSBJTiB1c2Vyc1xuICAgICAgICAgIEZJTFRFUiBpLnVzZXJJZCA9PSB1Ll9rZXlcbiAgICAgICAgICBMSU1JVCAxXG4gICAgICAgICAgUkVUVVJOIHVcbiAgICAgICAgKWApO1xuICAgICAgICBzZWxlY3RzLm9iamVjdHMucHVzaCgndXNlcnM6dXNlcnMnKTtcbiAgICAgICAgcmV0dXJuIHNlbGVjdHM7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIHJldHVybiBzZWxlY3RzO1xuICAgICAgfVxuICAgIH1cbiAgfSwge29iamVjdHM6IFtdLCBxdWVyaWVzOiBbXX0pO1xuXG5leHBvcnQgY29uc3QgZ2V0SW1hZ2VzQnlVc2VyID0gKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICB1c2VySWQ6IHN0cmluZyxcbiAgZnJvbTogbnVtYmVyID0gMCxcbiAgdG86IG51bWJlciA9IDMwXG4pOiBQcm9taXNlPEltYWdlVHlwZVtdPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2dldEltYWdlc0J5VXNlcic7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3QgZm9ybWF0VXNlcklkOiBzdHJpbmcgPSBwYXJzZUlkKHVzZXJJZCk7XG4gIGNvbnN0IGxpbWl0OiBBcmFuZ29EYkxpbWl0ID0gZ2V0TGltaXQoZnJvbSwgdG8pO1xuICBjb25zdCBhcWxRcnk6IHN0cmluZyA9IGBGT1IgaSBJTiBpbWFnZXNcbiAgICAgIEZJTFRFUiBpLnVzZXJJZCA9PSBcIiR7Zm9ybWF0VXNlcklkfVwiXG4gICAgICBMRVQgdXNlciA9IEZJUlNUKFxuICAgICAgICBGT1IgdSBJTiB1c2Vyc1xuICAgICAgICBGSUxURVIgdS5fa2V5ID09IGkudXNlcklkXG4gICAgICAgIExJTUlUIDFcbiAgICAgICAgUkVUVVJOIHVcbiAgICAgIClcbiAgICAgICR7bGltaXQuYXFsfVxuICAgICAgU09SVCBpLmFkZGVkXG4gICAgICBSRVRVUk4gTUVSR0UoaSwge3VzZXI6dXNlcn0pYDtcblxuICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpIGFzIHVua25vd24gYXMgSW1hZ2VUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgcGFyYW1zOiB7ZnJvbSwgdG8sIHVzZXJJZH0sXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCk7XG5cbiAgICAgIHJldHVybiBbXTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRJbWFnZUNvdW50QnlJdGVtID0gKGNvbnRleHQ6IEFwaUNvbnRleHQsIGl0ZW1JZDogc3RyaW5nKTogUHJvbWlzZTxudW1iZXI+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZ2V0SW1hZ2VDb3VudEJ5SXRlbSc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3QgZm9ybWF0SXRlbUlkOiBzdHJpbmcgPSBwYXJzZUFyYW5nb0lkKGl0ZW1JZCk7XG4gIGNvbnN0IGFxbFFyeTogQXFsUXVlcnkgPSBhcWxgRk9SIGkgSU4gaGFzSW1hZ2VcbiAgICAgIEZJTFRFUiBpLl90byA9PSAke2Zvcm1hdEl0ZW1JZH1cbiAgICAgIFJFVFVSTiB7Y291bnQ6IENPVU5UKGkpfWA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLnRoZW4oKHtjb3VudH0pID0+IGNvdW50KVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge2l0ZW1JZH0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0SW1hZ2VzQnlJdGVtID0gYXN5bmMgKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICBpdGVtSWQ6IHN0cmluZyxcbiAgb3B0aW9uczogSW1hZ2VPcHRpb25zID0ge31cbik6IFByb21pc2U8SW1hZ2VUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZ2V0SW1hZ2VzQnlJdGVtJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgZmllbGRzID0gW119ID0gY29udGV4dDtcbiAgY29uc3QgZm9ybWF0SXRlbUlkOiBzdHJpbmcgPSBwYXJzZUFyYW5nb0lkKGl0ZW1JZCk7XG4gIGNvbnN0IHtsaW1pdH0gPSBwYXJzZUltYWdlT3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0SW1hZ2VPcHRpb25hbChmaWVsZHMpO1xuICBjb25zdCBhcWxRcnk6IHN0cmluZyA9IGBGT1IgaSwgbCBJTiAxLi4xIE9VVEJPVU5EIFwiJHtmb3JtYXRJdGVtSWR9XCIgaGFzSW1hZ2VcbiAgICBGSUxURVIgTk9UIElTX05VTEwoaSlcbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgU09SVCBpLmFkZGVkXG4gICAgJHtsaW1pdC5hcWx9XG4gICAgUkVUVVJOIE1FUkdFKGksIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIEltYWdlVHlwZVtdKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIHBhcmFtczoge2l0ZW1JZCwgb3B0aW9uc30sXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCk7XG4gICAgICByZXR1cm4gW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0SW1hZ2VzQnlHcm91cCA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgcGFyYW1zOiB7ZmlsdGVyczogUXVlcnlGaWx0ZXJbXSwgZ3JvdXBJZDogc3RyaW5nLCBmcm9tOiBudW1iZXIsIHRvOiBudW1iZXJ9XG4pOiBQcm9taXNlPEltYWdlVHlwZVtdPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2dldEltYWdlc0J5R3JvdXAnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtmaWx0ZXJzLCBncm91cElkLCBmcm9tLCB0b30gPSBwYXJhbXM7XG4gIGNvbnN0IGZvcm1hdEdyb3VwSWQ6IHN0cmluZyA9IHBhcnNlSWQoZ3JvdXBJZCk7XG4gIGNvbnN0IGxpbWl0OiBBcmFuZ29EYkxpbWl0ID0gZ2V0TGltaXQoZnJvbSwgdG8pO1xuXG4gIGZpbHRlcnNcbiAgICAubWFwKChmaWx0ZXI6IFF1ZXJ5RmlsdGVyKSA9PiB7XG4gICAgICBjb25zdCB7Y29uZGl0aW9uYWwsIG5hbWUsIHZhbHVlfSA9IGZpbHRlcjtcbiAgICAgIGxldCBmb3JtYXRDb25kOiBzdHJpbmcgPSBjb25kaXRpb25hbDtcblxuICAgICAgaWYoY29uZGl0aW9uYWwgIT09ICc+PScgJiYgY29uZGl0aW9uYWwgIT09ICc8PScgJiYgY29uZGl0aW9uYWwgIT09ICc+JyAmJiBjb25kaXRpb25hbCAhPT0gJzwnKSB7XG4gICAgICAgIGZvcm1hdENvbmQgPSAnPT0nO1xuICAgICAgfVxuXG4gICAgICBzd2l0Y2gobmFtZSkge1xuICAgICAgICBjYXNlICdhZGRlZCc6XG4gICAgICAgICAgcmV0dXJuIGBwLmFkZGVkICR7Zm9ybWF0Q29uZH0gJHtwYXJzZU51bSh2YWx1ZSl9YDtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgcmV0dXJuIGdldEdyb3VwRGV0YWlscyhjb250ZXh0LCBmb3JtYXRHcm91cElkKVxuICAgIC50aGVuKChncm91cDogR3JvdXBUeXBlKSA9PiB7XG4gICAgICBpZihncm91cC5wcml2YWN5ID09PSAncHVibGljJykge1xuICAgICAgICBmaWx0ZXJzLnB1c2goe2NvbmRpdGlvbmFsOiAnPT0nLCBuYW1lOiAnZ3JvdXBJZCcsIHZhbHVlOiBmb3JtYXRHcm91cElkfSk7XG4gICAgICAgIGNvbnN0IGZpbHRlclN0ciA9IGZpbHRlcnMuam9pbignICYmICcpO1xuICAgICAgICBjb25zdCBhcWxRcnk6IHN0cmluZyA9IGBGT1IgaSBJTlxuICAgICAgICAgIEZMQVRURU4oXG4gICAgICAgICAgICBGT1IgcCBJTiBwb3N0c1xuICAgICAgICAgICAgRklMVEVSICR7ZmlsdGVyU3RyfVxuICAgICAgICAgICAgTEVUIGltYWdlcyA9IChcbiAgICAgICAgICAgICAgRk9SIGksIGUgSU4gSU5CT1VORCBwLl9pZCBoYXNJbWFnZVxuICAgICAgICAgICAgICBSRVRVUk4gaVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgU09SVCBwLmFkZGVkIERFU0NcbiAgICAgICAgICAgIFJFVFVSTiBpbWFnZXNcbiAgICAgICAgICApXG4gICAgICAgICAgU09SVCBpLmFkZGVkIERFU0NcbiAgICAgICAgICAke2xpbWl0LmFxbH1cbiAgICAgICAgICBSRVRVUk4gaWA7XG5cbiAgICAgICAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXJ5KVxuICAgICAgICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIEltYWdlVHlwZVtdKVxuICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICBsb2dFcnJvcih7XG4gICAgICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgICAgICAgIHBhcmFtczoge2ZpbHRlcnMsIGZyb20sIGdyb3VwSWQsIHRvfSxcbiAgICAgICAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgICAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpc0dyb3VwZWQoY29udGV4dCwgc2Vzc2lvbklkLCBncm91cElkKVxuICAgICAgICAudGhlbigoZ3JvdXBlZDogR3JvdXBVc2VyKSA9PiB7XG4gICAgICAgICAgaWYoZ3JvdXBlZC5pc1ZhbGlkKSB7XG4gICAgICAgICAgICBmaWx0ZXJzLnB1c2goe2NvbmRpdGlvbmFsOiAnPT0nLCBuYW1lOiAnZ3JvdXBJZCcsIHZhbHVlOiBncm91cGVkLmdyb3VwSWR9KTtcbiAgICAgICAgICAgIGNvbnN0IGZpbHRlckxpc3Q6IHN0cmluZyA9IGZpbHRlcnMuam9pbignICYmICcpO1xuICAgICAgICAgICAgY29uc3QgYXFsUXJ5OiBzdHJpbmcgPSBgRk9SIHAgSU4gcG9zdFxuICAgICAgICAgICAgICAgIEZJTFRFUiAke2ZpbHRlckxpc3R9XG4gICAgICAgICAgICAgICAgRk9SIGYgSU4gcC5maWxlc1xuICAgICAgICAgICAgICAgIEZJTFRFUiBmLnR5cGUgPT0gXCJpbWFnZS9qcGVnXCIgfHwgZi50eXBlID09IFwiaW1hZ2UvcG5nXCJcbiAgICAgICAgICAgICAgICAke2xpbWl0LmFxbH1cbiAgICAgICAgICAgICAgICBTT1JUIHAuYWRkZWQgREVTQ1xuICAgICAgICAgICAgICAgIFJFVFVSTiBmYDtcblxuICAgICAgICAgICAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXJ5KVxuICAgICAgICAgICAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkgYXMgdW5rbm93biBhcyBJbWFnZVR5cGVbXSlcbiAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dFcnJvcih7XG4gICAgICAgICAgICAgICAgICBhY3Rpb24sXG4gICAgICAgICAgICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgICAgICAgICAgIHBhcmFtczoge2ZpbHRlcnMsIGZyb20sIGdyb3VwSWQsIHRvfSxcbiAgICAgICAgICAgICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICAgICAgICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0SW1hZ2VzQnlSZWFjdGlvbnMgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHJlYWN0aW9uczogc3RyaW5nW10gPSBbXSxcbiAgb3B0aW9ucz86IEltYWdlT3B0aW9uc1xuKTogUHJvbWlzZTxJbWFnZVR5cGVbXT4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdnZXRVc2Vyc0J5SW1hZ2UnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMgPSBbXSwgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfX0gPSBjb250ZXh0O1xuICBjb25zdCB7bGltaXR9ID0gcGFyc2VJbWFnZU9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldEltYWdlT3B0aW9uYWwoZmllbGRzKTtcbiAgY29uc3QgZm9ybWF0U2Vzc2lvbklkOiBzdHJpbmcgPSBgdXNlcnMvJHtzZXNzaW9uSWR9YDtcbiAgY29uc3QgZm9ybWF0UmVhY3Rpb25zOiBzdHJpbmdbXSA9IHJlYWN0aW9ucy5tYXAoKHJlYWN0aW9uTmFtZSkgPT4gcGFyc2VDaGFyKHJlYWN0aW9uTmFtZSwgMzIpKTtcbiAgY29uc3QgZmlsdGVyQnk6IHN0cmluZ1tdID0gW1xuICAgICdyLnR5cGUgPT0gXCJpbWFnZXNcIicsXG4gICAgYFBPU0lUSU9OKCR7SlNPTi5zdHJpbmdpZnkoZm9ybWF0UmVhY3Rpb25zKX0sIExPV0VSKHIubmFtZSkpYF07XG5cbiAgLy8gR2V0IGRhdGEgZnJvbSBkYXRhYmFzZVxuICBjb25zdCBhcWxRcnk6IHN0cmluZyA9IGBGT1IgaSwgciBJTiBPVVRCT1VORCBcIiR7Zm9ybWF0U2Vzc2lvbklkfVwiIGhhc1JlYWN0aW9uXG4gICAgT1BUSU9OUyB7dmVydGV4Q29sbGVjdGlvbnM6IFwiaW1hZ2VzXCJ9XG4gICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuICAgIEZJTFRFUiAke2ZpbHRlckJ5LmpvaW4oJyAmJiAnKX1cbiAgICAke2xpbWl0LmFxbH1cbiAgICBSRVRVUk4gTUVSR0UoaSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcblxuICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpIGFzIHVua25vd24gYXMgSW1hZ2VUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgcGFyYW1zOiB7b3B0aW9ucywgcmVhY3Rpb25zfSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRJbWFnZSA9IChjb250ZXh0OiBBcGlDb250ZXh0LCBpbWFnZUlkOiBzdHJpbmcpOiBQcm9taXNlPEltYWdlVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdnZXRJdGVtJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZX0gPSBjb250ZXh0O1xuICBjb25zdCBmb3JtYXRJbWFnZUlkOiBzdHJpbmcgPSBwYXJzZUlkKGltYWdlSWQpO1xuICBjb25zdCBhcWxRcnk6IEFxbFF1ZXJ5ID0gYXFsYEZPUiBpIElOIGltYWdlc1xuICAgIEZJTFRFUiBpLl9rZXk9PSR7Zm9ybWF0SW1hZ2VJZH1cbiAgICBMSU1JVCAxXG4gICAgUkVUVVJOIGlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFFyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge2ltYWdlSWR9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvciwgY29udGV4dCkpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFBhdGhVc2VySW1hZ2VzID0gKHVzZXJJZDogc3RyaW5nLCBpbWFnZUlkOiBzdHJpbmcsIGltYWdlVHlwZTogc3RyaW5nLCBkaXI6IHN0cmluZyA9ICdpbWFnZXMnKTogc3RyaW5nID0+IHtcbiAgbGV0IGZpbGVuYW1lOiBzdHJpbmcgPSBpbWFnZUlkO1xuXG4gIHN3aXRjaChpbWFnZVR5cGUpIHtcbiAgICBjYXNlICdpbWFnZS9wbmcnOlxuICAgICAgZmlsZW5hbWUgPSBgJHtpbWFnZUlkfS5wbmdgO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIGZpbGVuYW1lID0gYCR7aW1hZ2VJZH0uanBnYDtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIGB1c2Vycy8ke3VzZXJJZH0vJHtkaXJ9LyR7ZmlsZW5hbWV9YDtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRBcHBJbWFnZVVybCA9ICh7XG4gIGJ1Y2tldCxcbiAgZGlyZWN0b3J5ID0gJ2ltYWdlcycsXG4gIGltYWdlSWQsXG4gIGltYWdlVHlwZSA9ICdqcGcnLFxuICBpc1RodW1iID0gZmFsc2UsXG4gIHR5cGUsXG4gIHR5cGVJZFxufTogSW1hZ2VVcmxEYXRhKTogc3RyaW5nID0+IHtcbiAgaWYoIXR5cGUpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBpZighaW1hZ2VJZCkge1xuICAgIGlmKGltYWdlVHlwZSA9PT0gJ3Byb2ZpbGUnKSB7XG4gICAgICByZXR1cm4gYCR7Q29uZmlnLmdldCgnaW1hZ2UuZGVmYXVsdFVybCcpfS91c2Vyc19iay5qcGdgO1xuICAgIH1cbiAgICByZXR1cm4gYCR7Q29uZmlnLmdldCgnaW1hZ2UuZGVmYXVsdFVybCcpfS91c2Vyc193aC5qcGdgO1xuICB9XG5cbiAgY29uc3QgYnVja2V0TmFtZSA9IGJ1Y2tldCB8fCBDb25maWcuZ2V0KCdpbWFnZS5idWNrZXQnKSB8fCAnZGV2LnJlYWt0b3IuaW8nO1xuICBjb25zdCBpbWFnZU5hbWUgPSBpc1RodW1iID8gYCR7aW1hZ2VJZH0tdGguJHtpbWFnZVR5cGV9YCA6IGAke2ltYWdlSWR9LiR7aW1hZ2VUeXBlID09PSAncHJvZmlsZScgfHwgaW1hZ2VUeXBlID09PSAnb3RoZXInID8gJ2pwZycgOiBpbWFnZVR5cGV9YDtcbiAgY29uc3QgaW1hZ2VVcmwgPSBDb25maWcuZ2V0KCdpbWFnZS51cmwnKSB8fCBgaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tLyR7YnVja2V0TmFtZX1gO1xuXG4gIGlmKHR5cGUgPT09ICdhcHBzJykge1xuICAgIHJldHVybiBgJHtpbWFnZVVybH0vJHt0eXBlfS8ke2RpcmVjdG9yeX0vJHtpbWFnZU5hbWV9YDtcbiAgfVxuXG4gIHJldHVybiBgJHtpbWFnZVVybH0vJHt0eXBlfS8ke3R5cGVJZH0vJHtkaXJlY3Rvcnl9LyR7aW1hZ2VOYW1lfWA7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0SW1hZ2VVcmwgPSBhc3luYyAoe1xuICBidWNrZXQsXG4gIGltYWdlRGlyID0gJ2ltYWdlcycsXG4gIGltYWdlSWQsXG4gIGltYWdlVHlwZSA9ICdqcGcnLFxuICBpc1RodW1iID0gZmFsc2UsXG4gIHR5cGUsXG4gIHR5cGVJZCxcbiAgdXJsVHlwZSA9ICdwdWJsaWMnXG59OiBJbWFnZVVybERhdGEpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICBpZighaW1hZ2VJZCkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIC8vIEFsd2F5cyB1c2Ugc2lnbmVkIFVSTHMgZm9yIHRodW1ibmFpbHNcbiAgaWYoaXNUaHVtYikge1xuICAgIHVybFR5cGUgPSAnc2lnbmVkJztcbiAgfVxuXG4gIGNvbnN0IHRodW1iU3VmZml4ID0gaXNUaHVtYiA/ICctdGgnIDogJyc7XG4gIGNvbnN0IGltYWdlS2V5OiBzdHJpbmcgPSBgJHt0eXBlfS8ke3R5cGVJZH0vJHtpbWFnZURpcn0vJHtpbWFnZUlkfSR7dGh1bWJTdWZmaXh9LiR7aW1hZ2VUeXBlfWA7XG5cbiAgc3dpdGNoKHVybFR5cGUpIHtcbiAgICBjYXNlICdzaWduZWQnOiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBkZWZhdWx0QnVja2V0ID0gQ29uZmlnLmdldCgnaW1hZ2UuYnVja2V0JykgfHwgJ2Rldi5yZWFrdG9yLmlvJztcbiAgICAgICAgcmV0dXJuIGF3YWl0IHMzR2V0U2lnbmVkVXJsKHtCdWNrZXQ6IGJ1Y2tldCB8fCBkZWZhdWx0QnVja2V0LCBFeHBpcmVzOiA5MDAsIEtleTogaW1hZ2VLZXl9KTtcbiAgICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfVxuICAgIGNhc2UgJ3B1YmxpYyc6IHtcbiAgICAgIHJldHVybiBgaHR0cHM6Ly9ib3guJHtDb25maWcuZ2V0KCdhcHAudXJsJyl9LyR7aW1hZ2VLZXl9YDtcbiAgICB9XG4gICAgY2FzZSAnZGV2Jzoge1xuICAgICAgcmV0dXJuIGBodHRwczovL3MzLmFtYXpvbmF3cy5jb20vZGV2LiR7Q29uZmlnLmdldCgnYXBwLnVybCcpfS8ke2ltYWdlS2V5fWA7XG4gICAgfVxuICAgIGRlZmF1bHQ6IHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCByZXNpemVTYXZlSW1hZ2UgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIGltYWdlSWQ6IHN0cmluZyxcbiAgYnVmZmVyOiBCdWZmZXIsXG4gIGZpbGVUeXBlOiBzdHJpbmcgPSAnaW1hZ2UvanBlZycsIHMzT3B0aW9ucz86IFB1dE9iamVjdENvbW1hbmRJbnB1dFxuKTogUHJvbWlzZTxJbWFnZVR5cGU+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAncmVzaXplU2F2ZUltYWdlJztcbiAgY29uc3Qge3Nlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH19ID0gY29udGV4dDtcbiAgY29uc3QgaW1nVzogbnVtYmVyID0gQ29uZmlnLmdldCgnaW1hZ2UuaW1nU2l6ZScpO1xuICBjb25zdCBpbWdROiBudW1iZXIgPSBDb25maWcuZ2V0KCdpbWFnZS5pbWdRdWFsaXR5Jyk7XG4gIGNvbnN0IGZvcm1hdDogc3RyaW5nID0gKGZpbGVUeXBlLnNwbGl0KCcvJykpWzFdO1xuXG4gIGNvbnN0IGltYWdlT3B0aW1pemVkQnVmZmVyOiBCdWZmZXIgPSBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgZ20oYnVmZmVyLCAnaW1nJylcbiAgICAgIC5zZXRGb3JtYXQoZm9ybWF0KVxuICAgICAgLnF1YWxpdHkoaW1nUSlcbiAgICAgIC5hdXRvT3JpZW50KClcbiAgICAgIC5yZXNpemUoaW1nVywgaW1nVywgJz4nKVxuICAgICAgLnN0cmVhbSgoc3RyZWFtRXJyb3I6IEVycm9yLCBzdGRvdXQpOiB2b2lkID0+IHtcbiAgICAgICAgaWYoc3RyZWFtRXJyb3IpIHtcbiAgICAgICAgICByZWplY3QoXG4gICAgICAgICAgICBsb2dFcnJvcih7XG4gICAgICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgICAgICAgIHBhcmFtczoge2ZpbGVUeXBlLCBpbWFnZUlkfSxcbiAgICAgICAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU1BR0VfU0FWRVxuICAgICAgICAgICAgfSwgc3RyZWFtRXJyb3IsIGNvbnRleHQpXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgaW1hZ2VCdWZmZXI6IEJ1ZmZlciA9IEJ1ZmZlci5mcm9tKCcnKTtcblxuICAgICAgICBzdGRvdXQub24oJ2RhdGEnLCAoZGF0YSkgPT4ge1xuICAgICAgICAgIGltYWdlQnVmZmVyID0gQnVmZmVyLmNvbmNhdChbaW1hZ2VCdWZmZXIsIGRhdGFdKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc3Rkb3V0Lm9uKCdlbmQnLCAoKSA9PiByZXNvbHZlKGltYWdlQnVmZmVyKSk7XG4gICAgICB9KTtcbiAgfSk7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBpbWFnZU9iajogUHV0T2JqZWN0Q29tbWFuZElucHV0ID0ge1xuICAgICAgQUNMOiAnYXV0aGVudGljYXRlZC1yZWFkJyxcbiAgICAgIEJvZHk6IGltYWdlT3B0aW1pemVkQnVmZmVyLFxuICAgICAgQnVja2V0OiBudWxsLFxuICAgICAgQ29udGVudFR5cGU6IGZpbGVUeXBlLFxuICAgICAgLi4uKHMzT3B0aW9ucyB8fCB7fSksXG4gICAgICBLZXk6IGdldFBhdGhVc2VySW1hZ2VzKHNlc3Npb25JZCwgaW1hZ2VJZCwgZmlsZVR5cGUsICdpbWFnZXMnKVxuICAgIH07XG4gICAgYXdhaXQgczNQdXQoaW1hZ2VPYmopO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgcmV0dXJuIGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7ZmlsZVR5cGUsIGltYWdlSWR9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU1BR0VfU0FWRVxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgfVxuXG4gIGNvbnN0IGltYWdlSWRlbnRpdHkgPSBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGdtKGltYWdlT3B0aW1pemVkQnVmZmVyLCAnaW1nJylcbiAgICAgIC5pZGVudGlmeSh7YnVmZmVyU3RyZWFtOiB0cnVlfSwgKGVycm9yOiBFcnJvciwgaW1hZ2VEYXRhOiBJbWFnZUlkZW50aWZ5VHlwZSA9IHt9KSA9PiB7XG4gICAgICAgIGlmKGVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIGxvZ0Vycm9yKHtcbiAgICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU1BR0VfU0FWRVxuICAgICAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZvcm1hdFZhbHVlcyA9IGxvd2VyQ2FzZUtleXMoaW1hZ2VEYXRhKTtcbiAgICAgICAgY29uc3Qge21ha2U6IGNhbWVyYU1ha2UsIG1vZGVsOiBjYW1lcmFNb2RlbCwgZGF0ZXRpbWVvcmlnaW5hbDogdGFrZW59OiBJbWFnZUlkZW50aWZ5VHlwZSA9IGZvcm1hdFZhbHVlcztcbiAgICAgICAgY29uc3Qgc3RhdHMgPSBmb3JtYXRWYWx1ZXNbJ2NoYW5uZWwgc3RhdGlzdGljcyddO1xuICAgICAgICBsZXQgY29sb3I6IHN0cmluZztcblxuICAgICAgICBpZihzdGF0cykge1xuICAgICAgICAgIGxldCB7cmVkLCBncmVlbiwgYmx1ZSwgbWVhbn0gPSBzdGF0cztcblxuICAgICAgICAgIGlmKHJlZCkge1xuICAgICAgICAgICAgbWVhbiA9IHJlZFsnc3RhbmRhcmQgZGV2aWF0aW9uJ10gfHwgcmVkLm1lYW47XG4gICAgICAgICAgICByZWQgPSBtZWFuID8gKygobWVhbi5zcGxpdCgnICcpWzBdKS5zdWJzdHJpbmcoMCwgMykpIDogMDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVkID0gMDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZihncmVlbikge1xuICAgICAgICAgICAgbWVhbiA9IGdyZWVuWydzdGFuZGFyZCBkZXZpYXRpb24nXSB8fCBncmVlbi5tZWFuO1xuICAgICAgICAgICAgZ3JlZW4gPSBtZWFuID8gKygobWVhbi5zcGxpdCgnICcpWzBdKS5zdWJzdHJpbmcoMCwgMykpIDogMDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ3JlZW4gPSAwO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmKGJsdWUpIHtcbiAgICAgICAgICAgIG1lYW4gPSBibHVlWydzdGFuZGFyZCBkZXZpYXRpb24nXSB8fCBibHVlLm1lYW47XG4gICAgICAgICAgICBibHVlID0gbWVhbiA/ICsoKG1lYW4uc3BsaXQoJyAnKVswXSkuc3Vic3RyaW5nKDAsIDMpKSA6IDA7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGJsdWUgPSAwO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHJnYiA9IGJsdWUgfCAoZ3JlZW4gPDwgOCkgfCAocmVkIDw8IDE2KTtcbiAgICAgICAgICBjb25zdCByZ2JDb2xvciA9IHJnYi50b1N0cmluZygxNik7XG4gICAgICAgICAgY29sb3IgPSByZ2JDb2xvciA9PT0gJzAnID8gJzAwMDAwMCcgOiByZ2JDb2xvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAnSlBFRy1RdWFsaXR5JzogcXVhbGl0eSxcbiAgICAgICAgICBPcmllbnRhdGlvbjogb3JpZW50YXRpb25EYXRhLFxuICAgICAgICAgIFJlc29sdXRpb246IHJlc29sdXRpb25EYXRhLFxuICAgICAgICAgIHNpemVcbiAgICAgICAgfSA9IGltYWdlRGF0YTtcbiAgICAgICAgbGV0IHJlc29sdXRpb247XG5cbiAgICAgICAgaWYocmVzb2x1dGlvbkRhdGEpIHtcbiAgICAgICAgICBjb25zdCBbcmVzb2x1dGlvbk51bWJlciwgcmVzb2x1dGlvblVuaXRdID0gcmVzb2x1dGlvbkRhdGEuc3BsaXQoJyAnKTtcbiAgICAgICAgICBjb25zdCByZXNvbHV0aW9uVmFsdWUgPSByZXNvbHV0aW9uTnVtYmVyLnNwbGl0KCd4JylbMF07XG4gICAgICAgICAgY29uc3QgcmVzb2x1dGlvblVuaXRWYWx1ZSA9IHJlc29sdXRpb25Vbml0ID09PSAncGl4ZWxzL2luY2gnID8gJ3BwaScgOiAnJztcbiAgICAgICAgICByZXNvbHV0aW9uID0gYCR7cmVzb2x1dGlvblZhbHVlfSAke3Jlc29sdXRpb25Vbml0VmFsdWV9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXNvbHZlKHtcbiAgICAgICAgICBjb2xvcixcbiAgICAgICAgICBmaWxlU2l6ZTogaW1hZ2VPcHRpbWl6ZWRCdWZmZXIubGVuZ3RoLFxuICAgICAgICAgIGZpbGVUeXBlOiBmb3JtYXQsXG4gICAgICAgICAgaGVpZ2h0OiBzaXplPy5oZWlnaHQgfHwgMCxcbiAgICAgICAgICBpbWFnZUlkLFxuICAgICAgICAgIG1ha2U6IGNhbWVyYU1ha2UsXG4gICAgICAgICAgbW9kZWw6IGNhbWVyYU1vZGVsLFxuICAgICAgICAgIG9yaWVudGF0aW9uOiBvcmllbnRhdGlvbkRhdGEgPT09ICdVbmtub3duJyA/IHVuZGVmaW5lZCA6IG9yaWVudGF0aW9uRGF0YT8udG9Mb3dlckNhc2UoKSxcbiAgICAgICAgICBxdWFsaXR5OiBxdWFsaXR5ID8gK3F1YWxpdHkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgcmVzb2x1dGlvbixcbiAgICAgICAgICB0YWtlbjogdGFrZW4gPyBEYXRlVGltZS5mcm9tTWlsbGlzKHRha2VuKS5taWxsaXNlY29uZCA6IHVuZGVmaW5lZCxcbiAgICAgICAgICB3aWR0aDogc2l6ZT8ud2lkdGggfHwgMFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICB9KTtcblxuICBjb25zdCB0aHVtYk9wdGltaXplZEJ1ZmZlcjogQnVmZmVyID0gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHRobVcgPSBDb25maWcuZ2V0KCdpbWFnZS50aG1TaXplJyk7XG4gICAgY29uc3QgdGhtUSA9IENvbmZpZy5nZXQoJ2ltYWdlLnRobVF1YWxpdHknKTtcblxuICAgIGdtKGltYWdlT3B0aW1pemVkQnVmZmVyLCAnaW1nJylcbiAgICAgIC5zZXRGb3JtYXQoZm9ybWF0KVxuICAgICAgLmdyYXZpdHkoJ0NlbnRlcicpXG4gICAgICAucmVzaXplKHRobVcsIHRobVcsICdeJylcbiAgICAgIC5leHRlbnQodGhtVywgdGhtVylcbiAgICAgIC5xdWFsaXR5KHRobVEpXG4gICAgICAuc3RyZWFtKChzdHJlYW1FcnJvcjogRXJyb3IsIHRodW1iU3Rkb3V0KTogdm9pZCA9PiB7XG4gICAgICAgIGlmKHN0cmVhbUVycm9yKSB7XG4gICAgICAgICAgbG9nRXJyb3Ioe1xuICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgICAgICBwYXJhbXM6IHtmaWxlVHlwZSwgaW1hZ2VJZH0sXG4gICAgICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTUFHRV9TQVZFXG4gICAgICAgICAgfSwgc3RyZWFtRXJyb3IsIGNvbnRleHQpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCB0aHVtYkJ1ZmZlcjogQnVmZmVyID0gQnVmZmVyLmZyb20oJycpO1xuXG4gICAgICAgIHRodW1iU3Rkb3V0Lm9uKCdkYXRhJywgKGRhdGEpID0+IHtcbiAgICAgICAgICB0aHVtYkJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW3RodW1iQnVmZmVyLCBkYXRhXSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRodW1iU3Rkb3V0Lm9uKCdlbmQnLCAoKSA9PiByZXNvbHZlKHRodW1iQnVmZmVyKSk7XG4gICAgICB9KTtcbiAgfSk7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCB0aHVtYk9iajogUHV0T2JqZWN0Q29tbWFuZElucHV0ID0ge1xuICAgICAgQUNMOiAnYXV0aGVudGljYXRlZC1yZWFkJyxcbiAgICAgIEJvZHk6IHRodW1iT3B0aW1pemVkQnVmZmVyLFxuICAgICAgQnVja2V0OiBudWxsLFxuICAgICAgQ29udGVudFR5cGU6IGZpbGVUeXBlLFxuICAgICAgLi4uKHMzT3B0aW9ucyB8fCB7fSksXG4gICAgICBLZXk6IGdldFBhdGhVc2VySW1hZ2VzKHNlc3Npb25JZCwgaW1hZ2VJZCwgZmlsZVR5cGUsICd0aHVtYnMnKVxuICAgIH07XG4gICAgYXdhaXQgczNQdXQodGh1bWJPYmopO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgcmV0dXJuIGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU1BR0VfU0FWRVxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgfVxuXG4gIHJldHVybiBpbWFnZUlkZW50aXR5O1xufTtcblxuZXhwb3J0IGNvbnN0IGFkZEltYWdlID0gKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICBpbWFnZTogSW1hZ2VUeXBlLFxuICBzM09wdGlvbnM/OiBQdXRPYmplY3RDb21tYW5kSW5wdXRcbik6IFByb21pc2U8SW1hZ2VUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2FkZEltYWdlJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfX0gPSBjb250ZXh0O1xuICBjb25zdCB7aW1hZ2VJZCwgZGVzY3JpcHRpb24sIGJ1ZmZlciwgZmlsZVR5cGV9ID0gaW1hZ2U7XG4gIGNvbnN0IG5vdzogbnVtYmVyID0gRGF0ZS5ub3coKTtcblxuICByZXR1cm4gcmVzaXplU2F2ZUltYWdlKGNvbnRleHQsIGltYWdlSWQsIGJ1ZmZlciwgZmlsZVR5cGUsIHMzT3B0aW9ucylcbiAgICAudGhlbigocmVzaXplZEltYWdlOiBJbWFnZVR5cGUpID0+IHtcbiAgICAgIGNvbnN0IGluc2VydDogSW1hZ2VUeXBlID0ge1xuICAgICAgICAuLi5yZXNpemVkSW1hZ2UsXG4gICAgICAgIF9rZXk6IGltYWdlSWQsXG4gICAgICAgIGFkZGVkOiBub3csXG4gICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICBmaWxlVHlwZSxcbiAgICAgICAgbW9kaWZpZWQ6IG5vdyxcbiAgICAgICAgdXNlcklkOiBzZXNzaW9uSWRcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGFxbFFyeTogQXFsUXVlcnkgPSBhcWxgSU5TRVJUICR7aW5zZXJ0fSBJTiBpbWFnZXMgUkVUVVJOIE5FV2A7XG5cbiAgICAgIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFFyeSlcbiAgICAgICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAgICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgICAgICBhY3Rpb24sXG4gICAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgICAgcGFyYW1zOiB7aW1hZ2UsIHMzT3B0aW9uc30sXG4gICAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgICAgfSwgZXJyb3IsIGNvbnRleHQpKTtcbiAgICB9KVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLklNQUdFX1JFU0laRVxuICAgIH0sIGVycm9yLCBjb250ZXh0KSk7XG59O1xuXG5leHBvcnQgY29uc3QgYWRkSW1hZ2VFZGdlID0gYXN5bmMgKGNvbnRleHQ6IEFwaUNvbnRleHQsIGltYWdlRWRnZTogSW1hZ2VFZGdlVHlwZSk6IFByb21pc2U8b2JqZWN0PiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2FkZEltYWdlRWRnZSc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH19ID0gY29udGV4dDtcbiAgY29uc3Qge2ltYWdlSWQsIGl0ZW1JZCwgaXRlbVR5cGV9ID0gaW1hZ2VFZGdlO1xuICBjb25zdCBub3c6IG51bWJlciA9IERhdGUubm93KCk7XG4gIC8vIGNvbnN0IGVkZ2VDb2xsZWN0aW9uOiBFZGdlQ29sbGVjdGlvbiA9IHVzZURiKGRhdGFiYXNlTmFtZSkuY29sbGVjdGlvbignaGFzSW1hZ2UnKTtcbiAgY29uc3QgZWRnZUlkOiBzdHJpbmcgPSBjcmVhdGVIYXNoKGBoYXNJbWFnZS0ke2ltYWdlSWR9LSR7aXRlbUlkfS0ke3Nlc3Npb25JZH1gKTtcbiAgY29uc3QgZm9ybWF0SXRlbVR5cGU6IEFyYW5nb0RiQ29sbGVjdGlvbiA9IHBhcnNlQ2hhcihpdGVtVHlwZSkudG9Mb3dlckNhc2UoKSBhcyBBcmFuZ29EYkNvbGxlY3Rpb247XG4gIGNvbnN0IGZvcm1hdEl0ZW1JZDogc3RyaW5nID0gcGFyc2VJZChpdGVtSWQpO1xuICBjb25zdCBpdGVtRG9jSWQ6IHN0cmluZyA9IGdldERvY0lkKGZvcm1hdEl0ZW1UeXBlLCB7X2tleTogZm9ybWF0SXRlbUlkfSk7XG4gIGNvbnN0IGZvcm1hdEltYWdlSWQ6IHN0cmluZyA9IHBhcnNlSWQoaW1hZ2VJZCk7XG4gIGNvbnN0IGZpbGVEb2NJZDogc3RyaW5nID0gYGltYWdlcy8ke2Zvcm1hdEltYWdlSWR9YDtcblxuICBjb25zdCBlZGdlOiBJbWFnZUVkZ2VUeXBlID0ge1xuICAgIF9mcm9tOiBpdGVtRG9jSWQsXG4gICAgX2tleTogZWRnZUlkLFxuICAgIF90bzogZmlsZURvY0lkLFxuICAgIGFkZGVkOiBub3csXG4gICAgaXRlbVR5cGVcbiAgfTtcblxuICBpZihpdGVtRG9jSWQpIHtcbiAgICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5jb2xsZWN0aW9uKCdoYXNJbWFnZScpLnNhdmUoZWRnZSwge3JldHVybk5ldzogdHJ1ZX0pXG4gICAgICAudGhlbigoZmlsZUVkZ2UpID0+IHVzZURiKGRhdGFiYXNlTmFtZSkuY29sbGVjdGlvbignaGFzSW1hZ2UnKS5kb2N1bWVudChmaWxlRWRnZSkpXG4gICAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4gbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBlZGdlLFxuICAgICAgICAgIGZpbGVEb2NJZCxcbiAgICAgICAgICBpbWFnZUlkLFxuICAgICAgICAgIGl0ZW1Eb2NJZCxcbiAgICAgICAgICBpdGVtSWQsXG4gICAgICAgICAgaXRlbVR5cGVcbiAgICAgICAgfSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn07XG5cbmV4cG9ydCBjb25zdCB1cGRhdGVJbWFnZSA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgaW1hZ2U6IEltYWdlVHlwZSxcbiAgczNPcHRpb25zPzogUHV0T2JqZWN0Q29tbWFuZElucHV0XG4pOiBQcm9taXNlPEltYWdlVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICd1cGRhdGVJbWFnZSc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH19ID0gY29udGV4dDtcbiAgY29uc3Qge1xuICAgIGJhc2U2NCA9ICcnLFxuICAgIGJ1ZmZlcjogaW1hZ2VCdWZmZXIsXG4gICAgZGVzY3JpcHRpb24gPSAnJyxcbiAgICBpbWFnZUlkLFxuICAgIGl0ZW1JZCxcbiAgICBpdGVtVHlwZSxcbiAgICBmaWxlVHlwZSxcbiAgICB1cmwgPSAnJ1xuICB9ID0gaW1hZ2U7XG5cbiAgY29uc3Qgbm93OiBudW1iZXIgPSBEYXRlLm5vdygpO1xuICBjb25zdCBmb3JtYXRJbWFnZUlkOiBzdHJpbmcgPSBpbWFnZUlkIHx8IGNyZWF0ZUhhc2goYGltYWdlLSR7c2Vzc2lvbklkfWApO1xuICBjb25zdCBmb3JtYXRJdGVtSWQ6IHN0cmluZyA9IHBhcnNlSWQoaXRlbUlkKTtcbiAgY29uc3QgZm9ybWF0SXRlbVR5cGU6IEFyYW5nb0RiQ29sbGVjdGlvbiA9IHBhcnNlQ2hhcihpdGVtVHlwZSwgMTYpLnRvTG93ZXJDYXNlKCkgYXMgQXJhbmdvRGJDb2xsZWN0aW9uO1xuICBjb25zdCBjdXN0b21QYXJhbXM6IEltYWdlVHlwZSA9IHtcbiAgICBkZXNjcmlwdGlvbixcbiAgICBpbWFnZUlkOiBmb3JtYXRJbWFnZUlkLFxuICAgIHVzZXJJZDogc2Vzc2lvbklkXG4gIH07XG5cbiAgaWYoYmFzZTY0IHx8IGltYWdlQnVmZmVyKSB7XG4gICAgbGV0IGJ1ZmZlcjogQnVmZmVyID0gaW1hZ2VCdWZmZXI7XG5cbiAgICBpZihiYXNlNjQpIHtcbiAgICAgIGNvbnN0IGZvcm1hdEJhc2U2NDogc3RyaW5nID0gYmFzZTY0LnN1YnN0cihiYXNlNjQuaW5kZXhPZignLCcpICsgMSk7XG4gICAgICBidWZmZXIgPSBCdWZmZXIuZnJvbShmb3JtYXRCYXNlNjQsICdiYXNlNjQnKTtcbiAgICB9XG5cbiAgICBsZXQgdXBkYXRlZEZpbGVUeXBlID0gZmlsZVR5cGU7XG5cbiAgICBpZighZmlsZVR5cGUpIHtcbiAgICAgIGNvbnN0IHtmaWxlVHlwZUZyb21CdWZmZXJ9ID0gYXdhaXQgaW1wb3J0KCdmaWxlLXR5cGUnKTtcbiAgICAgIGNvbnN0IHttaW1lfSA9IGF3YWl0IGZpbGVUeXBlRnJvbUJ1ZmZlcihidWZmZXIpO1xuICAgICAgdXBkYXRlZEZpbGVUeXBlID0gbWltZTtcbiAgICB9XG5cbiAgICBjb25zdCBpbWdQYXJhbXM6IEltYWdlVHlwZSA9IHtcbiAgICAgIC4uLmN1c3RvbVBhcmFtcyxcbiAgICAgIGJ1ZmZlcixcbiAgICAgIGZpbGVUeXBlOiB1cGRhdGVkRmlsZVR5cGVcbiAgICB9O1xuXG4gICAgcmV0dXJuIGFkZEltYWdlKGNvbnRleHQsIGltZ1BhcmFtcywgczNPcHRpb25zKVxuICAgICAgLnRoZW4oKGltYWdlOiBJbWFnZVR5cGUpID0+IHtcbiAgICAgICAgaWYoZm9ybWF0SXRlbUlkICYmIGZvcm1hdEl0ZW1UeXBlKSB7XG4gICAgICAgICAgY29uc3QgaW1hZ2VFZGdlOiBJbWFnZUVkZ2VUeXBlID0ge1xuICAgICAgICAgICAgaW1hZ2VJZDogZm9ybWF0SW1hZ2VJZCxcbiAgICAgICAgICAgIGl0ZW1JZDogZm9ybWF0SXRlbUlkLFxuICAgICAgICAgICAgaXRlbVR5cGU6IGZvcm1hdEl0ZW1UeXBlXG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXR1cm4gYWRkSW1hZ2VFZGdlKGNvbnRleHQsIGltYWdlRWRnZSkudGhlbigoKSA9PiBpbWFnZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaW1hZ2U7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlcnJvcikgPT4gbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTUFHRV9TQVZFXG4gICAgICB9LCBlcnJvciwgY29udGV4dCkpO1xuICB9IGVsc2UgaWYodXJsICE9PSAnJykge1xuICAgIGxldCBjb250ZW50VHlwZTtcblxuICAgIHJldHVybiBodHRwR2V0KHVybClcbiAgICAgIC50aGVuKChyZXM6IEh0dHBSZXNwb25zZSkgPT4ge1xuICAgICAgICBpZihyZXMuc3RhdHVzICE9PSAyMDApIHtcbiAgICAgICAgICByZXR1cm4gbG9nRXhjZXB0aW9uKHtcbiAgICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU1BR0VfUkVRVUVTVFxuICAgICAgICAgIH0sIGNvbnRleHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29udGVudFR5cGUgPSByZXMuaGVhZGVycy5nZXQoJ2NvbnRlbnQtdHlwZScpO1xuXG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKHJlcykgPT4gKHJlcyBhcyBIdHRwUmVzcG9uc2UpLmJ1ZmZlcigpKVxuICAgICAgLnRoZW4oKGJ1ZmZlcjogQnVmZmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IGltZ1BhcmFtczogSW1hZ2VUeXBlID0ge1xuICAgICAgICAgIC4uLmN1c3RvbVBhcmFtcyxcbiAgICAgICAgICBidWZmZXIsXG4gICAgICAgICAgZmlsZVR5cGU6IGNvbnRlbnRUeXBlXG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIGFkZEltYWdlKGNvbnRleHQsIGltZ1BhcmFtcywgczNPcHRpb25zKVxuICAgICAgICAgIC50aGVuKChpbWFnZTogSW1hZ2VUeXBlKSA9PiB7XG4gICAgICAgICAgICBpZihmb3JtYXRJdGVtSWQgJiYgZm9ybWF0SXRlbVR5cGUpIHtcbiAgICAgICAgICAgICAgY29uc3QgaW1hZ2VFZGdlOiBJbWFnZUVkZ2VUeXBlID0ge2ltYWdlSWQ6IGZvcm1hdEltYWdlSWQsIGl0ZW1JZDogZm9ybWF0SXRlbUlkLCBpdGVtVHlwZTogZm9ybWF0SXRlbVR5cGV9O1xuICAgICAgICAgICAgICByZXR1cm4gYWRkSW1hZ2VFZGdlKGNvbnRleHQsIGltYWdlRWRnZSkudGhlbigoKSA9PiBpbWFnZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBpbWFnZTtcbiAgICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4gbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICB2YWx1ZTogJ2ZldGNoX2Vycm9yJ1xuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpKTtcbiAgfSBlbHNlIGlmKGltYWdlSWQgIT09ICcnKSB7XG4gICAgY29uc3QgdXBkYXRlID0ge1xuICAgICAgZGVzY3JpcHRpb24sXG4gICAgICBtb2RpZmllZDogbm93XG4gICAgfTtcbiAgICBjb25zdCBhcWxRcnk6IEFxbFF1ZXJ5ID0gYXFsYFVQREFURSB7X2tleTogJHtmb3JtYXRJbWFnZUlkfX0gV0lUSCAke3VwZGF0ZX0gSU4gaW1hZ2VzIFJFVFVSTiBORVdgO1xuXG4gICAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXJ5KVxuICAgICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIHBhcmFtczoge1xuICAgICAgICAgIGFxbFFyeSxcbiAgICAgICAgICBmb3JtYXRJbWFnZUlkLFxuICAgICAgICAgIHVwZGF0ZVxuICAgICAgICB9LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpKTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufTtcblxuZXhwb3J0IGNvbnN0IGRlbGV0ZUltYWdlID0gYXN5bmMgKGNvbnRleHQ6IEFwaUNvbnRleHQsIGltYWdlSWQ6IHN0cmluZyk6IFByb21pc2U8SW1hZ2VUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2RlbGV0ZSc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH19ID0gY29udGV4dDtcbiAgY29uc3QgZm9ybWF0SW1hZ2VJZCA9IHBhcnNlSWQoaW1hZ2VJZCk7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCByZW1vdmVFZGdlUXVlcnkgPSBhcWxgRk9SIGhpIElOIGhhc0ltYWdlXG4gICAgRklMVEVSIGhpLl9mcm9tID09ICR7Zm9ybWF0SW1hZ2VJZH1cbiAgICBSRU1PVkUgaGkgSU4gaGFzSW1hZ2VcbiAgICBSRVRVUk4gT0xEYDtcblxuICAgIGF3YWl0IHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkocmVtb3ZlRWRnZVF1ZXJ5KTtcblxuICAgIGNvbnN0IGFxbFF1ZXJ5ID0gYXFsYEZPUiBpIElOIGltYWdlc1xuICAgIEZJTFRFUiBpLl9rZXkgPT0gJHtmb3JtYXRJbWFnZUlkfSAmJiBpLnVzZXJJZCA9PSAke3Nlc3Npb25JZH1cbiAgICBSRU1PVkUgaSBJTiBpbWFnZXNcbiAgICBSRVRVUk4gT0xEYDtcblxuICAgIGNvbnN0IGltYWdlID0gYXdhaXQgdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRdWVyeSkudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKTtcblxuICAgIGlmKGltYWdlKSB7XG4gICAgICBjb25zdCB7X2tleTogaW1hZ2VLZXl9ID0gaW1hZ2U7XG4gICAgICBjb25zdCBwYXJhbXM6IERlbGV0ZU9iamVjdHNDb21tYW5kSW5wdXQgPSB7XG4gICAgICAgIEJ1Y2tldDogbnVsbCxcbiAgICAgICAgRGVsZXRlOiB7XG4gICAgICAgICAgT2JqZWN0czogW1xuICAgICAgICAgICAge0tleTogYHVzZXJzLyR7c2Vzc2lvbklkfS9pbWFnZXMvJHtpbWFnZUtleX0uanBnYH0sXG4gICAgICAgICAgICB7S2V5OiBgdXNlcnMvJHtzZXNzaW9uSWR9L3RodW1icy8ke2ltYWdlS2V5fS5qcGdgfVxuICAgICAgICAgIF0sXG4gICAgICAgICAgUXVpZXQ6IHRydWVcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHMzRGVsZXRlTGlzdChwYXJhbXMpLnRoZW4oKCkgPT4gaW1hZ2UpO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgcmV0dXJuIGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7aW1hZ2VJZH0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgfVxufTtcbiJdLAogICJtYXBwaW5ncyI6ICJBQUtBLE9BQVEsT0FBT0EsTUFBYyxvQkFDN0IsT0FBUSxZQUFBQyxNQUFlLCtCQUN2QixPQUFRLGNBQUFDLEVBQVksaUJBQUFDLEVBQWUsYUFBQUMsRUFBVyxXQUFBQyxNQUFjLCtCQUM1RCxPQUFRLE9BQUFDLE1BQVUsV0FFbEIsT0FBT0MsTUFBUSxLQUNmLE9BQVEsWUFBQUMsTUFBZSxRQUV2QixPQUFRLFVBQUFDLE1BQWEsZUFDckIsT0FBUSxjQUFBQyxNQUFpQiwwQkFDekIsT0FBUSxZQUFBQyxFQUFVLGdCQUFBQyxNQUFtQiw2QkFDckMsT0FBUSxZQUFBQyxHQUFVLFlBQUFDLEVBQVUsNkJBQUFDLEdBQTJCLFNBQUFDLE1BQVksNEJBQ25F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dUJBQ0VpRSxDQUFhLG1CQUFtQm5CLENBQVM7QUFBQTtBQUFBLGdCQUl0RCtFLEVBQVEsTUFBTW5ILEVBQU1xQixDQUFZLEVBQUUsTUFBTTBILENBQVEsRUFBRSxLQUFNdEgsR0FBV0EsRUFBTyxLQUFLLENBQUMsRUFFdEYsR0FBRzBGLEVBQU8sQ0FDUixLQUFNLENBQUMsS0FBTTVDLENBQVEsRUFBSTRDLEVBQ25CaEYsRUFBb0MsQ0FDeEMsT0FBUSxLQUNSLE9BQVEsQ0FDTixRQUFTLENBQ1AsQ0FBQyxJQUFLLFNBQVNDLENBQVMsV0FBV21DLENBQVEsTUFBTSxFQUNqRCxDQUFDLElBQUssU0FBU25DLENBQVMsV0FBV21DLENBQVEsTUFBTSxDQUNuRCxFQUNBLE1BQU8sRUFDVCxDQUNGLEVBRUEsT0FBT3BFLEdBQWFnQyxDQUFNLEVBQUUsS0FBSyxJQUFNZ0YsQ0FBSyxDQUM5QyxDQUVBLE9BQU8sSUFDVCxPQUFRekYsRUFBTyxDQUNiLE9BQU8vQixFQUFTLENBQ2QsT0FBQXlCLEVBQ0EsU0FBVWIsRUFDVixPQUFRLENBQUMsUUFBQStDLENBQU8sRUFDaEIsTUFBTzVELEVBQVcsY0FDcEIsRUFBR2dDLEVBQU9SLENBQU8sQ0FDbkIsQ0FDRiIsCiAgIm5hbWVzIjogWyJodHRwR2V0IiwgInBhcnNlTnVtIiwgImNyZWF0ZUhhc2giLCAicGFyc2VBcmFuZ29JZCIsICJwYXJzZUNoYXIiLCAicGFyc2VJZCIsICJhcWwiLCAiZ20iLCAiRGF0ZVRpbWUiLCAiQ29uZmlnIiwgIkVycm9yVHlwZXMiLCAibG9nRXJyb3IiLCAibG9nRXhjZXB0aW9uIiwgImdldERvY0lkIiwgImdldExpbWl0IiwgInNlbGVjdFJlYWN0aW9uQ291bnRCeVR5cGUiLCAidXNlRGIiLCAiZ2V0R3JvdXBEZXRhaWxzIiwgImlzR3JvdXBlZCIsICJzM0RlbGV0ZUxpc3QiLCAiczNHZXRTaWduZWRVcmwiLCAiczNQdXQiLCAibG93ZXJDYXNlS2V5cyIsICJldmVudENhdGVnb3J5IiwgInBhcnNlSW1hZ2VPcHRpb25zIiwgIm9wdGlvbnMiLCAiZnJvbSIsICJ0byIsICJ0eXBlIiwgImdldEltYWdlT3B0aW9uYWwiLCAiZmllbGRzIiwgInNlbGVjdHMiLCAiZmllbGQiLCAiZ2V0SW1hZ2VzQnlVc2VyIiwgImNvbnRleHQiLCAidXNlcklkIiwgImFjdGlvbiIsICJkYXRhYmFzZU5hbWUiLCAiZm9ybWF0VXNlcklkIiwgImxpbWl0IiwgImFxbFFyeSIsICJjdXJzb3IiLCAiZXJyb3IiLCAiZ2V0SW1hZ2VDb3VudEJ5SXRlbSIsICJpdGVtSWQiLCAiZm9ybWF0SXRlbUlkIiwgImNvdW50IiwgImdldEltYWdlc0J5SXRlbSIsICJzZWxlY3RPYmplY3RzIiwgInNlbGVjdFF1ZXJpZXMiLCAiZ2V0SW1hZ2VzQnlHcm91cCIsICJwYXJhbXMiLCAic2Vzc2lvbklkIiwgImZpbHRlcnMiLCAiZ3JvdXBJZCIsICJmb3JtYXRHcm91cElkIiwgImZpbHRlciIsICJjb25kaXRpb25hbCIsICJuYW1lIiwgInZhbHVlIiwgImZvcm1hdENvbmQiLCAiZ3JvdXAiLCAiZ3JvdXBlZCIsICJnZXRJbWFnZXNCeVJlYWN0aW9ucyIsICJyZWFjdGlvbnMiLCAiZm9ybWF0U2Vzc2lvbklkIiwgImZvcm1hdFJlYWN0aW9ucyIsICJyZWFjdGlvbk5hbWUiLCAiZmlsdGVyQnkiLCAiZ2V0SW1hZ2UiLCAiaW1hZ2VJZCIsICJmb3JtYXRJbWFnZUlkIiwgImdldFBhdGhVc2VySW1hZ2VzIiwgImltYWdlVHlwZSIsICJkaXIiLCAiZmlsZW5hbWUiLCAiZ2V0QXBwSW1hZ2VVcmwiLCAiYnVja2V0IiwgImRpcmVjdG9yeSIsICJpc1RodW1iIiwgInR5cGVJZCIsICJidWNrZXROYW1lIiwgImltYWdlTmFtZSIsICJpbWFnZVVybCIsICJnZXRJbWFnZVVybCIsICJpbWFnZURpciIsICJ1cmxUeXBlIiwgImltYWdlS2V5IiwgImRlZmF1bHRCdWNrZXQiLCAicmVzaXplU2F2ZUltYWdlIiwgImJ1ZmZlciIsICJmaWxlVHlwZSIsICJzM09wdGlvbnMiLCAiaW1nVyIsICJpbWdRIiwgImZvcm1hdCIsICJpbWFnZU9wdGltaXplZEJ1ZmZlciIsICJyZXNvbHZlIiwgInJlamVjdCIsICJzdHJlYW1FcnJvciIsICJzdGRvdXQiLCAiaW1hZ2VCdWZmZXIiLCAiZGF0YSIsICJpbWFnZU9iaiIsICJpbWFnZUlkZW50aXR5IiwgImltYWdlRGF0YSIsICJmb3JtYXRWYWx1ZXMiLCAiY2FtZXJhTWFrZSIsICJjYW1lcmFNb2RlbCIsICJ0YWtlbiIsICJzdGF0cyIsICJjb2xvciIsICJyZWQiLCAiZ3JlZW4iLCAiYmx1ZSIsICJtZWFuIiwgInJnYkNvbG9yIiwgInF1YWxpdHkiLCAib3JpZW50YXRpb25EYXRhIiwgInJlc29sdXRpb25EYXRhIiwgInNpemUiLCAicmVzb2x1dGlvbiIsICJyZXNvbHV0aW9uTnVtYmVyIiwgInJlc29sdXRpb25Vbml0IiwgInRodW1iT3B0aW1pemVkQnVmZmVyIiwgInRobVciLCAidGhtUSIsICJ0aHVtYlN0ZG91dCIsICJ0aHVtYkJ1ZmZlciIsICJ0aHVtYk9iaiIsICJhZGRJbWFnZSIsICJpbWFnZSIsICJkZXNjcmlwdGlvbiIsICJub3ciLCAicmVzaXplZEltYWdlIiwgImluc2VydCIsICJhZGRJbWFnZUVkZ2UiLCAiaW1hZ2VFZGdlIiwgIml0ZW1UeXBlIiwgImVkZ2VJZCIsICJmb3JtYXRJdGVtVHlwZSIsICJpdGVtRG9jSWQiLCAiZmlsZURvY0lkIiwgImVkZ2UiLCAiZmlsZUVkZ2UiLCAidXBkYXRlSW1hZ2UiLCAiYmFzZTY0IiwgInVybCIsICJjdXN0b21QYXJhbXMiLCAiZm9ybWF0QmFzZTY0IiwgInVwZGF0ZWRGaWxlVHlwZSIsICJmaWxlVHlwZUZyb21CdWZmZXIiLCAibWltZSIsICJpbWdQYXJhbXMiLCAiY29udGVudFR5cGUiLCAicmVzIiwgInVwZGF0ZSIsICJkZWxldGVJbWFnZSIsICJyZW1vdmVFZGdlUXVlcnkiLCAiYXFsUXVlcnkiXQp9Cg==
690
+ RETURN OLD`;
691
+ const image = await useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.next());
692
+ if (image) {
693
+ const { _key: imageKey } = image;
694
+ const params = {
695
+ Bucket: null,
696
+ Delete: {
697
+ Objects: [
698
+ {
699
+ Key: `users/${sessionId}/images/${imageKey}.jpg`
700
+ },
701
+ {
702
+ Key: `users/${sessionId}/thumbs/${imageKey}.jpg`
703
+ }
704
+ ],
705
+ Quiet: true
706
+ }
707
+ };
708
+ return s3DeleteList(params).then(()=>image);
709
+ }
710
+ return null;
711
+ } catch (error) {
712
+ return logError({
713
+ action,
714
+ category: eventCategory,
715
+ params: {
716
+ imageId
717
+ },
718
+ value: ErrorTypes.DATABASE_ERROR
719
+ }, error, context);
720
+ }
721
+ };
722
+
723
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3Ivc3JjL2FjdGlvbnMvaW1hZ2VzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDE5LVByZXNlbnQsIE5pdHJvZ2VuIExhYnMsIEluYy5cbiAqIENvcHlyaWdodHMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgdGhlIGFjY29tcGFueWluZyBMSUNFTlNFIGZpbGUgZm9yIHRlcm1zLlxuICovXG5pbXBvcnQge0RlbGV0ZU9iamVjdHNDb21tYW5kSW5wdXQsIFB1dE9iamVjdENvbW1hbmRJbnB1dH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXMzJztcbmltcG9ydCB7Z2V0IGFzIGh0dHBHZXR9IGZyb20gJ0BubGFicy9yaXAtaHVudGVyJztcbmltcG9ydCB7cGFyc2VOdW19IGZyb20gJ0BubGFicy91dGlscy9wYXJzZXJzL251bWJlcnMnO1xuaW1wb3J0IHtjcmVhdGVIYXNoLCBwYXJzZUFyYW5nb0lkLCBwYXJzZUNoYXIsIHBhcnNlSWR9IGZyb20gJ0BubGFicy91dGlscy9wYXJzZXJzL3N0cmluZ3MnO1xuaW1wb3J0IHthcWx9IGZyb20gJ2FyYW5nb2pzJztcbmltcG9ydCB7QXFsUXVlcnl9IGZyb20gJ2FyYW5nb2pzL2FxbCc7XG5pbXBvcnQgZ20gZnJvbSAnZ20nO1xuaW1wb3J0IHtEYXRlVGltZX0gZnJvbSAnbHV4b24nO1xuXG5pbXBvcnQge0NvbmZpZ30gZnJvbSAnLi4vY29uZmlnLmpzJztcbmltcG9ydCB7RXJyb3JUeXBlc30gZnJvbSAnLi4vdHlwZXMvZXJyb3IudHlwZXMuanMnO1xuaW1wb3J0IHtsb2dFcnJvciwgbG9nRXhjZXB0aW9ufSBmcm9tICcuLi91dGlscy9hbmFseXRpY3NVdGlscy5qcyc7XG5pbXBvcnQge2dldERvY0lkLCBnZXRMaW1pdCwgc2VsZWN0UmVhY3Rpb25Db3VudEJ5VHlwZSwgdXNlRGJ9IGZyb20gJy4uL3V0aWxzL2FyYW5nb2RiVXRpbHMuanMnO1xuaW1wb3J0IHtnZXRHcm91cERldGFpbHMsIGlzR3JvdXBlZH0gZnJvbSAnLi9ncm91cHMuanMnO1xuaW1wb3J0IHtzM0RlbGV0ZUxpc3QsIHMzR2V0U2lnbmVkVXJsLCBzM1B1dH0gZnJvbSAnLi9zMy5qcyc7XG5cbmltcG9ydCB7bG93ZXJDYXNlS2V5c30gZnJvbSAnQG5sYWJzL3V0aWxzL3BhcnNlcnMvb2JqZWN0cyc7XG5pbXBvcnQgdHlwZSB7UXVlcnlGaWx0ZXJ9IGZyb20gJy4uL3R5cGVzL2FwcHMudHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge0FyYW5nb0RiQ29sbGVjdGlvbiwgQXJhbmdvRGJMaW1pdH0gZnJvbSAnLi4vdHlwZXMvYXJhbmdvZGIudHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge0FwaUNvbnRleHR9IGZyb20gJy4uL3R5cGVzL2F1dGgudHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge0dyb3VwVHlwZSwgR3JvdXBVc2VyfSBmcm9tICcuLi90eXBlcy9ncm91cHMudHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge0ltYWdlRWRnZVR5cGUsIEltYWdlSWRlbnRpZnlUeXBlLCBJbWFnZU9wdGlvbnMsIEltYWdlVHlwZSwgSW1hZ2VVcmxEYXRhfSBmcm9tICcuLi90eXBlcy9pbWFnZXMudHlwZXMuanMnO1xuXG4vLyBEZWZpbmUgaW50ZXJmYWNlIGZvciBIVFRQIHJlc3BvbnNlIHdpdGggYnVmZmVyIG1ldGhvZFxuaW50ZXJmYWNlIEh0dHBSZXNwb25zZSBleHRlbmRzIFJlc3BvbnNlIHtcbiAgYnVmZmVyKCk6IFByb21pc2U8QnVmZmVyPjtcbn1cblxuY29uc3QgZXZlbnRDYXRlZ29yeTogc3RyaW5nID0gJ2ltYWdlcyc7XG5nbS5zdWJDbGFzcyh7aW1hZ2VNYWdpY2s6ICc3Kyd9KTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlSW1hZ2VPcHRpb25zID0gKG9wdGlvbnM6IEltYWdlT3B0aW9ucyA9IHt9KSA9PiB7XG4gIGNvbnN0IHtcbiAgICBmcm9tID0gMCxcbiAgICB0byA9IDMwLFxuICAgIHR5cGUgPSAnZGVmYXVsdCdcbiAgfSA9IG9wdGlvbnM7XG5cbiAgcmV0dXJuIHtcbiAgICBsaW1pdDogZ2V0TGltaXQoZnJvbSwgdG8pIGFzIEFyYW5nb0RiTGltaXQsXG4gICAgdHlwZTogcGFyc2VDaGFyKHR5cGUsIDMyKVxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEltYWdlT3B0aW9uYWwgPSAoZmllbGRzOiBzdHJpbmdbXSA9IFtdKSA9PlxuICBmaWVsZHMucmVkdWNlKChzZWxlY3RzLCBmaWVsZDogc3RyaW5nKSA9PiB7XG4gICAgaWYoZmllbGQuaW5jbHVkZXMoJ0NvdW50JykpIHtcbiAgICAgIHJldHVybiBzZWxlY3RSZWFjdGlvbkNvdW50QnlUeXBlKCdpbWFnZXMnLCAnaScsIGZpZWxkLCBzZWxlY3RzKTtcbiAgICB9XG5cbiAgICBzd2l0Y2goZmllbGQpIHtcbiAgICAgIGNhc2UgJ3JlYWN0aW9ucyc6IHtcbiAgICAgICAgc2VsZWN0cy5xdWVyaWVzLnB1c2goYExFVCByZWFjdGlvbnMgPSAoXG4gICAgICAgICAgRk9SIGltYWdlLCByIElOIElOQk9VTkQgaS5faWQgcmVhY3Rpb25zXG4gICAgICAgICAgQ09MTEVDVCByZWFjdGlvbk5hbWUgPSByLnZhbHVlIElOVE8gcmVhY3Rpb25JdGVtc1xuICAgICAgICAgIFJFVFVSTiB7bmFtZTogcmVhY3Rpb25OYW1lLCBjb3VudDogTEVOR1RIKHJlYWN0aW9uSXRlbXNbKl0uci52YWx1ZSl9XG4gICAgICAgIClgKTtcbiAgICAgICAgc2VsZWN0cy5vYmplY3RzLnB1c2goJ3JlYWN0aW9uczpyZWFjdGlvbnMnKTtcbiAgICAgICAgcmV0dXJuIHNlbGVjdHM7XG4gICAgICB9XG4gICAgICBjYXNlICd0YWdzJzoge1xuICAgICAgICBzZWxlY3RzLnF1ZXJpZXMucHVzaChgTEVUIHRhZ3MgPSAoXG4gICAgICAgICAgRk9SIHQsIHBsIElOIElOQk9VTkQgaS5faWQgaXNUYWdnZWRcbiAgICAgICAgICBSRVRVUk4gdFxuICAgICAgICApYCk7XG4gICAgICAgIHNlbGVjdHMub2JqZWN0cy5wdXNoKCd0YWdzOnRhZ3MnKTtcbiAgICAgICAgcmV0dXJuIHNlbGVjdHM7XG4gICAgICB9XG4gICAgICBjYXNlICd1c2Vycyc6IHtcbiAgICAgICAgc2VsZWN0cy5xdWVyaWVzLnB1c2goYExFVCB1c2VycyA9IEZJUlNUKFxuICAgICAgICAgIEZPUiB1IElOIHVzZXJzXG4gICAgICAgICAgRklMVEVSIGkudXNlcklkID09IHUuX2tleVxuICAgICAgICAgIExJTUlUIDFcbiAgICAgICAgICBSRVRVUk4gdVxuICAgICAgICApYCk7XG4gICAgICAgIHNlbGVjdHMub2JqZWN0cy5wdXNoKCd1c2Vyczp1c2VycycpO1xuICAgICAgICByZXR1cm4gc2VsZWN0cztcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgcmV0dXJuIHNlbGVjdHM7XG4gICAgICB9XG4gICAgfVxuICB9LCB7b2JqZWN0czogW10sIHF1ZXJpZXM6IFtdfSk7XG5cbmV4cG9ydCBjb25zdCBnZXRJbWFnZXNCeVVzZXIgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHVzZXJJZDogc3RyaW5nLFxuICBmcm9tOiBudW1iZXIgPSAwLFxuICB0bzogbnVtYmVyID0gMzBcbik6IFByb21pc2U8SW1hZ2VUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZ2V0SW1hZ2VzQnlVc2VyJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZX0gPSBjb250ZXh0O1xuICBjb25zdCBmb3JtYXRVc2VySWQ6IHN0cmluZyA9IHBhcnNlSWQodXNlcklkKTtcbiAgY29uc3QgbGltaXQ6IEFyYW5nb0RiTGltaXQgPSBnZXRMaW1pdChmcm9tLCB0byk7XG4gIGNvbnN0IGFxbFFyeTogc3RyaW5nID0gYEZPUiBpIElOIGltYWdlc1xuICAgICAgRklMVEVSIGkudXNlcklkID09IFwiJHtmb3JtYXRVc2VySWR9XCJcbiAgICAgIExFVCB1c2VyID0gRklSU1QoXG4gICAgICAgIEZPUiB1IElOIHVzZXJzXG4gICAgICAgIEZJTFRFUiB1Ll9rZXkgPT0gaS51c2VySWRcbiAgICAgICAgTElNSVQgMVxuICAgICAgICBSRVRVUk4gdVxuICAgICAgKVxuICAgICAgJHtsaW1pdC5hcWx9XG4gICAgICBTT1JUIGkuYWRkZWRcbiAgICAgIFJFVFVSTiBNRVJHRShpLCB7dXNlcjp1c2VyfSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFFyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkgYXMgdW5rbm93biBhcyBJbWFnZVR5cGVbXSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBwYXJhbXM6IHtmcm9tLCB0bywgdXNlcklkfSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEltYWdlQ291bnRCeUl0ZW0gPSAoY29udGV4dDogQXBpQ29udGV4dCwgaXRlbUlkOiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcj4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdnZXRJbWFnZUNvdW50QnlJdGVtJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZX0gPSBjb250ZXh0O1xuICBjb25zdCBmb3JtYXRJdGVtSWQ6IHN0cmluZyA9IHBhcnNlQXJhbmdvSWQoaXRlbUlkKTtcbiAgY29uc3QgYXFsUXJ5OiBBcWxRdWVyeSA9IGFxbGBGT1IgaSBJTiBoYXNJbWFnZVxuICAgICAgRklMVEVSIGkuX3RvID09ICR7Zm9ybWF0SXRlbUlkfVxuICAgICAgUkVUVVJOIHtjb3VudDogQ09VTlQoaSl9YDtcblxuICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAudGhlbigoe2NvdW50fSkgPT4gY291bnQpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7aXRlbUlkfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRJbWFnZXNCeUl0ZW0gPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIGl0ZW1JZDogc3RyaW5nLFxuICBvcHRpb25zOiBJbWFnZU9wdGlvbnMgPSB7fVxuKTogUHJvbWlzZTxJbWFnZVR5cGVbXT4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdnZXRJbWFnZXNCeUl0ZW0nO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMgPSBbXX0gPSBjb250ZXh0O1xuICBjb25zdCBmb3JtYXRJdGVtSWQ6IHN0cmluZyA9IHBhcnNlQXJhbmdvSWQoaXRlbUlkKTtcbiAgY29uc3Qge2xpbWl0fSA9IHBhcnNlSW1hZ2VPcHRpb25zKG9wdGlvbnMpO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRJbWFnZU9wdGlvbmFsKGZpZWxkcyk7XG4gIGNvbnN0IGFxbFFyeTogc3RyaW5nID0gYEZPUiBpLCBsIElOIDEuLjEgT1VUQk9VTkQgXCIke2Zvcm1hdEl0ZW1JZH1cIiBoYXNJbWFnZVxuICAgIEZJTFRFUiBOT1QgSVNfTlVMTChpKVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICBTT1JUIGkuYWRkZWRcbiAgICAke2xpbWl0LmFxbH1cbiAgICBSRVRVUk4gTUVSR0UoaSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcblxuICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpIGFzIHVua25vd24gYXMgSW1hZ2VUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgcGFyYW1zOiB7aXRlbUlkLCBvcHRpb25zfSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRJbWFnZXNCeUdyb3VwID0gKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICBwYXJhbXM6IHtmaWx0ZXJzOiBRdWVyeUZpbHRlcltdLCBncm91cElkOiBzdHJpbmcsIGZyb206IG51bWJlciwgdG86IG51bWJlcn1cbik6IFByb21pc2U8SW1hZ2VUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZ2V0SW1hZ2VzQnlHcm91cCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH19ID0gY29udGV4dDtcbiAgY29uc3Qge2ZpbHRlcnMsIGdyb3VwSWQsIGZyb20sIHRvfSA9IHBhcmFtcztcbiAgY29uc3QgZm9ybWF0R3JvdXBJZDogc3RyaW5nID0gcGFyc2VJZChncm91cElkKTtcbiAgY29uc3QgbGltaXQ6IEFyYW5nb0RiTGltaXQgPSBnZXRMaW1pdChmcm9tLCB0byk7XG5cbiAgZmlsdGVyc1xuICAgIC5tYXAoKGZpbHRlcjogUXVlcnlGaWx0ZXIpID0+IHtcbiAgICAgIGNvbnN0IHtjb25kaXRpb25hbCwgbmFtZSwgdmFsdWV9ID0gZmlsdGVyO1xuICAgICAgbGV0IGZvcm1hdENvbmQ6IHN0cmluZyA9IGNvbmRpdGlvbmFsO1xuXG4gICAgICBpZihjb25kaXRpb25hbCAhPT0gJz49JyAmJiBjb25kaXRpb25hbCAhPT0gJzw9JyAmJiBjb25kaXRpb25hbCAhPT0gJz4nICYmIGNvbmRpdGlvbmFsICE9PSAnPCcpIHtcbiAgICAgICAgZm9ybWF0Q29uZCA9ICc9PSc7XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaChuYW1lKSB7XG4gICAgICAgIGNhc2UgJ2FkZGVkJzpcbiAgICAgICAgICByZXR1cm4gYHAuYWRkZWQgJHtmb3JtYXRDb25kfSAke3BhcnNlTnVtKHZhbHVlKX1gO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cbiAgICB9KTtcblxuICByZXR1cm4gZ2V0R3JvdXBEZXRhaWxzKGNvbnRleHQsIGZvcm1hdEdyb3VwSWQpXG4gICAgLnRoZW4oKGdyb3VwOiBHcm91cFR5cGUpID0+IHtcbiAgICAgIGlmKGdyb3VwLnByaXZhY3kgPT09ICdwdWJsaWMnKSB7XG4gICAgICAgIGZpbHRlcnMucHVzaCh7Y29uZGl0aW9uYWw6ICc9PScsIG5hbWU6ICdncm91cElkJywgdmFsdWU6IGZvcm1hdEdyb3VwSWR9KTtcbiAgICAgICAgY29uc3QgZmlsdGVyU3RyID0gZmlsdGVycy5qb2luKCcgJiYgJyk7XG4gICAgICAgIGNvbnN0IGFxbFFyeTogc3RyaW5nID0gYEZPUiBpIElOXG4gICAgICAgICAgRkxBVFRFTihcbiAgICAgICAgICAgIEZPUiBwIElOIHBvc3RzXG4gICAgICAgICAgICBGSUxURVIgJHtmaWx0ZXJTdHJ9XG4gICAgICAgICAgICBMRVQgaW1hZ2VzID0gKFxuICAgICAgICAgICAgICBGT1IgaSwgZSBJTiBJTkJPVU5EIHAuX2lkIGhhc0ltYWdlXG4gICAgICAgICAgICAgIFJFVFVSTiBpXG4gICAgICAgICAgICApXG4gICAgICAgICAgICBTT1JUIHAuYWRkZWQgREVTQ1xuICAgICAgICAgICAgUkVUVVJOIGltYWdlc1xuICAgICAgICAgIClcbiAgICAgICAgICBTT1JUIGkuYWRkZWQgREVTQ1xuICAgICAgICAgICR7bGltaXQuYXFsfVxuICAgICAgICAgIFJFVFVSTiBpYDtcblxuICAgICAgICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRcnkpXG4gICAgICAgICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpIGFzIHVua25vd24gYXMgSW1hZ2VUeXBlW10pXG4gICAgICAgICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgICAgICAgcGFyYW1zOiB7ZmlsdGVycywgZnJvbSwgZ3JvdXBJZCwgdG99LFxuICAgICAgICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzR3JvdXBlZChjb250ZXh0LCBzZXNzaW9uSWQsIGdyb3VwSWQpXG4gICAgICAgIC50aGVuKChncm91cGVkOiBHcm91cFVzZXIpID0+IHtcbiAgICAgICAgICBpZihncm91cGVkLmlzVmFsaWQpIHtcbiAgICAgICAgICAgIGZpbHRlcnMucHVzaCh7Y29uZGl0aW9uYWw6ICc9PScsIG5hbWU6ICdncm91cElkJywgdmFsdWU6IGdyb3VwZWQuZ3JvdXBJZH0pO1xuICAgICAgICAgICAgY29uc3QgZmlsdGVyTGlzdDogc3RyaW5nID0gZmlsdGVycy5qb2luKCcgJiYgJyk7XG4gICAgICAgICAgICBjb25zdCBhcWxRcnk6IHN0cmluZyA9IGBGT1IgcCBJTiBwb3N0XG4gICAgICAgICAgICAgICAgRklMVEVSICR7ZmlsdGVyTGlzdH1cbiAgICAgICAgICAgICAgICBGT1IgZiBJTiBwLmZpbGVzXG4gICAgICAgICAgICAgICAgRklMVEVSIGYudHlwZSA9PSBcImltYWdlL2pwZWdcIiB8fCBmLnR5cGUgPT0gXCJpbWFnZS9wbmdcIlxuICAgICAgICAgICAgICAgICR7bGltaXQuYXFsfVxuICAgICAgICAgICAgICAgIFNPUlQgcC5hZGRlZCBERVNDXG4gICAgICAgICAgICAgICAgUkVUVVJOIGZgO1xuXG4gICAgICAgICAgICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRcnkpXG4gICAgICAgICAgICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIEltYWdlVHlwZVtdKVxuICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICAgICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICAgICAgICAgICAgcGFyYW1zOiB7ZmlsdGVycywgZnJvbSwgZ3JvdXBJZCwgdG99LFxuICAgICAgICAgICAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgICAgICAgICAgICB9LCBlcnJvciwgY29udGV4dCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRJbWFnZXNCeVJlYWN0aW9ucyA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgcmVhY3Rpb25zOiBzdHJpbmdbXSA9IFtdLFxuICBvcHRpb25zPzogSW1hZ2VPcHRpb25zXG4pOiBQcm9taXNlPEltYWdlVHlwZVtdPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2dldFVzZXJzQnlJbWFnZSc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIGZpZWxkcyA9IFtdLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtsaW1pdH0gPSBwYXJzZUltYWdlT3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0SW1hZ2VPcHRpb25hbChmaWVsZHMpO1xuICBjb25zdCBmb3JtYXRTZXNzaW9uSWQ6IHN0cmluZyA9IGB1c2Vycy8ke3Nlc3Npb25JZH1gO1xuICBjb25zdCBmb3JtYXRSZWFjdGlvbnM6IHN0cmluZ1tdID0gcmVhY3Rpb25zLm1hcCgocmVhY3Rpb25OYW1lKSA9PiBwYXJzZUNoYXIocmVhY3Rpb25OYW1lLCAzMikpO1xuICBjb25zdCBmaWx0ZXJCeTogc3RyaW5nW10gPSBbXG4gICAgJ3IudHlwZSA9PSBcImltYWdlc1wiJyxcbiAgICBgUE9TSVRJT04oJHtKU09OLnN0cmluZ2lmeShmb3JtYXRSZWFjdGlvbnMpfSwgTE9XRVIoci5uYW1lKSlgXTtcblxuICAvLyBHZXQgZGF0YSBmcm9tIGRhdGFiYXNlXG4gIGNvbnN0IGFxbFFyeTogc3RyaW5nID0gYEZPUiBpLCByIElOIE9VVEJPVU5EIFwiJHtmb3JtYXRTZXNzaW9uSWR9XCIgaGFzUmVhY3Rpb25cbiAgICBPUFRJT05TIHt2ZXJ0ZXhDb2xsZWN0aW9uczogXCJpbWFnZXNcIn1cbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgRklMVEVSICR7ZmlsdGVyQnkuam9pbignICYmICcpfVxuICAgICR7bGltaXQuYXFsfVxuICAgIFJFVFVSTiBNRVJHRShpLCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFFyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkgYXMgdW5rbm93biBhcyBJbWFnZVR5cGVbXSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBwYXJhbXM6IHtvcHRpb25zLCByZWFjdGlvbnN9LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEltYWdlID0gKGNvbnRleHQ6IEFwaUNvbnRleHQsIGltYWdlSWQ6IHN0cmluZyk6IFByb21pc2U8SW1hZ2VUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2dldEl0ZW0nO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lfSA9IGNvbnRleHQ7XG4gIGNvbnN0IGZvcm1hdEltYWdlSWQ6IHN0cmluZyA9IHBhcnNlSWQoaW1hZ2VJZCk7XG4gIGNvbnN0IGFxbFFyeTogQXFsUXVlcnkgPSBhcWxgRk9SIGkgSU4gaW1hZ2VzXG4gICAgRklMVEVSIGkuX2tleT09JHtmb3JtYXRJbWFnZUlkfVxuICAgIExJTUlUIDFcbiAgICBSRVRVUk4gaWA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7aW1hZ2VJZH0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0UGF0aFVzZXJJbWFnZXMgPSAodXNlcklkOiBzdHJpbmcsIGltYWdlSWQ6IHN0cmluZywgaW1hZ2VUeXBlOiBzdHJpbmcsIGRpcjogc3RyaW5nID0gJ2ltYWdlcycpOiBzdHJpbmcgPT4ge1xuICBsZXQgZmlsZW5hbWU6IHN0cmluZyA9IGltYWdlSWQ7XG5cbiAgc3dpdGNoKGltYWdlVHlwZSkge1xuICAgIGNhc2UgJ2ltYWdlL3BuZyc6XG4gICAgICBmaWxlbmFtZSA9IGAke2ltYWdlSWR9LnBuZ2A7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgZmlsZW5hbWUgPSBgJHtpbWFnZUlkfS5qcGdgO1xuICAgICAgYnJlYWs7XG4gIH1cblxuICByZXR1cm4gYHVzZXJzLyR7dXNlcklkfS8ke2Rpcn0vJHtmaWxlbmFtZX1gO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEFwcEltYWdlVXJsID0gKHtcbiAgYnVja2V0LFxuICBkaXJlY3RvcnkgPSAnaW1hZ2VzJyxcbiAgaW1hZ2VJZCxcbiAgaW1hZ2VUeXBlID0gJ2pwZycsXG4gIGlzVGh1bWIgPSBmYWxzZSxcbiAgdHlwZSxcbiAgdHlwZUlkXG59OiBJbWFnZVVybERhdGEpOiBzdHJpbmcgPT4ge1xuICBpZighdHlwZSkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGlmKCFpbWFnZUlkKSB7XG4gICAgaWYoaW1hZ2VUeXBlID09PSAncHJvZmlsZScpIHtcbiAgICAgIHJldHVybiBgJHtDb25maWcuZ2V0KCdpbWFnZS5kZWZhdWx0VXJsJyl9L3VzZXJzX2JrLmpwZ2A7XG4gICAgfVxuICAgIHJldHVybiBgJHtDb25maWcuZ2V0KCdpbWFnZS5kZWZhdWx0VXJsJyl9L3VzZXJzX3doLmpwZ2A7XG4gIH1cblxuICBjb25zdCBidWNrZXROYW1lID0gYnVja2V0IHx8IENvbmZpZy5nZXQoJ2ltYWdlLmJ1Y2tldCcpIHx8ICdkZXYucmVha3Rvci5pbyc7XG4gIGNvbnN0IGltYWdlTmFtZSA9IGlzVGh1bWIgPyBgJHtpbWFnZUlkfS10aC4ke2ltYWdlVHlwZX1gIDogYCR7aW1hZ2VJZH0uJHtpbWFnZVR5cGUgPT09ICdwcm9maWxlJyB8fCBpbWFnZVR5cGUgPT09ICdvdGhlcicgPyAnanBnJyA6IGltYWdlVHlwZX1gO1xuICBjb25zdCBpbWFnZVVybCA9IENvbmZpZy5nZXQoJ2ltYWdlLnVybCcpIHx8IGBodHRwczovL3MzLmFtYXpvbmF3cy5jb20vJHtidWNrZXROYW1lfWA7XG5cbiAgaWYodHlwZSA9PT0gJ2FwcHMnKSB7XG4gICAgcmV0dXJuIGAke2ltYWdlVXJsfS8ke3R5cGV9LyR7ZGlyZWN0b3J5fS8ke2ltYWdlTmFtZX1gO1xuICB9XG5cbiAgcmV0dXJuIGAke2ltYWdlVXJsfS8ke3R5cGV9LyR7dHlwZUlkfS8ke2RpcmVjdG9yeX0vJHtpbWFnZU5hbWV9YDtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRJbWFnZVVybCA9IGFzeW5jICh7XG4gIGJ1Y2tldCxcbiAgaW1hZ2VEaXIgPSAnaW1hZ2VzJyxcbiAgaW1hZ2VJZCxcbiAgaW1hZ2VUeXBlID0gJ2pwZycsXG4gIGlzVGh1bWIgPSBmYWxzZSxcbiAgdHlwZSxcbiAgdHlwZUlkLFxuICB1cmxUeXBlID0gJ3B1YmxpYydcbn06IEltYWdlVXJsRGF0YSk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gIGlmKCFpbWFnZUlkKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgLy8gQWx3YXlzIHVzZSBzaWduZWQgVVJMcyBmb3IgdGh1bWJuYWlsc1xuICBpZihpc1RodW1iKSB7XG4gICAgdXJsVHlwZSA9ICdzaWduZWQnO1xuICB9XG5cbiAgY29uc3QgdGh1bWJTdWZmaXggPSBpc1RodW1iID8gJy10aCcgOiAnJztcbiAgY29uc3QgaW1hZ2VLZXk6IHN0cmluZyA9IGAke3R5cGV9LyR7dHlwZUlkfS8ke2ltYWdlRGlyfS8ke2ltYWdlSWR9JHt0aHVtYlN1ZmZpeH0uJHtpbWFnZVR5cGV9YDtcblxuICBzd2l0Y2godXJsVHlwZSkge1xuICAgIGNhc2UgJ3NpZ25lZCc6IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRCdWNrZXQgPSBDb25maWcuZ2V0KCdpbWFnZS5idWNrZXQnKSB8fCAnZGV2LnJlYWt0b3IuaW8nO1xuICAgICAgICByZXR1cm4gYXdhaXQgczNHZXRTaWduZWRVcmwoe0J1Y2tldDogYnVja2V0IHx8IGRlZmF1bHRCdWNrZXQsIEV4cGlyZXM6IDkwMCwgS2V5OiBpbWFnZUtleX0pO1xuICAgICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9XG4gICAgY2FzZSAncHVibGljJzoge1xuICAgICAgcmV0dXJuIGBodHRwczovL2JveC4ke0NvbmZpZy5nZXQoJ2FwcC51cmwnKX0vJHtpbWFnZUtleX1gO1xuICAgIH1cbiAgICBjYXNlICdkZXYnOiB7XG4gICAgICByZXR1cm4gYGh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9kZXYuJHtDb25maWcuZ2V0KCdhcHAudXJsJyl9LyR7aW1hZ2VLZXl9YDtcbiAgICB9XG4gICAgZGVmYXVsdDoge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHJlc2l6ZVNhdmVJbWFnZSA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgaW1hZ2VJZDogc3RyaW5nLFxuICBidWZmZXI6IEJ1ZmZlcixcbiAgZmlsZVR5cGU6IHN0cmluZyA9ICdpbWFnZS9qcGVnJywgczNPcHRpb25zPzogUHV0T2JqZWN0Q29tbWFuZElucHV0XG4pOiBQcm9taXNlPEltYWdlVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdyZXNpemVTYXZlSW1hZ2UnO1xuICBjb25zdCB7c2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfX0gPSBjb250ZXh0O1xuICBjb25zdCBpbWdXOiBudW1iZXIgPSBDb25maWcuZ2V0KCdpbWFnZS5pbWdTaXplJyk7XG4gIGNvbnN0IGltZ1E6IG51bWJlciA9IENvbmZpZy5nZXQoJ2ltYWdlLmltZ1F1YWxpdHknKTtcbiAgY29uc3QgZm9ybWF0OiBzdHJpbmcgPSAoZmlsZVR5cGUuc3BsaXQoJy8nKSlbMV07XG5cbiAgY29uc3QgaW1hZ2VPcHRpbWl6ZWRCdWZmZXI6IEJ1ZmZlciA9IGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBnbShidWZmZXIsICdpbWcnKVxuICAgICAgLnNldEZvcm1hdChmb3JtYXQpXG4gICAgICAucXVhbGl0eShpbWdRKVxuICAgICAgLmF1dG9PcmllbnQoKVxuICAgICAgLnJlc2l6ZShpbWdXLCBpbWdXLCAnPicpXG4gICAgICAuc3RyZWFtKChzdHJlYW1FcnJvcjogRXJyb3IsIHN0ZG91dCk6IHZvaWQgPT4ge1xuICAgICAgICBpZihzdHJlYW1FcnJvcikge1xuICAgICAgICAgIHJlamVjdChcbiAgICAgICAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgICAgICAgcGFyYW1zOiB7ZmlsZVR5cGUsIGltYWdlSWR9LFxuICAgICAgICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTUFHRV9TQVZFXG4gICAgICAgICAgICB9LCBzdHJlYW1FcnJvciwgY29udGV4dClcbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBpbWFnZUJ1ZmZlcjogQnVmZmVyID0gQnVmZmVyLmZyb20oJycpO1xuXG4gICAgICAgIHN0ZG91dC5vbignZGF0YScsIChkYXRhKSA9PiB7XG4gICAgICAgICAgaW1hZ2VCdWZmZXIgPSBCdWZmZXIuY29uY2F0KFtpbWFnZUJ1ZmZlciwgZGF0YV0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBzdGRvdXQub24oJ2VuZCcsICgpID0+IHJlc29sdmUoaW1hZ2VCdWZmZXIpKTtcbiAgICAgIH0pO1xuICB9KTtcblxuICB0cnkge1xuICAgIGNvbnN0IGltYWdlT2JqOiBQdXRPYmplY3RDb21tYW5kSW5wdXQgPSB7XG4gICAgICBBQ0w6ICdhdXRoZW50aWNhdGVkLXJlYWQnLFxuICAgICAgQm9keTogaW1hZ2VPcHRpbWl6ZWRCdWZmZXIsXG4gICAgICBCdWNrZXQ6IG51bGwsXG4gICAgICBDb250ZW50VHlwZTogZmlsZVR5cGUsXG4gICAgICAuLi4oczNPcHRpb25zIHx8IHt9KSxcbiAgICAgIEtleTogZ2V0UGF0aFVzZXJJbWFnZXMoc2Vzc2lvbklkLCBpbWFnZUlkLCBmaWxlVHlwZSwgJ2ltYWdlcycpXG4gICAgfTtcbiAgICBhd2FpdCBzM1B1dChpbWFnZU9iaik7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICByZXR1cm4gbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHtmaWxlVHlwZSwgaW1hZ2VJZH0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTUFHRV9TQVZFXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICB9XG5cbiAgY29uc3QgaW1hZ2VJZGVudGl0eSA9IGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgZ20oaW1hZ2VPcHRpbWl6ZWRCdWZmZXIsICdpbWcnKVxuICAgICAgLmlkZW50aWZ5KHtidWZmZXJTdHJlYW06IHRydWV9LCAoZXJyb3I6IEVycm9yLCBpbWFnZURhdGE6IEltYWdlSWRlbnRpZnlUeXBlID0ge30pID0+IHtcbiAgICAgICAgaWYoZXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gbG9nRXJyb3Ioe1xuICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTUFHRV9TQVZFXG4gICAgICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZm9ybWF0VmFsdWVzID0gbG93ZXJDYXNlS2V5cyhpbWFnZURhdGEpO1xuICAgICAgICBjb25zdCB7bWFrZTogY2FtZXJhTWFrZSwgbW9kZWw6IGNhbWVyYU1vZGVsLCBkYXRldGltZW9yaWdpbmFsOiB0YWtlbn06IEltYWdlSWRlbnRpZnlUeXBlID0gZm9ybWF0VmFsdWVzO1xuICAgICAgICBjb25zdCBzdGF0cyA9IGZvcm1hdFZhbHVlc1snY2hhbm5lbCBzdGF0aXN0aWNzJ107XG4gICAgICAgIGxldCBjb2xvcjogc3RyaW5nO1xuXG4gICAgICAgIGlmKHN0YXRzKSB7XG4gICAgICAgICAgbGV0IHtyZWQsIGdyZWVuLCBibHVlLCBtZWFufSA9IHN0YXRzO1xuXG4gICAgICAgICAgaWYocmVkKSB7XG4gICAgICAgICAgICBtZWFuID0gcmVkWydzdGFuZGFyZCBkZXZpYXRpb24nXSB8fCByZWQubWVhbjtcbiAgICAgICAgICAgIHJlZCA9IG1lYW4gPyArKChtZWFuLnNwbGl0KCcgJylbMF0pLnN1YnN0cmluZygwLCAzKSkgOiAwO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZWQgPSAwO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmKGdyZWVuKSB7XG4gICAgICAgICAgICBtZWFuID0gZ3JlZW5bJ3N0YW5kYXJkIGRldmlhdGlvbiddIHx8IGdyZWVuLm1lYW47XG4gICAgICAgICAgICBncmVlbiA9IG1lYW4gPyArKChtZWFuLnNwbGl0KCcgJylbMF0pLnN1YnN0cmluZygwLCAzKSkgOiAwO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBncmVlbiA9IDA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYoYmx1ZSkge1xuICAgICAgICAgICAgbWVhbiA9IGJsdWVbJ3N0YW5kYXJkIGRldmlhdGlvbiddIHx8IGJsdWUubWVhbjtcbiAgICAgICAgICAgIGJsdWUgPSBtZWFuID8gKygobWVhbi5zcGxpdCgnICcpWzBdKS5zdWJzdHJpbmcoMCwgMykpIDogMDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYmx1ZSA9IDA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcmdiID0gYmx1ZSB8IChncmVlbiA8PCA4KSB8IChyZWQgPDwgMTYpO1xuICAgICAgICAgIGNvbnN0IHJnYkNvbG9yID0gcmdiLnRvU3RyaW5nKDE2KTtcbiAgICAgICAgICBjb2xvciA9IHJnYkNvbG9yID09PSAnMCcgPyAnMDAwMDAwJyA6IHJnYkNvbG9yO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgICdKUEVHLVF1YWxpdHknOiBxdWFsaXR5LFxuICAgICAgICAgIE9yaWVudGF0aW9uOiBvcmllbnRhdGlvbkRhdGEsXG4gICAgICAgICAgUmVzb2x1dGlvbjogcmVzb2x1dGlvbkRhdGEsXG4gICAgICAgICAgc2l6ZVxuICAgICAgICB9ID0gaW1hZ2VEYXRhO1xuICAgICAgICBsZXQgcmVzb2x1dGlvbjtcblxuICAgICAgICBpZihyZXNvbHV0aW9uRGF0YSkge1xuICAgICAgICAgIGNvbnN0IFtyZXNvbHV0aW9uTnVtYmVyLCByZXNvbHV0aW9uVW5pdF0gPSByZXNvbHV0aW9uRGF0YS5zcGxpdCgnICcpO1xuICAgICAgICAgIGNvbnN0IHJlc29sdXRpb25WYWx1ZSA9IHJlc29sdXRpb25OdW1iZXIuc3BsaXQoJ3gnKVswXTtcbiAgICAgICAgICBjb25zdCByZXNvbHV0aW9uVW5pdFZhbHVlID0gcmVzb2x1dGlvblVuaXQgPT09ICdwaXhlbHMvaW5jaCcgPyAncHBpJyA6ICcnO1xuICAgICAgICAgIHJlc29sdXRpb24gPSBgJHtyZXNvbHV0aW9uVmFsdWV9ICR7cmVzb2x1dGlvblVuaXRWYWx1ZX1gO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc29sdmUoe1xuICAgICAgICAgIGNvbG9yLFxuICAgICAgICAgIGZpbGVTaXplOiBpbWFnZU9wdGltaXplZEJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICAgZmlsZVR5cGU6IGZvcm1hdCxcbiAgICAgICAgICBoZWlnaHQ6IHNpemU/LmhlaWdodCB8fCAwLFxuICAgICAgICAgIGltYWdlSWQsXG4gICAgICAgICAgbWFrZTogY2FtZXJhTWFrZSxcbiAgICAgICAgICBtb2RlbDogY2FtZXJhTW9kZWwsXG4gICAgICAgICAgb3JpZW50YXRpb246IG9yaWVudGF0aW9uRGF0YSA9PT0gJ1Vua25vd24nID8gdW5kZWZpbmVkIDogb3JpZW50YXRpb25EYXRhPy50b0xvd2VyQ2FzZSgpLFxuICAgICAgICAgIHF1YWxpdHk6IHF1YWxpdHkgPyArcXVhbGl0eSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICByZXNvbHV0aW9uLFxuICAgICAgICAgIHRha2VuOiB0YWtlbiA/IERhdGVUaW1lLmZyb21NaWxsaXModGFrZW4pLm1pbGxpc2Vjb25kIDogdW5kZWZpbmVkLFxuICAgICAgICAgIHdpZHRoOiBzaXplPy53aWR0aCB8fCAwXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH0pO1xuXG4gIGNvbnN0IHRodW1iT3B0aW1pemVkQnVmZmVyOiBCdWZmZXIgPSBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgdGhtVyA9IENvbmZpZy5nZXQoJ2ltYWdlLnRobVNpemUnKTtcbiAgICBjb25zdCB0aG1RID0gQ29uZmlnLmdldCgnaW1hZ2UudGhtUXVhbGl0eScpO1xuXG4gICAgZ20oaW1hZ2VPcHRpbWl6ZWRCdWZmZXIsICdpbWcnKVxuICAgICAgLnNldEZvcm1hdChmb3JtYXQpXG4gICAgICAuZ3Jhdml0eSgnQ2VudGVyJylcbiAgICAgIC5yZXNpemUodGhtVywgdGhtVywgJ14nKVxuICAgICAgLmV4dGVudCh0aG1XLCB0aG1XKVxuICAgICAgLnF1YWxpdHkodGhtUSlcbiAgICAgIC5zdHJlYW0oKHN0cmVhbUVycm9yOiBFcnJvciwgdGh1bWJTdGRvdXQpOiB2b2lkID0+IHtcbiAgICAgICAgaWYoc3RyZWFtRXJyb3IpIHtcbiAgICAgICAgICBsb2dFcnJvcih7XG4gICAgICAgICAgICBhY3Rpb24sXG4gICAgICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgICAgIHBhcmFtczoge2ZpbGVUeXBlLCBpbWFnZUlkfSxcbiAgICAgICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLklNQUdFX1NBVkVcbiAgICAgICAgICB9LCBzdHJlYW1FcnJvciwgY29udGV4dCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHRodW1iQnVmZmVyOiBCdWZmZXIgPSBCdWZmZXIuZnJvbSgnJyk7XG5cbiAgICAgICAgdGh1bWJTdGRvdXQub24oJ2RhdGEnLCAoZGF0YSkgPT4ge1xuICAgICAgICAgIHRodW1iQnVmZmVyID0gQnVmZmVyLmNvbmNhdChbdGh1bWJCdWZmZXIsIGRhdGFdKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGh1bWJTdGRvdXQub24oJ2VuZCcsICgpID0+IHJlc29sdmUodGh1bWJCdWZmZXIpKTtcbiAgICAgIH0pO1xuICB9KTtcblxuICB0cnkge1xuICAgIGNvbnN0IHRodW1iT2JqOiBQdXRPYmplY3RDb21tYW5kSW5wdXQgPSB7XG4gICAgICBBQ0w6ICdhdXRoZW50aWNhdGVkLXJlYWQnLFxuICAgICAgQm9keTogdGh1bWJPcHRpbWl6ZWRCdWZmZXIsXG4gICAgICBCdWNrZXQ6IG51bGwsXG4gICAgICBDb250ZW50VHlwZTogZmlsZVR5cGUsXG4gICAgICAuLi4oczNPcHRpb25zIHx8IHt9KSxcbiAgICAgIEtleTogZ2V0UGF0aFVzZXJJbWFnZXMoc2Vzc2lvbklkLCBpbWFnZUlkLCBmaWxlVHlwZSwgJ3RodW1icycpXG4gICAgfTtcbiAgICBhd2FpdCBzM1B1dCh0aHVtYk9iaik7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICByZXR1cm4gbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTUFHRV9TQVZFXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICB9XG5cbiAgcmV0dXJuIGltYWdlSWRlbnRpdHk7XG59O1xuXG5leHBvcnQgY29uc3QgYWRkSW1hZ2UgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIGltYWdlOiBJbWFnZVR5cGUsXG4gIHMzT3B0aW9ucz86IFB1dE9iamVjdENvbW1hbmRJbnB1dFxuKTogUHJvbWlzZTxJbWFnZVR5cGU+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnYWRkSW1hZ2UnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtpbWFnZUlkLCBkZXNjcmlwdGlvbiwgYnVmZmVyLCBmaWxlVHlwZX0gPSBpbWFnZTtcbiAgY29uc3Qgbm93OiBudW1iZXIgPSBEYXRlLm5vdygpO1xuXG4gIHJldHVybiByZXNpemVTYXZlSW1hZ2UoY29udGV4dCwgaW1hZ2VJZCwgYnVmZmVyLCBmaWxlVHlwZSwgczNPcHRpb25zKVxuICAgIC50aGVuKChyZXNpemVkSW1hZ2U6IEltYWdlVHlwZSkgPT4ge1xuICAgICAgY29uc3QgaW5zZXJ0OiBJbWFnZVR5cGUgPSB7XG4gICAgICAgIC4uLnJlc2l6ZWRJbWFnZSxcbiAgICAgICAgX2tleTogaW1hZ2VJZCxcbiAgICAgICAgYWRkZWQ6IG5vdyxcbiAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgIGZpbGVUeXBlLFxuICAgICAgICBtb2RpZmllZDogbm93LFxuICAgICAgICB1c2VySWQ6IHNlc3Npb25JZFxuICAgICAgfTtcblxuICAgICAgY29uc3QgYXFsUXJ5OiBBcWxRdWVyeSA9IGFxbGBJTlNFUlQgJHtpbnNlcnR9IElOIGltYWdlcyBSRVRVUk4gTkVXYDtcblxuICAgICAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXJ5KVxuICAgICAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgICAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4gbG9nRXJyb3Ioe1xuICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgICBwYXJhbXM6IHtpbWFnZSwgczNPcHRpb25zfSxcbiAgICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgICB9LCBlcnJvciwgY29udGV4dCkpO1xuICAgIH0pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU1BR0VfUkVTSVpFXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBhZGRJbWFnZUVkZ2UgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwgaW1hZ2VFZGdlOiBJbWFnZUVkZ2VUeXBlKTogUHJvbWlzZTxvYmplY3Q+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnYWRkSW1hZ2VFZGdlJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfX0gPSBjb250ZXh0O1xuICBjb25zdCB7aW1hZ2VJZCwgaXRlbUlkLCBpdGVtVHlwZX0gPSBpbWFnZUVkZ2U7XG4gIGNvbnN0IG5vdzogbnVtYmVyID0gRGF0ZS5ub3coKTtcbiAgLy8gY29uc3QgZWRnZUNvbGxlY3Rpb246IEVkZ2VDb2xsZWN0aW9uID0gdXNlRGIoZGF0YWJhc2VOYW1lKS5jb2xsZWN0aW9uKCdoYXNJbWFnZScpO1xuICBjb25zdCBlZGdlSWQ6IHN0cmluZyA9IGNyZWF0ZUhhc2goYGhhc0ltYWdlLSR7aW1hZ2VJZH0tJHtpdGVtSWR9LSR7c2Vzc2lvbklkfWApO1xuICBjb25zdCBmb3JtYXRJdGVtVHlwZTogQXJhbmdvRGJDb2xsZWN0aW9uID0gcGFyc2VDaGFyKGl0ZW1UeXBlKS50b0xvd2VyQ2FzZSgpIGFzIEFyYW5nb0RiQ29sbGVjdGlvbjtcbiAgY29uc3QgZm9ybWF0SXRlbUlkOiBzdHJpbmcgPSBwYXJzZUlkKGl0ZW1JZCk7XG4gIGNvbnN0IGl0ZW1Eb2NJZDogc3RyaW5nID0gZ2V0RG9jSWQoZm9ybWF0SXRlbVR5cGUsIHtfa2V5OiBmb3JtYXRJdGVtSWR9KTtcbiAgY29uc3QgZm9ybWF0SW1hZ2VJZDogc3RyaW5nID0gcGFyc2VJZChpbWFnZUlkKTtcbiAgY29uc3QgZmlsZURvY0lkOiBzdHJpbmcgPSBgaW1hZ2VzLyR7Zm9ybWF0SW1hZ2VJZH1gO1xuXG4gIGNvbnN0IGVkZ2U6IEltYWdlRWRnZVR5cGUgPSB7XG4gICAgX2Zyb206IGl0ZW1Eb2NJZCxcbiAgICBfa2V5OiBlZGdlSWQsXG4gICAgX3RvOiBmaWxlRG9jSWQsXG4gICAgYWRkZWQ6IG5vdyxcbiAgICBpdGVtVHlwZVxuICB9O1xuXG4gIGlmKGl0ZW1Eb2NJZCkge1xuICAgIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLmNvbGxlY3Rpb24oJ2hhc0ltYWdlJykuc2F2ZShlZGdlLCB7cmV0dXJuTmV3OiB0cnVlfSlcbiAgICAgIC50aGVuKChmaWxlRWRnZSkgPT4gdXNlRGIoZGF0YWJhc2VOYW1lKS5jb2xsZWN0aW9uKCdoYXNJbWFnZScpLmRvY3VtZW50KGZpbGVFZGdlKSlcbiAgICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIHBhcmFtczoge1xuICAgICAgICAgIGVkZ2UsXG4gICAgICAgICAgZmlsZURvY0lkLFxuICAgICAgICAgIGltYWdlSWQsXG4gICAgICAgICAgaXRlbURvY0lkLFxuICAgICAgICAgIGl0ZW1JZCxcbiAgICAgICAgICBpdGVtVHlwZVxuICAgICAgICB9LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpKTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufTtcblxuZXhwb3J0IGNvbnN0IHVwZGF0ZUltYWdlID0gYXN5bmMgKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICBpbWFnZTogSW1hZ2VUeXBlLFxuICBzM09wdGlvbnM/OiBQdXRPYmplY3RDb21tYW5kSW5wdXRcbik6IFByb21pc2U8SW1hZ2VUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ3VwZGF0ZUltYWdlJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfX0gPSBjb250ZXh0O1xuICBjb25zdCB7XG4gICAgYmFzZTY0ID0gJycsXG4gICAgYnVmZmVyOiBpbWFnZUJ1ZmZlcixcbiAgICBkZXNjcmlwdGlvbiA9ICcnLFxuICAgIGltYWdlSWQsXG4gICAgaXRlbUlkLFxuICAgIGl0ZW1UeXBlLFxuICAgIGZpbGVUeXBlLFxuICAgIHVybCA9ICcnXG4gIH0gPSBpbWFnZTtcblxuICBjb25zdCBub3c6IG51bWJlciA9IERhdGUubm93KCk7XG4gIGNvbnN0IGZvcm1hdEltYWdlSWQ6IHN0cmluZyA9IGltYWdlSWQgfHwgY3JlYXRlSGFzaChgaW1hZ2UtJHtzZXNzaW9uSWR9YCk7XG4gIGNvbnN0IGZvcm1hdEl0ZW1JZDogc3RyaW5nID0gcGFyc2VJZChpdGVtSWQpO1xuICBjb25zdCBmb3JtYXRJdGVtVHlwZTogQXJhbmdvRGJDb2xsZWN0aW9uID0gcGFyc2VDaGFyKGl0ZW1UeXBlLCAxNikudG9Mb3dlckNhc2UoKSBhcyBBcmFuZ29EYkNvbGxlY3Rpb247XG4gIGNvbnN0IGN1c3RvbVBhcmFtczogSW1hZ2VUeXBlID0ge1xuICAgIGRlc2NyaXB0aW9uLFxuICAgIGltYWdlSWQ6IGZvcm1hdEltYWdlSWQsXG4gICAgdXNlcklkOiBzZXNzaW9uSWRcbiAgfTtcblxuICBpZihiYXNlNjQgfHwgaW1hZ2VCdWZmZXIpIHtcbiAgICBsZXQgYnVmZmVyOiBCdWZmZXIgPSBpbWFnZUJ1ZmZlcjtcblxuICAgIGlmKGJhc2U2NCkge1xuICAgICAgY29uc3QgZm9ybWF0QmFzZTY0OiBzdHJpbmcgPSBiYXNlNjQuc3Vic3RyKGJhc2U2NC5pbmRleE9mKCcsJykgKyAxKTtcbiAgICAgIGJ1ZmZlciA9IEJ1ZmZlci5mcm9tKGZvcm1hdEJhc2U2NCwgJ2Jhc2U2NCcpO1xuICAgIH1cblxuICAgIGxldCB1cGRhdGVkRmlsZVR5cGUgPSBmaWxlVHlwZTtcblxuICAgIGlmKCFmaWxlVHlwZSkge1xuICAgICAgY29uc3Qge2ZpbGVUeXBlRnJvbUJ1ZmZlcn0gPSBhd2FpdCBpbXBvcnQoJ2ZpbGUtdHlwZScpO1xuICAgICAgY29uc3Qge21pbWV9ID0gYXdhaXQgZmlsZVR5cGVGcm9tQnVmZmVyKGJ1ZmZlcik7XG4gICAgICB1cGRhdGVkRmlsZVR5cGUgPSBtaW1lO1xuICAgIH1cblxuICAgIGNvbnN0IGltZ1BhcmFtczogSW1hZ2VUeXBlID0ge1xuICAgICAgLi4uY3VzdG9tUGFyYW1zLFxuICAgICAgYnVmZmVyLFxuICAgICAgZmlsZVR5cGU6IHVwZGF0ZWRGaWxlVHlwZVxuICAgIH07XG5cbiAgICByZXR1cm4gYWRkSW1hZ2UoY29udGV4dCwgaW1nUGFyYW1zLCBzM09wdGlvbnMpXG4gICAgICAudGhlbigoaW1hZ2U6IEltYWdlVHlwZSkgPT4ge1xuICAgICAgICBpZihmb3JtYXRJdGVtSWQgJiYgZm9ybWF0SXRlbVR5cGUpIHtcbiAgICAgICAgICBjb25zdCBpbWFnZUVkZ2U6IEltYWdlRWRnZVR5cGUgPSB7XG4gICAgICAgICAgICBpbWFnZUlkOiBmb3JtYXRJbWFnZUlkLFxuICAgICAgICAgICAgaXRlbUlkOiBmb3JtYXRJdGVtSWQsXG4gICAgICAgICAgICBpdGVtVHlwZTogZm9ybWF0SXRlbVR5cGVcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJldHVybiBhZGRJbWFnZUVkZ2UoY29udGV4dCwgaW1hZ2VFZGdlKS50aGVuKCgpID0+IGltYWdlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpbWFnZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLklNQUdFX1NBVkVcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KSk7XG4gIH0gZWxzZSBpZih1cmwgIT09ICcnKSB7XG4gICAgbGV0IGNvbnRlbnRUeXBlO1xuXG4gICAgcmV0dXJuIGh0dHBHZXQodXJsKVxuICAgICAgLnRoZW4oKHJlczogSHR0cFJlc3BvbnNlKSA9PiB7XG4gICAgICAgIGlmKHJlcy5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgICAgIHJldHVybiBsb2dFeGNlcHRpb24oe1xuICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTUFHRV9SRVFVRVNUXG4gICAgICAgICAgfSwgY29udGV4dCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb250ZW50VHlwZSA9IHJlcy5oZWFkZXJzLmdldCgnY29udGVudC10eXBlJyk7XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgIH0pXG4gICAgICAudGhlbigocmVzKSA9PiAocmVzIGFzIEh0dHBSZXNwb25zZSkuYnVmZmVyKCkpXG4gICAgICAudGhlbigoYnVmZmVyOiBCdWZmZXIpID0+IHtcbiAgICAgICAgY29uc3QgaW1nUGFyYW1zOiBJbWFnZVR5cGUgPSB7XG4gICAgICAgICAgLi4uY3VzdG9tUGFyYW1zLFxuICAgICAgICAgIGJ1ZmZlcixcbiAgICAgICAgICBmaWxlVHlwZTogY29udGVudFR5cGVcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gYWRkSW1hZ2UoY29udGV4dCwgaW1nUGFyYW1zLCBzM09wdGlvbnMpXG4gICAgICAgICAgLnRoZW4oKGltYWdlOiBJbWFnZVR5cGUpID0+IHtcbiAgICAgICAgICAgIGlmKGZvcm1hdEl0ZW1JZCAmJiBmb3JtYXRJdGVtVHlwZSkge1xuICAgICAgICAgICAgICBjb25zdCBpbWFnZUVkZ2U6IEltYWdlRWRnZVR5cGUgPSB7aW1hZ2VJZDogZm9ybWF0SW1hZ2VJZCwgaXRlbUlkOiBmb3JtYXRJdGVtSWQsIGl0ZW1UeXBlOiBmb3JtYXRJdGVtVHlwZX07XG4gICAgICAgICAgICAgIHJldHVybiBhZGRJbWFnZUVkZ2UoY29udGV4dCwgaW1hZ2VFZGdlKS50aGVuKCgpID0+IGltYWdlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGltYWdlO1xuICAgICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIHZhbHVlOiAnZmV0Y2hfZXJyb3InXG4gICAgICB9LCBlcnJvciwgY29udGV4dCkpO1xuICB9IGVsc2UgaWYoaW1hZ2VJZCAhPT0gJycpIHtcbiAgICBjb25zdCB1cGRhdGUgPSB7XG4gICAgICBkZXNjcmlwdGlvbixcbiAgICAgIG1vZGlmaWVkOiBub3dcbiAgICB9O1xuICAgIGNvbnN0IGFxbFFyeTogQXFsUXVlcnkgPSBhcWxgVVBEQVRFIHtfa2V5OiAke2Zvcm1hdEltYWdlSWR9fSBXSVRIICR7dXBkYXRlfSBJTiBpbWFnZXMgUkVUVVJOIE5FV2A7XG5cbiAgICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRcnkpXG4gICAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgYXFsUXJ5LFxuICAgICAgICAgIGZvcm1hdEltYWdlSWQsXG4gICAgICAgICAgdXBkYXRlXG4gICAgICAgIH0sXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCkpO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5leHBvcnQgY29uc3QgZGVsZXRlSW1hZ2UgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwgaW1hZ2VJZDogc3RyaW5nKTogUHJvbWlzZTxJbWFnZVR5cGU+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZGVsZXRlJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfX0gPSBjb250ZXh0O1xuICBjb25zdCBmb3JtYXRJbWFnZUlkID0gcGFyc2VJZChpbWFnZUlkKTtcblxuICB0cnkge1xuICAgIGNvbnN0IHJlbW92ZUVkZ2VRdWVyeSA9IGFxbGBGT1IgaGkgSU4gaGFzSW1hZ2VcbiAgICBGSUxURVIgaGkuX2Zyb20gPT0gJHtmb3JtYXRJbWFnZUlkfVxuICAgIFJFTU9WRSBoaSBJTiBoYXNJbWFnZVxuICAgIFJFVFVSTiBPTERgO1xuXG4gICAgYXdhaXQgdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShyZW1vdmVFZGdlUXVlcnkpO1xuXG4gICAgY29uc3QgYXFsUXVlcnkgPSBhcWxgRk9SIGkgSU4gaW1hZ2VzXG4gICAgRklMVEVSIGkuX2tleSA9PSAke2Zvcm1hdEltYWdlSWR9ICYmIGkudXNlcklkID09ICR7c2Vzc2lvbklkfVxuICAgIFJFTU9WRSBpIElOIGltYWdlc1xuICAgIFJFVFVSTiBPTERgO1xuXG4gICAgY29uc3QgaW1hZ2UgPSBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KS50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpO1xuXG4gICAgaWYoaW1hZ2UpIHtcbiAgICAgIGNvbnN0IHtfa2V5OiBpbWFnZUtleX0gPSBpbWFnZTtcbiAgICAgIGNvbnN0IHBhcmFtczogRGVsZXRlT2JqZWN0c0NvbW1hbmRJbnB1dCA9IHtcbiAgICAgICAgQnVja2V0OiBudWxsLFxuICAgICAgICBEZWxldGU6IHtcbiAgICAgICAgICBPYmplY3RzOiBbXG4gICAgICAgICAgICB7S2V5OiBgdXNlcnMvJHtzZXNzaW9uSWR9L2ltYWdlcy8ke2ltYWdlS2V5fS5qcGdgfSxcbiAgICAgICAgICAgIHtLZXk6IGB1c2Vycy8ke3Nlc3Npb25JZH0vdGh1bWJzLyR7aW1hZ2VLZXl9LmpwZ2B9XG4gICAgICAgICAgXSxcbiAgICAgICAgICBRdWlldDogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gczNEZWxldGVMaXN0KHBhcmFtcykudGhlbigoKSA9PiBpbWFnZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICByZXR1cm4gbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHtpbWFnZUlkfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICB9XG59O1xuIl0sIm5hbWVzIjpbImdldCIsImh0dHBHZXQiLCJwYXJzZU51bSIsImNyZWF0ZUhhc2giLCJwYXJzZUFyYW5nb0lkIiwicGFyc2VDaGFyIiwicGFyc2VJZCIsImFxbCIsImdtIiwiRGF0ZVRpbWUiLCJDb25maWciLCJFcnJvclR5cGVzIiwibG9nRXJyb3IiLCJsb2dFeGNlcHRpb24iLCJnZXREb2NJZCIsImdldExpbWl0Iiwic2VsZWN0UmVhY3Rpb25Db3VudEJ5VHlwZSIsInVzZURiIiwiZ2V0R3JvdXBEZXRhaWxzIiwiaXNHcm91cGVkIiwiczNEZWxldGVMaXN0IiwiczNHZXRTaWduZWRVcmwiLCJzM1B1dCIsImxvd2VyQ2FzZUtleXMiLCJldmVudENhdGVnb3J5Iiwic3ViQ2xhc3MiLCJpbWFnZU1hZ2ljayIsInBhcnNlSW1hZ2VPcHRpb25zIiwib3B0aW9ucyIsImZyb20iLCJ0byIsInR5cGUiLCJsaW1pdCIsImdldEltYWdlT3B0aW9uYWwiLCJmaWVsZHMiLCJyZWR1Y2UiLCJzZWxlY3RzIiwiZmllbGQiLCJpbmNsdWRlcyIsInF1ZXJpZXMiLCJwdXNoIiwib2JqZWN0cyIsImdldEltYWdlc0J5VXNlciIsImNvbnRleHQiLCJ1c2VySWQiLCJhY3Rpb24iLCJkYXRhYmFzZU5hbWUiLCJmb3JtYXRVc2VySWQiLCJhcWxRcnkiLCJxdWVyeSIsInRoZW4iLCJjdXJzb3IiLCJhbGwiLCJjYXRjaCIsImVycm9yIiwiY2F0ZWdvcnkiLCJwYXJhbXMiLCJ2YWx1ZSIsIkRBVEFCQVNFX0VSUk9SIiwiZ2V0SW1hZ2VDb3VudEJ5SXRlbSIsIml0ZW1JZCIsImZvcm1hdEl0ZW1JZCIsIm5leHQiLCJjb3VudCIsImdldEltYWdlc0J5SXRlbSIsInNlbGVjdE9iamVjdHMiLCJzZWxlY3RRdWVyaWVzIiwiam9pbiIsImdldEltYWdlc0J5R3JvdXAiLCJzZXNzaW9uIiwic2Vzc2lvbklkIiwiZmlsdGVycyIsImdyb3VwSWQiLCJmb3JtYXRHcm91cElkIiwibWFwIiwiZmlsdGVyIiwiY29uZGl0aW9uYWwiLCJuYW1lIiwiZm9ybWF0Q29uZCIsImdyb3VwIiwicHJpdmFjeSIsImZpbHRlclN0ciIsImdyb3VwZWQiLCJpc1ZhbGlkIiwiZmlsdGVyTGlzdCIsImdldEltYWdlc0J5UmVhY3Rpb25zIiwicmVhY3Rpb25zIiwiZm9ybWF0U2Vzc2lvbklkIiwiZm9ybWF0UmVhY3Rpb25zIiwicmVhY3Rpb25OYW1lIiwiZmlsdGVyQnkiLCJKU09OIiwic3RyaW5naWZ5IiwiZ2V0SW1hZ2UiLCJpbWFnZUlkIiwiZm9ybWF0SW1hZ2VJZCIsImdldFBhdGhVc2VySW1hZ2VzIiwiaW1hZ2VUeXBlIiwiZGlyIiwiZmlsZW5hbWUiLCJnZXRBcHBJbWFnZVVybCIsImJ1Y2tldCIsImRpcmVjdG9yeSIsImlzVGh1bWIiLCJ0eXBlSWQiLCJidWNrZXROYW1lIiwiaW1hZ2VOYW1lIiwiaW1hZ2VVcmwiLCJnZXRJbWFnZVVybCIsImltYWdlRGlyIiwidXJsVHlwZSIsInRodW1iU3VmZml4IiwiaW1hZ2VLZXkiLCJkZWZhdWx0QnVja2V0IiwiQnVja2V0IiwiRXhwaXJlcyIsIktleSIsInJlc2l6ZVNhdmVJbWFnZSIsImJ1ZmZlciIsImZpbGVUeXBlIiwiczNPcHRpb25zIiwiaW1nVyIsImltZ1EiLCJmb3JtYXQiLCJzcGxpdCIsImltYWdlT3B0aW1pemVkQnVmZmVyIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJzZXRGb3JtYXQiLCJxdWFsaXR5IiwiYXV0b09yaWVudCIsInJlc2l6ZSIsInN0cmVhbSIsInN0cmVhbUVycm9yIiwic3Rkb3V0IiwiSU1BR0VfU0FWRSIsImltYWdlQnVmZmVyIiwiQnVmZmVyIiwib24iLCJkYXRhIiwiY29uY2F0IiwiaW1hZ2VPYmoiLCJBQ0wiLCJCb2R5IiwiQ29udGVudFR5cGUiLCJpbWFnZUlkZW50aXR5IiwiaWRlbnRpZnkiLCJidWZmZXJTdHJlYW0iLCJpbWFnZURhdGEiLCJmb3JtYXRWYWx1ZXMiLCJtYWtlIiwiY2FtZXJhTWFrZSIsIm1vZGVsIiwiY2FtZXJhTW9kZWwiLCJkYXRldGltZW9yaWdpbmFsIiwidGFrZW4iLCJzdGF0cyIsImNvbG9yIiwicmVkIiwiZ3JlZW4iLCJibHVlIiwibWVhbiIsInN1YnN0cmluZyIsInJnYiIsInJnYkNvbG9yIiwidG9TdHJpbmciLCJPcmllbnRhdGlvbiIsIm9yaWVudGF0aW9uRGF0YSIsIlJlc29sdXRpb24iLCJyZXNvbHV0aW9uRGF0YSIsInNpemUiLCJyZXNvbHV0aW9uIiwicmVzb2x1dGlvbk51bWJlciIsInJlc29sdXRpb25Vbml0IiwicmVzb2x1dGlvblZhbHVlIiwicmVzb2x1dGlvblVuaXRWYWx1ZSIsImZpbGVTaXplIiwibGVuZ3RoIiwiaGVpZ2h0Iiwib3JpZW50YXRpb24iLCJ1bmRlZmluZWQiLCJ0b0xvd2VyQ2FzZSIsImZyb21NaWxsaXMiLCJtaWxsaXNlY29uZCIsIndpZHRoIiwidGh1bWJPcHRpbWl6ZWRCdWZmZXIiLCJ0aG1XIiwidGhtUSIsImdyYXZpdHkiLCJleHRlbnQiLCJ0aHVtYlN0ZG91dCIsInRodW1iQnVmZmVyIiwidGh1bWJPYmoiLCJhZGRJbWFnZSIsImltYWdlIiwiZGVzY3JpcHRpb24iLCJub3ciLCJEYXRlIiwicmVzaXplZEltYWdlIiwiaW5zZXJ0IiwiX2tleSIsImFkZGVkIiwibW9kaWZpZWQiLCJJTUFHRV9SRVNJWkUiLCJhZGRJbWFnZUVkZ2UiLCJpbWFnZUVkZ2UiLCJpdGVtVHlwZSIsImVkZ2VJZCIsImZvcm1hdEl0ZW1UeXBlIiwiaXRlbURvY0lkIiwiZmlsZURvY0lkIiwiZWRnZSIsIl9mcm9tIiwiX3RvIiwiY29sbGVjdGlvbiIsInNhdmUiLCJyZXR1cm5OZXciLCJmaWxlRWRnZSIsImRvY3VtZW50IiwidXBkYXRlSW1hZ2UiLCJiYXNlNjQiLCJ1cmwiLCJjdXN0b21QYXJhbXMiLCJmb3JtYXRCYXNlNjQiLCJzdWJzdHIiLCJpbmRleE9mIiwidXBkYXRlZEZpbGVUeXBlIiwiZmlsZVR5cGVGcm9tQnVmZmVyIiwibWltZSIsImltZ1BhcmFtcyIsImNvbnRlbnRUeXBlIiwicmVzIiwic3RhdHVzIiwiSU1BR0VfUkVRVUVTVCIsImhlYWRlcnMiLCJ1cGRhdGUiLCJkZWxldGVJbWFnZSIsInJlbW92ZUVkZ2VRdWVyeSIsImFxbFF1ZXJ5IiwiRGVsZXRlIiwiT2JqZWN0cyIsIlF1aWV0Il0sIm1hcHBpbmdzIjoiQUFBQTs7O0NBR0MsR0FFRCxTQUFRQSxPQUFPQyxPQUFPLFFBQU8sb0JBQW9CO0FBQ2pELFNBQVFDLFFBQVEsUUFBTywrQkFBK0I7QUFDdEQsU0FBUUMsVUFBVSxFQUFFQyxhQUFhLEVBQUVDLFNBQVMsRUFBRUMsT0FBTyxRQUFPLCtCQUErQjtBQUMzRixTQUFRQyxHQUFHLFFBQU8sV0FBVztBQUU3QixPQUFPQyxRQUFRLEtBQUs7QUFDcEIsU0FB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