@excalidraw/excalidraw 0.12.0-fe7fbff → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (829) hide show
  1. package/CHANGELOG.md +101 -754
  2. package/README.md +82 -28
  3. package/dist/excalidraw-assets/locales/ar-SA-json-f62d0199267ac26dcc46.js +1 -0
  4. package/dist/excalidraw-assets/locales/bg-BG-json-2dae80c8675231d2508f.js +1 -0
  5. package/dist/excalidraw-assets/locales/bn-BD-json-7de0976b3dd235c50367.js +1 -0
  6. package/dist/excalidraw-assets/locales/ca-ES-json-df30bc43d1809c17e950.js +1 -0
  7. package/dist/excalidraw-assets/locales/cs-CZ-json-f99ec89695d02c158738.js +1 -0
  8. package/dist/excalidraw-assets/locales/da-DK-json-129c5a554846dcec2446.js +1 -0
  9. package/dist/excalidraw-assets/locales/de-DE-json-de8ce52f58b63b5d7cac.js +1 -0
  10. package/dist/excalidraw-assets/locales/el-GR-json-42b124da4348680272cf.js +1 -0
  11. package/dist/excalidraw-assets/locales/es-ES-json-1d54804f6846a77665e7.js +1 -0
  12. package/dist/excalidraw-assets/locales/eu-ES-json-20bb942caf2be5fb31fa.js +1 -0
  13. package/dist/excalidraw-assets/locales/fa-IR-json-dc0297c83b07d4e32c5d.js +1 -0
  14. package/dist/excalidraw-assets/locales/fi-FI-json-4a39cbd2be73e7ef11ab.js +1 -0
  15. package/dist/excalidraw-assets/locales/fr-FR-json-a6cca9c86e1695df72c5.js +1 -0
  16. package/dist/excalidraw-assets/locales/gl-ES-json-e612f476ea04f792c0cb.js +1 -0
  17. package/dist/excalidraw-assets/locales/he-IL-json-cdc633d78db32de9de16.js +1 -0
  18. package/dist/excalidraw-assets/locales/hi-IN-json-7421bffd8a0b1b4baefd.js +1 -0
  19. package/dist/excalidraw-assets/locales/hu-HU-json-195f20911aa8343a4765.js +1 -0
  20. package/dist/excalidraw-assets/locales/id-ID-json-f6613f95abceb22d4334.js +1 -0
  21. package/dist/excalidraw-assets/locales/it-IT-json-7c0884df61edb349074e.js +1 -0
  22. package/dist/excalidraw-assets/locales/ja-JP-json-ef14f8d870b98cce213c.js +1 -0
  23. package/dist/excalidraw-assets/locales/kab-KAB-json-4637f465a71f864f4541.js +1 -0
  24. package/dist/excalidraw-assets/locales/kk-KZ-json-754a1a92ec1065f31d3d.js +1 -0
  25. package/dist/excalidraw-assets/locales/ko-KR-json-bc46bfce6edd97614e6a.js +1 -0
  26. package/dist/excalidraw-assets/locales/ku-TR-json-fdfa8b6bee1e0641bc22.js +1 -0
  27. package/dist/excalidraw-assets/locales/lt-LT-json-d5269bb2d2b60fd38a5a.js +1 -0
  28. package/dist/excalidraw-assets/locales/lv-LV-json-1d8885395dbcbd394b9d.js +1 -0
  29. package/dist/excalidraw-assets/locales/mr-IN-json-80a3137f998226b197b5.js +1 -0
  30. package/dist/excalidraw-assets/locales/my-MM-json-3d2e8072ecfc933ff405.js +1 -0
  31. package/dist/excalidraw-assets/locales/nb-NO-json-c3d61f50504ac09dcc64.js +1 -0
  32. package/dist/excalidraw-assets/locales/nl-NL-json-87c4bd52e9abb75aaaf4.js +1 -0
  33. package/dist/excalidraw-assets/locales/nn-NO-json-92ac810aa0d36d73abd5.js +1 -0
  34. package/dist/excalidraw-assets/locales/oc-FR-json-5ea7d0994898ab2c9f00.js +1 -0
  35. package/dist/excalidraw-assets/locales/pa-IN-json-a1e20a0ff8fddca3d0f8.js +1 -0
  36. package/dist/excalidraw-assets/locales/pl-PL-json-c93ff741bb4aca4676e9.js +1 -0
  37. package/dist/excalidraw-assets/locales/pt-BR-json-5b53e5bc1e2745a96718.js +1 -0
  38. package/dist/excalidraw-assets/locales/pt-PT-json-9be05fd920a91a610e9f.js +1 -0
  39. package/dist/excalidraw-assets/locales/ro-RO-json-1a69dd60c4c802d6dcfc.js +1 -0
  40. package/dist/excalidraw-assets/locales/ru-RU-json-fbb4c10ed14cf28c501a.js +1 -0
  41. package/dist/excalidraw-assets/locales/si-LK-json-f21fa92c1726fda0c56b.js +1 -0
  42. package/dist/excalidraw-assets/locales/sk-SK-json-02bfb6c6ae8657ba7c10.js +1 -0
  43. package/dist/excalidraw-assets/locales/sl-SI-json-28142a1698858ae0423f.js +1 -0
  44. package/dist/excalidraw-assets/locales/sv-SE-json-355010df9dd71e3815aa.js +1 -0
  45. package/dist/excalidraw-assets/locales/ta-IN-json-aa8488d4a7eba863eafa.js +1 -0
  46. package/dist/excalidraw-assets/locales/tr-TR-json-0647ae69354eacfcfe79.js +1 -0
  47. package/dist/excalidraw-assets/locales/uk-UA-json-5c05732cd5338c4b299a.js +1 -0
  48. package/dist/excalidraw-assets/locales/{si-LK-json-f48a64dfd1cb9c075d2e.js → vi-VN-json-13f82887207123a51a6a.js} +1 -1
  49. package/dist/excalidraw-assets/locales/zh-CN-json-ccec3aebee2e2775a326.js +1 -0
  50. package/dist/excalidraw-assets/locales/zh-HK-json-2f216981a653096b6541.js +1 -0
  51. package/dist/excalidraw-assets/locales/zh-TW-json-d8becf928388ee71ea47.js +1 -0
  52. package/dist/excalidraw-assets/vendor-03e611bf80e4dd79b9dd.js +2 -0
  53. package/dist/excalidraw-assets/{vendor-52b1f3361986b6c6a4fe.js.LICENSE.txt → vendor-03e611bf80e4dd79b9dd.js.LICENSE.txt} +0 -0
  54. package/dist/excalidraw-assets-dev/locales/ar-SA-json-e18bf994a8a492e04c5b.js +22 -0
  55. package/dist/excalidraw-assets-dev/locales/bg-BG-json-c4822083b66facc7138b.js +22 -0
  56. package/dist/excalidraw-assets-dev/locales/bn-BD-json-a19c78a329a982867a27.js +22 -0
  57. package/dist/excalidraw-assets-dev/locales/ca-ES-json-81a1896a4b8113466237.js +22 -0
  58. package/dist/excalidraw-assets-dev/locales/cs-CZ-json-bd241b199b5154d21ca1.js +22 -0
  59. package/dist/excalidraw-assets-dev/locales/da-DK-json-4e6dd750a31d070daec9.js +22 -0
  60. package/dist/excalidraw-assets-dev/locales/de-DE-json-d0676faf8f1e90d3ce34.js +22 -0
  61. package/dist/excalidraw-assets-dev/locales/el-GR-json-9185ceab00e1598333d4.js +22 -0
  62. package/dist/excalidraw-assets-dev/locales/es-ES-json-a2870461506d73f41a72.js +22 -0
  63. package/dist/excalidraw-assets-dev/locales/eu-ES-json-3530634f7d5a3db297de.js +22 -0
  64. package/dist/excalidraw-assets-dev/locales/fa-IR-json-66f5b4a41dc3aa7c8c45.js +22 -0
  65. package/dist/excalidraw-assets-dev/locales/fi-FI-json-7885764c835895664e0b.js +22 -0
  66. package/dist/excalidraw-assets-dev/locales/fr-FR-json-db1925f49529ff2c6ec1.js +22 -0
  67. package/dist/excalidraw-assets-dev/locales/gl-ES-json-ab9c245372378f5f8c9b.js +22 -0
  68. package/dist/excalidraw-assets-dev/locales/he-IL-json-7bfd6ca43596df3a84a1.js +22 -0
  69. package/dist/excalidraw-assets-dev/locales/hi-IN-json-311afde0e51db172b1b4.js +22 -0
  70. package/dist/excalidraw-assets-dev/locales/hu-HU-json-f6436471ba8cccff3ac4.js +22 -0
  71. package/dist/excalidraw-assets-dev/locales/id-ID-json-9328a35688d0537730ae.js +22 -0
  72. package/dist/excalidraw-assets-dev/locales/it-IT-json-508f57463d4037918ebb.js +22 -0
  73. package/dist/excalidraw-assets-dev/locales/ja-JP-json-c670cda6d6c171611c79.js +22 -0
  74. package/dist/excalidraw-assets-dev/locales/kab-KAB-json-396d5e8936a8362b536c.js +22 -0
  75. package/dist/excalidraw-assets-dev/locales/kk-KZ-json-7c301df4020cd7c670e2.js +22 -0
  76. package/dist/excalidraw-assets-dev/locales/ko-KR-json-d6850be7bac8fc43af84.js +22 -0
  77. package/dist/excalidraw-assets-dev/locales/ku-TR-json-9837b398f7df5f1bb711.js +22 -0
  78. package/dist/excalidraw-assets-dev/locales/lt-LT-json-263c5629ddf0ee7d7572.js +22 -0
  79. package/dist/excalidraw-assets-dev/locales/lv-LV-json-44a18e46e8c68310c7c8.js +22 -0
  80. package/dist/excalidraw-assets-dev/locales/mr-IN-json-b0cd94322c2b39884d52.js +22 -0
  81. package/dist/excalidraw-assets-dev/locales/my-MM-json-b0c8ffa53fa7c9f7fc4d.js +22 -0
  82. package/dist/excalidraw-assets-dev/locales/nb-NO-json-216bb67091fd4a2e70e6.js +22 -0
  83. package/dist/excalidraw-assets-dev/locales/nl-NL-json-820135e0dcbb62d8f23c.js +22 -0
  84. package/dist/excalidraw-assets-dev/locales/nn-NO-json-059b39da1c7b19e93db6.js +22 -0
  85. package/dist/excalidraw-assets-dev/locales/oc-FR-json-54a63799c742875f8b9b.js +22 -0
  86. package/dist/excalidraw-assets-dev/locales/pa-IN-json-e535caa54102fbcee393.js +22 -0
  87. package/dist/excalidraw-assets-dev/locales/pl-PL-json-73e6bd0c53922c9c71ba.js +22 -0
  88. package/dist/excalidraw-assets-dev/locales/pt-BR-json-f8d16d6d47abde7f52c8.js +22 -0
  89. package/dist/excalidraw-assets-dev/locales/pt-PT-json-4b8554cd18248130c618.js +22 -0
  90. package/dist/excalidraw-assets-dev/locales/ro-RO-json-718b6921865260332b51.js +22 -0
  91. package/dist/excalidraw-assets-dev/locales/ru-RU-json-f941229aeb3c961f6afe.js +22 -0
  92. package/dist/excalidraw-assets-dev/locales/si-LK-json-2f1de88a189ba6ba696d.js +22 -0
  93. package/dist/excalidraw-assets-dev/locales/sk-SK-json-733bf7834531da06e409.js +22 -0
  94. package/dist/excalidraw-assets-dev/locales/sl-SI-json-302c47db8bdde83cfd9a.js +22 -0
  95. package/dist/excalidraw-assets-dev/locales/sv-SE-json-a3fbe43174a0b8c11dbe.js +22 -0
  96. package/dist/excalidraw-assets-dev/locales/ta-IN-json-97dde0a466b7ef9a293c.js +22 -0
  97. package/dist/excalidraw-assets-dev/locales/tr-TR-json-d387c2ab9f0dabccb94c.js +22 -0
  98. package/dist/excalidraw-assets-dev/locales/uk-UA-json-9b412ee83d32be90b91b.js +22 -0
  99. package/dist/excalidraw-assets-dev/locales/vi-VN-json-5d796333807e34aee311.js +22 -0
  100. package/dist/excalidraw-assets-dev/locales/zh-CN-json-9089c24ecdc4c4b7c5cf.js +22 -0
  101. package/dist/excalidraw-assets-dev/locales/zh-HK-json-66e5d1f5e052d9b895e2.js +22 -0
  102. package/dist/excalidraw-assets-dev/locales/zh-TW-json-a05cd2023060266e8e0e.js +22 -0
  103. package/dist/excalidraw-assets-dev/{vendor-c0592035c3911af79359.js → vendor-e6df8519da951026ff69.js} +2 -2
  104. package/dist/excalidraw.development.js +163 -104
  105. package/dist/excalidraw.production.min.js +1 -1
  106. package/dist/excalidraw.production.min.js.LICENSE.txt +0 -9
  107. package/package.json +2 -2
  108. package/types/actions/actionAddToLibrary.d.ts +12 -9
  109. package/types/actions/actionAddToLibrary.d.ts.map +1 -0
  110. package/types/actions/actionAlign.d.ts.map +1 -0
  111. package/types/actions/actionBoundText.d.ts +4 -3
  112. package/types/actions/actionBoundText.d.ts.map +1 -0
  113. package/types/actions/actionCanvas.d.ts +32 -24
  114. package/types/actions/actionCanvas.d.ts.map +1 -0
  115. package/types/actions/actionClipboard.d.ts +22 -15
  116. package/types/actions/actionClipboard.d.ts.map +1 -0
  117. package/types/actions/actionDeleteSelected.d.ts +14 -9
  118. package/types/actions/actionDeleteSelected.d.ts.map +1 -0
  119. package/types/actions/actionDistribute.d.ts.map +1 -0
  120. package/types/actions/actionDuplicateSelection.d.ts.map +1 -0
  121. package/types/actions/actionExport.d.ts +37 -28
  122. package/types/actions/actionExport.d.ts.map +1 -0
  123. package/types/actions/actionFinalize.d.ts +8 -6
  124. package/types/actions/actionFinalize.d.ts.map +1 -0
  125. package/types/actions/actionFlip.d.ts.map +1 -0
  126. package/types/actions/actionGroup.d.ts.map +1 -0
  127. package/types/actions/actionHistory.d.ts.map +1 -0
  128. package/types/actions/actionLinearEditor.d.ts +114 -0
  129. package/types/actions/actionMenu.d.ts +12 -9
  130. package/types/actions/actionMenu.d.ts.map +1 -0
  131. package/types/actions/actionNavigate.d.ts.map +1 -0
  132. package/types/actions/actionProperties.d.ts +52 -39
  133. package/types/actions/actionProperties.d.ts.map +1 -0
  134. package/types/actions/actionSelectAll.d.ts +1 -1
  135. package/types/actions/actionSelectAll.d.ts.map +1 -0
  136. package/types/actions/actionStyles.d.ts +4 -3
  137. package/types/actions/actionStyles.d.ts.map +1 -0
  138. package/types/actions/actionToggleGridMode.d.ts +4 -3
  139. package/types/actions/actionToggleGridMode.d.ts.map +1 -0
  140. package/types/actions/actionToggleLock.d.ts +99 -1
  141. package/types/actions/actionToggleLock.d.ts.map +1 -0
  142. package/types/actions/actionToggleStats.d.ts +4 -3
  143. package/types/actions/actionToggleStats.d.ts.map +1 -0
  144. package/types/actions/actionToggleViewMode.d.ts +4 -3
  145. package/types/actions/actionToggleViewMode.d.ts.map +1 -0
  146. package/types/actions/actionToggleZenMode.d.ts +4 -3
  147. package/types/actions/actionToggleZenMode.d.ts.map +1 -0
  148. package/types/actions/actionZindex.d.ts.map +1 -0
  149. package/types/actions/index.d.ts +1 -0
  150. package/types/actions/index.d.ts.map +1 -0
  151. package/types/actions/manager.d.ts.map +1 -0
  152. package/types/actions/register.d.ts.map +1 -0
  153. package/types/actions/shortcuts.d.ts.map +1 -0
  154. package/types/actions/types.d.ts +1 -1
  155. package/types/actions/types.d.ts.map +1 -0
  156. package/types/align.d.ts.map +1 -0
  157. package/types/analytics.d.ts.map +1 -0
  158. package/types/appState.d.ts +4 -3
  159. package/types/appState.d.ts.map +1 -0
  160. package/types/charts.d.ts.map +1 -0
  161. package/types/clients.d.ts.map +1 -0
  162. package/types/clipboard.d.ts.map +1 -0
  163. package/types/colors.d.ts.map +1 -0
  164. package/types/components/Actions.d.ts +13 -2
  165. package/types/components/Actions.d.ts.map +1 -0
  166. package/types/components/ActiveFile.d.ts.map +1 -0
  167. package/types/components/App.d.ts +11 -1
  168. package/types/components/App.d.ts.map +1 -0
  169. package/types/components/Avatar.d.ts.map +1 -0
  170. package/types/components/BackgroundPickerAndDarkModeToggle.d.ts +1 -6
  171. package/types/components/BackgroundPickerAndDarkModeToggle.d.ts.map +1 -0
  172. package/types/components/ButtonIconSelect.d.ts.map +1 -0
  173. package/types/components/Card.d.ts.map +1 -0
  174. package/types/components/CheckboxItem.d.ts.map +1 -0
  175. package/types/components/ClearCanvas.d.ts.map +1 -0
  176. package/types/components/CollabButton.d.ts.map +1 -0
  177. package/types/components/ColorPicker.d.ts.map +1 -0
  178. package/types/components/ConfirmDialog.d.ts.map +1 -0
  179. package/types/components/ContextMenu.d.ts.map +1 -0
  180. package/types/components/DarkModeToggle.d.ts.map +1 -0
  181. package/types/components/Dialog.d.ts.map +1 -0
  182. package/types/components/ErrorDialog.d.ts.map +1 -0
  183. package/types/components/FixedSideContainer.d.ts.map +1 -0
  184. package/types/components/Footer.d.ts +9 -0
  185. package/types/components/HelpDialog.d.ts.map +1 -0
  186. package/types/components/HelpIcon.d.ts.map +1 -0
  187. package/types/components/HintViewer.d.ts +3 -2
  188. package/types/components/HintViewer.d.ts.map +1 -0
  189. package/types/components/IconPicker.d.ts.map +1 -0
  190. package/types/components/ImageExportDialog.d.ts.map +1 -0
  191. package/types/components/InitializeApp.d.ts +2 -0
  192. package/types/components/InitializeApp.d.ts.map +1 -0
  193. package/types/components/Island.d.ts.map +1 -0
  194. package/types/components/JSONExportDialog.d.ts.map +1 -0
  195. package/types/components/LayerUI.d.ts +2 -2
  196. package/types/components/LayerUI.d.ts.map +1 -0
  197. package/types/components/LibraryButton.d.ts.map +1 -0
  198. package/types/components/LibraryMenu.d.ts +14 -6
  199. package/types/components/LibraryMenu.d.ts.map +1 -0
  200. package/types/components/LibraryMenuHeaderContent.d.ts +12 -0
  201. package/types/components/LibraryMenuItems.d.ts +2 -14
  202. package/types/components/LibraryMenuItems.d.ts.map +1 -0
  203. package/types/components/LibraryUnit.d.ts +2 -3
  204. package/types/components/LibraryUnit.d.ts.map +1 -0
  205. package/types/components/LoadingMessage.d.ts +2 -0
  206. package/types/components/LoadingMessage.d.ts.map +1 -0
  207. package/types/components/LockButton.d.ts.map +1 -0
  208. package/types/components/MobileMenu.d.ts +5 -5
  209. package/types/components/MobileMenu.d.ts.map +1 -0
  210. package/types/components/PasteChartDialog.d.ts.map +1 -0
  211. package/types/components/PenModeButton.d.ts.map +1 -0
  212. package/types/components/Popover.d.ts.map +1 -0
  213. package/types/components/ProjectName.d.ts.map +1 -0
  214. package/types/components/PublishLibrary.d.ts.map +1 -0
  215. package/types/components/Section.d.ts.map +1 -0
  216. package/types/components/Sidebar/Sidebar.d.ts +73 -0
  217. package/types/components/Sidebar/SidebarHeader.d.ts +20 -0
  218. package/types/components/Sidebar/common.d.ts +15 -0
  219. package/types/components/SidebarLockButton.d.ts.map +1 -0
  220. package/types/components/SingleLibraryItem.d.ts.map +1 -0
  221. package/types/components/Spinner.d.ts.map +1 -0
  222. package/types/components/Stack.d.ts.map +1 -0
  223. package/types/components/Stats.d.ts +1 -1
  224. package/types/components/Stats.d.ts.map +1 -0
  225. package/types/components/Toast.d.ts.map +1 -0
  226. package/types/components/ToolButton.d.ts.map +1 -0
  227. package/types/components/Tooltip.d.ts.map +1 -0
  228. package/types/components/UserList.d.ts.map +1 -0
  229. package/types/components/hoc/withUpstreamOverride.d.ts +10 -0
  230. package/types/components/icons.d.ts.map +1 -0
  231. package/types/constants.d.ts +12 -1
  232. package/types/constants.d.ts.map +1 -0
  233. package/types/data/blob.d.ts +1 -1
  234. package/types/data/blob.d.ts.map +1 -0
  235. package/types/data/encode.d.ts.map +1 -0
  236. package/types/data/encryption.d.ts.map +1 -0
  237. package/types/data/filesystem.d.ts.map +1 -0
  238. package/types/data/image.d.ts.map +1 -0
  239. package/types/data/index.d.ts.map +1 -0
  240. package/types/data/json.d.ts.map +1 -0
  241. package/types/data/library.d.ts.map +1 -0
  242. package/types/data/resave.d.ts.map +1 -0
  243. package/types/data/restore.d.ts.map +1 -0
  244. package/types/data/types.d.ts +16 -1
  245. package/types/data/types.d.ts.map +1 -0
  246. package/types/distribute.d.ts.map +1 -0
  247. package/types/element/Hyperlink.d.ts +5 -5
  248. package/types/element/Hyperlink.d.ts.map +1 -0
  249. package/types/element/binding.d.ts.map +1 -0
  250. package/types/element/bounds.d.ts +1 -1
  251. package/types/element/bounds.d.ts.map +1 -0
  252. package/types/element/collision.d.ts.map +1 -0
  253. package/types/element/dragElements.d.ts.map +1 -0
  254. package/types/element/image.d.ts +1 -1
  255. package/types/element/image.d.ts.map +1 -0
  256. package/types/element/index.d.ts.map +1 -0
  257. package/types/element/linearElementEditor.d.ts +42 -19
  258. package/types/element/linearElementEditor.d.ts.map +1 -0
  259. package/types/element/mutateElement.d.ts.map +1 -0
  260. package/types/element/newElement.d.ts +6 -1
  261. package/types/element/newElement.d.ts.map +1 -0
  262. package/types/element/resizeElements.d.ts.map +1 -0
  263. package/types/element/resizeTest.d.ts.map +1 -0
  264. package/types/element/showSelectedShapeActions.d.ts.map +1 -0
  265. package/types/element/sizeHelpers.d.ts.map +1 -0
  266. package/types/element/textElement.d.ts +6 -2
  267. package/types/element/textElement.d.ts.map +1 -0
  268. package/types/element/textWysiwyg.d.ts.map +1 -0
  269. package/types/element/transformHandles.d.ts +5 -4
  270. package/types/element/transformHandles.d.ts.map +1 -0
  271. package/types/element/typeChecks.d.ts.map +1 -0
  272. package/types/element/types.d.ts +3 -2
  273. package/types/element/types.d.ts.map +1 -0
  274. package/types/errors.d.ts.map +1 -0
  275. package/types/ga.d.ts.map +1 -0
  276. package/types/gadirections.d.ts.map +1 -0
  277. package/types/galines.d.ts.map +1 -0
  278. package/types/gapoints.d.ts.map +1 -0
  279. package/types/gatransforms.d.ts.map +1 -0
  280. package/types/gesture.d.ts.map +1 -0
  281. package/types/groups.d.ts.map +1 -0
  282. package/types/history.d.ts.map +1 -0
  283. package/types/hooks/useCallbackRefState.d.ts.map +1 -0
  284. package/types/i18n.d.ts.map +1 -0
  285. package/types/jotai.d.ts.map +1 -0
  286. package/types/keys.d.ts +3 -3
  287. package/types/keys.d.ts.map +1 -0
  288. package/types/math.d.ts +8 -1
  289. package/types/math.d.ts.map +1 -0
  290. package/types/packages/common.webpack.dev.config.d.ts +71 -0
  291. package/types/packages/common.webpack.prod.config.d.ts +83 -0
  292. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{es-ES-json-ffb4e65453db2f3058d4.d.ts → ar-SA-json-3f3939003e50137eb96e.d.ts} +0 -0
  293. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ar-SA-json-3f3939003e50137eb96e.d.ts.map +1 -0
  294. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{ko-KR-json-f27d159b2556809076aa.d.ts → ar-SA-json-f62d0199267ac26dcc46.d.ts} +0 -0
  295. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{pt-BR-json-686219f43cd76123b7fa.d.ts → bg-BG-json-2dae80c8675231d2508f.d.ts} +0 -0
  296. package/types/packages/excalidraw/dist/excalidraw-assets/locales/{pt-PT-json-be4502ca3a1250845c39.d.ts → bg-BG-json-41978e51de89ecb69832.d.ts} +0 -0
  297. package/types/packages/excalidraw/dist/excalidraw-assets/locales/bg-BG-json-41978e51de89ecb69832.d.ts.map +1 -0
  298. package/types/packages/excalidraw/dist/excalidraw-assets/locales/bn-BD-json-270049304edfc328feb0.d.ts +0 -0
  299. package/types/packages/excalidraw/dist/excalidraw-assets/locales/bn-BD-json-270049304edfc328feb0.d.ts.map +1 -0
  300. package/types/packages/excalidraw/dist/excalidraw-assets/locales/bn-BD-json-7de0976b3dd235c50367.d.ts +0 -0
  301. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ca-ES-json-2e2ec4a6db0dadecd932.d.ts +0 -0
  302. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ca-ES-json-2e2ec4a6db0dadecd932.d.ts.map +1 -0
  303. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ca-ES-json-7f3f0a2c7f428fa60e01.d.ts +0 -0
  304. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ca-ES-json-df30bc43d1809c17e950.d.ts +0 -0
  305. package/types/packages/excalidraw/dist/excalidraw-assets/locales/cs-CZ-json-294f73284f7603f8b308.d.ts +0 -0
  306. package/types/packages/excalidraw/dist/excalidraw-assets/locales/cs-CZ-json-294f73284f7603f8b308.d.ts.map +1 -0
  307. package/types/packages/excalidraw/dist/excalidraw-assets/locales/cs-CZ-json-f99ec89695d02c158738.d.ts +0 -0
  308. package/types/packages/excalidraw/dist/excalidraw-assets/locales/da-DK-json-129c5a554846dcec2446.d.ts +0 -0
  309. package/types/packages/excalidraw/dist/excalidraw-assets/locales/da-DK-json-7cec75a31335c8eaab69.d.ts +0 -0
  310. package/types/packages/excalidraw/dist/excalidraw-assets/locales/da-DK-json-7cec75a31335c8eaab69.d.ts.map +1 -0
  311. package/types/packages/excalidraw/dist/excalidraw-assets/locales/de-DE-json-b972f335652b31abc478.d.ts +0 -0
  312. package/types/packages/excalidraw/dist/excalidraw-assets/locales/de-DE-json-b972f335652b31abc478.d.ts.map +1 -0
  313. package/types/packages/excalidraw/dist/excalidraw-assets/locales/de-DE-json-de8ce52f58b63b5d7cac.d.ts +0 -0
  314. package/types/packages/excalidraw/dist/excalidraw-assets/locales/el-GR-json-0a17ab9d0298049bcf5f.d.ts +0 -0
  315. package/types/packages/excalidraw/dist/excalidraw-assets/locales/el-GR-json-0a17ab9d0298049bcf5f.d.ts.map +1 -0
  316. package/types/packages/excalidraw/dist/excalidraw-assets/locales/el-GR-json-18ce48894d32ca4895b8.d.ts +0 -0
  317. package/types/packages/excalidraw/dist/excalidraw-assets/locales/el-GR-json-42b124da4348680272cf.d.ts +0 -0
  318. package/types/packages/excalidraw/dist/excalidraw-assets/locales/es-ES-json-1d54804f6846a77665e7.d.ts +0 -0
  319. package/types/packages/excalidraw/dist/excalidraw-assets/locales/es-ES-json-2a821ff3ff417c43b325.d.ts +0 -0
  320. package/types/packages/excalidraw/dist/excalidraw-assets/locales/es-ES-json-2a821ff3ff417c43b325.d.ts.map +1 -0
  321. package/types/packages/excalidraw/dist/excalidraw-assets/locales/es-ES-json-69a6c81b0e5dc370ea1a.d.ts +0 -0
  322. package/types/packages/excalidraw/dist/excalidraw-assets/locales/eu-ES-json-20bb942caf2be5fb31fa.d.ts +0 -0
  323. package/types/packages/excalidraw/dist/excalidraw-assets/locales/eu-ES-json-807880ff10379aea34f5.d.ts +0 -0
  324. package/types/packages/excalidraw/dist/excalidraw-assets/locales/eu-ES-json-807880ff10379aea34f5.d.ts.map +1 -0
  325. package/types/packages/excalidraw/dist/excalidraw-assets/locales/fa-IR-json-30ce6b716d375cd90b9b.d.ts +0 -0
  326. package/types/packages/excalidraw/dist/excalidraw-assets/locales/fa-IR-json-30ce6b716d375cd90b9b.d.ts.map +1 -0
  327. package/types/packages/excalidraw/dist/excalidraw-assets/locales/fa-IR-json-dc0297c83b07d4e32c5d.d.ts +0 -0
  328. package/types/packages/excalidraw/dist/excalidraw-assets/locales/fi-FI-json-4a39cbd2be73e7ef11ab.d.ts +0 -0
  329. package/types/packages/excalidraw/dist/excalidraw-assets/locales/fi-FI-json-d71c23aabcb9ca7449d9.d.ts +0 -0
  330. package/types/packages/excalidraw/dist/excalidraw-assets/locales/fi-FI-json-d71c23aabcb9ca7449d9.d.ts.map +1 -0
  331. package/types/packages/excalidraw/dist/excalidraw-assets/locales/fr-FR-json-a6cca9c86e1695df72c5.d.ts +0 -0
  332. package/types/packages/excalidraw/dist/excalidraw-assets/locales/fr-FR-json-d53486b6942cd134938f.d.ts +0 -0
  333. package/types/packages/excalidraw/dist/excalidraw-assets/locales/fr-FR-json-d53486b6942cd134938f.d.ts.map +1 -0
  334. package/types/packages/excalidraw/dist/excalidraw-assets/locales/gl-ES-json-24b9a50f57184ae44f99.d.ts +0 -0
  335. package/types/packages/excalidraw/dist/excalidraw-assets/locales/gl-ES-json-24b9a50f57184ae44f99.d.ts.map +1 -0
  336. package/types/packages/excalidraw/dist/excalidraw-assets/locales/gl-ES-json-e612f476ea04f792c0cb.d.ts +0 -0
  337. package/types/packages/excalidraw/dist/excalidraw-assets/locales/he-IL-json-cdc633d78db32de9de16.d.ts +0 -0
  338. package/types/packages/excalidraw/dist/excalidraw-assets/locales/he-IL-json-f91ace474afb01d8f3ed.d.ts +0 -0
  339. package/types/packages/excalidraw/dist/excalidraw-assets/locales/he-IL-json-f91ace474afb01d8f3ed.d.ts.map +1 -0
  340. package/types/packages/excalidraw/dist/excalidraw-assets/locales/hi-IN-json-7421bffd8a0b1b4baefd.d.ts +0 -0
  341. package/types/packages/excalidraw/dist/excalidraw-assets/locales/hi-IN-json-9af974be0987a846db82.d.ts +0 -0
  342. package/types/packages/excalidraw/dist/excalidraw-assets/locales/hi-IN-json-9af974be0987a846db82.d.ts.map +1 -0
  343. package/types/packages/excalidraw/dist/excalidraw-assets/locales/hu-HU-json-195f20911aa8343a4765.d.ts +0 -0
  344. package/types/packages/excalidraw/dist/excalidraw-assets/locales/hu-HU-json-dd5d9a15eb412598f794.d.ts +0 -0
  345. package/types/packages/excalidraw/dist/excalidraw-assets/locales/hu-HU-json-dd5d9a15eb412598f794.d.ts.map +1 -0
  346. package/types/packages/excalidraw/dist/excalidraw-assets/locales/id-ID-json-acdf1f60176cd026af64.d.ts +0 -0
  347. package/types/packages/excalidraw/dist/excalidraw-assets/locales/id-ID-json-acdf1f60176cd026af64.d.ts.map +1 -0
  348. package/types/packages/excalidraw/dist/excalidraw-assets/locales/id-ID-json-f6613f95abceb22d4334.d.ts +0 -0
  349. package/types/packages/excalidraw/dist/excalidraw-assets/locales/it-IT-json-790983f96414735e8451.d.ts +0 -0
  350. package/types/packages/excalidraw/dist/excalidraw-assets/locales/it-IT-json-790983f96414735e8451.d.ts.map +1 -0
  351. package/types/packages/excalidraw/dist/excalidraw-assets/locales/it-IT-json-7c0884df61edb349074e.d.ts +0 -0
  352. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ja-JP-json-b57e6afb227d9247b3c8.d.ts +0 -0
  353. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ja-JP-json-b57e6afb227d9247b3c8.d.ts.map +1 -0
  354. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ja-JP-json-ef14f8d870b98cce213c.d.ts +0 -0
  355. package/types/packages/excalidraw/dist/excalidraw-assets/locales/kab-KAB-json-4637f465a71f864f4541.d.ts +0 -0
  356. package/types/packages/excalidraw/dist/excalidraw-assets/locales/kab-KAB-json-b3aced3d4ddccfb4127d.d.ts +0 -0
  357. package/types/packages/excalidraw/dist/excalidraw-assets/locales/kab-KAB-json-b3aced3d4ddccfb4127d.d.ts.map +1 -0
  358. package/types/packages/excalidraw/dist/excalidraw-assets/locales/kk-KZ-json-6f477840db7f293c3ff3.d.ts +0 -0
  359. package/types/packages/excalidraw/dist/excalidraw-assets/locales/kk-KZ-json-6f477840db7f293c3ff3.d.ts.map +1 -0
  360. package/types/packages/excalidraw/dist/excalidraw-assets/locales/kk-KZ-json-754a1a92ec1065f31d3d.d.ts +0 -0
  361. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ko-KR-json-8e7ae1bb19a7677a8190.d.ts +0 -0
  362. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ko-KR-json-bc46bfce6edd97614e6a.d.ts +0 -0
  363. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ko-KR-json-d2e67336d6b43a42ff1e.d.ts +0 -0
  364. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ko-KR-json-d2e67336d6b43a42ff1e.d.ts.map +1 -0
  365. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ku-TR-json-fdfa8b6bee1e0641bc22.d.ts +0 -0
  366. package/types/packages/excalidraw/dist/excalidraw-assets/locales/lt-LT-json-1a57a9a7596eb235b3e5.d.ts +0 -0
  367. package/types/packages/excalidraw/dist/excalidraw-assets/locales/lt-LT-json-1a57a9a7596eb235b3e5.d.ts.map +1 -0
  368. package/types/packages/excalidraw/dist/excalidraw-assets/locales/lt-LT-json-d5269bb2d2b60fd38a5a.d.ts +0 -0
  369. package/types/packages/excalidraw/dist/excalidraw-assets/locales/lv-LV-json-1d8885395dbcbd394b9d.d.ts +0 -0
  370. package/types/packages/excalidraw/dist/excalidraw-assets/locales/lv-LV-json-40863b1530d2015aa72e.d.ts +0 -0
  371. package/types/packages/excalidraw/dist/excalidraw-assets/locales/lv-LV-json-40863b1530d2015aa72e.d.ts.map +1 -0
  372. package/types/packages/excalidraw/dist/excalidraw-assets/locales/mr-IN-json-3295641c432b154ab60f.d.ts +0 -0
  373. package/types/packages/excalidraw/dist/excalidraw-assets/locales/mr-IN-json-3295641c432b154ab60f.d.ts.map +1 -0
  374. package/types/packages/excalidraw/dist/excalidraw-assets/locales/mr-IN-json-80a3137f998226b197b5.d.ts +0 -0
  375. package/types/packages/excalidraw/dist/excalidraw-assets/locales/my-MM-json-3d2e8072ecfc933ff405.d.ts +0 -0
  376. package/types/packages/excalidraw/dist/excalidraw-assets/locales/my-MM-json-dc1320c2d6c1adca77d0.d.ts +0 -0
  377. package/types/packages/excalidraw/dist/excalidraw-assets/locales/my-MM-json-dc1320c2d6c1adca77d0.d.ts.map +1 -0
  378. package/types/packages/excalidraw/dist/excalidraw-assets/locales/nb-NO-json-c3d61f50504ac09dcc64.d.ts +0 -0
  379. package/types/packages/excalidraw/dist/excalidraw-assets/locales/nb-NO-json-f073266126f35722bd87.d.ts +0 -0
  380. package/types/packages/excalidraw/dist/excalidraw-assets/locales/nb-NO-json-f073266126f35722bd87.d.ts.map +1 -0
  381. package/types/packages/excalidraw/dist/excalidraw-assets/locales/nl-NL-json-5d4a291a77a27fadddc1.d.ts +0 -0
  382. package/types/packages/excalidraw/dist/excalidraw-assets/locales/nl-NL-json-5d4a291a77a27fadddc1.d.ts.map +1 -0
  383. package/types/packages/excalidraw/dist/excalidraw-assets/locales/nl-NL-json-87c4bd52e9abb75aaaf4.d.ts +0 -0
  384. package/types/packages/excalidraw/dist/excalidraw-assets/locales/nn-NO-json-92ac810aa0d36d73abd5.d.ts +0 -0
  385. package/types/packages/excalidraw/dist/excalidraw-assets/locales/nn-NO-json-9fe14d0a715c691bb9aa.d.ts +0 -0
  386. package/types/packages/excalidraw/dist/excalidraw-assets/locales/nn-NO-json-9fe14d0a715c691bb9aa.d.ts.map +1 -0
  387. package/types/packages/excalidraw/dist/excalidraw-assets/locales/oc-FR-json-5ea7d0994898ab2c9f00.d.ts +0 -0
  388. package/types/packages/excalidraw/dist/excalidraw-assets/locales/oc-FR-json-b7a10ed3433fcb6dd59a.d.ts +0 -0
  389. package/types/packages/excalidraw/dist/excalidraw-assets/locales/oc-FR-json-b7a10ed3433fcb6dd59a.d.ts.map +1 -0
  390. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pa-IN-json-a1e20a0ff8fddca3d0f8.d.ts +0 -0
  391. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pa-IN-json-e11565cbf1ccc3a53a3b.d.ts +0 -0
  392. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pa-IN-json-e11565cbf1ccc3a53a3b.d.ts.map +1 -0
  393. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pl-PL-json-843eb6fd0616dace3255.d.ts +0 -0
  394. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pl-PL-json-843eb6fd0616dace3255.d.ts.map +1 -0
  395. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pl-PL-json-c93ff741bb4aca4676e9.d.ts +0 -0
  396. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pt-BR-json-4ffa2f70c2863bca4f91.d.ts +0 -0
  397. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pt-BR-json-5b53e5bc1e2745a96718.d.ts +0 -0
  398. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pt-BR-json-e24132703235bd25ba2f.d.ts +0 -0
  399. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pt-BR-json-e24132703235bd25ba2f.d.ts.map +1 -0
  400. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pt-PT-json-0501abbca76504a7d110.d.ts +0 -0
  401. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pt-PT-json-0501abbca76504a7d110.d.ts.map +1 -0
  402. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pt-PT-json-4368eca89d2b2b3fb444.d.ts +0 -0
  403. package/types/packages/excalidraw/dist/excalidraw-assets/locales/pt-PT-json-9be05fd920a91a610e9f.d.ts +0 -0
  404. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ro-RO-json-1a69dd60c4c802d6dcfc.d.ts +0 -0
  405. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ro-RO-json-79dbe0225dfe06a010a6.d.ts +0 -0
  406. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ro-RO-json-79dbe0225dfe06a010a6.d.ts.map +1 -0
  407. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ru-RU-json-1d73c3f8bae6d1f3d779.d.ts +0 -0
  408. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ru-RU-json-1d73c3f8bae6d1f3d779.d.ts.map +1 -0
  409. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ru-RU-json-fbb4c10ed14cf28c501a.d.ts +0 -0
  410. package/types/packages/excalidraw/dist/excalidraw-assets/locales/si-LK-json-dfe5be591dc8bbe15cd1.d.ts +0 -0
  411. package/types/packages/excalidraw/dist/excalidraw-assets/locales/si-LK-json-dfe5be591dc8bbe15cd1.d.ts.map +1 -0
  412. package/types/packages/excalidraw/dist/excalidraw-assets/locales/si-LK-json-f21fa92c1726fda0c56b.d.ts +0 -0
  413. package/types/packages/excalidraw/dist/excalidraw-assets/locales/sk-SK-json-02bfb6c6ae8657ba7c10.d.ts +0 -0
  414. package/types/packages/excalidraw/dist/excalidraw-assets/locales/sk-SK-json-bd7dbe4c1e42c016fcb5.d.ts +0 -0
  415. package/types/packages/excalidraw/dist/excalidraw-assets/locales/sk-SK-json-bd7dbe4c1e42c016fcb5.d.ts.map +1 -0
  416. package/types/packages/excalidraw/dist/excalidraw-assets/locales/sl-SI-json-28142a1698858ae0423f.d.ts +0 -0
  417. package/types/packages/excalidraw/dist/excalidraw-assets/locales/sl-SI-json-85c2d64d8aa86fcd537e.d.ts +0 -0
  418. package/types/packages/excalidraw/dist/excalidraw-assets/locales/sl-SI-json-85c2d64d8aa86fcd537e.d.ts.map +1 -0
  419. package/types/packages/excalidraw/dist/excalidraw-assets/locales/sv-SE-json-355010df9dd71e3815aa.d.ts +0 -0
  420. package/types/packages/excalidraw/dist/excalidraw-assets/locales/sv-SE-json-74107fd3674c60fbe593.d.ts +0 -0
  421. package/types/packages/excalidraw/dist/excalidraw-assets/locales/sv-SE-json-74107fd3674c60fbe593.d.ts.map +1 -0
  422. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ta-IN-json-aa8488d4a7eba863eafa.d.ts +0 -0
  423. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ta-IN-json-c5b41d8c83aab479a2c6.d.ts +0 -0
  424. package/types/packages/excalidraw/dist/excalidraw-assets/locales/ta-IN-json-c5b41d8c83aab479a2c6.d.ts.map +1 -0
  425. package/types/packages/excalidraw/dist/excalidraw-assets/locales/tr-TR-json-0647ae69354eacfcfe79.d.ts +0 -0
  426. package/types/packages/excalidraw/dist/excalidraw-assets/locales/tr-TR-json-75f46a2579a01cf32ba7.d.ts +0 -0
  427. package/types/packages/excalidraw/dist/excalidraw-assets/locales/tr-TR-json-75f46a2579a01cf32ba7.d.ts.map +1 -0
  428. package/types/packages/excalidraw/dist/excalidraw-assets/locales/uk-UA-json-5c05732cd5338c4b299a.d.ts +0 -0
  429. package/types/packages/excalidraw/dist/excalidraw-assets/locales/uk-UA-json-f5b7b281f867489710d7.d.ts +0 -0
  430. package/types/packages/excalidraw/dist/excalidraw-assets/locales/uk-UA-json-f5b7b281f867489710d7.d.ts.map +1 -0
  431. package/types/packages/excalidraw/dist/excalidraw-assets/locales/vi-VN-json-13f82887207123a51a6a.d.ts +0 -0
  432. package/types/packages/excalidraw/dist/excalidraw-assets/locales/vi-VN-json-a56a1980b98f933cd604.d.ts +0 -0
  433. package/types/packages/excalidraw/dist/excalidraw-assets/locales/vi-VN-json-a56a1980b98f933cd604.d.ts.map +1 -0
  434. package/types/packages/excalidraw/dist/excalidraw-assets/locales/zh-CN-json-af7e4dc6eb1d97a22272.d.ts +0 -0
  435. package/types/packages/excalidraw/dist/excalidraw-assets/locales/zh-CN-json-af7e4dc6eb1d97a22272.d.ts.map +1 -0
  436. package/types/packages/excalidraw/dist/excalidraw-assets/locales/zh-CN-json-ccec3aebee2e2775a326.d.ts +0 -0
  437. package/types/packages/excalidraw/dist/excalidraw-assets/locales/zh-HK-json-2f216981a653096b6541.d.ts +0 -0
  438. package/types/packages/excalidraw/dist/excalidraw-assets/locales/zh-HK-json-d0511bd8842fe92cc42e.d.ts +0 -0
  439. package/types/packages/excalidraw/dist/excalidraw-assets/locales/zh-HK-json-d0511bd8842fe92cc42e.d.ts.map +1 -0
  440. package/types/packages/excalidraw/dist/excalidraw-assets/locales/zh-TW-json-43bef01a6edb6e4da73c.d.ts +0 -0
  441. package/types/packages/excalidraw/dist/excalidraw-assets/locales/zh-TW-json-43bef01a6edb6e4da73c.d.ts.map +1 -0
  442. package/types/packages/excalidraw/dist/excalidraw-assets/locales/zh-TW-json-d8becf928388ee71ea47.d.ts +0 -0
  443. package/types/packages/excalidraw/dist/excalidraw-assets/vendor-03e611bf80e4dd79b9dd.d.ts +0 -0
  444. package/types/packages/excalidraw/dist/excalidraw-assets/vendor-52b1f3361986b6c6a4fe.d.ts.map +1 -0
  445. package/types/packages/excalidraw/dist/excalidraw-assets/vendor-ddc717b6da3bea42bb67.d.ts +0 -0
  446. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ar-SA-json-c8fa653de4977a22dad1.d.ts → ar-SA-json-4bad5b5ff43b48c1e9a5.d.ts} +0 -0
  447. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{bg-BG-json-d7e517c7462119871c76.d.ts → ar-SA-json-684b5e25f971902bd933.d.ts} +0 -0
  448. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ar-SA-json-684b5e25f971902bd933.d.ts.map +1 -0
  449. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{bn-BD-json-02993b6dba9e7f115b53.d.ts → ar-SA-json-e18bf994a8a492e04c5b.d.ts} +0 -0
  450. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ca-ES-json-7aabb5b31e7a995a90e3.d.ts → bg-BG-json-c4822083b66facc7138b.d.ts} +0 -0
  451. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{cs-CZ-json-a9cc158d187424de71d7.d.ts → bg-BG-json-cbcbc92839539ec1816e.d.ts} +0 -0
  452. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{da-DK-json-81b641c9b272e91762b8.d.ts → bg-BG-json-d78c84e8962f5d754019.d.ts} +0 -0
  453. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/bg-BG-json-d78c84e8962f5d754019.d.ts.map +1 -0
  454. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{de-DE-json-e9f68b4434bb76d28151.d.ts → bn-BD-json-3724646eaa6735b9ebf7.d.ts} +0 -0
  455. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{el-GR-json-2bc44d5450554154e110.d.ts → bn-BD-json-79007d6cd3d09b6c1e82.d.ts} +0 -0
  456. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/bn-BD-json-79007d6cd3d09b6c1e82.d.ts.map +1 -0
  457. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{es-ES-json-9e5e962b234d2fa5aac2.d.ts → bn-BD-json-a19c78a329a982867a27.d.ts} +0 -0
  458. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{eu-ES-json-05199638b0e1e11061f3.d.ts → ca-ES-json-81a1896a4b8113466237.d.ts} +0 -0
  459. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{fa-IR-json-2a69e87cf2308b8e78f5.d.ts → ca-ES-json-84b33ecd3096b99533c1.d.ts} +0 -0
  460. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ca-ES-json-84b33ecd3096b99533c1.d.ts.map +1 -0
  461. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{fi-FI-json-6f0f0bcd3593bcc8930a.d.ts → ca-ES-json-8cc8fbe5df66d604ffc3.d.ts} +0 -0
  462. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{fr-FR-json-f53c7082a6f8691b7258.d.ts → cs-CZ-json-1d48380fd54bd715a21c.d.ts} +0 -0
  463. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/cs-CZ-json-1d48380fd54bd715a21c.d.ts.map +1 -0
  464. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{gl-ES-json-5295fdf24f032f998f75.d.ts → cs-CZ-json-bd241b199b5154d21ca1.d.ts} +0 -0
  465. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{he-IL-json-19fae6e424c8b418735d.d.ts → cs-CZ-json-dba21e0272554995c7d1.d.ts} +0 -0
  466. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{hi-IN-json-f04242b20685f34378a5.d.ts → da-DK-json-4e6dd750a31d070daec9.d.ts} +0 -0
  467. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{hu-HU-json-c8014a1b2a44d4885691.d.ts → da-DK-json-9dc062ac2b2aee3ad4ec.d.ts} +0 -0
  468. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/da-DK-json-9dc062ac2b2aee3ad4ec.d.ts.map +1 -0
  469. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{id-ID-json-bcd3ce43f1dbefe3f4d0.d.ts → da-DK-json-bfbe643a377800d3d122.d.ts} +0 -0
  470. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{it-IT-json-946dc662ecab93b77e69.d.ts → de-DE-json-2d48c0ec0901cee81272.d.ts} +0 -0
  471. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/de-DE-json-2d48c0ec0901cee81272.d.ts.map +1 -0
  472. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ja-JP-json-77b3461742458e757b59.d.ts → de-DE-json-d0676faf8f1e90d3ce34.d.ts} +0 -0
  473. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{kab-KAB-json-5e733b113476a350e900.d.ts → de-DE-json-fe631cebdb2da354de25.d.ts} +0 -0
  474. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{kk-KZ-json-5ec5044574589896438e.d.ts → el-GR-json-71dd4a99c18b08517ea4.d.ts} +0 -0
  475. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ko-KR-json-09de6762eea271167b56.d.ts → el-GR-json-8ec22bd0cbf376e3ba5d.d.ts} +0 -0
  476. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/el-GR-json-8ec22bd0cbf376e3ba5d.d.ts.map +1 -0
  477. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{lt-LT-json-a17971ff33b8929e96d3.d.ts → el-GR-json-9185ceab00e1598333d4.d.ts} +0 -0
  478. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{lv-LV-json-2d1a7d044c33d030ecca.d.ts → es-ES-json-5dd577ba17baf0f4382c.d.ts} +0 -0
  479. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/es-ES-json-5dd577ba17baf0f4382c.d.ts.map +1 -0
  480. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{mr-IN-json-ed8cde2f50a5f3c08e85.d.ts → es-ES-json-78ffeeedb2103c8e9e15.d.ts} +0 -0
  481. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{my-MM-json-600fc533d1a1c8d3e2f9.d.ts → es-ES-json-a2870461506d73f41a72.d.ts} +0 -0
  482. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{nb-NO-json-c7c63cfd529a92ac3510.d.ts → eu-ES-json-3530634f7d5a3db297de.d.ts} +0 -0
  483. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{nl-NL-json-7e7200dded88b465781e.d.ts → eu-ES-json-9ba2e12372db6b5be813.d.ts} +0 -0
  484. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/eu-ES-json-9ba2e12372db6b5be813.d.ts.map +1 -0
  485. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{nn-NO-json-d654941277fcbace33bf.d.ts → eu-ES-json-cb70f440de0a76f6d69b.d.ts} +0 -0
  486. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{oc-FR-json-2d347b7f54a867a5478f.d.ts → fa-IR-json-19fa55327f56b34b74d3.d.ts} +0 -0
  487. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{pa-IN-json-63518bb328bf8b92790c.d.ts → fa-IR-json-66f5b4a41dc3aa7c8c45.d.ts} +0 -0
  488. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{pl-PL-json-92de366ba93223fa3d6a.d.ts → fa-IR-json-9866fde07b07d55f2cb9.d.ts} +0 -0
  489. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/fa-IR-json-9866fde07b07d55f2cb9.d.ts.map +1 -0
  490. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{pt-BR-json-5e4c8cd83b785ed859c2.d.ts → fi-FI-json-2dcf087c4ff34b8a8ad7.d.ts} +0 -0
  491. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/fi-FI-json-2dcf087c4ff34b8a8ad7.d.ts.map +1 -0
  492. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{pt-PT-json-a7f89a1c6f1c380141e5.d.ts → fi-FI-json-50208311f1e4fc7cde1d.d.ts} +0 -0
  493. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ro-RO-json-6903d070f824f8b91709.d.ts → fi-FI-json-7885764c835895664e0b.d.ts} +0 -0
  494. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ru-RU-json-110d8aec7823819bf4e3.d.ts → fr-FR-json-aa188d6228335106e7a0.d.ts} +0 -0
  495. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{si-LK-json-ad2dff740d16a23684ff.d.ts → fr-FR-json-db1925f49529ff2c6ec1.d.ts} +0 -0
  496. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{sk-SK-json-209333495d21be527f89.d.ts → fr-FR-json-e4bbc872fed09a689b27.d.ts} +0 -0
  497. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/fr-FR-json-e4bbc872fed09a689b27.d.ts.map +1 -0
  498. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{sl-SI-json-76bdeb34579c5b1f944f.d.ts → gl-ES-json-4ab7103bd7905741cf7e.d.ts} +0 -0
  499. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/gl-ES-json-4ab7103bd7905741cf7e.d.ts.map +1 -0
  500. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{sv-SE-json-6e768d07fff4e3ed6560.d.ts → gl-ES-json-72548540dc6a9c01b240.d.ts} +0 -0
  501. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{ta-IN-json-059a459deba6d6230393.d.ts → gl-ES-json-ab9c245372378f5f8c9b.d.ts} +0 -0
  502. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{tr-TR-json-7cc28f1f798ef2dd9864.d.ts → he-IL-json-7bfd6ca43596df3a84a1.d.ts} +0 -0
  503. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{uk-UA-json-80b2990c3144c6bb1270.d.ts → he-IL-json-a62ed6086276dffb71fd.d.ts} +0 -0
  504. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{vi-VN-json-670ecb0ad40c0453bdfd.d.ts → he-IL-json-abac6b158c54984aecba.d.ts} +0 -0
  505. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/he-IL-json-abac6b158c54984aecba.d.ts.map +1 -0
  506. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{zh-CN-json-26caa1a6379860230513.d.ts → hi-IN-json-311afde0e51db172b1b4.d.ts} +0 -0
  507. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{zh-HK-json-179f6dc61b14b96215fa.d.ts → hi-IN-json-3aba9d37f6dae9ca2445.d.ts} +0 -0
  508. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/hi-IN-json-3aba9d37f6dae9ca2445.d.ts.map +1 -0
  509. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/{zh-TW-json-2aeeb73d79793ee69bfc.d.ts → hi-IN-json-a929ddf2945cc4079a77.d.ts} +0 -0
  510. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/hu-HU-json-8d604fcc349f93bc4440.d.ts +2 -0
  511. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/hu-HU-json-8d604fcc349f93bc4440.d.ts.map +1 -0
  512. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/hu-HU-json-aaa54da52ca5ee068466.d.ts +2 -0
  513. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/hu-HU-json-f6436471ba8cccff3ac4.d.ts +2 -0
  514. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/id-ID-json-6d9b771568900ad6f055.d.ts +2 -0
  515. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/id-ID-json-6d9b771568900ad6f055.d.ts.map +1 -0
  516. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/id-ID-json-9328a35688d0537730ae.d.ts +2 -0
  517. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/id-ID-json-fbee4b09ecbf4791e1e0.d.ts +2 -0
  518. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/it-IT-json-508f57463d4037918ebb.d.ts +2 -0
  519. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/it-IT-json-7086cd6c6f1f61016ba1.d.ts +2 -0
  520. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/it-IT-json-7086cd6c6f1f61016ba1.d.ts.map +1 -0
  521. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/it-IT-json-b0eae328c3a49c21699f.d.ts +2 -0
  522. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ja-JP-json-512054894cd1fae408e3.d.ts +2 -0
  523. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ja-JP-json-c670cda6d6c171611c79.d.ts +2 -0
  524. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ja-JP-json-d864fb849b2a3874b290.d.ts +2 -0
  525. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ja-JP-json-d864fb849b2a3874b290.d.ts.map +1 -0
  526. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/kab-KAB-json-396d5e8936a8362b536c.d.ts +2 -0
  527. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/kab-KAB-json-c69f8a1079a411de837c.d.ts +2 -0
  528. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/kab-KAB-json-c69f8a1079a411de837c.d.ts.map +1 -0
  529. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/kab-KAB-json-dd04a087066d4715e744.d.ts +2 -0
  530. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/kk-KZ-json-7c301df4020cd7c670e2.d.ts +2 -0
  531. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/kk-KZ-json-8c7f34edcdac22c11c72.d.ts +2 -0
  532. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/kk-KZ-json-8c7f34edcdac22c11c72.d.ts.map +1 -0
  533. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/kk-KZ-json-e7ce817c4e68640b3099.d.ts +2 -0
  534. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ko-KR-json-8b9fc794d8a77b6dffc4.d.ts +2 -0
  535. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ko-KR-json-c80065dfa01e02f28695.d.ts +2 -0
  536. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ko-KR-json-c80065dfa01e02f28695.d.ts.map +1 -0
  537. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ko-KR-json-d6850be7bac8fc43af84.d.ts +2 -0
  538. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ku-TR-json-9837b398f7df5f1bb711.d.ts +2 -0
  539. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/lt-LT-json-0c85f6ccfc05406cc1b7.d.ts +2 -0
  540. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/lt-LT-json-263c5629ddf0ee7d7572.d.ts +2 -0
  541. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/lt-LT-json-edaae0abc84fb205ee70.d.ts +2 -0
  542. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/lt-LT-json-edaae0abc84fb205ee70.d.ts.map +1 -0
  543. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/lv-LV-json-21cc252dcf4524c98e55.d.ts +2 -0
  544. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/lv-LV-json-21cc252dcf4524c98e55.d.ts.map +1 -0
  545. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/lv-LV-json-44a18e46e8c68310c7c8.d.ts +2 -0
  546. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/lv-LV-json-4c20b8e2ee74634c57ae.d.ts +2 -0
  547. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/mr-IN-json-165ab79d55f507272fd4.d.ts +2 -0
  548. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/mr-IN-json-b0cd94322c2b39884d52.d.ts +2 -0
  549. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/mr-IN-json-d28b9664c21ee08d79eb.d.ts +2 -0
  550. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/mr-IN-json-d28b9664c21ee08d79eb.d.ts.map +1 -0
  551. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/my-MM-json-098977a1778f20f3a53c.d.ts +2 -0
  552. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/my-MM-json-56d51a30e815283e7260.d.ts +2 -0
  553. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/my-MM-json-56d51a30e815283e7260.d.ts.map +1 -0
  554. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/my-MM-json-b0c8ffa53fa7c9f7fc4d.d.ts +2 -0
  555. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/nb-NO-json-216bb67091fd4a2e70e6.d.ts +2 -0
  556. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/nb-NO-json-3b7796c103baa51271a9.d.ts +2 -0
  557. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/nb-NO-json-827603cac737fb4bb00f.d.ts +2 -0
  558. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/nb-NO-json-827603cac737fb4bb00f.d.ts.map +1 -0
  559. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/nl-NL-json-820135e0dcbb62d8f23c.d.ts +2 -0
  560. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/nl-NL-json-9c5c4b7bfbfe3328e561.d.ts +2 -0
  561. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/nl-NL-json-9c5c4b7bfbfe3328e561.d.ts.map +1 -0
  562. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/nl-NL-json-f2b834e213d9831504ac.d.ts +2 -0
  563. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/nn-NO-json-059b39da1c7b19e93db6.d.ts +2 -0
  564. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/nn-NO-json-82be69040c1ec437138f.d.ts +2 -0
  565. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/nn-NO-json-cb21e50c1afeb6a8f01d.d.ts +2 -0
  566. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/nn-NO-json-cb21e50c1afeb6a8f01d.d.ts.map +1 -0
  567. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/oc-FR-json-54a63799c742875f8b9b.d.ts +2 -0
  568. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/oc-FR-json-bec2ee705e7d3980fd61.d.ts +2 -0
  569. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/oc-FR-json-bec2ee705e7d3980fd61.d.ts.map +1 -0
  570. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/oc-FR-json-e98b96eea154dfcded8b.d.ts +2 -0
  571. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pa-IN-json-189c7e5cad9e781f0ce5.d.ts +2 -0
  572. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pa-IN-json-189c7e5cad9e781f0ce5.d.ts.map +1 -0
  573. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pa-IN-json-bb695a155f66b1c9385b.d.ts +2 -0
  574. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pa-IN-json-e535caa54102fbcee393.d.ts +2 -0
  575. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pl-PL-json-73e6bd0c53922c9c71ba.d.ts +2 -0
  576. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pl-PL-json-9cc770276a511a05e638.d.ts +2 -0
  577. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pl-PL-json-9cc770276a511a05e638.d.ts.map +1 -0
  578. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pl-PL-json-c802b8e3353ee92b1297.d.ts +2 -0
  579. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pt-BR-json-395becbd0a0762796d55.d.ts +2 -0
  580. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pt-BR-json-788b2c323ae4afd36853.d.ts +2 -0
  581. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pt-BR-json-788b2c323ae4afd36853.d.ts.map +1 -0
  582. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pt-BR-json-f8d16d6d47abde7f52c8.d.ts +2 -0
  583. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pt-PT-json-28b0243edfd2d1188d78.d.ts +2 -0
  584. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pt-PT-json-4b8554cd18248130c618.d.ts +2 -0
  585. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pt-PT-json-4f16b87e256eb838c91a.d.ts +2 -0
  586. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/pt-PT-json-4f16b87e256eb838c91a.d.ts.map +1 -0
  587. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ro-RO-json-0b6a9ed696ac7c243e8d.d.ts +2 -0
  588. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ro-RO-json-718b6921865260332b51.d.ts +2 -0
  589. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ro-RO-json-9ac079b4af3b20377160.d.ts +2 -0
  590. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ro-RO-json-9ac079b4af3b20377160.d.ts.map +1 -0
  591. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ru-RU-json-a6c6479bfe4febbbc162.d.ts +2 -0
  592. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ru-RU-json-eda247a0b10c11a51eec.d.ts +2 -0
  593. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ru-RU-json-eda247a0b10c11a51eec.d.ts.map +1 -0
  594. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ru-RU-json-f941229aeb3c961f6afe.d.ts +2 -0
  595. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/si-LK-json-2f1de88a189ba6ba696d.d.ts +2 -0
  596. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/si-LK-json-de30e8b93b04c9aa5708.d.ts +2 -0
  597. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/si-LK-json-ee3083905b0cf879022d.d.ts +2 -0
  598. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/si-LK-json-ee3083905b0cf879022d.d.ts.map +1 -0
  599. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/sk-SK-json-03a80aeb3e09f77b1be6.d.ts +2 -0
  600. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/sk-SK-json-03a80aeb3e09f77b1be6.d.ts.map +1 -0
  601. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/sk-SK-json-1c1cc59d67308156afce.d.ts +2 -0
  602. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/sk-SK-json-733bf7834531da06e409.d.ts +2 -0
  603. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/sl-SI-json-302c47db8bdde83cfd9a.d.ts +2 -0
  604. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/sl-SI-json-55f372eebf814a422031.d.ts +2 -0
  605. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/sl-SI-json-55f372eebf814a422031.d.ts.map +1 -0
  606. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/sl-SI-json-eaf07f8494e7b5091add.d.ts +2 -0
  607. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/sv-SE-json-79dcebebf235b23c717e.d.ts +2 -0
  608. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/sv-SE-json-a3fbe43174a0b8c11dbe.d.ts +2 -0
  609. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/sv-SE-json-ca85dde4f9c34d5ee346.d.ts +2 -0
  610. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/sv-SE-json-ca85dde4f9c34d5ee346.d.ts.map +1 -0
  611. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ta-IN-json-5212782b6c72fafb8ec2.d.ts +2 -0
  612. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ta-IN-json-97dde0a466b7ef9a293c.d.ts +2 -0
  613. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ta-IN-json-f9d1822384bc4ce086b6.d.ts +2 -0
  614. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/ta-IN-json-f9d1822384bc4ce086b6.d.ts.map +1 -0
  615. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/tr-TR-json-30a4d84bda3152292dbe.d.ts +2 -0
  616. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/tr-TR-json-30a4d84bda3152292dbe.d.ts.map +1 -0
  617. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/tr-TR-json-d387c2ab9f0dabccb94c.d.ts +2 -0
  618. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/tr-TR-json-f38f946cfbce79e9e21b.d.ts +2 -0
  619. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/uk-UA-json-45d77feb9074985d4877.d.ts +2 -0
  620. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/uk-UA-json-9b412ee83d32be90b91b.d.ts +2 -0
  621. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/uk-UA-json-b271ae2bf2e210aa582b.d.ts +2 -0
  622. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/uk-UA-json-b271ae2bf2e210aa582b.d.ts.map +1 -0
  623. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/vi-VN-json-5d796333807e34aee311.d.ts +2 -0
  624. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/vi-VN-json-9a1f8e4ce0b77e05baa7.d.ts +2 -0
  625. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/vi-VN-json-9a1f8e4ce0b77e05baa7.d.ts.map +1 -0
  626. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/vi-VN-json-b122b560b6c0d519c143.d.ts +2 -0
  627. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/zh-CN-json-043751132a42a13d3de4.d.ts +2 -0
  628. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/zh-CN-json-29856d6541bf2cbd6aea.d.ts +2 -0
  629. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/zh-CN-json-29856d6541bf2cbd6aea.d.ts.map +1 -0
  630. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/zh-CN-json-9089c24ecdc4c4b7c5cf.d.ts +2 -0
  631. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/zh-HK-json-64105c4a0af0047b4d46.d.ts +2 -0
  632. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/zh-HK-json-66e5d1f5e052d9b895e2.d.ts +2 -0
  633. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/zh-HK-json-8bb0f0928ccbce98f995.d.ts +2 -0
  634. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/zh-HK-json-8bb0f0928ccbce98f995.d.ts.map +1 -0
  635. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/zh-TW-json-517b39d1a3184844b4d7.d.ts +2 -0
  636. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/zh-TW-json-517b39d1a3184844b4d7.d.ts.map +1 -0
  637. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/zh-TW-json-68624f1171bf9f71bf25.d.ts +2 -0
  638. package/types/packages/excalidraw/dist/excalidraw-assets-dev/locales/zh-TW-json-a05cd2023060266e8e0e.d.ts +2 -0
  639. package/types/packages/excalidraw/dist/{excalidraw-assets/locales/ca-ES-json-32cf66a0dfdbbafb6903.d.ts → excalidraw-assets-dev/vendor-2811fad3dc3b42ee3357.d.ts} +0 -0
  640. package/types/packages/excalidraw/dist/excalidraw-assets-dev/vendor-c0592035c3911af79359.d.ts.map +1 -0
  641. package/types/packages/excalidraw/dist/{excalidraw-assets/locales/el-GR-json-74f57c0f8b11ac1b6dde.d.ts → excalidraw-assets-dev/vendor-e6df8519da951026ff69.d.ts} +0 -0
  642. package/types/packages/excalidraw/dist/excalidraw.development.d.ts.map +1 -0
  643. package/types/packages/excalidraw/dist/excalidraw.production.min.d.ts.map +1 -0
  644. package/types/packages/excalidraw/entry.d.ts.map +1 -0
  645. package/types/packages/excalidraw/env.d.ts.map +1 -0
  646. package/types/packages/excalidraw/example/App.d.ts +2 -1
  647. package/types/packages/excalidraw/example/App.d.ts.map +1 -0
  648. package/types/packages/excalidraw/example/index.d.ts.map +1 -0
  649. package/types/packages/excalidraw/example/initialData.d.ts.map +1 -0
  650. package/types/packages/excalidraw/example/public/bundle.d.ts +4 -0
  651. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/ar-SA-json-422720aeae76b43f4e34.d.ts +2 -0
  652. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/bg-BG-json-ae0d3ff13ac91abf996f.d.ts +2 -0
  653. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/bn-BD-json-32cdc6ced24b13f36bbc.d.ts +2 -0
  654. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/ca-ES-json-a49f03ca494b1ca8ed9b.d.ts +2 -0
  655. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/cs-CZ-json-2f07dbffe26aa12a024c.d.ts +2 -0
  656. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/da-DK-json-6ae97a313d4264946e31.d.ts +2 -0
  657. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/de-DE-json-c80daaed2a67b2f15223.d.ts +2 -0
  658. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/el-GR-json-51bfd33c7f83bbd7f6db.d.ts +2 -0
  659. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/es-ES-json-8b67d656368fbf73428a.d.ts +2 -0
  660. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/eu-ES-json-5e56699d66f76750fe41.d.ts +2 -0
  661. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/fa-IR-json-d0c9c049db458a8ca59b.d.ts +2 -0
  662. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/fi-FI-json-1ae181bce5d26c50d814.d.ts +2 -0
  663. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/fr-FR-json-0956ba0a6dca32f13c7c.d.ts +2 -0
  664. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/gl-ES-json-1d1f4fc2134412b9c96a.d.ts +2 -0
  665. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/he-IL-json-1f78737fd8e123db1288.d.ts +2 -0
  666. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/hi-IN-json-5be1ea05cc7ee8432cb8.d.ts +2 -0
  667. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/hu-HU-json-107000c3f76466f229a2.d.ts +2 -0
  668. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/id-ID-json-f782bb0be319848f497f.d.ts +2 -0
  669. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/it-IT-json-c10398560de544c3d260.d.ts +2 -0
  670. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/ja-JP-json-e6171aca80f24923fe78.d.ts +2 -0
  671. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/kab-KAB-json-24afe8bf173c1ff2b0fb.d.ts +2 -0
  672. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/kk-KZ-json-ebcf4e820011c8b8947f.d.ts +2 -0
  673. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/ko-KR-json-8ea51a4ccc4dcc5ad697.d.ts +2 -0
  674. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/lt-LT-json-5bbbf30868522c7bc767.d.ts +2 -0
  675. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/lv-LV-json-b098759876ad0f66ffeb.d.ts +2 -0
  676. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/mr-IN-json-095d9331dce2f1e28fe2.d.ts +2 -0
  677. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/my-MM-json-6d5eac0f31d26c9151d0.d.ts +2 -0
  678. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/nb-NO-json-3212c5604c8178216a20.d.ts +2 -0
  679. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/nl-NL-json-a0917464058630804509.d.ts +2 -0
  680. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/nn-NO-json-acadf455071816b2e1ed.d.ts +2 -0
  681. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/oc-FR-json-09009791e68cc185268f.d.ts +2 -0
  682. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/pa-IN-json-0b4a87b2f3a174822e14.d.ts +2 -0
  683. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/pl-PL-json-e9f93bc2be954bd5cd6f.d.ts +2 -0
  684. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/pt-BR-json-1d39c9c817cafb4df7bc.d.ts +2 -0
  685. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/pt-PT-json-bf4365a3b12692290c60.d.ts +2 -0
  686. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/ro-RO-json-b5a994918893bdb7f12a.d.ts +2 -0
  687. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/ru-RU-json-4ca260298f98f8b9d64b.d.ts +2 -0
  688. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/si-LK-json-036efbecc1473ea2654c.d.ts +2 -0
  689. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/sk-SK-json-01a56bd743bfafa0ea7f.d.ts +2 -0
  690. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/sl-SI-json-7c07dba5b6bcb7072b72.d.ts +2 -0
  691. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/sv-SE-json-344d32171a6dcaa49e4b.d.ts +2 -0
  692. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/ta-IN-json-972a32d06dc37eae0265.d.ts +2 -0
  693. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/tr-TR-json-fe7706a48e8c387f0efa.d.ts +2 -0
  694. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/uk-UA-json-3530ec9aa3e0e74258f2.d.ts +2 -0
  695. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/vi-VN-json-8787bf8cf6bfb42f8db7.d.ts +2 -0
  696. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/zh-CN-json-973f54c2e185ded6c3aa.d.ts +2 -0
  697. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/zh-HK-json-327e43ba85bde53f4508.d.ts +2 -0
  698. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/locales/zh-TW-json-76cff34960ab6a8ef9ae.d.ts +2 -0
  699. package/types/packages/excalidraw/example/public/excalidraw-assets-dev/vendor-045ba36ab51d57ee5669.d.ts +0 -0
  700. package/types/packages/excalidraw/example/public/excalidraw.development.d.ts +4 -0
  701. package/types/packages/excalidraw/example/sidebar/ExampleSidebar.d.ts +5 -0
  702. package/types/packages/excalidraw/example/sidebar/Sidebar.d.ts.map +1 -0
  703. package/types/packages/excalidraw/index.d.ts +1 -0
  704. package/types/packages/excalidraw/index.d.ts.map +1 -0
  705. package/types/packages/excalidraw/main.d.ts.map +1 -0
  706. package/types/packages/excalidraw/publicPath.d.ts.map +1 -0
  707. package/types/packages/excalidraw/webpack.dev-server.config.d.ts.map +1 -0
  708. package/types/packages/excalidraw/webpack.dev.config.d.ts.map +1 -0
  709. package/types/packages/excalidraw/webpack.prod.config.d.ts.map +1 -0
  710. package/types/packages/utils.d.ts +4 -1
  711. package/types/packages/utils.d.ts.map +1 -0
  712. package/types/points.d.ts +2 -1
  713. package/types/points.d.ts.map +1 -0
  714. package/types/polyfill.d.ts +2 -0
  715. package/types/random.d.ts.map +1 -0
  716. package/types/renderer/renderElement.d.ts.map +1 -0
  717. package/types/renderer/renderScene.d.ts +18 -2
  718. package/types/renderer/renderScene.d.ts.map +1 -0
  719. package/types/renderer/roundRect.d.ts.map +1 -0
  720. package/types/scene/Scene.d.ts.map +1 -0
  721. package/types/scene/comparisons.d.ts.map +1 -0
  722. package/types/scene/export.d.ts.map +1 -0
  723. package/types/scene/index.d.ts.map +1 -0
  724. package/types/scene/scroll.d.ts.map +1 -0
  725. package/types/scene/scrollbars.d.ts.map +1 -0
  726. package/types/scene/selection.d.ts.map +1 -0
  727. package/types/scene/types.d.ts.map +1 -0
  728. package/types/scene/zoom.d.ts.map +1 -0
  729. package/types/shapes.d.ts.map +1 -0
  730. package/types/types.d.ts +10 -4
  731. package/types/types.d.ts.map +1 -0
  732. package/types/utils.d.ts.map +1 -0
  733. package/types/zindex.d.ts.map +1 -0
  734. package/dist/excalidraw-assets/locales/ar-SA-json-4ff31c0432fe4c84d726.js +0 -1
  735. package/dist/excalidraw-assets/locales/bg-BG-json-1c6eb789a5c90a61edf8.js +0 -1
  736. package/dist/excalidraw-assets/locales/bn-BD-json-aa99c5a33f005fb00c6b.js +0 -1
  737. package/dist/excalidraw-assets/locales/ca-ES-json-32cf66a0dfdbbafb6903.js +0 -1
  738. package/dist/excalidraw-assets/locales/cs-CZ-json-304d08cac870aa0684ec.js +0 -1
  739. package/dist/excalidraw-assets/locales/da-DK-json-80c7153473e1427a9a3b.js +0 -1
  740. package/dist/excalidraw-assets/locales/de-DE-json-9b88838b2648d7d61f1b.js +0 -1
  741. package/dist/excalidraw-assets/locales/el-GR-json-74f57c0f8b11ac1b6dde.js +0 -1
  742. package/dist/excalidraw-assets/locales/es-ES-json-ffb4e65453db2f3058d4.js +0 -1
  743. package/dist/excalidraw-assets/locales/eu-ES-json-a61838a778c9eacb61ec.js +0 -1
  744. package/dist/excalidraw-assets/locales/fa-IR-json-2d0cb1044744ed8e4139.js +0 -1
  745. package/dist/excalidraw-assets/locales/fi-FI-json-32bcb6481756ef8af590.js +0 -1
  746. package/dist/excalidraw-assets/locales/fr-FR-json-935424b03b86c1d82dcd.js +0 -1
  747. package/dist/excalidraw-assets/locales/gl-ES-json-5b417484d91976bce190.js +0 -1
  748. package/dist/excalidraw-assets/locales/he-IL-json-3f5bfefb1ad0baf19b6c.js +0 -1
  749. package/dist/excalidraw-assets/locales/hi-IN-json-71a38dbb2202baec2bad.js +0 -1
  750. package/dist/excalidraw-assets/locales/hu-HU-json-e1275f2b1e6ae6ef4427.js +0 -1
  751. package/dist/excalidraw-assets/locales/id-ID-json-da38cd847aaf195c3c20.js +0 -1
  752. package/dist/excalidraw-assets/locales/it-IT-json-10923c290e23bd31a5b4.js +0 -1
  753. package/dist/excalidraw-assets/locales/ja-JP-json-4c357f8206b88dc44840.js +0 -1
  754. package/dist/excalidraw-assets/locales/kab-KAB-json-8303afee283a95237f2b.js +0 -1
  755. package/dist/excalidraw-assets/locales/kk-KZ-json-ccf0876179807d1d685a.js +0 -1
  756. package/dist/excalidraw-assets/locales/ko-KR-json-f27d159b2556809076aa.js +0 -1
  757. package/dist/excalidraw-assets/locales/lt-LT-json-7277ad8dae6d3e6607b3.js +0 -1
  758. package/dist/excalidraw-assets/locales/lv-LV-json-cc5e03ed2a09f8f8b60b.js +0 -1
  759. package/dist/excalidraw-assets/locales/mr-IN-json-cb316f30d7b40d3e6766.js +0 -1
  760. package/dist/excalidraw-assets/locales/my-MM-json-5dcc8e9cb97a4aa1d8bc.js +0 -1
  761. package/dist/excalidraw-assets/locales/nb-NO-json-61192c4af6e2231d38ae.js +0 -1
  762. package/dist/excalidraw-assets/locales/nl-NL-json-861ac93c048b5296b791.js +0 -1
  763. package/dist/excalidraw-assets/locales/nn-NO-json-808362c0cd4eccb6a885.js +0 -1
  764. package/dist/excalidraw-assets/locales/oc-FR-json-d5706569ab4023f94c66.js +0 -1
  765. package/dist/excalidraw-assets/locales/pa-IN-json-eb38ce8bfc1b974c1455.js +0 -1
  766. package/dist/excalidraw-assets/locales/pl-PL-json-55d8dd8a44917364ef63.js +0 -1
  767. package/dist/excalidraw-assets/locales/pt-BR-json-686219f43cd76123b7fa.js +0 -1
  768. package/dist/excalidraw-assets/locales/pt-PT-json-be4502ca3a1250845c39.js +0 -1
  769. package/dist/excalidraw-assets/locales/ro-RO-json-232ea1e0c18745ec6ed9.js +0 -1
  770. package/dist/excalidraw-assets/locales/ru-RU-json-ce5fedd8812aa76a0b41.js +0 -1
  771. package/dist/excalidraw-assets/locales/sk-SK-json-537132ec043d4db7f328.js +0 -1
  772. package/dist/excalidraw-assets/locales/sl-SI-json-b69c9fd9b85dac1310c6.js +0 -1
  773. package/dist/excalidraw-assets/locales/sv-SE-json-9a8520b202b7181625cf.js +0 -1
  774. package/dist/excalidraw-assets/locales/ta-IN-json-15175d03785f7a482568.js +0 -1
  775. package/dist/excalidraw-assets/locales/tr-TR-json-c53ae37e848043dd0b89.js +0 -1
  776. package/dist/excalidraw-assets/locales/uk-UA-json-15fda426e55236408ef9.js +0 -1
  777. package/dist/excalidraw-assets/locales/vi-VN-json-5c276b534d762658589c.js +0 -1
  778. package/dist/excalidraw-assets/locales/zh-CN-json-0e3236ea93581e6ac2d3.js +0 -1
  779. package/dist/excalidraw-assets/locales/zh-HK-json-9e8b36ecb4c8399449b1.js +0 -1
  780. package/dist/excalidraw-assets/locales/zh-TW-json-441a30840e0721d7f2e2.js +0 -1
  781. package/dist/excalidraw-assets/vendor-52b1f3361986b6c6a4fe.js +0 -2
  782. package/dist/excalidraw-assets-dev/locales/ar-SA-json-c8fa653de4977a22dad1.js +0 -22
  783. package/dist/excalidraw-assets-dev/locales/bg-BG-json-d7e517c7462119871c76.js +0 -22
  784. package/dist/excalidraw-assets-dev/locales/bn-BD-json-02993b6dba9e7f115b53.js +0 -22
  785. package/dist/excalidraw-assets-dev/locales/ca-ES-json-7aabb5b31e7a995a90e3.js +0 -22
  786. package/dist/excalidraw-assets-dev/locales/cs-CZ-json-a9cc158d187424de71d7.js +0 -22
  787. package/dist/excalidraw-assets-dev/locales/da-DK-json-81b641c9b272e91762b8.js +0 -22
  788. package/dist/excalidraw-assets-dev/locales/de-DE-json-e9f68b4434bb76d28151.js +0 -22
  789. package/dist/excalidraw-assets-dev/locales/el-GR-json-2bc44d5450554154e110.js +0 -22
  790. package/dist/excalidraw-assets-dev/locales/es-ES-json-9e5e962b234d2fa5aac2.js +0 -22
  791. package/dist/excalidraw-assets-dev/locales/eu-ES-json-05199638b0e1e11061f3.js +0 -22
  792. package/dist/excalidraw-assets-dev/locales/fa-IR-json-2a69e87cf2308b8e78f5.js +0 -22
  793. package/dist/excalidraw-assets-dev/locales/fi-FI-json-6f0f0bcd3593bcc8930a.js +0 -22
  794. package/dist/excalidraw-assets-dev/locales/fr-FR-json-f53c7082a6f8691b7258.js +0 -22
  795. package/dist/excalidraw-assets-dev/locales/gl-ES-json-5295fdf24f032f998f75.js +0 -22
  796. package/dist/excalidraw-assets-dev/locales/he-IL-json-19fae6e424c8b418735d.js +0 -22
  797. package/dist/excalidraw-assets-dev/locales/hi-IN-json-f04242b20685f34378a5.js +0 -22
  798. package/dist/excalidraw-assets-dev/locales/hu-HU-json-c8014a1b2a44d4885691.js +0 -22
  799. package/dist/excalidraw-assets-dev/locales/id-ID-json-bcd3ce43f1dbefe3f4d0.js +0 -22
  800. package/dist/excalidraw-assets-dev/locales/it-IT-json-946dc662ecab93b77e69.js +0 -22
  801. package/dist/excalidraw-assets-dev/locales/ja-JP-json-77b3461742458e757b59.js +0 -22
  802. package/dist/excalidraw-assets-dev/locales/kab-KAB-json-5e733b113476a350e900.js +0 -22
  803. package/dist/excalidraw-assets-dev/locales/kk-KZ-json-5ec5044574589896438e.js +0 -22
  804. package/dist/excalidraw-assets-dev/locales/ko-KR-json-09de6762eea271167b56.js +0 -22
  805. package/dist/excalidraw-assets-dev/locales/lt-LT-json-a17971ff33b8929e96d3.js +0 -22
  806. package/dist/excalidraw-assets-dev/locales/lv-LV-json-2d1a7d044c33d030ecca.js +0 -22
  807. package/dist/excalidraw-assets-dev/locales/mr-IN-json-ed8cde2f50a5f3c08e85.js +0 -22
  808. package/dist/excalidraw-assets-dev/locales/my-MM-json-600fc533d1a1c8d3e2f9.js +0 -22
  809. package/dist/excalidraw-assets-dev/locales/nb-NO-json-c7c63cfd529a92ac3510.js +0 -22
  810. package/dist/excalidraw-assets-dev/locales/nl-NL-json-7e7200dded88b465781e.js +0 -22
  811. package/dist/excalidraw-assets-dev/locales/nn-NO-json-d654941277fcbace33bf.js +0 -22
  812. package/dist/excalidraw-assets-dev/locales/oc-FR-json-2d347b7f54a867a5478f.js +0 -22
  813. package/dist/excalidraw-assets-dev/locales/pa-IN-json-63518bb328bf8b92790c.js +0 -22
  814. package/dist/excalidraw-assets-dev/locales/pl-PL-json-92de366ba93223fa3d6a.js +0 -22
  815. package/dist/excalidraw-assets-dev/locales/pt-BR-json-5e4c8cd83b785ed859c2.js +0 -22
  816. package/dist/excalidraw-assets-dev/locales/pt-PT-json-a7f89a1c6f1c380141e5.js +0 -22
  817. package/dist/excalidraw-assets-dev/locales/ro-RO-json-6903d070f824f8b91709.js +0 -22
  818. package/dist/excalidraw-assets-dev/locales/ru-RU-json-110d8aec7823819bf4e3.js +0 -22
  819. package/dist/excalidraw-assets-dev/locales/si-LK-json-ad2dff740d16a23684ff.js +0 -22
  820. package/dist/excalidraw-assets-dev/locales/sk-SK-json-209333495d21be527f89.js +0 -22
  821. package/dist/excalidraw-assets-dev/locales/sl-SI-json-76bdeb34579c5b1f944f.js +0 -22
  822. package/dist/excalidraw-assets-dev/locales/sv-SE-json-6e768d07fff4e3ed6560.js +0 -22
  823. package/dist/excalidraw-assets-dev/locales/ta-IN-json-059a459deba6d6230393.js +0 -22
  824. package/dist/excalidraw-assets-dev/locales/tr-TR-json-7cc28f1f798ef2dd9864.js +0 -22
  825. package/dist/excalidraw-assets-dev/locales/uk-UA-json-80b2990c3144c6bb1270.js +0 -22
  826. package/dist/excalidraw-assets-dev/locales/vi-VN-json-670ecb0ad40c0453bdfd.js +0 -22
  827. package/dist/excalidraw-assets-dev/locales/zh-CN-json-26caa1a6379860230513.js +0 -22
  828. package/dist/excalidraw-assets-dev/locales/zh-HK-json-179f6dc61b14b96215fa.js +0 -22
  829. package/dist/excalidraw-assets-dev/locales/zh-TW-json-2aeeb73d79793ee69bfc.js +0 -22
@@ -14,7 +14,7 @@
14
14
  \***********************************************/
15
15
  /***/ ((module) => {
16
16
 
17
- eval("/*!\n\npica\nhttps://github.com/nodeca/pica\n\n*/\n\n(function(f){if(true){module.exports=f()}else { var g; }})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=undefined;if(!f&&c)return require(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=undefined,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){\n// Collection of math functions\n//\n// 1. Combine components together\n// 2. Has async init to load wasm modules\n//\n'use strict';\n\nvar inherits = _dereq_('inherits');\n\nvar Multimath = _dereq_('multimath');\n\nvar mm_unsharp_mask = _dereq_('./mm_unsharp_mask');\n\nvar mm_resize = _dereq_('./mm_resize');\n\nfunction MathLib(requested_features) {\n var __requested_features = requested_features || [];\n\n var features = {\n js: __requested_features.indexOf('js') >= 0,\n wasm: __requested_features.indexOf('wasm') >= 0\n };\n Multimath.call(this, features);\n this.features = {\n js: features.js,\n wasm: features.wasm && this.has_wasm()\n };\n this.use(mm_unsharp_mask);\n this.use(mm_resize);\n}\n\ninherits(MathLib, Multimath);\n\nMathLib.prototype.resizeAndUnsharp = function resizeAndUnsharp(options, cache) {\n var result = this.resize(options, cache);\n\n if (options.unsharpAmount) {\n this.unsharp_mask(result, options.toWidth, options.toHeight, options.unsharpAmount, options.unsharpRadius, options.unsharpThreshold);\n }\n\n return result;\n};\n\nmodule.exports = MathLib;\n\n},{\"./mm_resize\":4,\"./mm_unsharp_mask\":9,\"inherits\":19,\"multimath\":20}],2:[function(_dereq_,module,exports){\n// Resize convolvers, pure JS implementation\n//\n'use strict'; // Precision of fixed FP values\n//var FIXED_FRAC_BITS = 14;\n\nfunction clampTo8(i) {\n return i < 0 ? 0 : i > 255 ? 255 : i;\n} // Convolve image in horizontal directions and transpose output. In theory,\n// transpose allow:\n//\n// - use the same convolver for both passes (this fails due different\n// types of input array and temporary buffer)\n// - making vertical pass by horisonltal lines inprove CPU cache use.\n//\n// But in real life this doesn't work :)\n//\n\n\nfunction convolveHorizontally(src, dest, srcW, srcH, destW, filters) {\n var r, g, b, a;\n var filterPtr, filterShift, filterSize;\n var srcPtr, srcY, destX, filterVal;\n var srcOffset = 0,\n destOffset = 0; // For each row\n\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0; // Apply precomputed filters to each destination row point\n\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++];\n filterSize = filters[filterPtr++];\n srcPtr = srcOffset + filterShift * 4 | 0;\n r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a\n\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n\n a = a + filterVal * src[srcPtr + 3] | 0;\n b = b + filterVal * src[srcPtr + 2] | 0;\n g = g + filterVal * src[srcPtr + 1] | 0;\n r = r + filterVal * src[srcPtr] | 0;\n srcPtr = srcPtr + 4 | 0;\n } // Bring this value back in range. All of the filter scaling factors\n // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n //\n // (!) Add 1/2 of value before clamping to get proper rounding. In other\n // case brightness loss will be noticeable if you resize image with white\n // border and place it on white background.\n //\n\n\n dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset] = clampTo8(r + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n destOffset = destOffset + srcH * 4 | 0;\n }\n\n destOffset = (srcY + 1) * 4 | 0;\n srcOffset = (srcY + 1) * srcW * 4 | 0;\n }\n} // Technically, convolvers are the same. But input array and temporary\n// buffer can be of different type (especially, in old browsers). So,\n// keep code in separate functions to avoid deoptimizations & speed loss.\n\n\nfunction convolveVertically(src, dest, srcW, srcH, destW, filters) {\n var r, g, b, a;\n var filterPtr, filterShift, filterSize;\n var srcPtr, srcY, destX, filterVal;\n var srcOffset = 0,\n destOffset = 0; // For each row\n\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0; // Apply precomputed filters to each destination row point\n\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++];\n filterSize = filters[filterPtr++];\n srcPtr = srcOffset + filterShift * 4 | 0;\n r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a\n\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n\n a = a + filterVal * src[srcPtr + 3] | 0;\n b = b + filterVal * src[srcPtr + 2] | 0;\n g = g + filterVal * src[srcPtr + 1] | 0;\n r = r + filterVal * src[srcPtr] | 0;\n srcPtr = srcPtr + 4 | 0;\n } // Bring this value back in range. All of the filter scaling factors\n // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n //\n // (!) Add 1/2 of value before clamping to get proper rounding. In other\n // case brightness loss will be noticeable if you resize image with white\n // border and place it on white background.\n //\n\n\n dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset] = clampTo8(r + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n destOffset = destOffset + srcH * 4 | 0;\n }\n\n destOffset = (srcY + 1) * 4 | 0;\n srcOffset = (srcY + 1) * srcW * 4 | 0;\n }\n}\n\nmodule.exports = {\n convolveHorizontally: convolveHorizontally,\n convolveVertically: convolveVertically\n};\n\n},{}],3:[function(_dereq_,module,exports){\n// This is autogenerated file from math.wasm, don't edit.\n//\n'use strict';\n/* eslint-disable max-len */\n\nmodule.exports = 'AGFzbQEAAAAADAZkeWxpbmsAAAAAAAEXA2AAAGAGf39/f39/AGAHf39/f39/fwACDwEDZW52Bm1lbW9yeQIAAAMEAwABAgYGAX8AQQALB1cFEV9fd2FzbV9jYWxsX2N0b3JzAAAIY29udm9sdmUAAQpjb252b2x2ZUhWAAIMX19kc29faGFuZGxlAwAYX193YXNtX2FwcGx5X2RhdGFfcmVsb2NzAAAK7AMDAwABC8YDAQ9/AkAgA0UNACAERQ0AA0AgDCENQQAhE0EAIQcDQCAHQQJqIQYCfyAHQQF0IAVqIgcuAQIiFEUEQEGAwAAhCEGAwAAhCUGAwAAhCkGAwAAhCyAGDAELIBIgBy4BAGohCEEAIQsgFCEHQQAhDiAGIQlBACEPQQAhEANAIAUgCUEBdGouAQAiESAAIAhBAnRqKAIAIgpBGHZsIBBqIRAgCkH/AXEgEWwgC2ohCyAKQRB2Qf8BcSARbCAPaiEPIApBCHZB/wFxIBFsIA5qIQ4gCEEBaiEIIAlBAWohCSAHQQFrIgcNAAsgC0GAQGshCCAOQYBAayEJIA9BgEBrIQogEEGAQGshCyAGIBRqCyEHIAEgDUECdGogCUEOdSIGQf8BIAZB/wFIGyIGQQAgBkEAShtBCHRBgP4DcSAKQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EQdEGAgPwHcSALQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EYdHJyIAhBDnUiBkH/ASAGQf8BSBsiBkEAIAZBAEobcjYCACADIA1qIQ0gE0EBaiITIARHDQALIAxBAWoiDCACbCESIAMgDEcNAAsLCx4AQQAgAiADIAQgBSAAEAEgAkEAIAQgBSAGIAEQAQs=';\n\n},{}],4:[function(_dereq_,module,exports){\n'use strict';\n\nmodule.exports = {\n name: 'resize',\n fn: _dereq_('./resize'),\n wasm_fn: _dereq_('./resize_wasm'),\n wasm_src: _dereq_('./convolve_wasm_base64')\n};\n\n},{\"./convolve_wasm_base64\":3,\"./resize\":5,\"./resize_wasm\":8}],5:[function(_dereq_,module,exports){\n'use strict';\n\nvar createFilters = _dereq_('./resize_filter_gen');\n\nvar convolveHorizontally = _dereq_('./convolve').convolveHorizontally;\n\nvar convolveVertically = _dereq_('./convolve').convolveVertically;\n\nfunction resetAlpha(dst, width, height) {\n var ptr = 3,\n len = width * height * 4 | 0;\n\n while (ptr < len) {\n dst[ptr] = 0xFF;\n ptr = ptr + 4 | 0;\n }\n}\n\nmodule.exports = function resize(options) {\n var src = options.src;\n var srcW = options.width;\n var srcH = options.height;\n var destW = options.toWidth;\n var destH = options.toHeight;\n var scaleX = options.scaleX || options.toWidth / options.width;\n var scaleY = options.scaleY || options.toHeight / options.height;\n var offsetX = options.offsetX || 0;\n var offsetY = options.offsetY || 0;\n var dest = options.dest || new Uint8Array(destW * destH * 4);\n var quality = typeof options.quality === 'undefined' ? 3 : options.quality;\n var alpha = options.alpha || false;\n var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(quality, srcH, destH, scaleY, offsetY);\n var tmp = new Uint8Array(destW * srcH * 4); // To use single function we need src & tmp of the same type.\n // But src can be CanvasPixelArray, and tmp - Uint8Array. So, keep\n // vertical and horizontal passes separately to avoid deoptimization.\n\n convolveHorizontally(src, tmp, srcW, srcH, destW, filtersX);\n convolveVertically(tmp, dest, srcH, destW, destH, filtersY); // That's faster than doing checks in convolver.\n // !!! Note, canvas data is not premultipled. We don't need other\n // alpha corrections.\n\n if (!alpha) resetAlpha(dest, destW, destH);\n return dest;\n};\n\n},{\"./convolve\":2,\"./resize_filter_gen\":6}],6:[function(_dereq_,module,exports){\n// Calculate convolution filters for each destination point,\n// and pack data to Int16Array:\n//\n// [ shift, length, data..., shift2, length2, data..., ... ]\n//\n// - shift - offset in src image\n// - length - filter length (in src points)\n// - data - filter values sequence\n//\n'use strict';\n\nvar FILTER_INFO = _dereq_('./resize_filter_info'); // Precision of fixed FP values\n\n\nvar FIXED_FRAC_BITS = 14;\n\nfunction toFixedPoint(num) {\n return Math.round(num * ((1 << FIXED_FRAC_BITS) - 1));\n}\n\nmodule.exports = function resizeFilterGen(quality, srcSize, destSize, scale, offset) {\n var filterFunction = FILTER_INFO[quality].filter;\n var scaleInverted = 1.0 / scale;\n var scaleClamped = Math.min(1.0, scale); // For upscale\n // Filter window (averaging interval), scaled to src image\n\n var srcWindow = FILTER_INFO[quality].win / scaleClamped;\n var destPixel, srcPixel, srcFirst, srcLast, filterElementSize, floatFilter, fxpFilter, total, pxl, idx, floatVal, filterTotal, filterVal;\n var leftNotEmpty, rightNotEmpty, filterShift, filterSize;\n var maxFilterElementSize = Math.floor((srcWindow + 1) * 2);\n var packedFilter = new Int16Array((maxFilterElementSize + 2) * destSize);\n var packedFilterPtr = 0;\n var slowCopy = !packedFilter.subarray || !packedFilter.set; // For each destination pixel calculate source range and built filter values\n\n for (destPixel = 0; destPixel < destSize; destPixel++) {\n // Scaling should be done relative to central pixel point\n srcPixel = (destPixel + 0.5) * scaleInverted + offset;\n srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow));\n srcLast = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow));\n filterElementSize = srcLast - srcFirst + 1;\n floatFilter = new Float32Array(filterElementSize);\n fxpFilter = new Int16Array(filterElementSize);\n total = 0.0; // Fill filter values for calculated range\n\n for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {\n floatVal = filterFunction((pxl + 0.5 - srcPixel) * scaleClamped);\n total += floatVal;\n floatFilter[idx] = floatVal;\n } // Normalize filter, convert to fixed point and accumulate conversion error\n\n\n filterTotal = 0;\n\n for (idx = 0; idx < floatFilter.length; idx++) {\n filterVal = floatFilter[idx] / total;\n filterTotal += filterVal;\n fxpFilter[idx] = toFixedPoint(filterVal);\n } // Compensate normalization error, to minimize brightness drift\n\n\n fxpFilter[destSize >> 1] += toFixedPoint(1.0 - filterTotal); //\n // Now pack filter to useable form\n //\n // 1. Trim heading and tailing zero values, and compensate shitf/length\n // 2. Put all to single array in this format:\n //\n // [ pos shift, data length, value1, value2, value3, ... ]\n //\n\n leftNotEmpty = 0;\n\n while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) {\n leftNotEmpty++;\n }\n\n if (leftNotEmpty < fxpFilter.length) {\n rightNotEmpty = fxpFilter.length - 1;\n\n while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) {\n rightNotEmpty--;\n }\n\n filterShift = srcFirst + leftNotEmpty;\n filterSize = rightNotEmpty - leftNotEmpty + 1;\n packedFilter[packedFilterPtr++] = filterShift; // shift\n\n packedFilter[packedFilterPtr++] = filterSize; // size\n\n if (!slowCopy) {\n packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr);\n packedFilterPtr += filterSize;\n } else {\n // fallback for old IE < 11, without subarray/set methods\n for (idx = leftNotEmpty; idx <= rightNotEmpty; idx++) {\n packedFilter[packedFilterPtr++] = fxpFilter[idx];\n }\n }\n } else {\n // zero data, write header only\n packedFilter[packedFilterPtr++] = 0; // shift\n\n packedFilter[packedFilterPtr++] = 0; // size\n }\n }\n\n return packedFilter;\n};\n\n},{\"./resize_filter_info\":7}],7:[function(_dereq_,module,exports){\n// Filter definitions to build tables for\n// resizing convolvers.\n//\n// Presets for quality 0..3. Filter functions + window size\n//\n'use strict';\n\nmodule.exports = [{\n // Nearest neibor (Box)\n win: 0.5,\n filter: function filter(x) {\n return x >= -0.5 && x < 0.5 ? 1.0 : 0.0;\n }\n}, {\n // Hamming\n win: 1.0,\n filter: function filter(x) {\n if (x <= -1.0 || x >= 1.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * (0.54 + 0.46 * Math.cos(xpi / 1.0));\n }\n}, {\n // Lanczos, win = 2\n win: 2.0,\n filter: function filter(x) {\n if (x <= -2.0 || x >= 2.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * Math.sin(xpi / 2.0) / (xpi / 2.0);\n }\n}, {\n // Lanczos, win = 3\n win: 3.0,\n filter: function filter(x) {\n if (x <= -3.0 || x >= 3.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * Math.sin(xpi / 3.0) / (xpi / 3.0);\n }\n}];\n\n},{}],8:[function(_dereq_,module,exports){\n'use strict';\n\nvar createFilters = _dereq_('./resize_filter_gen');\n\nfunction resetAlpha(dst, width, height) {\n var ptr = 3,\n len = width * height * 4 | 0;\n\n while (ptr < len) {\n dst[ptr] = 0xFF;\n ptr = ptr + 4 | 0;\n }\n}\n\nfunction asUint8Array(src) {\n return new Uint8Array(src.buffer, 0, src.byteLength);\n}\n\nvar IS_LE = true; // should not crash everything on module load in old browsers\n\ntry {\n IS_LE = new Uint32Array(new Uint8Array([1, 0, 0, 0]).buffer)[0] === 1;\n} catch (__) {}\n\nfunction copyInt16asLE(src, target, target_offset) {\n if (IS_LE) {\n target.set(asUint8Array(src), target_offset);\n return;\n }\n\n for (var ptr = target_offset, i = 0; i < src.length; i++) {\n var data = src[i];\n target[ptr++] = data & 0xFF;\n target[ptr++] = data >> 8 & 0xFF;\n }\n}\n\nmodule.exports = function resize_wasm(options) {\n var src = options.src;\n var srcW = options.width;\n var srcH = options.height;\n var destW = options.toWidth;\n var destH = options.toHeight;\n var scaleX = options.scaleX || options.toWidth / options.width;\n var scaleY = options.scaleY || options.toHeight / options.height;\n var offsetX = options.offsetX || 0.0;\n var offsetY = options.offsetY || 0.0;\n var dest = options.dest || new Uint8Array(destW * destH * 4);\n var quality = typeof options.quality === 'undefined' ? 3 : options.quality;\n var alpha = options.alpha || false;\n var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(quality, srcH, destH, scaleY, offsetY); // destination is 0 too.\n\n var src_offset = 0; // buffer between convolve passes\n\n var tmp_offset = this.__align(src_offset + Math.max(src.byteLength, dest.byteLength));\n\n var filtersX_offset = this.__align(tmp_offset + srcH * destW * 4);\n\n var filtersY_offset = this.__align(filtersX_offset + filtersX.byteLength);\n\n var alloc_bytes = filtersY_offset + filtersY.byteLength;\n\n var instance = this.__instance('resize', alloc_bytes); //\n // Fill memory block with data to process\n //\n\n\n var mem = new Uint8Array(this.__memory.buffer);\n var mem32 = new Uint32Array(this.__memory.buffer); // 32-bit copy is much faster in chrome\n\n var src32 = new Uint32Array(src.buffer);\n mem32.set(src32); // We should guarantee LE bytes order. Filters are not big, so\n // speed difference is not significant vs direct .set()\n\n copyInt16asLE(filtersX, mem, filtersX_offset);\n copyInt16asLE(filtersY, mem, filtersY_offset); //\n // Now call webassembly method\n // emsdk does method names with '_'\n\n var fn = instance.exports.convolveHV || instance.exports._convolveHV;\n fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH); //\n // Copy data back to typed array\n //\n // 32-bit copy is much faster in chrome\n\n var dest32 = new Uint32Array(dest.buffer);\n dest32.set(new Uint32Array(this.__memory.buffer, 0, destH * destW)); // That's faster than doing checks in convolver.\n // !!! Note, canvas data is not premultipled. We don't need other\n // alpha corrections.\n\n if (!alpha) resetAlpha(dest, destW, destH);\n return dest;\n};\n\n},{\"./resize_filter_gen\":6}],9:[function(_dereq_,module,exports){\n'use strict';\n\nmodule.exports = {\n name: 'unsharp_mask',\n fn: _dereq_('./unsharp_mask'),\n wasm_fn: _dereq_('./unsharp_mask_wasm'),\n wasm_src: _dereq_('./unsharp_mask_wasm_base64')\n};\n\n},{\"./unsharp_mask\":10,\"./unsharp_mask_wasm\":11,\"./unsharp_mask_wasm_base64\":12}],10:[function(_dereq_,module,exports){\n// Unsharp mask filter\n//\n// http://stackoverflow.com/a/23322820/1031804\n// USM(O) = O + (2 * (Amount / 100) * (O - GB))\n// GB - gaussian blur.\n//\n// Image is converted from RGB to HSV, unsharp mask is applied to the\n// brightness channel and then image is converted back to RGB.\n//\n'use strict';\n\nvar glur_mono16 = _dereq_('glur/mono16');\n\nfunction hsv_v16(img, width, height) {\n var size = width * height;\n var out = new Uint16Array(size);\n var r, g, b, max;\n\n for (var i = 0; i < size; i++) {\n r = img[4 * i];\n g = img[4 * i + 1];\n b = img[4 * i + 2];\n max = r >= g && r >= b ? r : g >= b && g >= r ? g : b;\n out[i] = max << 8;\n }\n\n return out;\n}\n\nmodule.exports = function unsharp(img, width, height, amount, radius, threshold) {\n var v1, v2, vmul;\n var diff, iTimes4;\n\n if (amount === 0 || radius < 0.5) {\n return;\n }\n\n if (radius > 2.0) {\n radius = 2.0;\n }\n\n var brightness = hsv_v16(img, width, height);\n var blured = new Uint16Array(brightness); // copy, because blur modify src\n\n glur_mono16(blured, width, height, radius);\n var amountFp = amount / 100 * 0x1000 + 0.5 | 0;\n var thresholdFp = threshold << 8;\n var size = width * height;\n /* eslint-disable indent */\n\n for (var i = 0; i < size; i++) {\n v1 = brightness[i];\n diff = v1 - blured[i];\n\n if (Math.abs(diff) >= thresholdFp) {\n // add unsharp mask to the brightness channel\n v2 = v1 + (amountFp * diff + 0x800 >> 12); // Both v1 and v2 are within [0.0 .. 255.0] (0000-FF00) range, never going into\n // [255.003 .. 255.996] (FF01-FFFF). This allows to round this value as (x+.5)|0\n // later without overflowing.\n\n v2 = v2 > 0xff00 ? 0xff00 : v2;\n v2 = v2 < 0x0000 ? 0x0000 : v2; // Avoid division by 0. V=0 means rgb(0,0,0), unsharp with unsharpAmount>0 cannot\n // change this value (because diff between colors gets inflated), so no need to verify correctness.\n\n v1 = v1 !== 0 ? v1 : 1; // Multiplying V in HSV model by a constant is equivalent to multiplying each component\n // in RGB by the same constant (same for HSL), see also:\n // https://beesbuzz.biz/code/16-hsv-color-transforms\n\n vmul = (v2 << 12) / v1 | 0; // Result will be in [0..255] range because:\n // - all numbers are positive\n // - r,g,b <= (v1/256)\n // - r,g,b,(v1/256),(v2/256) <= 255\n // So highest this number can get is X*255/X+0.5=255.5 which is < 256 and rounds down.\n\n iTimes4 = i * 4;\n img[iTimes4] = img[iTimes4] * vmul + 0x800 >> 12; // R\n\n img[iTimes4 + 1] = img[iTimes4 + 1] * vmul + 0x800 >> 12; // G\n\n img[iTimes4 + 2] = img[iTimes4 + 2] * vmul + 0x800 >> 12; // B\n }\n }\n};\n\n},{\"glur/mono16\":18}],11:[function(_dereq_,module,exports){\n'use strict';\n\nmodule.exports = function unsharp(img, width, height, amount, radius, threshold) {\n if (amount === 0 || radius < 0.5) {\n return;\n }\n\n if (radius > 2.0) {\n radius = 2.0;\n }\n\n var pixels = width * height;\n var img_bytes_cnt = pixels * 4;\n var hsv_bytes_cnt = pixels * 2;\n var blur_bytes_cnt = pixels * 2;\n var blur_line_byte_cnt = Math.max(width, height) * 4; // float32 array\n\n var blur_coeffs_byte_cnt = 8 * 4; // float32 array\n\n var img_offset = 0;\n var hsv_offset = img_bytes_cnt;\n var blur_offset = hsv_offset + hsv_bytes_cnt;\n var blur_tmp_offset = blur_offset + blur_bytes_cnt;\n var blur_line_offset = blur_tmp_offset + blur_bytes_cnt;\n var blur_coeffs_offset = blur_line_offset + blur_line_byte_cnt;\n\n var instance = this.__instance('unsharp_mask', img_bytes_cnt + hsv_bytes_cnt + blur_bytes_cnt * 2 + blur_line_byte_cnt + blur_coeffs_byte_cnt, {\n exp: Math.exp\n }); // 32-bit copy is much faster in chrome\n\n\n var img32 = new Uint32Array(img.buffer);\n var mem32 = new Uint32Array(this.__memory.buffer);\n mem32.set(img32); // HSL\n\n var fn = instance.exports.hsv_v16 || instance.exports._hsv_v16;\n fn(img_offset, hsv_offset, width, height); // BLUR\n\n fn = instance.exports.blurMono16 || instance.exports._blurMono16;\n fn(hsv_offset, blur_offset, blur_tmp_offset, blur_line_offset, blur_coeffs_offset, width, height, radius); // UNSHARP\n\n fn = instance.exports.unsharp || instance.exports._unsharp;\n fn(img_offset, img_offset, hsv_offset, blur_offset, width, height, amount, threshold); // 32-bit copy is much faster in chrome\n\n img32.set(new Uint32Array(this.__memory.buffer, 0, pixels));\n};\n\n},{}],12:[function(_dereq_,module,exports){\n// This is autogenerated file from math.wasm, don't edit.\n//\n'use strict';\n/* eslint-disable max-len */\n\nmodule.exports = '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';\n\n},{}],13:[function(_dereq_,module,exports){\n'use strict';\n\nvar GC_INTERVAL = 100;\n\nfunction Pool(create, idle) {\n this.create = create;\n this.available = [];\n this.acquired = {};\n this.lastId = 1;\n this.timeoutId = 0;\n this.idle = idle || 2000;\n}\n\nPool.prototype.acquire = function () {\n var _this = this;\n\n var resource;\n\n if (this.available.length !== 0) {\n resource = this.available.pop();\n } else {\n resource = this.create();\n resource.id = this.lastId++;\n\n resource.release = function () {\n return _this.release(resource);\n };\n }\n\n this.acquired[resource.id] = resource;\n return resource;\n};\n\nPool.prototype.release = function (resource) {\n var _this2 = this;\n\n delete this.acquired[resource.id];\n resource.lastUsed = Date.now();\n this.available.push(resource);\n\n if (this.timeoutId === 0) {\n this.timeoutId = setTimeout(function () {\n return _this2.gc();\n }, GC_INTERVAL);\n }\n};\n\nPool.prototype.gc = function () {\n var _this3 = this;\n\n var now = Date.now();\n this.available = this.available.filter(function (resource) {\n if (now - resource.lastUsed > _this3.idle) {\n resource.destroy();\n return false;\n }\n\n return true;\n });\n\n if (this.available.length !== 0) {\n this.timeoutId = setTimeout(function () {\n return _this3.gc();\n }, GC_INTERVAL);\n } else {\n this.timeoutId = 0;\n }\n};\n\nmodule.exports = Pool;\n\n},{}],14:[function(_dereq_,module,exports){\n// Add intermediate resizing steps when scaling down by a very large factor.\n//\n// For example, when resizing 10000x10000 down to 10x10, it'll resize it to\n// 300x300 first.\n//\n// It's needed because tiler has issues when the entire tile is scaled down\n// to a few pixels (1024px source tile with border size 3 should result in\n// at least 3+3+2 = 8px target tile, so max scale factor is 128 here).\n//\n// Also, adding intermediate steps can speed up processing if we use lower\n// quality algorithms for first stages.\n//\n'use strict'; // min size = 0 results in infinite loop,\n// min size = 1 can consume large amount of memory\n\nvar MIN_INNER_TILE_SIZE = 2;\n\nmodule.exports = function createStages(fromWidth, fromHeight, toWidth, toHeight, srcTileSize, destTileBorder) {\n var scaleX = toWidth / fromWidth;\n var scaleY = toHeight / fromHeight; // derived from createRegions equation:\n // innerTileWidth = pixelFloor(srcTileSize * scaleX) - 2 * destTileBorder;\n\n var minScale = (2 * destTileBorder + MIN_INNER_TILE_SIZE + 1) / srcTileSize; // refuse to scale image multiple times by less than twice each time,\n // it could only happen because of invalid options\n\n if (minScale > 0.5) return [[toWidth, toHeight]];\n var stageCount = Math.ceil(Math.log(Math.min(scaleX, scaleY)) / Math.log(minScale)); // no additional resizes are necessary,\n // stageCount can be zero or be negative when enlarging the image\n\n if (stageCount <= 1) return [[toWidth, toHeight]];\n var result = [];\n\n for (var i = 0; i < stageCount; i++) {\n var width = Math.round(Math.pow(Math.pow(fromWidth, stageCount - i - 1) * Math.pow(toWidth, i + 1), 1 / stageCount));\n var height = Math.round(Math.pow(Math.pow(fromHeight, stageCount - i - 1) * Math.pow(toHeight, i + 1), 1 / stageCount));\n result.push([width, height]);\n }\n\n return result;\n};\n\n},{}],15:[function(_dereq_,module,exports){\n// Split original image into multiple 1024x1024 chunks to reduce memory usage\n// (images have to be unpacked into typed arrays for resizing) and allow\n// parallel processing of multiple tiles at a time.\n//\n'use strict';\n/*\n * pixelFloor and pixelCeil are modified versions of Math.floor and Math.ceil\n * functions which take into account floating point arithmetic errors.\n * Those errors can cause undesired increments/decrements of sizes and offsets:\n * Math.ceil(36 / (36 / 500)) = 501\n * pixelCeil(36 / (36 / 500)) = 500\n */\n\nvar PIXEL_EPSILON = 1e-5;\n\nfunction pixelFloor(x) {\n var nearest = Math.round(x);\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) {\n return nearest;\n }\n\n return Math.floor(x);\n}\n\nfunction pixelCeil(x) {\n var nearest = Math.round(x);\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) {\n return nearest;\n }\n\n return Math.ceil(x);\n}\n\nmodule.exports = function createRegions(options) {\n var scaleX = options.toWidth / options.width;\n var scaleY = options.toHeight / options.height;\n var innerTileWidth = pixelFloor(options.srcTileSize * scaleX) - 2 * options.destTileBorder;\n var innerTileHeight = pixelFloor(options.srcTileSize * scaleY) - 2 * options.destTileBorder; // prevent infinite loop, this should never happen\n\n if (innerTileWidth < 1 || innerTileHeight < 1) {\n throw new Error('Internal error in pica: target tile width/height is too small.');\n }\n\n var x, y;\n var innerX, innerY, toTileWidth, toTileHeight;\n var tiles = [];\n var tile; // we go top-to-down instead of left-to-right to make image displayed from top to\n // doesn in the browser\n\n for (innerY = 0; innerY < options.toHeight; innerY += innerTileHeight) {\n for (innerX = 0; innerX < options.toWidth; innerX += innerTileWidth) {\n x = innerX - options.destTileBorder;\n\n if (x < 0) {\n x = 0;\n }\n\n toTileWidth = innerX + innerTileWidth + options.destTileBorder - x;\n\n if (x + toTileWidth >= options.toWidth) {\n toTileWidth = options.toWidth - x;\n }\n\n y = innerY - options.destTileBorder;\n\n if (y < 0) {\n y = 0;\n }\n\n toTileHeight = innerY + innerTileHeight + options.destTileBorder - y;\n\n if (y + toTileHeight >= options.toHeight) {\n toTileHeight = options.toHeight - y;\n }\n\n tile = {\n toX: x,\n toY: y,\n toWidth: toTileWidth,\n toHeight: toTileHeight,\n toInnerX: innerX,\n toInnerY: innerY,\n toInnerWidth: innerTileWidth,\n toInnerHeight: innerTileHeight,\n offsetX: x / scaleX - pixelFloor(x / scaleX),\n offsetY: y / scaleY - pixelFloor(y / scaleY),\n scaleX: scaleX,\n scaleY: scaleY,\n x: pixelFloor(x / scaleX),\n y: pixelFloor(y / scaleY),\n width: pixelCeil(toTileWidth / scaleX),\n height: pixelCeil(toTileHeight / scaleY)\n };\n tiles.push(tile);\n }\n }\n\n return tiles;\n};\n\n},{}],16:[function(_dereq_,module,exports){\n'use strict';\n\nfunction objClass(obj) {\n return Object.prototype.toString.call(obj);\n}\n\nmodule.exports.isCanvas = function isCanvas(element) {\n var cname = objClass(element);\n return cname === '[object HTMLCanvasElement]'\n /* browser */\n || cname === '[object OffscreenCanvas]' || cname === '[object Canvas]'\n /* node-canvas */\n ;\n};\n\nmodule.exports.isImage = function isImage(element) {\n return objClass(element) === '[object HTMLImageElement]';\n};\n\nmodule.exports.isImageBitmap = function isImageBitmap(element) {\n return objClass(element) === '[object ImageBitmap]';\n};\n\nmodule.exports.limiter = function limiter(concurrency) {\n var active = 0,\n queue = [];\n\n function roll() {\n if (active < concurrency && queue.length) {\n active++;\n queue.shift()();\n }\n }\n\n return function limit(fn) {\n return new Promise(function (resolve, reject) {\n queue.push(function () {\n fn().then(function (result) {\n resolve(result);\n active--;\n roll();\n }, function (err) {\n reject(err);\n active--;\n roll();\n });\n });\n roll();\n });\n };\n};\n\nmodule.exports.cib_quality_name = function cib_quality_name(num) {\n switch (num) {\n case 0:\n return 'pixelated';\n\n case 1:\n return 'low';\n\n case 2:\n return 'medium';\n }\n\n return 'high';\n};\n\nmodule.exports.cib_support = function cib_support(createCanvas) {\n return Promise.resolve().then(function () {\n if (typeof createImageBitmap === 'undefined') {\n return false;\n }\n\n var c = createCanvas(100, 100);\n return createImageBitmap(c, 0, 0, 100, 100, {\n resizeWidth: 10,\n resizeHeight: 10,\n resizeQuality: 'high'\n }).then(function (bitmap) {\n var status = bitmap.width === 10; // Branch below is filtered on upper level. We do not call resize\n // detection for basic ImageBitmap.\n //\n // https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap\n // old Crome 51 has ImageBitmap without .close(). Then this code\n // will throw and return 'false' as expected.\n //\n\n bitmap.close();\n c = null;\n return status;\n });\n })[\"catch\"](function () {\n return false;\n });\n};\n\nmodule.exports.worker_offscreen_canvas_support = function worker_offscreen_canvas_support() {\n return new Promise(function (resolve, reject) {\n if (typeof OffscreenCanvas === 'undefined') {\n // if OffscreenCanvas is present, we assume browser supports Worker and built-in Promise as well\n resolve(false);\n return;\n }\n\n function workerPayload(self) {\n if (typeof createImageBitmap === 'undefined') {\n self.postMessage(false);\n return;\n }\n\n Promise.resolve().then(function () {\n var canvas = new OffscreenCanvas(10, 10); // test that 2d context can be used in worker\n\n var ctx = canvas.getContext('2d');\n ctx.rect(0, 0, 1, 1); // test that cib can be used to return image bitmap from worker\n\n return createImageBitmap(canvas, 0, 0, 1, 1);\n }).then(function () {\n return self.postMessage(true);\n }, function () {\n return self.postMessage(false);\n });\n }\n\n var code = btoa(\"(\".concat(workerPayload.toString(), \")(self);\"));\n var w = new Worker(\"data:text/javascript;base64,\".concat(code));\n\n w.onmessage = function (ev) {\n return resolve(ev.data);\n };\n\n w.onerror = reject;\n }).then(function (result) {\n return result;\n }, function () {\n return false;\n });\n}; // Check if canvas.getContext('2d').getImageData can be used,\n// FireFox randomizes the output of that function in `privacy.resistFingerprinting` mode\n\n\nmodule.exports.can_use_canvas = function can_use_canvas(createCanvas) {\n var usable = false;\n\n try {\n var canvas = createCanvas(2, 1);\n var ctx = canvas.getContext('2d');\n var d = ctx.createImageData(2, 1);\n d.data[0] = 12;\n d.data[1] = 23;\n d.data[2] = 34;\n d.data[3] = 255;\n d.data[4] = 45;\n d.data[5] = 56;\n d.data[6] = 67;\n d.data[7] = 255;\n ctx.putImageData(d, 0, 0);\n d = null;\n d = ctx.getImageData(0, 0, 2, 1);\n\n if (d.data[0] === 12 && d.data[1] === 23 && d.data[2] === 34 && d.data[3] === 255 && d.data[4] === 45 && d.data[5] === 56 && d.data[6] === 67 && d.data[7] === 255) {\n usable = true;\n }\n } catch (err) {}\n\n return usable;\n}; // Check if createImageBitmap(img, sx, sy, sw, sh) signature works correctly\n// with JPEG images oriented with Exif;\n// https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n// TODO: remove after it's fixed in chrome for at least 2 releases\n\n\nmodule.exports.cib_can_use_region = function cib_can_use_region() {\n return new Promise(function (resolve) {\n if (typeof createImageBitmap === 'undefined') {\n resolve(false);\n return;\n }\n\n var image = new Image();\n image.src = 'data:image/jpeg;base64,' + '/9j/4QBiRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAYAAAEaAAUAAAABAAAASgEbAAUAA' + 'AABAAAAUgEoAAMAAAABAAIAAAITAAMAAAABAAEAAAAAAAAAAABIAAAAAQAAAEgAAAAB/9' + 'sAQwAEAwMEAwMEBAMEBQQEBQYKBwYGBgYNCQoICg8NEBAPDQ8OERMYFBESFxIODxUcFRc' + 'ZGRsbGxAUHR8dGh8YGhsa/9sAQwEEBQUGBQYMBwcMGhEPERoaGhoaGhoaGhoaGhoaGhoa' + 'GhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoa/8IAEQgAAQACAwERAAIRAQMRA' + 'f/EABQAAQAAAAAAAAAAAAAAAAAAAAf/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAA' + 'IQAxAAAAF/P//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAQUCf//EABQRAQAAAAA' + 'AAAAAAAAAAAAAAAD/2gAIAQMBAT8Bf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIB' + 'AT8Bf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEABj8Cf//EABQQAQAAAAAAAAAAA' + 'AAAAAAAAAD/2gAIAQEAAT8hf//aAAwDAQACAAMAAAAQH//EABQRAQAAAAAAAAAAAAAAAA' + 'AAAAD/2gAIAQMBAT8Qf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Qf//EABQ' + 'QAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8Qf//Z';\n\n image.onload = function () {\n createImageBitmap(image, 0, 0, image.width, image.height).then(function (bitmap) {\n if (bitmap.width === image.width && bitmap.height === image.height) {\n resolve(true);\n } else {\n resolve(false);\n }\n }, function () {\n return resolve(false);\n });\n };\n\n image.onerror = function () {\n return resolve(false);\n };\n });\n};\n\n},{}],17:[function(_dereq_,module,exports){\n// Web Worker wrapper for image resize function\n'use strict';\n\nmodule.exports = function () {\n var MathLib = _dereq_('./mathlib');\n\n var mathLib;\n /* eslint-disable no-undef */\n\n onmessage = function onmessage(ev) {\n var tileOpts = ev.data.opts;\n var returnBitmap = false;\n\n if (!tileOpts.src && tileOpts.srcBitmap) {\n var canvas = new OffscreenCanvas(tileOpts.width, tileOpts.height);\n var ctx = canvas.getContext('2d', {\n alpha: Boolean(tileOpts.alpha)\n });\n ctx.drawImage(tileOpts.srcBitmap, 0, 0);\n tileOpts.src = ctx.getImageData(0, 0, tileOpts.width, tileOpts.height).data;\n canvas.width = canvas.height = 0;\n canvas = null;\n tileOpts.srcBitmap.close();\n tileOpts.srcBitmap = null;\n returnBitmap = true;\n }\n\n if (!mathLib) mathLib = new MathLib(ev.data.features); // Use multimath's sync auto-init. Avoid Promise use in old browsers,\n // because polyfills are not propagated to webworker.\n\n var data = mathLib.resizeAndUnsharp(tileOpts);\n\n if (returnBitmap) {\n var toImageData = new ImageData(new Uint8ClampedArray(data), tileOpts.toWidth, tileOpts.toHeight);\n\n var _canvas = new OffscreenCanvas(tileOpts.toWidth, tileOpts.toHeight);\n\n var _ctx = _canvas.getContext('2d', {\n alpha: Boolean(tileOpts.alpha)\n });\n\n _ctx.putImageData(toImageData, 0, 0);\n\n createImageBitmap(_canvas).then(function (bitmap) {\n postMessage({\n bitmap: bitmap\n }, [bitmap]);\n });\n } else {\n postMessage({\n data: data\n }, [data.buffer]);\n }\n };\n};\n\n},{\"./mathlib\":1}],18:[function(_dereq_,module,exports){\n// Calculate Gaussian blur of an image using IIR filter\n// The method is taken from Intel's white paper and code example attached to it:\n// https://software.intel.com/en-us/articles/iir-gaussian-blur-filter\n// -implementation-using-intel-advanced-vector-extensions\n\nvar a0, a1, a2, a3, b1, b2, left_corner, right_corner;\n\nfunction gaussCoef(sigma) {\n if (sigma < 0.5) {\n sigma = 0.5;\n }\n\n var a = Math.exp(0.726 * 0.726) / sigma,\n g1 = Math.exp(-a),\n g2 = Math.exp(-2 * a),\n k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2);\n\n a0 = k;\n a1 = k * (a - 1) * g1;\n a2 = k * (a + 1) * g1;\n a3 = -k * g2;\n b1 = 2 * g1;\n b2 = -g2;\n left_corner = (a0 + a1) / (1 - b1 - b2);\n right_corner = (a2 + a3) / (1 - b1 - b2);\n\n // Attempt to force type to FP32.\n return new Float32Array([ a0, a1, a2, a3, b1, b2, left_corner, right_corner ]);\n}\n\nfunction convolveMono16(src, out, line, coeff, width, height) {\n // takes src image and writes the blurred and transposed result into out\n\n var prev_src, curr_src, curr_out, prev_out, prev_prev_out;\n var src_index, out_index, line_index;\n var i, j;\n var coeff_a0, coeff_a1, coeff_b1, coeff_b2;\n\n for (i = 0; i < height; i++) {\n src_index = i * width;\n out_index = i;\n line_index = 0;\n\n // left to right\n prev_src = src[src_index];\n prev_prev_out = prev_src * coeff[6];\n prev_out = prev_prev_out;\n\n coeff_a0 = coeff[0];\n coeff_a1 = coeff[1];\n coeff_b1 = coeff[4];\n coeff_b2 = coeff[5];\n\n for (j = 0; j < width; j++) {\n curr_src = src[src_index];\n\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2;\n\n prev_prev_out = prev_out;\n prev_out = curr_out;\n prev_src = curr_src;\n\n line[line_index] = prev_out;\n line_index++;\n src_index++;\n }\n\n src_index--;\n line_index--;\n out_index += height * (width - 1);\n\n // right to left\n prev_src = src[src_index];\n prev_prev_out = prev_src * coeff[7];\n prev_out = prev_prev_out;\n curr_src = prev_src;\n\n coeff_a0 = coeff[2];\n coeff_a1 = coeff[3];\n\n for (j = width - 1; j >= 0; j--) {\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2;\n\n prev_prev_out = prev_out;\n prev_out = curr_out;\n\n prev_src = curr_src;\n curr_src = src[src_index];\n\n out[out_index] = line[line_index] + prev_out;\n\n src_index--;\n line_index--;\n out_index -= height;\n }\n }\n}\n\n\nfunction blurMono16(src, width, height, radius) {\n // Quick exit on zero radius\n if (!radius) { return; }\n\n var out = new Uint16Array(src.length),\n tmp_line = new Float32Array(Math.max(width, height));\n\n var coeff = gaussCoef(radius);\n\n convolveMono16(src, out, tmp_line, coeff, width, height, radius);\n convolveMono16(out, src, tmp_line, coeff, height, width, radius);\n}\n\nmodule.exports = blurMono16;\n\n},{}],19:[function(_dereq_,module,exports){\nif (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n })\n }\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n }\n}\n\n},{}],20:[function(_dereq_,module,exports){\n'use strict';\n\n\nvar assign = _dereq_('object-assign');\nvar base64decode = _dereq_('./lib/base64decode');\nvar hasWebAssembly = _dereq_('./lib/wa_detect');\n\n\nvar DEFAULT_OPTIONS = {\n js: true,\n wasm: true\n};\n\n\nfunction MultiMath(options) {\n if (!(this instanceof MultiMath)) return new MultiMath(options);\n\n var opts = assign({}, DEFAULT_OPTIONS, options || {});\n\n this.options = opts;\n\n this.__cache = {};\n\n this.__init_promise = null;\n this.__modules = opts.modules || {};\n this.__memory = null;\n this.__wasm = {};\n\n this.__isLE = ((new Uint32Array((new Uint8Array([ 1, 0, 0, 0 ])).buffer))[0] === 1);\n\n if (!this.options.js && !this.options.wasm) {\n throw new Error('mathlib: at least \"js\" or \"wasm\" should be enabled');\n }\n}\n\n\nMultiMath.prototype.has_wasm = hasWebAssembly;\n\n\nMultiMath.prototype.use = function (module) {\n this.__modules[module.name] = module;\n\n // Pin the best possible implementation\n if (this.options.wasm && this.has_wasm() && module.wasm_fn) {\n this[module.name] = module.wasm_fn;\n } else {\n this[module.name] = module.fn;\n }\n\n return this;\n};\n\n\nMultiMath.prototype.init = function () {\n if (this.__init_promise) return this.__init_promise;\n\n if (!this.options.js && this.options.wasm && !this.has_wasm()) {\n return Promise.reject(new Error('mathlib: only \"wasm\" was enabled, but it\\'s not supported'));\n }\n\n var self = this;\n\n this.__init_promise = Promise.all(Object.keys(self.__modules).map(function (name) {\n var module = self.__modules[name];\n\n if (!self.options.wasm || !self.has_wasm() || !module.wasm_fn) return null;\n\n // If already compiled - exit\n if (self.__wasm[name]) return null;\n\n // Compile wasm source\n return WebAssembly.compile(self.__base64decode(module.wasm_src))\n .then(function (m) { self.__wasm[name] = m; });\n }))\n .then(function () { return self; });\n\n return this.__init_promise;\n};\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Methods below are for internal use from plugins\n\n\n// Simple decode base64 to typed array. Useful to load embedded webassembly\n// code. You probably don't need to call this method directly.\n//\nMultiMath.prototype.__base64decode = base64decode;\n\n\n// Increase current memory to include specified number of bytes. Do nothing if\n// size is already ok. You probably don't need to call this method directly,\n// because it will be invoked from `.__instance()`.\n//\nMultiMath.prototype.__reallocate = function mem_grow_to(bytes) {\n if (!this.__memory) {\n this.__memory = new WebAssembly.Memory({\n initial: Math.ceil(bytes / (64 * 1024))\n });\n return this.__memory;\n }\n\n var mem_size = this.__memory.buffer.byteLength;\n\n if (mem_size < bytes) {\n this.__memory.grow(Math.ceil((bytes - mem_size) / (64 * 1024)));\n }\n\n return this.__memory;\n};\n\n\n// Returns instantinated webassembly item by name, with specified memory size\n// and environment.\n// - use cache if available\n// - do sync module init, if async init was not called earlier\n// - allocate memory if not enougth\n// - can export functions to webassembly via \"env_extra\",\n// for example, { exp: Math.exp }\n//\nMultiMath.prototype.__instance = function instance(name, memsize, env_extra) {\n if (memsize) this.__reallocate(memsize);\n\n // If .init() was not called, do sync compile\n if (!this.__wasm[name]) {\n var module = this.__modules[name];\n this.__wasm[name] = new WebAssembly.Module(this.__base64decode(module.wasm_src));\n }\n\n if (!this.__cache[name]) {\n var env_base = {\n memoryBase: 0,\n memory: this.__memory,\n tableBase: 0,\n table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })\n };\n\n this.__cache[name] = new WebAssembly.Instance(this.__wasm[name], {\n env: assign(env_base, env_extra || {})\n });\n }\n\n return this.__cache[name];\n};\n\n\n// Helper to calculate memory aligh for pointers. Webassembly does not require\n// this, but you may wish to experiment. Default base = 8;\n//\nMultiMath.prototype.__align = function align(number, base) {\n base = base || 8;\n var reminder = number % base;\n return number + (reminder ? base - reminder : 0);\n};\n\n\nmodule.exports = MultiMath;\n\n},{\"./lib/base64decode\":21,\"./lib/wa_detect\":22,\"object-assign\":23}],21:[function(_dereq_,module,exports){\n// base64 decode str -> Uint8Array, to load WA modules\n//\n'use strict';\n\n\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n\nmodule.exports = function base64decode(str) {\n var input = str.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length;\n\n var out = new Uint8Array((max * 3) >> 2);\n\n // Collect by 6*4 bits (3 bytes)\n\n var bits = 0;\n var ptr = 0;\n\n for (var idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n out[ptr++] = (bits >> 16) & 0xFF;\n out[ptr++] = (bits >> 8) & 0xFF;\n out[ptr++] = bits & 0xFF;\n }\n\n bits = (bits << 6) | BASE64_MAP.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n var tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n out[ptr++] = (bits >> 16) & 0xFF;\n out[ptr++] = (bits >> 8) & 0xFF;\n out[ptr++] = bits & 0xFF;\n } else if (tailbits === 18) {\n out[ptr++] = (bits >> 10) & 0xFF;\n out[ptr++] = (bits >> 2) & 0xFF;\n } else if (tailbits === 12) {\n out[ptr++] = (bits >> 4) & 0xFF;\n }\n\n return out;\n};\n\n},{}],22:[function(_dereq_,module,exports){\n// Detect WebAssembly support.\n// - Check global WebAssembly object\n// - Try to load simple module (can be disabled via CSP)\n//\n'use strict';\n\n\nvar wa;\n\n\nmodule.exports = function hasWebAssembly() {\n // use cache if called before;\n if (typeof wa !== 'undefined') return wa;\n\n wa = false;\n\n if (typeof WebAssembly === 'undefined') return wa;\n\n // If WebAssenbly is disabled, code can throw on compile\n try {\n // https://github.com/brion/min-wasm-fail/blob/master/min-wasm-fail.in.js\n // Additional check that WA internals are correct\n\n /* eslint-disable comma-spacing, max-len */\n var bin = new Uint8Array([ 0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11 ]);\n var module = new WebAssembly.Module(bin);\n var instance = new WebAssembly.Instance(module, {});\n\n // test storing to and loading from a non-zero location via a parameter.\n // Safari on iOS 11.2.5 returns 0 unexpectedly at non-zero locations\n if (instance.exports.test(4) !== 0) wa = true;\n\n return wa;\n } catch (__) {}\n\n return wa;\n};\n\n},{}],23:[function(_dereq_,module,exports){\n/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n'use strict';\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n\n},{}],24:[function(_dereq_,module,exports){\nvar bundleFn = arguments[3];\nvar sources = arguments[4];\nvar cache = arguments[5];\n\nvar stringify = JSON.stringify;\n\nmodule.exports = function (fn, options) {\n var wkey;\n var cacheKeys = Object.keys(cache);\n\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n var exp = cache[key].exports;\n // Using babel as a transpiler to use esmodule, the export will always\n // be an object with the default export as a property of it. To ensure\n // the existing api and babel esmodule exports are both supported we\n // check for both\n if (exp === fn || exp && exp.default === fn) {\n wkey = key;\n break;\n }\n }\n\n if (!wkey) {\n wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n var wcache = {};\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n wcache[key] = key;\n }\n sources[wkey] = [\n 'function(require,module,exports){' + fn + '(self); }',\n wcache\n ];\n }\n var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n\n var scache = {}; scache[wkey] = wkey;\n sources[skey] = [\n 'function(require,module,exports){' +\n // try to call default if defined to also support babel esmodule exports\n 'var f = require(' + stringify(wkey) + ');' +\n '(f.default ? f.default : f)(self);' +\n '}',\n scache\n ];\n\n var workerSources = {};\n resolveSources(skey);\n\n function resolveSources(key) {\n workerSources[key] = true;\n\n for (var depPath in sources[key][1]) {\n var depKey = sources[key][1][depPath];\n if (!workerSources[depKey]) {\n resolveSources(depKey);\n }\n }\n }\n\n var src = '(' + bundleFn + ')({'\n + Object.keys(workerSources).map(function (key) {\n return stringify(key) + ':['\n + sources[key][0]\n + ',' + stringify(sources[key][1]) + ']'\n ;\n }).join(',')\n + '},{},[' + stringify(skey) + '])'\n ;\n\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n var blob = new Blob([src], { type: 'text/javascript' });\n if (options && options.bare) { return blob; }\n var workerUrl = URL.createObjectURL(blob);\n var worker = new Worker(workerUrl);\n worker.objectURL = workerUrl;\n return worker;\n};\n\n},{}],\"/index.js\":[function(_dereq_,module,exports){\n'use strict';\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nvar assign = _dereq_('object-assign');\n\nvar webworkify = _dereq_('webworkify');\n\nvar MathLib = _dereq_('./lib/mathlib');\n\nvar Pool = _dereq_('./lib/pool');\n\nvar utils = _dereq_('./lib/utils');\n\nvar worker = _dereq_('./lib/worker');\n\nvar createStages = _dereq_('./lib/stepper');\n\nvar createRegions = _dereq_('./lib/tiler'); // Deduplicate pools & limiters with the same configs\n// when user creates multiple pica instances.\n\n\nvar singletones = {};\nvar NEED_SAFARI_FIX = false;\n\ntry {\n if (typeof navigator !== 'undefined' && navigator.userAgent) {\n NEED_SAFARI_FIX = navigator.userAgent.indexOf('Safari') >= 0;\n }\n} catch (e) {}\n\nvar concurrency = 1;\n\nif (typeof navigator !== 'undefined') {\n concurrency = Math.min(navigator.hardwareConcurrency || 1, 4);\n}\n\nvar DEFAULT_PICA_OPTS = {\n tile: 1024,\n concurrency: concurrency,\n features: ['js', 'wasm', 'ww'],\n idle: 2000,\n createCanvas: function createCanvas(width, height) {\n var tmpCanvas = document.createElement('canvas');\n tmpCanvas.width = width;\n tmpCanvas.height = height;\n return tmpCanvas;\n }\n};\nvar DEFAULT_RESIZE_OPTS = {\n quality: 3,\n alpha: false,\n unsharpAmount: 0,\n unsharpRadius: 0.0,\n unsharpThreshold: 0\n};\nvar CAN_NEW_IMAGE_DATA = false;\nvar CAN_CREATE_IMAGE_BITMAP = false;\nvar CAN_USE_CANVAS_GET_IMAGE_DATA = false;\nvar CAN_USE_OFFSCREEN_CANVAS = false;\nvar CAN_USE_CIB_REGION_FOR_IMAGE = false;\n\nfunction workerFabric() {\n return {\n value: webworkify(worker),\n destroy: function destroy() {\n this.value.terminate();\n\n if (typeof window !== 'undefined') {\n var url = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n if (url && url.revokeObjectURL && this.value.objectURL) {\n url.revokeObjectURL(this.value.objectURL);\n }\n }\n }\n };\n} ////////////////////////////////////////////////////////////////////////////////\n// API methods\n\n\nfunction Pica(options) {\n if (!(this instanceof Pica)) return new Pica(options);\n this.options = assign({}, DEFAULT_PICA_OPTS, options || {});\n var limiter_key = \"lk_\".concat(this.options.concurrency); // Share limiters to avoid multiple parallel workers when user creates\n // multiple pica instances.\n\n this.__limit = singletones[limiter_key] || utils.limiter(this.options.concurrency);\n if (!singletones[limiter_key]) singletones[limiter_key] = this.__limit; // List of supported features, according to options & browser/node.js\n\n this.features = {\n js: false,\n // pure JS implementation, can be disabled for testing\n wasm: false,\n // webassembly implementation for heavy functions\n cib: false,\n // resize via createImageBitmap (only FF at this moment)\n ww: false // webworkers\n\n };\n this.__workersPool = null; // Store requested features for webworkers\n\n this.__requested_features = [];\n this.__mathlib = null;\n}\n\nPica.prototype.init = function () {\n var _this = this;\n\n if (this.__initPromise) return this.__initPromise; // Test if we can create ImageData without canvas and memory copy\n\n if (typeof ImageData !== 'undefined' && typeof Uint8ClampedArray !== 'undefined') {\n try {\n /* eslint-disable no-new */\n new ImageData(new Uint8ClampedArray(400), 10, 10);\n CAN_NEW_IMAGE_DATA = true;\n } catch (__) {}\n } // ImageBitmap can be effective in 2 places:\n //\n // 1. Threaded jpeg unpack (basic)\n // 2. Built-in resize (blocked due problem in chrome, see issue #89)\n //\n // For basic use we also need ImageBitmap wo support .close() method,\n // see https://developer.mozilla.org/ru/docs/Web/API/ImageBitmap\n\n\n if (typeof ImageBitmap !== 'undefined') {\n if (ImageBitmap.prototype && ImageBitmap.prototype.close) {\n CAN_CREATE_IMAGE_BITMAP = true;\n } else {\n this.debug('ImageBitmap does not support .close(), disabled');\n }\n }\n\n var features = this.options.features.slice();\n\n if (features.indexOf('all') >= 0) {\n features = ['cib', 'wasm', 'js', 'ww'];\n }\n\n this.__requested_features = features;\n this.__mathlib = new MathLib(features); // Check WebWorker support if requested\n\n if (features.indexOf('ww') >= 0) {\n if (typeof window !== 'undefined' && 'Worker' in window) {\n // IE <= 11 don't allow to create webworkers from string. We should check it.\n // https://connect.microsoft.com/IE/feedback/details/801810/web-workers-from-blob-urls-in-ie-10-and-11\n try {\n var wkr = _dereq_('webworkify')(function () {});\n\n wkr.terminate();\n this.features.ww = true; // pool uniqueness depends on pool config + webworker config\n\n var wpool_key = \"wp_\".concat(JSON.stringify(this.options));\n\n if (singletones[wpool_key]) {\n this.__workersPool = singletones[wpool_key];\n } else {\n this.__workersPool = new Pool(workerFabric, this.options.idle);\n singletones[wpool_key] = this.__workersPool;\n }\n } catch (__) {}\n }\n }\n\n var initMath = this.__mathlib.init().then(function (mathlib) {\n // Copy detected features\n assign(_this.features, mathlib.features);\n });\n\n var checkCibResize;\n\n if (!CAN_CREATE_IMAGE_BITMAP) {\n checkCibResize = Promise.resolve(false);\n } else {\n checkCibResize = utils.cib_support(this.options.createCanvas).then(function (status) {\n if (_this.features.cib && features.indexOf('cib') < 0) {\n _this.debug('createImageBitmap() resize supported, but disabled by config');\n\n return;\n }\n\n if (features.indexOf('cib') >= 0) _this.features.cib = status;\n });\n }\n\n CAN_USE_CANVAS_GET_IMAGE_DATA = utils.can_use_canvas(this.options.createCanvas);\n var checkOffscreenCanvas;\n\n if (CAN_CREATE_IMAGE_BITMAP && CAN_NEW_IMAGE_DATA && features.indexOf('ww') !== -1) {\n checkOffscreenCanvas = utils.worker_offscreen_canvas_support();\n } else {\n checkOffscreenCanvas = Promise.resolve(false);\n }\n\n checkOffscreenCanvas = checkOffscreenCanvas.then(function (result) {\n CAN_USE_OFFSCREEN_CANVAS = result;\n }); // we use createImageBitmap to crop image data and pass it to workers,\n // so need to check whether function works correctly;\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n\n var checkCibRegion = utils.cib_can_use_region().then(function (result) {\n CAN_USE_CIB_REGION_FOR_IMAGE = result;\n }); // Init math lib. That's async because can load some\n\n this.__initPromise = Promise.all([initMath, checkCibResize, checkOffscreenCanvas, checkCibRegion]).then(function () {\n return _this;\n });\n return this.__initPromise;\n}; // Call resizer in webworker or locally, depending on config\n\n\nPica.prototype.__invokeResize = function (tileOpts, opts) {\n var _this2 = this;\n\n // Share cache between calls:\n //\n // - wasm instance\n // - wasm memory object\n //\n opts.__mathCache = opts.__mathCache || {};\n return Promise.resolve().then(function () {\n if (!_this2.features.ww) {\n // not possible to have ImageBitmap here if user disabled WW\n return {\n data: _this2.__mathlib.resizeAndUnsharp(tileOpts, opts.__mathCache)\n };\n }\n\n return new Promise(function (resolve, reject) {\n var w = _this2.__workersPool.acquire();\n\n if (opts.cancelToken) opts.cancelToken[\"catch\"](function (err) {\n return reject(err);\n });\n\n w.value.onmessage = function (ev) {\n w.release();\n if (ev.data.err) reject(ev.data.err);else resolve(ev.data);\n };\n\n var transfer = [];\n if (tileOpts.src) transfer.push(tileOpts.src.buffer);\n if (tileOpts.srcBitmap) transfer.push(tileOpts.srcBitmap);\n w.value.postMessage({\n opts: tileOpts,\n features: _this2.__requested_features,\n preload: {\n wasm_nodule: _this2.__mathlib.__\n }\n }, transfer);\n });\n });\n}; // this function can return promise if createImageBitmap is used\n\n\nPica.prototype.__extractTileData = function (tile, from, opts, stageEnv, extractTo) {\n if (this.features.ww && CAN_USE_OFFSCREEN_CANVAS && ( // createImageBitmap doesn't work for images (Image, ImageBitmap) with Exif orientation in Chrome,\n // can use canvas because canvas doesn't have orientation;\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n utils.isCanvas(from) || CAN_USE_CIB_REGION_FOR_IMAGE)) {\n this.debug('Create tile for OffscreenCanvas');\n return createImageBitmap(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height).then(function (bitmap) {\n extractTo.srcBitmap = bitmap;\n return extractTo;\n });\n } // Extract tile RGBA buffer, depending on input type\n\n\n if (utils.isCanvas(from)) {\n if (!stageEnv.srcCtx) stageEnv.srcCtx = from.getContext('2d', {\n alpha: Boolean(opts.alpha)\n }); // If input is Canvas - extract region data directly\n\n this.debug('Get tile pixel data');\n extractTo.src = stageEnv.srcCtx.getImageData(tile.x, tile.y, tile.width, tile.height).data;\n return extractTo;\n } // If input is Image or decoded to ImageBitmap,\n // draw region to temporary canvas and extract data from it\n //\n // Note! Attempt to reuse this canvas causes significant slowdown in chrome\n //\n\n\n this.debug('Draw tile imageBitmap/image to temporary canvas');\n var tmpCanvas = this.options.createCanvas(tile.width, tile.height);\n var tmpCtx = tmpCanvas.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n tmpCtx.globalCompositeOperation = 'copy';\n tmpCtx.drawImage(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height, 0, 0, tile.width, tile.height);\n this.debug('Get tile pixel data');\n extractTo.src = tmpCtx.getImageData(0, 0, tile.width, tile.height).data; // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n\n tmpCanvas.width = tmpCanvas.height = 0;\n return extractTo;\n};\n\nPica.prototype.__landTileData = function (tile, result, stageEnv) {\n var toImageData;\n this.debug('Convert raw rgba tile result to ImageData');\n\n if (result.bitmap) {\n stageEnv.toCtx.drawImage(result.bitmap, tile.toX, tile.toY);\n return null;\n }\n\n if (CAN_NEW_IMAGE_DATA) {\n // this branch is for modern browsers\n // If `new ImageData()` & Uint8ClampedArray suported\n toImageData = new ImageData(new Uint8ClampedArray(result.data), tile.toWidth, tile.toHeight);\n } else {\n // fallback for `node-canvas` and old browsers\n // (IE11 has ImageData but does not support `new ImageData()`)\n toImageData = stageEnv.toCtx.createImageData(tile.toWidth, tile.toHeight);\n\n if (toImageData.data.set) {\n toImageData.data.set(result.data);\n } else {\n // IE9 don't have `.set()`\n for (var i = toImageData.data.length - 1; i >= 0; i--) {\n toImageData.data[i] = result.data[i];\n }\n }\n }\n\n this.debug('Draw tile');\n\n if (NEED_SAFARI_FIX) {\n // Safari draws thin white stripes between tiles without this fix\n stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth + 1e-5, tile.toInnerHeight + 1e-5);\n } else {\n stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth, tile.toInnerHeight);\n }\n\n return null;\n};\n\nPica.prototype.__tileAndResize = function (from, to, opts) {\n var _this3 = this;\n\n var stageEnv = {\n srcCtx: null,\n srcImageBitmap: null,\n isImageBitmapReused: false,\n toCtx: null\n };\n\n var processTile = function processTile(tile) {\n return _this3.__limit(function () {\n if (opts.canceled) return opts.cancelToken;\n var tileOpts = {\n width: tile.width,\n height: tile.height,\n toWidth: tile.toWidth,\n toHeight: tile.toHeight,\n scaleX: tile.scaleX,\n scaleY: tile.scaleY,\n offsetX: tile.offsetX,\n offsetY: tile.offsetY,\n quality: opts.quality,\n alpha: opts.alpha,\n unsharpAmount: opts.unsharpAmount,\n unsharpRadius: opts.unsharpRadius,\n unsharpThreshold: opts.unsharpThreshold\n };\n\n _this3.debug('Invoke resize math');\n\n return Promise.resolve(tileOpts).then(function (tileOpts) {\n return _this3.__extractTileData(tile, from, opts, stageEnv, tileOpts);\n }).then(function (tileOpts) {\n _this3.debug('Invoke resize math');\n\n return _this3.__invokeResize(tileOpts, opts);\n }).then(function (result) {\n if (opts.canceled) return opts.cancelToken;\n stageEnv.srcImageData = null;\n return _this3.__landTileData(tile, result, stageEnv);\n });\n });\n }; // Need to normalize data source first. It can be canvas or image.\n // If image - try to decode in background if possible\n\n\n return Promise.resolve().then(function () {\n stageEnv.toCtx = to.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n if (utils.isCanvas(from)) return null;\n\n if (utils.isImageBitmap(from)) {\n stageEnv.srcImageBitmap = from;\n stageEnv.isImageBitmapReused = true;\n return null;\n }\n\n if (utils.isImage(from)) {\n // try do decode image in background for faster next operations;\n // if we're using offscreen canvas, cib is called per tile, so not needed here\n if (!CAN_CREATE_IMAGE_BITMAP) return null;\n\n _this3.debug('Decode image via createImageBitmap');\n\n return createImageBitmap(from).then(function (imageBitmap) {\n stageEnv.srcImageBitmap = imageBitmap;\n }) // Suppress error to use fallback, if method fails\n // https://github.com/nodeca/pica/issues/190\n\n /* eslint-disable no-unused-vars */\n [\"catch\"](function (e) {\n return null;\n });\n }\n\n throw new Error('Pica: \".from\" should be Image, Canvas or ImageBitmap');\n }).then(function () {\n if (opts.canceled) return opts.cancelToken;\n\n _this3.debug('Calculate tiles'); //\n // Here we are with \"normalized\" source,\n // follow to tiling\n //\n\n\n var regions = createRegions({\n width: opts.width,\n height: opts.height,\n srcTileSize: _this3.options.tile,\n toWidth: opts.toWidth,\n toHeight: opts.toHeight,\n destTileBorder: opts.__destTileBorder\n });\n var jobs = regions.map(function (tile) {\n return processTile(tile);\n });\n\n function cleanup(stageEnv) {\n if (stageEnv.srcImageBitmap) {\n if (!stageEnv.isImageBitmapReused) stageEnv.srcImageBitmap.close();\n stageEnv.srcImageBitmap = null;\n }\n }\n\n _this3.debug('Process tiles');\n\n return Promise.all(jobs).then(function () {\n _this3.debug('Finished!');\n\n cleanup(stageEnv);\n return to;\n }, function (err) {\n cleanup(stageEnv);\n throw err;\n });\n });\n};\n\nPica.prototype.__processStages = function (stages, from, to, opts) {\n var _this4 = this;\n\n if (opts.canceled) return opts.cancelToken;\n\n var _stages$shift = stages.shift(),\n _stages$shift2 = _slicedToArray(_stages$shift, 2),\n toWidth = _stages$shift2[0],\n toHeight = _stages$shift2[1];\n\n var isLastStage = stages.length === 0;\n opts = assign({}, opts, {\n toWidth: toWidth,\n toHeight: toHeight,\n // only use user-defined quality for the last stage,\n // use simpler (Hamming) filter for the first stages where\n // scale factor is large enough (more than 2-3)\n quality: isLastStage ? opts.quality : Math.min(1, opts.quality)\n });\n var tmpCanvas;\n\n if (!isLastStage) {\n // create temporary canvas\n tmpCanvas = this.options.createCanvas(toWidth, toHeight);\n }\n\n return this.__tileAndResize(from, isLastStage ? to : tmpCanvas, opts).then(function () {\n if (isLastStage) return to;\n opts.width = toWidth;\n opts.height = toHeight;\n return _this4.__processStages(stages, tmpCanvas, to, opts);\n }).then(function (res) {\n if (tmpCanvas) {\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n tmpCanvas.width = tmpCanvas.height = 0;\n }\n\n return res;\n });\n};\n\nPica.prototype.__resizeViaCreateImageBitmap = function (from, to, opts) {\n var _this5 = this;\n\n var toCtx = to.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n this.debug('Resize via createImageBitmap()');\n return createImageBitmap(from, {\n resizeWidth: opts.toWidth,\n resizeHeight: opts.toHeight,\n resizeQuality: utils.cib_quality_name(opts.quality)\n }).then(function (imageBitmap) {\n if (opts.canceled) return opts.cancelToken; // if no unsharp - draw directly to output canvas\n\n if (!opts.unsharpAmount) {\n toCtx.drawImage(imageBitmap, 0, 0);\n imageBitmap.close();\n toCtx = null;\n\n _this5.debug('Finished!');\n\n return to;\n }\n\n _this5.debug('Unsharp result');\n\n var tmpCanvas = _this5.options.createCanvas(opts.toWidth, opts.toHeight);\n\n var tmpCtx = tmpCanvas.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n tmpCtx.drawImage(imageBitmap, 0, 0);\n imageBitmap.close();\n var iData = tmpCtx.getImageData(0, 0, opts.toWidth, opts.toHeight);\n\n _this5.__mathlib.unsharp_mask(iData.data, opts.toWidth, opts.toHeight, opts.unsharpAmount, opts.unsharpRadius, opts.unsharpThreshold);\n\n toCtx.putImageData(iData, 0, 0); // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n\n tmpCanvas.width = tmpCanvas.height = 0;\n iData = tmpCtx = tmpCanvas = toCtx = null;\n\n _this5.debug('Finished!');\n\n return to;\n });\n};\n\nPica.prototype.resize = function (from, to, options) {\n var _this6 = this;\n\n this.debug('Start resize...');\n var opts = assign({}, DEFAULT_RESIZE_OPTS);\n\n if (!isNaN(options)) {\n opts = assign(opts, {\n quality: options\n });\n } else if (options) {\n opts = assign(opts, options);\n }\n\n opts.toWidth = to.width;\n opts.toHeight = to.height;\n opts.width = from.naturalWidth || from.width;\n opts.height = from.naturalHeight || from.height; // Prevent stepper from infinite loop\n\n if (to.width === 0 || to.height === 0) {\n return Promise.reject(new Error(\"Invalid output size: \".concat(to.width, \"x\").concat(to.height)));\n }\n\n if (opts.unsharpRadius > 2) opts.unsharpRadius = 2;\n opts.canceled = false;\n\n if (opts.cancelToken) {\n // Wrap cancelToken to avoid successive resolve & set flag\n opts.cancelToken = opts.cancelToken.then(function (data) {\n opts.canceled = true;\n throw data;\n }, function (err) {\n opts.canceled = true;\n throw err;\n });\n }\n\n var DEST_TILE_BORDER = 3; // Max possible filter window size\n\n opts.__destTileBorder = Math.ceil(Math.max(DEST_TILE_BORDER, 2.5 * opts.unsharpRadius | 0));\n return this.init().then(function () {\n if (opts.canceled) return opts.cancelToken; // if createImageBitmap supports resize, just do it and return\n\n if (_this6.features.cib) {\n return _this6.__resizeViaCreateImageBitmap(from, to, opts);\n }\n\n if (!CAN_USE_CANVAS_GET_IMAGE_DATA) {\n var err = new Error('Pica: cannot use getImageData on canvas, ' + \"make sure fingerprinting protection isn't enabled\");\n err.code = 'ERR_GET_IMAGE_DATA';\n throw err;\n } //\n // No easy way, let's resize manually via arrays\n //\n\n\n var stages = createStages(opts.width, opts.height, opts.toWidth, opts.toHeight, _this6.options.tile, opts.__destTileBorder);\n return _this6.__processStages(stages, from, to, opts);\n });\n}; // RGBA buffer resize\n//\n\n\nPica.prototype.resizeBuffer = function (options) {\n var _this7 = this;\n\n var opts = assign({}, DEFAULT_RESIZE_OPTS, options);\n return this.init().then(function () {\n return _this7.__mathlib.resizeAndUnsharp(opts);\n });\n};\n\nPica.prototype.toBlob = function (canvas, mimeType, quality) {\n mimeType = mimeType || 'image/png';\n return new Promise(function (resolve) {\n if (canvas.toBlob) {\n canvas.toBlob(function (blob) {\n return resolve(blob);\n }, mimeType, quality);\n return;\n }\n\n if (canvas.convertToBlob) {\n resolve(canvas.convertToBlob({\n type: mimeType,\n quality: quality\n }));\n return;\n } // Fallback for old browsers\n\n\n var asString = atob(canvas.toDataURL(mimeType, quality).split(',')[1]);\n var len = asString.length;\n var asBuffer = new Uint8Array(len);\n\n for (var i = 0; i < len; i++) {\n asBuffer[i] = asString.charCodeAt(i);\n }\n\n resolve(new Blob([asBuffer], {\n type: mimeType\n }));\n });\n};\n\nPica.prototype.debug = function () {};\n\nmodule.exports = Pica;\n\n},{\"./lib/mathlib\":1,\"./lib/pool\":13,\"./lib/stepper\":14,\"./lib/tiler\":15,\"./lib/utils\":16,\"./lib/worker\":17,\"object-assign\":23,\"webworkify\":24}]},{},[])(\"/index.js\")\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3BpY2EvZGlzdC9waWNhLmpzLmpzIiwibWFwcGluZ3MiOiJBQUFBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEsYUFBYSxHQUFHLElBQXNELEVBQUUsbUJBQW1CLEtBQUssVUFBNk4sQ0FBQyxhQUFhLDBCQUEwQixtQkFBbUIsa0JBQWtCLGdCQUFnQixVQUFVLFVBQVUsTUFBTSxTQUFtQyxDQUFDLGdCQUFnQixPQUFDLE9BQU8sb0JBQW9CLDhDQUE4QyxrQ0FBa0MsWUFBWSxZQUFZLG1DQUFtQyxpQkFBaUIsZUFBZSxzQkFBc0Isb0JBQW9CLFVBQVUsU0FBbUMsS0FBSyxXQUFXLFlBQVksU0FBUyxTQUFTLEtBQUs7QUFDenpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSxtRUFBbUU7QUFDdEU7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7O0FBRXRCLGlCQUFpQixhQUFhO0FBQzlCLG1CQUFtQjs7QUFFbkIsb0JBQW9CLGVBQWU7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7O0FBRXpCLGFBQWEsZ0JBQWdCO0FBQzdCLDBDQUEwQztBQUMxQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxnREFBZ0QsUUFBUTtBQUN4RDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0wsS0FBSztBQUNMOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBLEdBQUc7QUFDSDs7QUFFQSxxQ0FBcUM7QUFDckM7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxnREFBZ0Q7O0FBRWhEO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEscUNBQXFDO0FBQ3JDOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHNCQUFzQjs7QUFFdEI7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1EQUFtRDs7QUFFbkQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBLDRCQUE0Qjs7QUFFNUI7QUFDQTtBQUNBLGdEQUFnRDs7QUFFaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsR0FBRztBQUNIOzs7QUFHQTtBQUNBOztBQUVBLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsTUFBTTs7O0FBR047QUFDQTtBQUNBOztBQUVBLG9CQUFvQixTQUFTO0FBQzdCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0g7O0FBRUE7O0FBRUE7O0FBRUEsQ0FBQyxFQUFFLDRJQUE0SSxFQUFFLEdBQUc7QUFDcEosQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovLy8uLi8uLi8uLi9ub2RlX21vZHVsZXMvcGljYS9kaXN0L3BpY2EuanM/ZmY1OSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcblxucGljYVxuaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhXG5cbiovXG5cbihmdW5jdGlvbihmKXtpZih0eXBlb2YgZXhwb3J0cz09PVwib2JqZWN0XCImJnR5cGVvZiBtb2R1bGUhPT1cInVuZGVmaW5lZFwiKXttb2R1bGUuZXhwb3J0cz1mKCl9ZWxzZSBpZih0eXBlb2YgZGVmaW5lPT09XCJmdW5jdGlvblwiJiZkZWZpbmUuYW1kKXtkZWZpbmUoW10sZil9ZWxzZXt2YXIgZztpZih0eXBlb2Ygd2luZG93IT09XCJ1bmRlZmluZWRcIil7Zz13aW5kb3d9ZWxzZSBpZih0eXBlb2YgZ2xvYmFsIT09XCJ1bmRlZmluZWRcIil7Zz1nbG9iYWx9ZWxzZSBpZih0eXBlb2Ygc2VsZiE9PVwidW5kZWZpbmVkXCIpe2c9c2VsZn1lbHNle2c9dGhpc31nLnBpY2EgPSBmKCl9fSkoZnVuY3Rpb24oKXt2YXIgZGVmaW5lLG1vZHVsZSxleHBvcnRzO3JldHVybiAoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpKHsxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIENvbGxlY3Rpb24gb2YgbWF0aCBmdW5jdGlvbnNcbi8vXG4vLyAxLiBDb21iaW5lIGNvbXBvbmVudHMgdG9nZXRoZXJcbi8vIDIuIEhhcyBhc3luYyBpbml0IHRvIGxvYWQgd2FzbSBtb2R1bGVzXG4vL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgaW5oZXJpdHMgPSBfZGVyZXFfKCdpbmhlcml0cycpO1xuXG52YXIgTXVsdGltYXRoID0gX2RlcmVxXygnbXVsdGltYXRoJyk7XG5cbnZhciBtbV91bnNoYXJwX21hc2sgPSBfZGVyZXFfKCcuL21tX3Vuc2hhcnBfbWFzaycpO1xuXG52YXIgbW1fcmVzaXplID0gX2RlcmVxXygnLi9tbV9yZXNpemUnKTtcblxuZnVuY3Rpb24gTWF0aExpYihyZXF1ZXN0ZWRfZmVhdHVyZXMpIHtcbiAgdmFyIF9fcmVxdWVzdGVkX2ZlYXR1cmVzID0gcmVxdWVzdGVkX2ZlYXR1cmVzIHx8IFtdO1xuXG4gIHZhciBmZWF0dXJlcyA9IHtcbiAgICBqczogX19yZXF1ZXN0ZWRfZmVhdHVyZXMuaW5kZXhPZignanMnKSA+PSAwLFxuICAgIHdhc206IF9fcmVxdWVzdGVkX2ZlYXR1cmVzLmluZGV4T2YoJ3dhc20nKSA+PSAwXG4gIH07XG4gIE11bHRpbWF0aC5jYWxsKHRoaXMsIGZlYXR1cmVzKTtcbiAgdGhpcy5mZWF0dXJlcyA9IHtcbiAgICBqczogZmVhdHVyZXMuanMsXG4gICAgd2FzbTogZmVhdHVyZXMud2FzbSAmJiB0aGlzLmhhc193YXNtKClcbiAgfTtcbiAgdGhpcy51c2UobW1fdW5zaGFycF9tYXNrKTtcbiAgdGhpcy51c2UobW1fcmVzaXplKTtcbn1cblxuaW5oZXJpdHMoTWF0aExpYiwgTXVsdGltYXRoKTtcblxuTWF0aExpYi5wcm90b3R5cGUucmVzaXplQW5kVW5zaGFycCA9IGZ1bmN0aW9uIHJlc2l6ZUFuZFVuc2hhcnAob3B0aW9ucywgY2FjaGUpIHtcbiAgdmFyIHJlc3VsdCA9IHRoaXMucmVzaXplKG9wdGlvbnMsIGNhY2hlKTtcblxuICBpZiAob3B0aW9ucy51bnNoYXJwQW1vdW50KSB7XG4gICAgdGhpcy51bnNoYXJwX21hc2socmVzdWx0LCBvcHRpb25zLnRvV2lkdGgsIG9wdGlvbnMudG9IZWlnaHQsIG9wdGlvbnMudW5zaGFycEFtb3VudCwgb3B0aW9ucy51bnNoYXJwUmFkaXVzLCBvcHRpb25zLnVuc2hhcnBUaHJlc2hvbGQpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gTWF0aExpYjtcblxufSx7XCIuL21tX3Jlc2l6ZVwiOjQsXCIuL21tX3Vuc2hhcnBfbWFza1wiOjksXCJpbmhlcml0c1wiOjE5LFwibXVsdGltYXRoXCI6MjB9XSwyOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIFJlc2l6ZSBjb252b2x2ZXJzLCBwdXJlIEpTIGltcGxlbWVudGF0aW9uXG4vL1xuJ3VzZSBzdHJpY3QnOyAvLyBQcmVjaXNpb24gb2YgZml4ZWQgRlAgdmFsdWVzXG4vL3ZhciBGSVhFRF9GUkFDX0JJVFMgPSAxNDtcblxuZnVuY3Rpb24gY2xhbXBUbzgoaSkge1xuICByZXR1cm4gaSA8IDAgPyAwIDogaSA+IDI1NSA/IDI1NSA6IGk7XG59IC8vIENvbnZvbHZlIGltYWdlIGluIGhvcml6b250YWwgZGlyZWN0aW9ucyBhbmQgdHJhbnNwb3NlIG91dHB1dC4gSW4gdGhlb3J5LFxuLy8gdHJhbnNwb3NlIGFsbG93OlxuLy9cbi8vIC0gdXNlIHRoZSBzYW1lIGNvbnZvbHZlciBmb3IgYm90aCBwYXNzZXMgKHRoaXMgZmFpbHMgZHVlIGRpZmZlcmVudFxuLy8gICB0eXBlcyBvZiBpbnB1dCBhcnJheSBhbmQgdGVtcG9yYXJ5IGJ1ZmZlcilcbi8vIC0gbWFraW5nIHZlcnRpY2FsIHBhc3MgYnkgaG9yaXNvbmx0YWwgbGluZXMgaW5wcm92ZSBDUFUgY2FjaGUgdXNlLlxuLy9cbi8vIEJ1dCBpbiByZWFsIGxpZmUgdGhpcyBkb2Vzbid0IHdvcmsgOilcbi8vXG5cblxuZnVuY3Rpb24gY29udm9sdmVIb3Jpem9udGFsbHkoc3JjLCBkZXN0LCBzcmNXLCBzcmNILCBkZXN0VywgZmlsdGVycykge1xuICB2YXIgciwgZywgYiwgYTtcbiAgdmFyIGZpbHRlclB0ciwgZmlsdGVyU2hpZnQsIGZpbHRlclNpemU7XG4gIHZhciBzcmNQdHIsIHNyY1ksIGRlc3RYLCBmaWx0ZXJWYWw7XG4gIHZhciBzcmNPZmZzZXQgPSAwLFxuICAgICAgZGVzdE9mZnNldCA9IDA7IC8vIEZvciBlYWNoIHJvd1xuXG4gIGZvciAoc3JjWSA9IDA7IHNyY1kgPCBzcmNIOyBzcmNZKyspIHtcbiAgICBmaWx0ZXJQdHIgPSAwOyAvLyBBcHBseSBwcmVjb21wdXRlZCBmaWx0ZXJzIHRvIGVhY2ggZGVzdGluYXRpb24gcm93IHBvaW50XG5cbiAgICBmb3IgKGRlc3RYID0gMDsgZGVzdFggPCBkZXN0VzsgZGVzdFgrKykge1xuICAgICAgLy8gR2V0IHRoZSBmaWx0ZXIgdGhhdCBkZXRlcm1pbmVzIHRoZSBjdXJyZW50IG91dHB1dCBwaXhlbC5cbiAgICAgIGZpbHRlclNoaWZ0ID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBmaWx0ZXJTaXplID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBzcmNQdHIgPSBzcmNPZmZzZXQgKyBmaWx0ZXJTaGlmdCAqIDQgfCAwO1xuICAgICAgciA9IGcgPSBiID0gYSA9IDA7IC8vIEFwcGx5IHRoZSBmaWx0ZXIgdG8gdGhlIHJvdyB0byBnZXQgdGhlIGRlc3RpbmF0aW9uIHBpeGVsIHIsIGcsIGIsIGFcblxuICAgICAgZm9yICg7IGZpbHRlclNpemUgPiAwOyBmaWx0ZXJTaXplLS0pIHtcbiAgICAgICAgZmlsdGVyVmFsID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107IC8vIFVzZSByZXZlcnNlIG9yZGVyIHRvIHdvcmthcm91bmQgZGVvcHRzIGluIG9sZCB2OCAobm9kZSB2LjEwKVxuICAgICAgICAvLyBCaWcgdGhhbmtzIHRvIEBtcmFsZXBoIChWeWFjaGVzbGF2IEVnb3JvdikgZm9yIHRoZSB0aXAuXG5cbiAgICAgICAgYSA9IGEgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyICsgM10gfCAwO1xuICAgICAgICBiID0gYiArIGZpbHRlclZhbCAqIHNyY1tzcmNQdHIgKyAyXSB8IDA7XG4gICAgICAgIGcgPSBnICsgZmlsdGVyVmFsICogc3JjW3NyY1B0ciArIDFdIHwgMDtcbiAgICAgICAgciA9IHIgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyXSB8IDA7XG4gICAgICAgIHNyY1B0ciA9IHNyY1B0ciArIDQgfCAwO1xuICAgICAgfSAvLyBCcmluZyB0aGlzIHZhbHVlIGJhY2sgaW4gcmFuZ2UuIEFsbCBvZiB0aGUgZmlsdGVyIHNjYWxpbmcgZmFjdG9yc1xuICAgICAgLy8gYXJlIGluIGZpeGVkIHBvaW50IHdpdGggRklYRURfRlJBQ19CSVRTIGJpdHMgb2YgZnJhY3Rpb25hbCBwYXJ0LlxuICAgICAgLy9cbiAgICAgIC8vICghKSBBZGQgMS8yIG9mIHZhbHVlIGJlZm9yZSBjbGFtcGluZyB0byBnZXQgcHJvcGVyIHJvdW5kaW5nLiBJbiBvdGhlclxuICAgICAgLy8gY2FzZSBicmlnaHRuZXNzIGxvc3Mgd2lsbCBiZSBub3RpY2VhYmxlIGlmIHlvdSByZXNpemUgaW1hZ2Ugd2l0aCB3aGl0ZVxuICAgICAgLy8gYm9yZGVyIGFuZCBwbGFjZSBpdCBvbiB3aGl0ZSBiYWNrZ3JvdW5kLlxuICAgICAgLy9cblxuXG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAzXSA9IGNsYW1wVG84KGEgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAyXSA9IGNsYW1wVG84KGIgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAxXSA9IGNsYW1wVG84KGcgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXRdID0gY2xhbXBUbzgociArICgxIDw8IDEzKSA+PiAxNFxuICAgICAgLypGSVhFRF9GUkFDX0JJVFMqL1xuICAgICAgKTtcbiAgICAgIGRlc3RPZmZzZXQgPSBkZXN0T2Zmc2V0ICsgc3JjSCAqIDQgfCAwO1xuICAgIH1cblxuICAgIGRlc3RPZmZzZXQgPSAoc3JjWSArIDEpICogNCB8IDA7XG4gICAgc3JjT2Zmc2V0ID0gKHNyY1kgKyAxKSAqIHNyY1cgKiA0IHwgMDtcbiAgfVxufSAvLyBUZWNobmljYWxseSwgY29udm9sdmVycyBhcmUgdGhlIHNhbWUuIEJ1dCBpbnB1dCBhcnJheSBhbmQgdGVtcG9yYXJ5XG4vLyBidWZmZXIgY2FuIGJlIG9mIGRpZmZlcmVudCB0eXBlIChlc3BlY2lhbGx5LCBpbiBvbGQgYnJvd3NlcnMpLiBTbyxcbi8vIGtlZXAgY29kZSBpbiBzZXBhcmF0ZSBmdW5jdGlvbnMgdG8gYXZvaWQgZGVvcHRpbWl6YXRpb25zICYgc3BlZWQgbG9zcy5cblxuXG5mdW5jdGlvbiBjb252b2x2ZVZlcnRpY2FsbHkoc3JjLCBkZXN0LCBzcmNXLCBzcmNILCBkZXN0VywgZmlsdGVycykge1xuICB2YXIgciwgZywgYiwgYTtcbiAgdmFyIGZpbHRlclB0ciwgZmlsdGVyU2hpZnQsIGZpbHRlclNpemU7XG4gIHZhciBzcmNQdHIsIHNyY1ksIGRlc3RYLCBmaWx0ZXJWYWw7XG4gIHZhciBzcmNPZmZzZXQgPSAwLFxuICAgICAgZGVzdE9mZnNldCA9IDA7IC8vIEZvciBlYWNoIHJvd1xuXG4gIGZvciAoc3JjWSA9IDA7IHNyY1kgPCBzcmNIOyBzcmNZKyspIHtcbiAgICBmaWx0ZXJQdHIgPSAwOyAvLyBBcHBseSBwcmVjb21wdXRlZCBmaWx0ZXJzIHRvIGVhY2ggZGVzdGluYXRpb24gcm93IHBvaW50XG5cbiAgICBmb3IgKGRlc3RYID0gMDsgZGVzdFggPCBkZXN0VzsgZGVzdFgrKykge1xuICAgICAgLy8gR2V0IHRoZSBmaWx0ZXIgdGhhdCBkZXRlcm1pbmVzIHRoZSBjdXJyZW50IG91dHB1dCBwaXhlbC5cbiAgICAgIGZpbHRlclNoaWZ0ID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBmaWx0ZXJTaXplID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBzcmNQdHIgPSBzcmNPZmZzZXQgKyBmaWx0ZXJTaGlmdCAqIDQgfCAwO1xuICAgICAgciA9IGcgPSBiID0gYSA9IDA7IC8vIEFwcGx5IHRoZSBmaWx0ZXIgdG8gdGhlIHJvdyB0byBnZXQgdGhlIGRlc3RpbmF0aW9uIHBpeGVsIHIsIGcsIGIsIGFcblxuICAgICAgZm9yICg7IGZpbHRlclNpemUgPiAwOyBmaWx0ZXJTaXplLS0pIHtcbiAgICAgICAgZmlsdGVyVmFsID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107IC8vIFVzZSByZXZlcnNlIG9yZGVyIHRvIHdvcmthcm91bmQgZGVvcHRzIGluIG9sZCB2OCAobm9kZSB2LjEwKVxuICAgICAgICAvLyBCaWcgdGhhbmtzIHRvIEBtcmFsZXBoIChWeWFjaGVzbGF2IEVnb3JvdikgZm9yIHRoZSB0aXAuXG5cbiAgICAgICAgYSA9IGEgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyICsgM10gfCAwO1xuICAgICAgICBiID0gYiArIGZpbHRlclZhbCAqIHNyY1tzcmNQdHIgKyAyXSB8IDA7XG4gICAgICAgIGcgPSBnICsgZmlsdGVyVmFsICogc3JjW3NyY1B0ciArIDFdIHwgMDtcbiAgICAgICAgciA9IHIgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyXSB8IDA7XG4gICAgICAgIHNyY1B0ciA9IHNyY1B0ciArIDQgfCAwO1xuICAgICAgfSAvLyBCcmluZyB0aGlzIHZhbHVlIGJhY2sgaW4gcmFuZ2UuIEFsbCBvZiB0aGUgZmlsdGVyIHNjYWxpbmcgZmFjdG9yc1xuICAgICAgLy8gYXJlIGluIGZpeGVkIHBvaW50IHdpdGggRklYRURfRlJBQ19CSVRTIGJpdHMgb2YgZnJhY3Rpb25hbCBwYXJ0LlxuICAgICAgLy9cbiAgICAgIC8vICghKSBBZGQgMS8yIG9mIHZhbHVlIGJlZm9yZSBjbGFtcGluZyB0byBnZXQgcHJvcGVyIHJvdW5kaW5nLiBJbiBvdGhlclxuICAgICAgLy8gY2FzZSBicmlnaHRuZXNzIGxvc3Mgd2lsbCBiZSBub3RpY2VhYmxlIGlmIHlvdSByZXNpemUgaW1hZ2Ugd2l0aCB3aGl0ZVxuICAgICAgLy8gYm9yZGVyIGFuZCBwbGFjZSBpdCBvbiB3aGl0ZSBiYWNrZ3JvdW5kLlxuICAgICAgLy9cblxuXG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAzXSA9IGNsYW1wVG84KGEgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAyXSA9IGNsYW1wVG84KGIgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAxXSA9IGNsYW1wVG84KGcgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXRdID0gY2xhbXBUbzgociArICgxIDw8IDEzKSA+PiAxNFxuICAgICAgLypGSVhFRF9GUkFDX0JJVFMqL1xuICAgICAgKTtcbiAgICAgIGRlc3RPZmZzZXQgPSBkZXN0T2Zmc2V0ICsgc3JjSCAqIDQgfCAwO1xuICAgIH1cblxuICAgIGRlc3RPZmZzZXQgPSAoc3JjWSArIDEpICogNCB8IDA7XG4gICAgc3JjT2Zmc2V0ID0gKHNyY1kgKyAxKSAqIHNyY1cgKiA0IHwgMDtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY29udm9sdmVIb3Jpem9udGFsbHk6IGNvbnZvbHZlSG9yaXpvbnRhbGx5LFxuICBjb252b2x2ZVZlcnRpY2FsbHk6IGNvbnZvbHZlVmVydGljYWxseVxufTtcblxufSx7fV0sMzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBUaGlzIGlzIGF1dG9nZW5lcmF0ZWQgZmlsZSBmcm9tIG1hdGgud2FzbSwgZG9uJ3QgZWRpdC5cbi8vXG4ndXNlIHN0cmljdCc7XG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cbm1vZHVsZS5leHBvcnRzID0gJ0FHRnpiUUVBQUFBQURBWmtlV3hwYm1zQUFBQUFBQUVYQTJBQUFHQUdmMzkvZjM5L0FHQUhmMzkvZjM5L2Z3QUNEd0VEWlc1MkJtMWxiVzl5ZVFJQUFBTUVBd0FCQWdZR0FYOEFRUUFMQjFjRkVWOWZkMkZ6YlY5allXeHNYMk4wYjNKekFBQUlZMjl1ZG05c2RtVUFBUXBqYjI1MmIyeDJaVWhXQUFJTVgxOWtjMjlmYUdGdVpHeGxBd0FZWDE5M1lYTnRYMkZ3Y0d4NVgyUmhkR0ZmY21Wc2IyTnpBQUFLN0FNREF3QUJDOFlEQVE5L0FrQWdBMFVOQUNBRVJRMEFBMEFnRENFTlFRQWhFMEVBSVFjRFFDQUhRUUpxSVFZQ2Z5QUhRUUYwSUFWcUlnY3VBUUlpRkVVRVFFR0F3QUFoQ0VHQXdBQWhDVUdBd0FBaENrR0F3QUFoQ3lBR0RBRUxJQklnQnk0QkFHb2hDRUVBSVFzZ0ZDRUhRUUFoRGlBR0lRbEJBQ0VQUVFBaEVBTkFJQVVnQ1VFQmRHb3VBUUFpRVNBQUlBaEJBblJxS0FJQUlncEJHSFpzSUJCcUlSQWdDa0gvQVhFZ0VXd2dDMm9oQ3lBS1FSQjJRZjhCY1NBUmJDQVBhaUVQSUFwQkNIWkIvd0Z4SUJGc0lBNXFJUTRnQ0VFQmFpRUlJQWxCQVdvaENTQUhRUUZySWdjTkFBc2dDMEdBUUdzaENDQU9RWUJBYXlFSklBOUJnRUJySVFvZ0VFR0FRR3NoQ3lBR0lCUnFDeUVISUFFZ0RVRUNkR29nQ1VFT2RTSUdRZjhCSUFaQi93RklHeUlHUVFBZ0JrRUFTaHRCQ0hSQmdQNERjU0FLUVE1MUlnWkIvd0VnQmtIL0FVZ2JJZ1pCQUNBR1FRQktHMEVRZEVHQWdQd0hjU0FMUVE1MUlnWkIvd0VnQmtIL0FVZ2JJZ1pCQUNBR1FRQktHMEVZZEhKeUlBaEJEblVpQmtIL0FTQUdRZjhCU0JzaUJrRUFJQVpCQUVvYmNqWUNBQ0FESUExcUlRMGdFMEVCYWlJVElBUkhEUUFMSUF4QkFXb2lEQ0FDYkNFU0lBTWdERWNOQUFzTEN4NEFRUUFnQWlBRElBUWdCU0FBRUFFZ0FrRUFJQVFnQlNBR0lBRVFBUXM9JztcblxufSx7fV0sNDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBuYW1lOiAncmVzaXplJyxcbiAgZm46IF9kZXJlcV8oJy4vcmVzaXplJyksXG4gIHdhc21fZm46IF9kZXJlcV8oJy4vcmVzaXplX3dhc20nKSxcbiAgd2FzbV9zcmM6IF9kZXJlcV8oJy4vY29udm9sdmVfd2FzbV9iYXNlNjQnKVxufTtcblxufSx7XCIuL2NvbnZvbHZlX3dhc21fYmFzZTY0XCI6MyxcIi4vcmVzaXplXCI6NSxcIi4vcmVzaXplX3dhc21cIjo4fV0sNTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBjcmVhdGVGaWx0ZXJzID0gX2RlcmVxXygnLi9yZXNpemVfZmlsdGVyX2dlbicpO1xuXG52YXIgY29udm9sdmVIb3Jpem9udGFsbHkgPSBfZGVyZXFfKCcuL2NvbnZvbHZlJykuY29udm9sdmVIb3Jpem9udGFsbHk7XG5cbnZhciBjb252b2x2ZVZlcnRpY2FsbHkgPSBfZGVyZXFfKCcuL2NvbnZvbHZlJykuY29udm9sdmVWZXJ0aWNhbGx5O1xuXG5mdW5jdGlvbiByZXNldEFscGhhKGRzdCwgd2lkdGgsIGhlaWdodCkge1xuICB2YXIgcHRyID0gMyxcbiAgICAgIGxlbiA9IHdpZHRoICogaGVpZ2h0ICogNCB8IDA7XG5cbiAgd2hpbGUgKHB0ciA8IGxlbikge1xuICAgIGRzdFtwdHJdID0gMHhGRjtcbiAgICBwdHIgPSBwdHIgKyA0IHwgMDtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlc2l6ZShvcHRpb25zKSB7XG4gIHZhciBzcmMgPSBvcHRpb25zLnNyYztcbiAgdmFyIHNyY1cgPSBvcHRpb25zLndpZHRoO1xuICB2YXIgc3JjSCA9IG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgZGVzdFcgPSBvcHRpb25zLnRvV2lkdGg7XG4gIHZhciBkZXN0SCA9IG9wdGlvbnMudG9IZWlnaHQ7XG4gIHZhciBzY2FsZVggPSBvcHRpb25zLnNjYWxlWCB8fCBvcHRpb25zLnRvV2lkdGggLyBvcHRpb25zLndpZHRoO1xuICB2YXIgc2NhbGVZID0gb3B0aW9ucy5zY2FsZVkgfHwgb3B0aW9ucy50b0hlaWdodCAvIG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgb2Zmc2V0WCA9IG9wdGlvbnMub2Zmc2V0WCB8fCAwO1xuICB2YXIgb2Zmc2V0WSA9IG9wdGlvbnMub2Zmc2V0WSB8fCAwO1xuICB2YXIgZGVzdCA9IG9wdGlvbnMuZGVzdCB8fCBuZXcgVWludDhBcnJheShkZXN0VyAqIGRlc3RIICogNCk7XG4gIHZhciBxdWFsaXR5ID0gdHlwZW9mIG9wdGlvbnMucXVhbGl0eSA9PT0gJ3VuZGVmaW5lZCcgPyAzIDogb3B0aW9ucy5xdWFsaXR5O1xuICB2YXIgYWxwaGEgPSBvcHRpb25zLmFscGhhIHx8IGZhbHNlO1xuICB2YXIgZmlsdGVyc1ggPSBjcmVhdGVGaWx0ZXJzKHF1YWxpdHksIHNyY1csIGRlc3RXLCBzY2FsZVgsIG9mZnNldFgpLFxuICAgICAgZmlsdGVyc1kgPSBjcmVhdGVGaWx0ZXJzKHF1YWxpdHksIHNyY0gsIGRlc3RILCBzY2FsZVksIG9mZnNldFkpO1xuICB2YXIgdG1wID0gbmV3IFVpbnQ4QXJyYXkoZGVzdFcgKiBzcmNIICogNCk7IC8vIFRvIHVzZSBzaW5nbGUgZnVuY3Rpb24gd2UgbmVlZCBzcmMgJiB0bXAgb2YgdGhlIHNhbWUgdHlwZS5cbiAgLy8gQnV0IHNyYyBjYW4gYmUgQ2FudmFzUGl4ZWxBcnJheSwgYW5kIHRtcCAtIFVpbnQ4QXJyYXkuIFNvLCBrZWVwXG4gIC8vIHZlcnRpY2FsIGFuZCBob3Jpem9udGFsIHBhc3NlcyBzZXBhcmF0ZWx5IHRvIGF2b2lkIGRlb3B0aW1pemF0aW9uLlxuXG4gIGNvbnZvbHZlSG9yaXpvbnRhbGx5KHNyYywgdG1wLCBzcmNXLCBzcmNILCBkZXN0VywgZmlsdGVyc1gpO1xuICBjb252b2x2ZVZlcnRpY2FsbHkodG1wLCBkZXN0LCBzcmNILCBkZXN0VywgZGVzdEgsIGZpbHRlcnNZKTsgLy8gVGhhdCdzIGZhc3RlciB0aGFuIGRvaW5nIGNoZWNrcyBpbiBjb252b2x2ZXIuXG4gIC8vICEhISBOb3RlLCBjYW52YXMgZGF0YSBpcyBub3QgcHJlbXVsdGlwbGVkLiBXZSBkb24ndCBuZWVkIG90aGVyXG4gIC8vIGFscGhhIGNvcnJlY3Rpb25zLlxuXG4gIGlmICghYWxwaGEpIHJlc2V0QWxwaGEoZGVzdCwgZGVzdFcsIGRlc3RIKTtcbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG59LHtcIi4vY29udm9sdmVcIjoyLFwiLi9yZXNpemVfZmlsdGVyX2dlblwiOjZ9XSw2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIENhbGN1bGF0ZSBjb252b2x1dGlvbiBmaWx0ZXJzIGZvciBlYWNoIGRlc3RpbmF0aW9uIHBvaW50LFxuLy8gYW5kIHBhY2sgZGF0YSB0byBJbnQxNkFycmF5OlxuLy9cbi8vIFsgc2hpZnQsIGxlbmd0aCwgZGF0YS4uLiwgc2hpZnQyLCBsZW5ndGgyLCBkYXRhLi4uLCAuLi4gXVxuLy9cbi8vIC0gc2hpZnQgLSBvZmZzZXQgaW4gc3JjIGltYWdlXG4vLyAtIGxlbmd0aCAtIGZpbHRlciBsZW5ndGggKGluIHNyYyBwb2ludHMpXG4vLyAtIGRhdGEgLSBmaWx0ZXIgdmFsdWVzIHNlcXVlbmNlXG4vL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRklMVEVSX0lORk8gPSBfZGVyZXFfKCcuL3Jlc2l6ZV9maWx0ZXJfaW5mbycpOyAvLyBQcmVjaXNpb24gb2YgZml4ZWQgRlAgdmFsdWVzXG5cblxudmFyIEZJWEVEX0ZSQUNfQklUUyA9IDE0O1xuXG5mdW5jdGlvbiB0b0ZpeGVkUG9pbnQobnVtKSB7XG4gIHJldHVybiBNYXRoLnJvdW5kKG51bSAqICgoMSA8PCBGSVhFRF9GUkFDX0JJVFMpIC0gMSkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlc2l6ZUZpbHRlckdlbihxdWFsaXR5LCBzcmNTaXplLCBkZXN0U2l6ZSwgc2NhbGUsIG9mZnNldCkge1xuICB2YXIgZmlsdGVyRnVuY3Rpb24gPSBGSUxURVJfSU5GT1txdWFsaXR5XS5maWx0ZXI7XG4gIHZhciBzY2FsZUludmVydGVkID0gMS4wIC8gc2NhbGU7XG4gIHZhciBzY2FsZUNsYW1wZWQgPSBNYXRoLm1pbigxLjAsIHNjYWxlKTsgLy8gRm9yIHVwc2NhbGVcbiAgLy8gRmlsdGVyIHdpbmRvdyAoYXZlcmFnaW5nIGludGVydmFsKSwgc2NhbGVkIHRvIHNyYyBpbWFnZVxuXG4gIHZhciBzcmNXaW5kb3cgPSBGSUxURVJfSU5GT1txdWFsaXR5XS53aW4gLyBzY2FsZUNsYW1wZWQ7XG4gIHZhciBkZXN0UGl4ZWwsIHNyY1BpeGVsLCBzcmNGaXJzdCwgc3JjTGFzdCwgZmlsdGVyRWxlbWVudFNpemUsIGZsb2F0RmlsdGVyLCBmeHBGaWx0ZXIsIHRvdGFsLCBweGwsIGlkeCwgZmxvYXRWYWwsIGZpbHRlclRvdGFsLCBmaWx0ZXJWYWw7XG4gIHZhciBsZWZ0Tm90RW1wdHksIHJpZ2h0Tm90RW1wdHksIGZpbHRlclNoaWZ0LCBmaWx0ZXJTaXplO1xuICB2YXIgbWF4RmlsdGVyRWxlbWVudFNpemUgPSBNYXRoLmZsb29yKChzcmNXaW5kb3cgKyAxKSAqIDIpO1xuICB2YXIgcGFja2VkRmlsdGVyID0gbmV3IEludDE2QXJyYXkoKG1heEZpbHRlckVsZW1lbnRTaXplICsgMikgKiBkZXN0U2l6ZSk7XG4gIHZhciBwYWNrZWRGaWx0ZXJQdHIgPSAwO1xuICB2YXIgc2xvd0NvcHkgPSAhcGFja2VkRmlsdGVyLnN1YmFycmF5IHx8ICFwYWNrZWRGaWx0ZXIuc2V0OyAvLyBGb3IgZWFjaCBkZXN0aW5hdGlvbiBwaXhlbCBjYWxjdWxhdGUgc291cmNlIHJhbmdlIGFuZCBidWlsdCBmaWx0ZXIgdmFsdWVzXG5cbiAgZm9yIChkZXN0UGl4ZWwgPSAwOyBkZXN0UGl4ZWwgPCBkZXN0U2l6ZTsgZGVzdFBpeGVsKyspIHtcbiAgICAvLyBTY2FsaW5nIHNob3VsZCBiZSBkb25lIHJlbGF0aXZlIHRvIGNlbnRyYWwgcGl4ZWwgcG9pbnRcbiAgICBzcmNQaXhlbCA9IChkZXN0UGl4ZWwgKyAwLjUpICogc2NhbGVJbnZlcnRlZCArIG9mZnNldDtcbiAgICBzcmNGaXJzdCA9IE1hdGgubWF4KDAsIE1hdGguZmxvb3Ioc3JjUGl4ZWwgLSBzcmNXaW5kb3cpKTtcbiAgICBzcmNMYXN0ID0gTWF0aC5taW4oc3JjU2l6ZSAtIDEsIE1hdGguY2VpbChzcmNQaXhlbCArIHNyY1dpbmRvdykpO1xuICAgIGZpbHRlckVsZW1lbnRTaXplID0gc3JjTGFzdCAtIHNyY0ZpcnN0ICsgMTtcbiAgICBmbG9hdEZpbHRlciA9IG5ldyBGbG9hdDMyQXJyYXkoZmlsdGVyRWxlbWVudFNpemUpO1xuICAgIGZ4cEZpbHRlciA9IG5ldyBJbnQxNkFycmF5KGZpbHRlckVsZW1lbnRTaXplKTtcbiAgICB0b3RhbCA9IDAuMDsgLy8gRmlsbCBmaWx0ZXIgdmFsdWVzIGZvciBjYWxjdWxhdGVkIHJhbmdlXG5cbiAgICBmb3IgKHB4bCA9IHNyY0ZpcnN0LCBpZHggPSAwOyBweGwgPD0gc3JjTGFzdDsgcHhsKyssIGlkeCsrKSB7XG4gICAgICBmbG9hdFZhbCA9IGZpbHRlckZ1bmN0aW9uKChweGwgKyAwLjUgLSBzcmNQaXhlbCkgKiBzY2FsZUNsYW1wZWQpO1xuICAgICAgdG90YWwgKz0gZmxvYXRWYWw7XG4gICAgICBmbG9hdEZpbHRlcltpZHhdID0gZmxvYXRWYWw7XG4gICAgfSAvLyBOb3JtYWxpemUgZmlsdGVyLCBjb252ZXJ0IHRvIGZpeGVkIHBvaW50IGFuZCBhY2N1bXVsYXRlIGNvbnZlcnNpb24gZXJyb3JcblxuXG4gICAgZmlsdGVyVG90YWwgPSAwO1xuXG4gICAgZm9yIChpZHggPSAwOyBpZHggPCBmbG9hdEZpbHRlci5sZW5ndGg7IGlkeCsrKSB7XG4gICAgICBmaWx0ZXJWYWwgPSBmbG9hdEZpbHRlcltpZHhdIC8gdG90YWw7XG4gICAgICBmaWx0ZXJUb3RhbCArPSBmaWx0ZXJWYWw7XG4gICAgICBmeHBGaWx0ZXJbaWR4XSA9IHRvRml4ZWRQb2ludChmaWx0ZXJWYWwpO1xuICAgIH0gLy8gQ29tcGVuc2F0ZSBub3JtYWxpemF0aW9uIGVycm9yLCB0byBtaW5pbWl6ZSBicmlnaHRuZXNzIGRyaWZ0XG5cblxuICAgIGZ4cEZpbHRlcltkZXN0U2l6ZSA+PiAxXSArPSB0b0ZpeGVkUG9pbnQoMS4wIC0gZmlsdGVyVG90YWwpOyAvL1xuICAgIC8vIE5vdyBwYWNrIGZpbHRlciB0byB1c2VhYmxlIGZvcm1cbiAgICAvL1xuICAgIC8vIDEuIFRyaW0gaGVhZGluZyBhbmQgdGFpbGluZyB6ZXJvIHZhbHVlcywgYW5kIGNvbXBlbnNhdGUgc2hpdGYvbGVuZ3RoXG4gICAgLy8gMi4gUHV0IGFsbCB0byBzaW5nbGUgYXJyYXkgaW4gdGhpcyBmb3JtYXQ6XG4gICAgLy9cbiAgICAvLyAgICBbIHBvcyBzaGlmdCwgZGF0YSBsZW5ndGgsIHZhbHVlMSwgdmFsdWUyLCB2YWx1ZTMsIC4uLiBdXG4gICAgLy9cblxuICAgIGxlZnROb3RFbXB0eSA9IDA7XG5cbiAgICB3aGlsZSAobGVmdE5vdEVtcHR5IDwgZnhwRmlsdGVyLmxlbmd0aCAmJiBmeHBGaWx0ZXJbbGVmdE5vdEVtcHR5XSA9PT0gMCkge1xuICAgICAgbGVmdE5vdEVtcHR5Kys7XG4gICAgfVxuXG4gICAgaWYgKGxlZnROb3RFbXB0eSA8IGZ4cEZpbHRlci5sZW5ndGgpIHtcbiAgICAgIHJpZ2h0Tm90RW1wdHkgPSBmeHBGaWx0ZXIubGVuZ3RoIC0gMTtcblxuICAgICAgd2hpbGUgKHJpZ2h0Tm90RW1wdHkgPiAwICYmIGZ4cEZpbHRlcltyaWdodE5vdEVtcHR5XSA9PT0gMCkge1xuICAgICAgICByaWdodE5vdEVtcHR5LS07XG4gICAgICB9XG5cbiAgICAgIGZpbHRlclNoaWZ0ID0gc3JjRmlyc3QgKyBsZWZ0Tm90RW1wdHk7XG4gICAgICBmaWx0ZXJTaXplID0gcmlnaHROb3RFbXB0eSAtIGxlZnROb3RFbXB0eSArIDE7XG4gICAgICBwYWNrZWRGaWx0ZXJbcGFja2VkRmlsdGVyUHRyKytdID0gZmlsdGVyU2hpZnQ7IC8vIHNoaWZ0XG5cbiAgICAgIHBhY2tlZEZpbHRlcltwYWNrZWRGaWx0ZXJQdHIrK10gPSBmaWx0ZXJTaXplOyAvLyBzaXplXG5cbiAgICAgIGlmICghc2xvd0NvcHkpIHtcbiAgICAgICAgcGFja2VkRmlsdGVyLnNldChmeHBGaWx0ZXIuc3ViYXJyYXkobGVmdE5vdEVtcHR5LCByaWdodE5vdEVtcHR5ICsgMSksIHBhY2tlZEZpbHRlclB0cik7XG4gICAgICAgIHBhY2tlZEZpbHRlclB0ciArPSBmaWx0ZXJTaXplO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZmFsbGJhY2sgZm9yIG9sZCBJRSA8IDExLCB3aXRob3V0IHN1YmFycmF5L3NldCBtZXRob2RzXG4gICAgICAgIGZvciAoaWR4ID0gbGVmdE5vdEVtcHR5OyBpZHggPD0gcmlnaHROb3RFbXB0eTsgaWR4KyspIHtcbiAgICAgICAgICBwYWNrZWRGaWx0ZXJbcGFja2VkRmlsdGVyUHRyKytdID0gZnhwRmlsdGVyW2lkeF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gemVybyBkYXRhLCB3cml0ZSBoZWFkZXIgb25seVxuICAgICAgcGFja2VkRmlsdGVyW3BhY2tlZEZpbHRlclB0cisrXSA9IDA7IC8vIHNoaWZ0XG5cbiAgICAgIHBhY2tlZEZpbHRlcltwYWNrZWRGaWx0ZXJQdHIrK10gPSAwOyAvLyBzaXplXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHBhY2tlZEZpbHRlcjtcbn07XG5cbn0se1wiLi9yZXNpemVfZmlsdGVyX2luZm9cIjo3fV0sNzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBGaWx0ZXIgZGVmaW5pdGlvbnMgdG8gYnVpbGQgdGFibGVzIGZvclxuLy8gcmVzaXppbmcgY29udm9sdmVycy5cbi8vXG4vLyBQcmVzZXRzIGZvciBxdWFsaXR5IDAuLjMuIEZpbHRlciBmdW5jdGlvbnMgKyB3aW5kb3cgc2l6ZVxuLy9cbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBbe1xuICAvLyBOZWFyZXN0IG5laWJvciAoQm94KVxuICB3aW46IDAuNSxcbiAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoeCkge1xuICAgIHJldHVybiB4ID49IC0wLjUgJiYgeCA8IDAuNSA/IDEuMCA6IDAuMDtcbiAgfVxufSwge1xuICAvLyBIYW1taW5nXG4gIHdpbjogMS4wLFxuICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcih4KSB7XG4gICAgaWYgKHggPD0gLTEuMCB8fCB4ID49IDEuMCkge1xuICAgICAgcmV0dXJuIDAuMDtcbiAgICB9XG5cbiAgICBpZiAoeCA+IC0xLjE5MjA5MjkwRS0wNyAmJiB4IDwgMS4xOTIwOTI5MEUtMDcpIHtcbiAgICAgIHJldHVybiAxLjA7XG4gICAgfVxuXG4gICAgdmFyIHhwaSA9IHggKiBNYXRoLlBJO1xuICAgIHJldHVybiBNYXRoLnNpbih4cGkpIC8geHBpICogKDAuNTQgKyAwLjQ2ICogTWF0aC5jb3MoeHBpIC8gMS4wKSk7XG4gIH1cbn0sIHtcbiAgLy8gTGFuY3pvcywgd2luID0gMlxuICB3aW46IDIuMCxcbiAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoeCkge1xuICAgIGlmICh4IDw9IC0yLjAgfHwgeCA+PSAyLjApIHtcbiAgICAgIHJldHVybiAwLjA7XG4gICAgfVxuXG4gICAgaWYgKHggPiAtMS4xOTIwOTI5MEUtMDcgJiYgeCA8IDEuMTkyMDkyOTBFLTA3KSB7XG4gICAgICByZXR1cm4gMS4wO1xuICAgIH1cblxuICAgIHZhciB4cGkgPSB4ICogTWF0aC5QSTtcbiAgICByZXR1cm4gTWF0aC5zaW4oeHBpKSAvIHhwaSAqIE1hdGguc2luKHhwaSAvIDIuMCkgLyAoeHBpIC8gMi4wKTtcbiAgfVxufSwge1xuICAvLyBMYW5jem9zLCB3aW4gPSAzXG4gIHdpbjogMy4wLFxuICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcih4KSB7XG4gICAgaWYgKHggPD0gLTMuMCB8fCB4ID49IDMuMCkge1xuICAgICAgcmV0dXJuIDAuMDtcbiAgICB9XG5cbiAgICBpZiAoeCA+IC0xLjE5MjA5MjkwRS0wNyAmJiB4IDwgMS4xOTIwOTI5MEUtMDcpIHtcbiAgICAgIHJldHVybiAxLjA7XG4gICAgfVxuXG4gICAgdmFyIHhwaSA9IHggKiBNYXRoLlBJO1xuICAgIHJldHVybiBNYXRoLnNpbih4cGkpIC8geHBpICogTWF0aC5zaW4oeHBpIC8gMy4wKSAvICh4cGkgLyAzLjApO1xuICB9XG59XTtcblxufSx7fV0sODpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBjcmVhdGVGaWx0ZXJzID0gX2RlcmVxXygnLi9yZXNpemVfZmlsdGVyX2dlbicpO1xuXG5mdW5jdGlvbiByZXNldEFscGhhKGRzdCwgd2lkdGgsIGhlaWdodCkge1xuICB2YXIgcHRyID0gMyxcbiAgICAgIGxlbiA9IHdpZHRoICogaGVpZ2h0ICogNCB8IDA7XG5cbiAgd2hpbGUgKHB0ciA8IGxlbikge1xuICAgIGRzdFtwdHJdID0gMHhGRjtcbiAgICBwdHIgPSBwdHIgKyA0IHwgMDtcbiAgfVxufVxuXG5mdW5jdGlvbiBhc1VpbnQ4QXJyYXkoc3JjKSB7XG4gIHJldHVybiBuZXcgVWludDhBcnJheShzcmMuYnVmZmVyLCAwLCBzcmMuYnl0ZUxlbmd0aCk7XG59XG5cbnZhciBJU19MRSA9IHRydWU7IC8vIHNob3VsZCBub3QgY3Jhc2ggZXZlcnl0aGluZyBvbiBtb2R1bGUgbG9hZCBpbiBvbGQgYnJvd3NlcnNcblxudHJ5IHtcbiAgSVNfTEUgPSBuZXcgVWludDMyQXJyYXkobmV3IFVpbnQ4QXJyYXkoWzEsIDAsIDAsIDBdKS5idWZmZXIpWzBdID09PSAxO1xufSBjYXRjaCAoX18pIHt9XG5cbmZ1bmN0aW9uIGNvcHlJbnQxNmFzTEUoc3JjLCB0YXJnZXQsIHRhcmdldF9vZmZzZXQpIHtcbiAgaWYgKElTX0xFKSB7XG4gICAgdGFyZ2V0LnNldChhc1VpbnQ4QXJyYXkoc3JjKSwgdGFyZ2V0X29mZnNldCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZm9yICh2YXIgcHRyID0gdGFyZ2V0X29mZnNldCwgaSA9IDA7IGkgPCBzcmMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZGF0YSA9IHNyY1tpXTtcbiAgICB0YXJnZXRbcHRyKytdID0gZGF0YSAmIDB4RkY7XG4gICAgdGFyZ2V0W3B0cisrXSA9IGRhdGEgPj4gOCAmIDB4RkY7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiByZXNpemVfd2FzbShvcHRpb25zKSB7XG4gIHZhciBzcmMgPSBvcHRpb25zLnNyYztcbiAgdmFyIHNyY1cgPSBvcHRpb25zLndpZHRoO1xuICB2YXIgc3JjSCA9IG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgZGVzdFcgPSBvcHRpb25zLnRvV2lkdGg7XG4gIHZhciBkZXN0SCA9IG9wdGlvbnMudG9IZWlnaHQ7XG4gIHZhciBzY2FsZVggPSBvcHRpb25zLnNjYWxlWCB8fCBvcHRpb25zLnRvV2lkdGggLyBvcHRpb25zLndpZHRoO1xuICB2YXIgc2NhbGVZID0gb3B0aW9ucy5zY2FsZVkgfHwgb3B0aW9ucy50b0hlaWdodCAvIG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgb2Zmc2V0WCA9IG9wdGlvbnMub2Zmc2V0WCB8fCAwLjA7XG4gIHZhciBvZmZzZXRZID0gb3B0aW9ucy5vZmZzZXRZIHx8IDAuMDtcbiAgdmFyIGRlc3QgPSBvcHRpb25zLmRlc3QgfHwgbmV3IFVpbnQ4QXJyYXkoZGVzdFcgKiBkZXN0SCAqIDQpO1xuICB2YXIgcXVhbGl0eSA9IHR5cGVvZiBvcHRpb25zLnF1YWxpdHkgPT09ICd1bmRlZmluZWQnID8gMyA6IG9wdGlvbnMucXVhbGl0eTtcbiAgdmFyIGFscGhhID0gb3B0aW9ucy5hbHBoYSB8fCBmYWxzZTtcbiAgdmFyIGZpbHRlcnNYID0gY3JlYXRlRmlsdGVycyhxdWFsaXR5LCBzcmNXLCBkZXN0Vywgc2NhbGVYLCBvZmZzZXRYKSxcbiAgICAgIGZpbHRlcnNZID0gY3JlYXRlRmlsdGVycyhxdWFsaXR5LCBzcmNILCBkZXN0SCwgc2NhbGVZLCBvZmZzZXRZKTsgLy8gZGVzdGluYXRpb24gaXMgMCB0b28uXG5cbiAgdmFyIHNyY19vZmZzZXQgPSAwOyAvLyBidWZmZXIgYmV0d2VlbiBjb252b2x2ZSBwYXNzZXNcblxuICB2YXIgdG1wX29mZnNldCA9IHRoaXMuX19hbGlnbihzcmNfb2Zmc2V0ICsgTWF0aC5tYXgoc3JjLmJ5dGVMZW5ndGgsIGRlc3QuYnl0ZUxlbmd0aCkpO1xuXG4gIHZhciBmaWx0ZXJzWF9vZmZzZXQgPSB0aGlzLl9fYWxpZ24odG1wX29mZnNldCArIHNyY0ggKiBkZXN0VyAqIDQpO1xuXG4gIHZhciBmaWx0ZXJzWV9vZmZzZXQgPSB0aGlzLl9fYWxpZ24oZmlsdGVyc1hfb2Zmc2V0ICsgZmlsdGVyc1guYnl0ZUxlbmd0aCk7XG5cbiAgdmFyIGFsbG9jX2J5dGVzID0gZmlsdGVyc1lfb2Zmc2V0ICsgZmlsdGVyc1kuYnl0ZUxlbmd0aDtcblxuICB2YXIgaW5zdGFuY2UgPSB0aGlzLl9faW5zdGFuY2UoJ3Jlc2l6ZScsIGFsbG9jX2J5dGVzKTsgLy9cbiAgLy8gRmlsbCBtZW1vcnkgYmxvY2sgd2l0aCBkYXRhIHRvIHByb2Nlc3NcbiAgLy9cblxuXG4gIHZhciBtZW0gPSBuZXcgVWludDhBcnJheSh0aGlzLl9fbWVtb3J5LmJ1ZmZlcik7XG4gIHZhciBtZW0zMiA9IG5ldyBVaW50MzJBcnJheSh0aGlzLl9fbWVtb3J5LmJ1ZmZlcik7IC8vIDMyLWJpdCBjb3B5IGlzIG11Y2ggZmFzdGVyIGluIGNocm9tZVxuXG4gIHZhciBzcmMzMiA9IG5ldyBVaW50MzJBcnJheShzcmMuYnVmZmVyKTtcbiAgbWVtMzIuc2V0KHNyYzMyKTsgLy8gV2Ugc2hvdWxkIGd1YXJhbnRlZSBMRSBieXRlcyBvcmRlci4gRmlsdGVycyBhcmUgbm90IGJpZywgc29cbiAgLy8gc3BlZWQgZGlmZmVyZW5jZSBpcyBub3Qgc2lnbmlmaWNhbnQgdnMgZGlyZWN0IC5zZXQoKVxuXG4gIGNvcHlJbnQxNmFzTEUoZmlsdGVyc1gsIG1lbSwgZmlsdGVyc1hfb2Zmc2V0KTtcbiAgY29weUludDE2YXNMRShmaWx0ZXJzWSwgbWVtLCBmaWx0ZXJzWV9vZmZzZXQpOyAvL1xuICAvLyBOb3cgY2FsbCB3ZWJhc3NlbWJseSBtZXRob2RcbiAgLy8gZW1zZGsgZG9lcyBtZXRob2QgbmFtZXMgd2l0aCAnXydcblxuICB2YXIgZm4gPSBpbnN0YW5jZS5leHBvcnRzLmNvbnZvbHZlSFYgfHwgaW5zdGFuY2UuZXhwb3J0cy5fY29udm9sdmVIVjtcbiAgZm4oZmlsdGVyc1hfb2Zmc2V0LCBmaWx0ZXJzWV9vZmZzZXQsIHRtcF9vZmZzZXQsIHNyY1csIHNyY0gsIGRlc3RXLCBkZXN0SCk7IC8vXG4gIC8vIENvcHkgZGF0YSBiYWNrIHRvIHR5cGVkIGFycmF5XG4gIC8vXG4gIC8vIDMyLWJpdCBjb3B5IGlzIG11Y2ggZmFzdGVyIGluIGNocm9tZVxuXG4gIHZhciBkZXN0MzIgPSBuZXcgVWludDMyQXJyYXkoZGVzdC5idWZmZXIpO1xuICBkZXN0MzIuc2V0KG5ldyBVaW50MzJBcnJheSh0aGlzLl9fbWVtb3J5LmJ1ZmZlciwgMCwgZGVzdEggKiBkZXN0VykpOyAvLyBUaGF0J3MgZmFzdGVyIHRoYW4gZG9pbmcgY2hlY2tzIGluIGNvbnZvbHZlci5cbiAgLy8gISEhIE5vdGUsIGNhbnZhcyBkYXRhIGlzIG5vdCBwcmVtdWx0aXBsZWQuIFdlIGRvbid0IG5lZWQgb3RoZXJcbiAgLy8gYWxwaGEgY29ycmVjdGlvbnMuXG5cbiAgaWYgKCFhbHBoYSkgcmVzZXRBbHBoYShkZXN0LCBkZXN0VywgZGVzdEgpO1xuICByZXR1cm4gZGVzdDtcbn07XG5cbn0se1wiLi9yZXNpemVfZmlsdGVyX2dlblwiOjZ9XSw5OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIG5hbWU6ICd1bnNoYXJwX21hc2snLFxuICBmbjogX2RlcmVxXygnLi91bnNoYXJwX21hc2snKSxcbiAgd2FzbV9mbjogX2RlcmVxXygnLi91bnNoYXJwX21hc2tfd2FzbScpLFxuICB3YXNtX3NyYzogX2RlcmVxXygnLi91bnNoYXJwX21hc2tfd2FzbV9iYXNlNjQnKVxufTtcblxufSx7XCIuL3Vuc2hhcnBfbWFza1wiOjEwLFwiLi91bnNoYXJwX21hc2tfd2FzbVwiOjExLFwiLi91bnNoYXJwX21hc2tfd2FzbV9iYXNlNjRcIjoxMn1dLDEwOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIFVuc2hhcnAgbWFzayBmaWx0ZXJcbi8vXG4vLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMzMyMjgyMC8xMDMxODA0XG4vLyBVU00oTykgPSBPICsgKDIgKiAoQW1vdW50IC8gMTAwKSAqIChPIC0gR0IpKVxuLy8gR0IgLSBnYXVzc2lhbiBibHVyLlxuLy9cbi8vIEltYWdlIGlzIGNvbnZlcnRlZCBmcm9tIFJHQiB0byBIU1YsIHVuc2hhcnAgbWFzayBpcyBhcHBsaWVkIHRvIHRoZVxuLy8gYnJpZ2h0bmVzcyBjaGFubmVsIGFuZCB0aGVuIGltYWdlIGlzIGNvbnZlcnRlZCBiYWNrIHRvIFJHQi5cbi8vXG4ndXNlIHN0cmljdCc7XG5cbnZhciBnbHVyX21vbm8xNiA9IF9kZXJlcV8oJ2dsdXIvbW9ubzE2Jyk7XG5cbmZ1bmN0aW9uIGhzdl92MTYoaW1nLCB3aWR0aCwgaGVpZ2h0KSB7XG4gIHZhciBzaXplID0gd2lkdGggKiBoZWlnaHQ7XG4gIHZhciBvdXQgPSBuZXcgVWludDE2QXJyYXkoc2l6ZSk7XG4gIHZhciByLCBnLCBiLCBtYXg7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICByID0gaW1nWzQgKiBpXTtcbiAgICBnID0gaW1nWzQgKiBpICsgMV07XG4gICAgYiA9IGltZ1s0ICogaSArIDJdO1xuICAgIG1heCA9IHIgPj0gZyAmJiByID49IGIgPyByIDogZyA+PSBiICYmIGcgPj0gciA/IGcgOiBiO1xuICAgIG91dFtpXSA9IG1heCA8PCA4O1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB1bnNoYXJwKGltZywgd2lkdGgsIGhlaWdodCwgYW1vdW50LCByYWRpdXMsIHRocmVzaG9sZCkge1xuICB2YXIgdjEsIHYyLCB2bXVsO1xuICB2YXIgZGlmZiwgaVRpbWVzNDtcblxuICBpZiAoYW1vdW50ID09PSAwIHx8IHJhZGl1cyA8IDAuNSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChyYWRpdXMgPiAyLjApIHtcbiAgICByYWRpdXMgPSAyLjA7XG4gIH1cblxuICB2YXIgYnJpZ2h0bmVzcyA9IGhzdl92MTYoaW1nLCB3aWR0aCwgaGVpZ2h0KTtcbiAgdmFyIGJsdXJlZCA9IG5ldyBVaW50MTZBcnJheShicmlnaHRuZXNzKTsgLy8gY29weSwgYmVjYXVzZSBibHVyIG1vZGlmeSBzcmNcblxuICBnbHVyX21vbm8xNihibHVyZWQsIHdpZHRoLCBoZWlnaHQsIHJhZGl1cyk7XG4gIHZhciBhbW91bnRGcCA9IGFtb3VudCAvIDEwMCAqIDB4MTAwMCArIDAuNSB8IDA7XG4gIHZhciB0aHJlc2hvbGRGcCA9IHRocmVzaG9sZCA8PCA4O1xuICB2YXIgc2l6ZSA9IHdpZHRoICogaGVpZ2h0O1xuICAvKiBlc2xpbnQtZGlzYWJsZSBpbmRlbnQgKi9cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7IGkrKykge1xuICAgIHYxID0gYnJpZ2h0bmVzc1tpXTtcbiAgICBkaWZmID0gdjEgLSBibHVyZWRbaV07XG5cbiAgICBpZiAoTWF0aC5hYnMoZGlmZikgPj0gdGhyZXNob2xkRnApIHtcbiAgICAgIC8vIGFkZCB1bnNoYXJwIG1hc2sgdG8gdGhlIGJyaWdodG5lc3MgY2hhbm5lbFxuICAgICAgdjIgPSB2MSArIChhbW91bnRGcCAqIGRpZmYgKyAweDgwMCA+PiAxMik7IC8vIEJvdGggdjEgYW5kIHYyIGFyZSB3aXRoaW4gWzAuMCAuLiAyNTUuMF0gKDAwMDAtRkYwMCkgcmFuZ2UsIG5ldmVyIGdvaW5nIGludG9cbiAgICAgIC8vIFsyNTUuMDAzIC4uIDI1NS45OTZdIChGRjAxLUZGRkYpLiBUaGlzIGFsbG93cyB0byByb3VuZCB0aGlzIHZhbHVlIGFzICh4Ky41KXwwXG4gICAgICAvLyBsYXRlciB3aXRob3V0IG92ZXJmbG93aW5nLlxuXG4gICAgICB2MiA9IHYyID4gMHhmZjAwID8gMHhmZjAwIDogdjI7XG4gICAgICB2MiA9IHYyIDwgMHgwMDAwID8gMHgwMDAwIDogdjI7IC8vIEF2b2lkIGRpdmlzaW9uIGJ5IDAuIFY9MCBtZWFucyByZ2IoMCwwLDApLCB1bnNoYXJwIHdpdGggdW5zaGFycEFtb3VudD4wIGNhbm5vdFxuICAgICAgLy8gY2hhbmdlIHRoaXMgdmFsdWUgKGJlY2F1c2UgZGlmZiBiZXR3ZWVuIGNvbG9ycyBnZXRzIGluZmxhdGVkKSwgc28gbm8gbmVlZCB0byB2ZXJpZnkgY29ycmVjdG5lc3MuXG5cbiAgICAgIHYxID0gdjEgIT09IDAgPyB2MSA6IDE7IC8vIE11bHRpcGx5aW5nIFYgaW4gSFNWIG1vZGVsIGJ5IGEgY29uc3RhbnQgaXMgZXF1aXZhbGVudCB0byBtdWx0aXBseWluZyBlYWNoIGNvbXBvbmVudFxuICAgICAgLy8gaW4gUkdCIGJ5IHRoZSBzYW1lIGNvbnN0YW50IChzYW1lIGZvciBIU0wpLCBzZWUgYWxzbzpcbiAgICAgIC8vIGh0dHBzOi8vYmVlc2J1enouYml6L2NvZGUvMTYtaHN2LWNvbG9yLXRyYW5zZm9ybXNcblxuICAgICAgdm11bCA9ICh2MiA8PCAxMikgLyB2MSB8IDA7IC8vIFJlc3VsdCB3aWxsIGJlIGluIFswLi4yNTVdIHJhbmdlIGJlY2F1c2U6XG4gICAgICAvLyAgLSBhbGwgbnVtYmVycyBhcmUgcG9zaXRpdmVcbiAgICAgIC8vICAtIHIsZyxiIDw9ICh2MS8yNTYpXG4gICAgICAvLyAgLSByLGcsYiwodjEvMjU2KSwodjIvMjU2KSA8PSAyNTVcbiAgICAgIC8vIFNvIGhpZ2hlc3QgdGhpcyBudW1iZXIgY2FuIGdldCBpcyBYKjI1NS9YKzAuNT0yNTUuNSB3aGljaCBpcyA8IDI1NiBhbmQgcm91bmRzIGRvd24uXG5cbiAgICAgIGlUaW1lczQgPSBpICogNDtcbiAgICAgIGltZ1tpVGltZXM0XSA9IGltZ1tpVGltZXM0XSAqIHZtdWwgKyAweDgwMCA+PiAxMjsgLy8gUlxuXG4gICAgICBpbWdbaVRpbWVzNCArIDFdID0gaW1nW2lUaW1lczQgKyAxXSAqIHZtdWwgKyAweDgwMCA+PiAxMjsgLy8gR1xuXG4gICAgICBpbWdbaVRpbWVzNCArIDJdID0gaW1nW2lUaW1lczQgKyAyXSAqIHZtdWwgKyAweDgwMCA+PiAxMjsgLy8gQlxuICAgIH1cbiAgfVxufTtcblxufSx7XCJnbHVyL21vbm8xNlwiOjE4fV0sMTE6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHVuc2hhcnAoaW1nLCB3aWR0aCwgaGVpZ2h0LCBhbW91bnQsIHJhZGl1cywgdGhyZXNob2xkKSB7XG4gIGlmIChhbW91bnQgPT09IDAgfHwgcmFkaXVzIDwgMC41KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHJhZGl1cyA+IDIuMCkge1xuICAgIHJhZGl1cyA9IDIuMDtcbiAgfVxuXG4gIHZhciBwaXhlbHMgPSB3aWR0aCAqIGhlaWdodDtcbiAgdmFyIGltZ19ieXRlc19jbnQgPSBwaXhlbHMgKiA0O1xuICB2YXIgaHN2X2J5dGVzX2NudCA9IHBpeGVscyAqIDI7XG4gIHZhciBibHVyX2J5dGVzX2NudCA9IHBpeGVscyAqIDI7XG4gIHZhciBibHVyX2xpbmVfYnl0ZV9jbnQgPSBNYXRoLm1heCh3aWR0aCwgaGVpZ2h0KSAqIDQ7IC8vIGZsb2F0MzIgYXJyYXlcblxuICB2YXIgYmx1cl9jb2VmZnNfYnl0ZV9jbnQgPSA4ICogNDsgLy8gZmxvYXQzMiBhcnJheVxuXG4gIHZhciBpbWdfb2Zmc2V0ID0gMDtcbiAgdmFyIGhzdl9vZmZzZXQgPSBpbWdfYnl0ZXNfY250O1xuICB2YXIgYmx1cl9vZmZzZXQgPSBoc3Zfb2Zmc2V0ICsgaHN2X2J5dGVzX2NudDtcbiAgdmFyIGJsdXJfdG1wX29mZnNldCA9IGJsdXJfb2Zmc2V0ICsgYmx1cl9ieXRlc19jbnQ7XG4gIHZhciBibHVyX2xpbmVfb2Zmc2V0ID0gYmx1cl90bXBfb2Zmc2V0ICsgYmx1cl9ieXRlc19jbnQ7XG4gIHZhciBibHVyX2NvZWZmc19vZmZzZXQgPSBibHVyX2xpbmVfb2Zmc2V0ICsgYmx1cl9saW5lX2J5dGVfY250O1xuXG4gIHZhciBpbnN0YW5jZSA9IHRoaXMuX19pbnN0YW5jZSgndW5zaGFycF9tYXNrJywgaW1nX2J5dGVzX2NudCArIGhzdl9ieXRlc19jbnQgKyBibHVyX2J5dGVzX2NudCAqIDIgKyBibHVyX2xpbmVfYnl0ZV9jbnQgKyBibHVyX2NvZWZmc19ieXRlX2NudCwge1xuICAgIGV4cDogTWF0aC5leHBcbiAgfSk7IC8vIDMyLWJpdCBjb3B5IGlzIG11Y2ggZmFzdGVyIGluIGNocm9tZVxuXG5cbiAgdmFyIGltZzMyID0gbmV3IFVpbnQzMkFycmF5KGltZy5idWZmZXIpO1xuICB2YXIgbWVtMzIgPSBuZXcgVWludDMyQXJyYXkodGhpcy5fX21lbW9yeS5idWZmZXIpO1xuICBtZW0zMi5zZXQoaW1nMzIpOyAvLyBIU0xcblxuICB2YXIgZm4gPSBpbnN0YW5jZS5leHBvcnRzLmhzdl92MTYgfHwgaW5zdGFuY2UuZXhwb3J0cy5faHN2X3YxNjtcbiAgZm4oaW1nX29mZnNldCwgaHN2X29mZnNldCwgd2lkdGgsIGhlaWdodCk7IC8vIEJMVVJcblxuICBmbiA9IGluc3RhbmNlLmV4cG9ydHMuYmx1ck1vbm8xNiB8fCBpbnN0YW5jZS5leHBvcnRzLl9ibHVyTW9ubzE2O1xuICBmbihoc3Zfb2Zmc2V0LCBibHVyX29mZnNldCwgYmx1cl90bXBfb2Zmc2V0LCBibHVyX2xpbmVfb2Zmc2V0LCBibHVyX2NvZWZmc19vZmZzZXQsIHdpZHRoLCBoZWlnaHQsIHJhZGl1cyk7IC8vIFVOU0hBUlBcblxuICBmbiA9IGluc3RhbmNlLmV4cG9ydHMudW5zaGFycCB8fCBpbnN0YW5jZS5leHBvcnRzLl91bnNoYXJwO1xuICBmbihpbWdfb2Zmc2V0LCBpbWdfb2Zmc2V0LCBoc3Zfb2Zmc2V0LCBibHVyX29mZnNldCwgd2lkdGgsIGhlaWdodCwgYW1vdW50LCB0aHJlc2hvbGQpOyAvLyAzMi1iaXQgY29weSBpcyBtdWNoIGZhc3RlciBpbiBjaHJvbWVcblxuICBpbWczMi5zZXQobmV3IFVpbnQzMkFycmF5KHRoaXMuX19tZW1vcnkuYnVmZmVyLCAwLCBwaXhlbHMpKTtcbn07XG5cbn0se31dLDEyOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIFRoaXMgaXMgYXV0b2dlbmVyYXRlZCBmaWxlIGZyb20gbWF0aC53YXNtLCBkb24ndCBlZGl0LlxuLy9cbid1c2Ugc3RyaWN0Jztcbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSAnQUdGemJRRUFBQUFBREFaa2VXeHBibXNBQUFBQUFBRTBCMkFBQUdBRWYzOS9md0JnQm45L2YzOS9md0JnQ0g5L2YzOS9mMzkvQUdBSWYzOS9mMzkvZjMwQVlBSjlmd0JnQVh3QmZBSVpBZ05sYm5ZRFpYaHdBQVlEWlc1MkJtMWxiVzl5ZVFJQUFBTUhCZ0FGQWdRQkF3WUdBWDhBUVFBTEI0b0JDQkZmWDNkaGMyMWZZMkZzYkY5amRHOXljd0FCRmw5ZlluVnBiR1JmWjJGMWMzTnBZVzVmWTI5bFpuTUFBZzVmWDJkaGRYTnpNVFpmYkdsdVpRQURDbUpzZFhKTmIyNXZNVFlBQkFkb2MzWmZkakUyQUFVSGRXNXphR0Z5Y0FBR0RGOWZaSE52WDJoaGJtUnNaUU1BR0Y5ZmQyRnpiVjloY0hCc2VWOWtZWFJoWDNKbGJHOWpjd0FCQ3NVTUJnTUFBUXZXQVFFSGZDQUJSTnVHdWtPQ0d2cy9JQUM3b3lJQ1JBQUFBQUFBQUFEQW9oQUFJZ1cyakRnQ0ZDQUJJQUthRUFBaUF5QURvQ0lHdGpnQ0VDQUJSQUFBQUFBQUFQQS9JQU9oSWdRZ0JLSWdBeUFDSUFLZ29rUUFBQUFBQUFEd1A2QWdCYUdqSWdTMk9BSUFJQUVnQlNBRW1xSWlCN1k0QWd3Z0FTQURJQUpFQUFBQUFBQUE4RCtnSUFTaW9pSUl0amdDQ0NBQklBTWdBa1FBQUFBQUFBRHd2NkFnQktLaUlnSzJPQUlFSUFFZ0J5QUlvQ0FGUkFBQUFBQUFBUEEvSUFhaG9DSURvN1k0QWh3Z0FTQUVJQUtnSUFPanRqZ0NHQXVHQlFNR2Z3bDhBbjBnQXlvQ0RDRVZJQU1xQWdnaEZpQURLZ0lVdXlFUklBTXFBaEM3SVJBQ1FDQUVRUUZySWdoQkFFZ2lDUVJBSUFJaEJ5QUFJUVlNQVFzZ0FpQUFMd0VBdUNJUElBTXFBaGk3b2lJTUlCR2lJZzBnRENBUW9pQVBJQU1xQWdTN0loT2lJaFFnQXlvQ0FMc2lFaUFQb3FDZ29DSU90amdDQUNBQ1FRUnFJUWNnQUVFQ2FpRUdJQWhGRFFBZ0NFRUJJQWhCQVVnYklncEJmM01oQ3dKL0lBUWdDbXRCQVhGRkJFQWdEaUVOSUFnTUFRc2dBaUFOSUE0Z0VLSWdGQ0FTSUFBdkFRSzRJZytpb0tDZ0lnMjJPQUlFSUFKQkNHb2hCeUFBUVFScUlRWWdEaUVNSUFSQkFtc0xJUUlnQzBFQUlBUnJSZzBBQTBBZ0J5QU1JQkdpSUEwZ0VLSWdEeUFUb2lBU0lBWXZBUUM0SWc2aW9LQ2dJZ3kyT0FJQUlBY2dEU0FSb2lBTUlCQ2lJQTRnRTZJZ0VpQUdMd0VDdUNJUG9xQ2dvQ0lOdGpnQ0JDQUhRUWhxSVFjZ0JrRUVhaUVHSUFKQkFrb2hBQ0FDUVFKcklRSWdBQTBBQ3dzQ1FDQUpEUUFnQVNBRklBaHNRUUYwYWlJQUFuOGdCa0VDYXk4QkFDSUN1Q0lOSUJXN0loS2lJQTBnRnJzaUU2S2dJQTBnQXlvQ0hMdWlJZ3dnRUtLZ0lBd2dFYUtnSWc4Z0IwRUVheUlIS2dJQXU2QWlEa1FBQUFBQUFBRHdRV01nRGtRQUFBQUFBQUFBQUdaeEJFQWdEcXNNQVF0QkFBczdBUUFnQ0VVTkFDQUdRUVJySVFaQkFDQUZhMEVCZENFQkEwQUNmeUFOSUJLaUlBSkIvLzhEY2JnaURTQVRvcUFnRHlJT0lCQ2lvQ0FNSUJHaW9DSVBJQWRCQkdzaUJ5b0NBTHVnSWd4RUFBQUFBQUFBOEVGaklBeEVBQUFBQUFBQUFBQm1jUVJBSUF5ckRBRUxRUUFMSVFNZ0JpOEJBQ0VDSUFBZ0FXb2lBQ0FET3dFQUlBWkJBbXNoQmlBSVFRRktJUU1nRGlFTUlBaEJBV3NoQ0NBRERRQUxDd3ZSQWdJQmZ3ZDhBa0FnQjBNQUFBQUFXdzBBSUFSRTI0YTZRNElhK3o4Z0IwTUFBQUEvbDd1aklnbEVBQUFBQUFBQUFNQ2lFQUFpRExhTU9BSVVJQVFnQ1pvUUFDSUtJQXFnSWcyMk9BSVFJQVJFQUFBQUFBQUE4RDhnQ3FFaUN5QUxvaUFLSUFrZ0NhQ2lSQUFBQUFBQUFQQS9vQ0FNb2FNaUM3WTRBZ0FnQkNBTUlBdWFvaUlPdGpnQ0RDQUVJQW9nQ1VRQUFBQUFBQUR3UDZBZ0M2S2lJZysyT0FJSUlBUWdDaUFKUkFBQUFBQUFBUEMvb0NBTG9xSWlDYlk0QWdRZ0JDQU9JQStnSUF4RUFBQUFBQUFBOEQ4Z0RhR2dJZ3FqdGpnQ0hDQUVJQXNnQ2FBZ0NxTzJPQUlZSUFZRVFBTkFJQUFnQlNBSWJFRUJkR29nQWlBSVFRRjBhaUFESUFRZ0JTQUdFQU1nQ0VFQmFpSUlJQVpIRFFBTEN5QUZSUTBBUVFBaENBTkFJQUlnQmlBSWJFRUJkR29nQVNBSVFRRjBhaUFESUFRZ0JpQUZFQU1nQ0VFQmFpSUlJQVZIRFFBTEN3dHhBUU4vSUFJZ0Eyd2lCUVJBQTBBZ0FTQUFLQUlBSWdSQkVIWkIvd0Z4SWdJZ0FpQUVRUWgyUWY4QmNTSURJQU1nQkVIL0FYRWlCRWtiSUFJZ0Ewc2JJZ1lnQmlBRUlBSWdCRXNiSUFNZ0JFc2JRUWgwT3dFQUlBRkJBbW9oQVNBQVFRUnFJUUFnQlVFQmF5SUZEUUFMQ3d1WkFnSURmd0Y4SUFRZ0JXd2hCQUovSUFhelF3QUFnRVdVUXdBQXlFS1Z1MFFBQUFBQUFBRGdQNkFpQzVsRUFBQUFBQUFBNEVGakJFQWdDNm9NQVF0QmdJQ0FnSGdMSVFVZ0JBUkFJQWRCQ0hRaENVRUFJUVlEUUNBSklBSWdCa0VCZENJSGFpOEJBQ0lCSUFNZ0Iyb3ZBUUJySWdjZ0IwRWZkU0lJYWlBSWMwMEVRQ0FBSUFaQkFuUWlDR29pQ2lBRklBZHNRWUFRYWtFTWRTQUJhaUlIUVlEK0F5QUhRWUQrQTBnYklnZEJBQ0FIUVFCS0cwRU1kQ0FCUVFFZ0FSdHVJZ0VnQ2kwQUFHeEJnQkJxUVF4Mk9nQUFJQUFnQ0VFQmNtb2lCeUFCSUFjdEFBQnNRWUFRYWtFTWRqb0FBQ0FBSUFoQkFuSnFJZ2NnQVNBSExRQUFiRUdBRUdwQkRIWTZBQUFMSUFaQkFXb2lCaUFFUncwQUN3c0wnO1xuXG59LHt9XSwxMzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBHQ19JTlRFUlZBTCA9IDEwMDtcblxuZnVuY3Rpb24gUG9vbChjcmVhdGUsIGlkbGUpIHtcbiAgdGhpcy5jcmVhdGUgPSBjcmVhdGU7XG4gIHRoaXMuYXZhaWxhYmxlID0gW107XG4gIHRoaXMuYWNxdWlyZWQgPSB7fTtcbiAgdGhpcy5sYXN0SWQgPSAxO1xuICB0aGlzLnRpbWVvdXRJZCA9IDA7XG4gIHRoaXMuaWRsZSA9IGlkbGUgfHwgMjAwMDtcbn1cblxuUG9vbC5wcm90b3R5cGUuYWNxdWlyZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcblxuICB2YXIgcmVzb3VyY2U7XG5cbiAgaWYgKHRoaXMuYXZhaWxhYmxlLmxlbmd0aCAhPT0gMCkge1xuICAgIHJlc291cmNlID0gdGhpcy5hdmFpbGFibGUucG9wKCk7XG4gIH0gZWxzZSB7XG4gICAgcmVzb3VyY2UgPSB0aGlzLmNyZWF0ZSgpO1xuICAgIHJlc291cmNlLmlkID0gdGhpcy5sYXN0SWQrKztcblxuICAgIHJlc291cmNlLnJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gX3RoaXMucmVsZWFzZShyZXNvdXJjZSk7XG4gICAgfTtcbiAgfVxuXG4gIHRoaXMuYWNxdWlyZWRbcmVzb3VyY2UuaWRdID0gcmVzb3VyY2U7XG4gIHJldHVybiByZXNvdXJjZTtcbn07XG5cblBvb2wucHJvdG90eXBlLnJlbGVhc2UgPSBmdW5jdGlvbiAocmVzb3VyY2UpIHtcbiAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgZGVsZXRlIHRoaXMuYWNxdWlyZWRbcmVzb3VyY2UuaWRdO1xuICByZXNvdXJjZS5sYXN0VXNlZCA9IERhdGUubm93KCk7XG4gIHRoaXMuYXZhaWxhYmxlLnB1c2gocmVzb3VyY2UpO1xuXG4gIGlmICh0aGlzLnRpbWVvdXRJZCA9PT0gMCkge1xuICAgIHRoaXMudGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gX3RoaXMyLmdjKCk7XG4gICAgfSwgR0NfSU5URVJWQUwpO1xuICB9XG59O1xuXG5Qb29sLnByb3RvdHlwZS5nYyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF90aGlzMyA9IHRoaXM7XG5cbiAgdmFyIG5vdyA9IERhdGUubm93KCk7XG4gIHRoaXMuYXZhaWxhYmxlID0gdGhpcy5hdmFpbGFibGUuZmlsdGVyKGZ1bmN0aW9uIChyZXNvdXJjZSkge1xuICAgIGlmIChub3cgLSByZXNvdXJjZS5sYXN0VXNlZCA+IF90aGlzMy5pZGxlKSB7XG4gICAgICByZXNvdXJjZS5kZXN0cm95KCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0pO1xuXG4gIGlmICh0aGlzLmF2YWlsYWJsZS5sZW5ndGggIT09IDApIHtcbiAgICB0aGlzLnRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIF90aGlzMy5nYygpO1xuICAgIH0sIEdDX0lOVEVSVkFMKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnRpbWVvdXRJZCA9IDA7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUG9vbDtcblxufSx7fV0sMTQ6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLy8gQWRkIGludGVybWVkaWF0ZSByZXNpemluZyBzdGVwcyB3aGVuIHNjYWxpbmcgZG93biBieSBhIHZlcnkgbGFyZ2UgZmFjdG9yLlxuLy9cbi8vIEZvciBleGFtcGxlLCB3aGVuIHJlc2l6aW5nIDEwMDAweDEwMDAwIGRvd24gdG8gMTB4MTAsIGl0J2xsIHJlc2l6ZSBpdCB0b1xuLy8gMzAweDMwMCBmaXJzdC5cbi8vXG4vLyBJdCdzIG5lZWRlZCBiZWNhdXNlIHRpbGVyIGhhcyBpc3N1ZXMgd2hlbiB0aGUgZW50aXJlIHRpbGUgaXMgc2NhbGVkIGRvd25cbi8vIHRvIGEgZmV3IHBpeGVscyAoMTAyNHB4IHNvdXJjZSB0aWxlIHdpdGggYm9yZGVyIHNpemUgMyBzaG91bGQgcmVzdWx0IGluXG4vLyBhdCBsZWFzdCAzKzMrMiA9IDhweCB0YXJnZXQgdGlsZSwgc28gbWF4IHNjYWxlIGZhY3RvciBpcyAxMjggaGVyZSkuXG4vL1xuLy8gQWxzbywgYWRkaW5nIGludGVybWVkaWF0ZSBzdGVwcyBjYW4gc3BlZWQgdXAgcHJvY2Vzc2luZyBpZiB3ZSB1c2UgbG93ZXJcbi8vIHF1YWxpdHkgYWxnb3JpdGhtcyBmb3IgZmlyc3Qgc3RhZ2VzLlxuLy9cbid1c2Ugc3RyaWN0JzsgLy8gbWluIHNpemUgPSAwIHJlc3VsdHMgaW4gaW5maW5pdGUgbG9vcCxcbi8vIG1pbiBzaXplID0gMSBjYW4gY29uc3VtZSBsYXJnZSBhbW91bnQgb2YgbWVtb3J5XG5cbnZhciBNSU5fSU5ORVJfVElMRV9TSVpFID0gMjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjcmVhdGVTdGFnZXMoZnJvbVdpZHRoLCBmcm9tSGVpZ2h0LCB0b1dpZHRoLCB0b0hlaWdodCwgc3JjVGlsZVNpemUsIGRlc3RUaWxlQm9yZGVyKSB7XG4gIHZhciBzY2FsZVggPSB0b1dpZHRoIC8gZnJvbVdpZHRoO1xuICB2YXIgc2NhbGVZID0gdG9IZWlnaHQgLyBmcm9tSGVpZ2h0OyAvLyBkZXJpdmVkIGZyb20gY3JlYXRlUmVnaW9ucyBlcXVhdGlvbjpcbiAgLy8gaW5uZXJUaWxlV2lkdGggPSBwaXhlbEZsb29yKHNyY1RpbGVTaXplICogc2NhbGVYKSAtIDIgKiBkZXN0VGlsZUJvcmRlcjtcblxuICB2YXIgbWluU2NhbGUgPSAoMiAqIGRlc3RUaWxlQm9yZGVyICsgTUlOX0lOTkVSX1RJTEVfU0laRSArIDEpIC8gc3JjVGlsZVNpemU7IC8vIHJlZnVzZSB0byBzY2FsZSBpbWFnZSBtdWx0aXBsZSB0aW1lcyBieSBsZXNzIHRoYW4gdHdpY2UgZWFjaCB0aW1lLFxuICAvLyBpdCBjb3VsZCBvbmx5IGhhcHBlbiBiZWNhdXNlIG9mIGludmFsaWQgb3B0aW9uc1xuXG4gIGlmIChtaW5TY2FsZSA+IDAuNSkgcmV0dXJuIFtbdG9XaWR0aCwgdG9IZWlnaHRdXTtcbiAgdmFyIHN0YWdlQ291bnQgPSBNYXRoLmNlaWwoTWF0aC5sb2coTWF0aC5taW4oc2NhbGVYLCBzY2FsZVkpKSAvIE1hdGgubG9nKG1pblNjYWxlKSk7IC8vIG5vIGFkZGl0aW9uYWwgcmVzaXplcyBhcmUgbmVjZXNzYXJ5LFxuICAvLyBzdGFnZUNvdW50IGNhbiBiZSB6ZXJvIG9yIGJlIG5lZ2F0aXZlIHdoZW4gZW5sYXJnaW5nIHRoZSBpbWFnZVxuXG4gIGlmIChzdGFnZUNvdW50IDw9IDEpIHJldHVybiBbW3RvV2lkdGgsIHRvSGVpZ2h0XV07XG4gIHZhciByZXN1bHQgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YWdlQ291bnQ7IGkrKykge1xuICAgIHZhciB3aWR0aCA9IE1hdGgucm91bmQoTWF0aC5wb3coTWF0aC5wb3coZnJvbVdpZHRoLCBzdGFnZUNvdW50IC0gaSAtIDEpICogTWF0aC5wb3codG9XaWR0aCwgaSArIDEpLCAxIC8gc3RhZ2VDb3VudCkpO1xuICAgIHZhciBoZWlnaHQgPSBNYXRoLnJvdW5kKE1hdGgucG93KE1hdGgucG93KGZyb21IZWlnaHQsIHN0YWdlQ291bnQgLSBpIC0gMSkgKiBNYXRoLnBvdyh0b0hlaWdodCwgaSArIDEpLCAxIC8gc3RhZ2VDb3VudCkpO1xuICAgIHJlc3VsdC5wdXNoKFt3aWR0aCwgaGVpZ2h0XSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxufSx7fV0sMTU6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLy8gU3BsaXQgb3JpZ2luYWwgaW1hZ2UgaW50byBtdWx0aXBsZSAxMDI0eDEwMjQgY2h1bmtzIHRvIHJlZHVjZSBtZW1vcnkgdXNhZ2Vcbi8vIChpbWFnZXMgaGF2ZSB0byBiZSB1bnBhY2tlZCBpbnRvIHR5cGVkIGFycmF5cyBmb3IgcmVzaXppbmcpIGFuZCBhbGxvd1xuLy8gcGFyYWxsZWwgcHJvY2Vzc2luZyBvZiBtdWx0aXBsZSB0aWxlcyBhdCBhIHRpbWUuXG4vL1xuJ3VzZSBzdHJpY3QnO1xuLypcbiAqIHBpeGVsRmxvb3IgYW5kIHBpeGVsQ2VpbCBhcmUgbW9kaWZpZWQgdmVyc2lvbnMgb2YgTWF0aC5mbG9vciBhbmQgTWF0aC5jZWlsXG4gKiBmdW5jdGlvbnMgd2hpY2ggdGFrZSBpbnRvIGFjY291bnQgZmxvYXRpbmcgcG9pbnQgYXJpdGhtZXRpYyBlcnJvcnMuXG4gKiBUaG9zZSBlcnJvcnMgY2FuIGNhdXNlIHVuZGVzaXJlZCBpbmNyZW1lbnRzL2RlY3JlbWVudHMgb2Ygc2l6ZXMgYW5kIG9mZnNldHM6XG4gKiBNYXRoLmNlaWwoMzYgLyAoMzYgLyA1MDApKSA9IDUwMVxuICogcGl4ZWxDZWlsKDM2IC8gKDM2IC8gNTAwKSkgPSA1MDBcbiAqL1xuXG52YXIgUElYRUxfRVBTSUxPTiA9IDFlLTU7XG5cbmZ1bmN0aW9uIHBpeGVsRmxvb3IoeCkge1xuICB2YXIgbmVhcmVzdCA9IE1hdGgucm91bmQoeCk7XG5cbiAgaWYgKE1hdGguYWJzKHggLSBuZWFyZXN0KSA8IFBJWEVMX0VQU0lMT04pIHtcbiAgICByZXR1cm4gbmVhcmVzdDtcbiAgfVxuXG4gIHJldHVybiBNYXRoLmZsb29yKHgpO1xufVxuXG5mdW5jdGlvbiBwaXhlbENlaWwoeCkge1xuICB2YXIgbmVhcmVzdCA9IE1hdGgucm91bmQoeCk7XG5cbiAgaWYgKE1hdGguYWJzKHggLSBuZWFyZXN0KSA8IFBJWEVMX0VQU0lMT04pIHtcbiAgICByZXR1cm4gbmVhcmVzdDtcbiAgfVxuXG4gIHJldHVybiBNYXRoLmNlaWwoeCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlUmVnaW9ucyhvcHRpb25zKSB7XG4gIHZhciBzY2FsZVggPSBvcHRpb25zLnRvV2lkdGggLyBvcHRpb25zLndpZHRoO1xuICB2YXIgc2NhbGVZID0gb3B0aW9ucy50b0hlaWdodCAvIG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgaW5uZXJUaWxlV2lkdGggPSBwaXhlbEZsb29yKG9wdGlvbnMuc3JjVGlsZVNpemUgKiBzY2FsZVgpIC0gMiAqIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7XG4gIHZhciBpbm5lclRpbGVIZWlnaHQgPSBwaXhlbEZsb29yKG9wdGlvbnMuc3JjVGlsZVNpemUgKiBzY2FsZVkpIC0gMiAqIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7IC8vIHByZXZlbnQgaW5maW5pdGUgbG9vcCwgdGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuXG5cbiAgaWYgKGlubmVyVGlsZVdpZHRoIDwgMSB8fCBpbm5lclRpbGVIZWlnaHQgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnRlcm5hbCBlcnJvciBpbiBwaWNhOiB0YXJnZXQgdGlsZSB3aWR0aC9oZWlnaHQgaXMgdG9vIHNtYWxsLicpO1xuICB9XG5cbiAgdmFyIHgsIHk7XG4gIHZhciBpbm5lclgsIGlubmVyWSwgdG9UaWxlV2lkdGgsIHRvVGlsZUhlaWdodDtcbiAgdmFyIHRpbGVzID0gW107XG4gIHZhciB0aWxlOyAvLyB3ZSBnbyB0b3AtdG8tZG93biBpbnN0ZWFkIG9mIGxlZnQtdG8tcmlnaHQgdG8gbWFrZSBpbWFnZSBkaXNwbGF5ZWQgZnJvbSB0b3AgdG9cbiAgLy8gZG9lc24gaW4gdGhlIGJyb3dzZXJcblxuICBmb3IgKGlubmVyWSA9IDA7IGlubmVyWSA8IG9wdGlvbnMudG9IZWlnaHQ7IGlubmVyWSArPSBpbm5lclRpbGVIZWlnaHQpIHtcbiAgICBmb3IgKGlubmVyWCA9IDA7IGlubmVyWCA8IG9wdGlvbnMudG9XaWR0aDsgaW5uZXJYICs9IGlubmVyVGlsZVdpZHRoKSB7XG4gICAgICB4ID0gaW5uZXJYIC0gb3B0aW9ucy5kZXN0VGlsZUJvcmRlcjtcblxuICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgIHggPSAwO1xuICAgICAgfVxuXG4gICAgICB0b1RpbGVXaWR0aCA9IGlubmVyWCArIGlubmVyVGlsZVdpZHRoICsgb3B0aW9ucy5kZXN0VGlsZUJvcmRlciAtIHg7XG5cbiAgICAgIGlmICh4ICsgdG9UaWxlV2lkdGggPj0gb3B0aW9ucy50b1dpZHRoKSB7XG4gICAgICAgIHRvVGlsZVdpZHRoID0gb3B0aW9ucy50b1dpZHRoIC0geDtcbiAgICAgIH1cblxuICAgICAgeSA9IGlubmVyWSAtIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7XG5cbiAgICAgIGlmICh5IDwgMCkge1xuICAgICAgICB5ID0gMDtcbiAgICAgIH1cblxuICAgICAgdG9UaWxlSGVpZ2h0ID0gaW5uZXJZICsgaW5uZXJUaWxlSGVpZ2h0ICsgb3B0aW9ucy5kZXN0VGlsZUJvcmRlciAtIHk7XG5cbiAgICAgIGlmICh5ICsgdG9UaWxlSGVpZ2h0ID49IG9wdGlvbnMudG9IZWlnaHQpIHtcbiAgICAgICAgdG9UaWxlSGVpZ2h0ID0gb3B0aW9ucy50b0hlaWdodCAtIHk7XG4gICAgICB9XG5cbiAgICAgIHRpbGUgPSB7XG4gICAgICAgIHRvWDogeCxcbiAgICAgICAgdG9ZOiB5LFxuICAgICAgICB0b1dpZHRoOiB0b1RpbGVXaWR0aCxcbiAgICAgICAgdG9IZWlnaHQ6IHRvVGlsZUhlaWdodCxcbiAgICAgICAgdG9Jbm5lclg6IGlubmVyWCxcbiAgICAgICAgdG9Jbm5lclk6IGlubmVyWSxcbiAgICAgICAgdG9Jbm5lcldpZHRoOiBpbm5lclRpbGVXaWR0aCxcbiAgICAgICAgdG9Jbm5lckhlaWdodDogaW5uZXJUaWxlSGVpZ2h0LFxuICAgICAgICBvZmZzZXRYOiB4IC8gc2NhbGVYIC0gcGl4ZWxGbG9vcih4IC8gc2NhbGVYKSxcbiAgICAgICAgb2Zmc2V0WTogeSAvIHNjYWxlWSAtIHBpeGVsRmxvb3IoeSAvIHNjYWxlWSksXG4gICAgICAgIHNjYWxlWDogc2NhbGVYLFxuICAgICAgICBzY2FsZVk6IHNjYWxlWSxcbiAgICAgICAgeDogcGl4ZWxGbG9vcih4IC8gc2NhbGVYKSxcbiAgICAgICAgeTogcGl4ZWxGbG9vcih5IC8gc2NhbGVZKSxcbiAgICAgICAgd2lkdGg6IHBpeGVsQ2VpbCh0b1RpbGVXaWR0aCAvIHNjYWxlWCksXG4gICAgICAgIGhlaWdodDogcGl4ZWxDZWlsKHRvVGlsZUhlaWdodCAvIHNjYWxlWSlcbiAgICAgIH07XG4gICAgICB0aWxlcy5wdXNoKHRpbGUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aWxlcztcbn07XG5cbn0se31dLDE2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gb2JqQ2xhc3Mob2JqKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKTtcbn1cblxubW9kdWxlLmV4cG9ydHMuaXNDYW52YXMgPSBmdW5jdGlvbiBpc0NhbnZhcyhlbGVtZW50KSB7XG4gIHZhciBjbmFtZSA9IG9iakNsYXNzKGVsZW1lbnQpO1xuICByZXR1cm4gY25hbWUgPT09ICdbb2JqZWN0IEhUTUxDYW52YXNFbGVtZW50XSdcbiAgLyogYnJvd3NlciAqL1xuICB8fCBjbmFtZSA9PT0gJ1tvYmplY3QgT2Zmc2NyZWVuQ2FudmFzXScgfHwgY25hbWUgPT09ICdbb2JqZWN0IENhbnZhc10nXG4gIC8qIG5vZGUtY2FudmFzICovXG4gIDtcbn07XG5cbm1vZHVsZS5leHBvcnRzLmlzSW1hZ2UgPSBmdW5jdGlvbiBpc0ltYWdlKGVsZW1lbnQpIHtcbiAgcmV0dXJuIG9iakNsYXNzKGVsZW1lbnQpID09PSAnW29iamVjdCBIVE1MSW1hZ2VFbGVtZW50XSc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5pc0ltYWdlQml0bWFwID0gZnVuY3Rpb24gaXNJbWFnZUJpdG1hcChlbGVtZW50KSB7XG4gIHJldHVybiBvYmpDbGFzcyhlbGVtZW50KSA9PT0gJ1tvYmplY3QgSW1hZ2VCaXRtYXBdJztcbn07XG5cbm1vZHVsZS5leHBvcnRzLmxpbWl0ZXIgPSBmdW5jdGlvbiBsaW1pdGVyKGNvbmN1cnJlbmN5KSB7XG4gIHZhciBhY3RpdmUgPSAwLFxuICAgICAgcXVldWUgPSBbXTtcblxuICBmdW5jdGlvbiByb2xsKCkge1xuICAgIGlmIChhY3RpdmUgPCBjb25jdXJyZW5jeSAmJiBxdWV1ZS5sZW5ndGgpIHtcbiAgICAgIGFjdGl2ZSsrO1xuICAgICAgcXVldWUuc2hpZnQoKSgpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiBsaW1pdChmbikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBxdWV1ZS5wdXNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZm4oKS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgYWN0aXZlLS07XG4gICAgICAgICAgcm9sbCgpO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgYWN0aXZlLS07XG4gICAgICAgICAgcm9sbCgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgcm9sbCgpO1xuICAgIH0pO1xuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMuY2liX3F1YWxpdHlfbmFtZSA9IGZ1bmN0aW9uIGNpYl9xdWFsaXR5X25hbWUobnVtKSB7XG4gIHN3aXRjaCAobnVtKSB7XG4gICAgY2FzZSAwOlxuICAgICAgcmV0dXJuICdwaXhlbGF0ZWQnO1xuXG4gICAgY2FzZSAxOlxuICAgICAgcmV0dXJuICdsb3cnO1xuXG4gICAgY2FzZSAyOlxuICAgICAgcmV0dXJuICdtZWRpdW0nO1xuICB9XG5cbiAgcmV0dXJuICdoaWdoJztcbn07XG5cbm1vZHVsZS5leHBvcnRzLmNpYl9zdXBwb3J0ID0gZnVuY3Rpb24gY2liX3N1cHBvcnQoY3JlYXRlQ2FudmFzKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodHlwZW9mIGNyZWF0ZUltYWdlQml0bWFwID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBjID0gY3JlYXRlQ2FudmFzKDEwMCwgMTAwKTtcbiAgICByZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAoYywgMCwgMCwgMTAwLCAxMDAsIHtcbiAgICAgIHJlc2l6ZVdpZHRoOiAxMCxcbiAgICAgIHJlc2l6ZUhlaWdodDogMTAsXG4gICAgICByZXNpemVRdWFsaXR5OiAnaGlnaCdcbiAgICB9KS50aGVuKGZ1bmN0aW9uIChiaXRtYXApIHtcbiAgICAgIHZhciBzdGF0dXMgPSBiaXRtYXAud2lkdGggPT09IDEwOyAvLyBCcmFuY2ggYmVsb3cgaXMgZmlsdGVyZWQgb24gdXBwZXIgbGV2ZWwuIFdlIGRvIG5vdCBjYWxsIHJlc2l6ZVxuICAgICAgLy8gZGV0ZWN0aW9uIGZvciBiYXNpYyBJbWFnZUJpdG1hcC5cbiAgICAgIC8vXG4gICAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSW1hZ2VCaXRtYXBcbiAgICAgIC8vIG9sZCBDcm9tZSA1MSBoYXMgSW1hZ2VCaXRtYXAgd2l0aG91dCAuY2xvc2UoKS4gVGhlbiB0aGlzIGNvZGVcbiAgICAgIC8vIHdpbGwgdGhyb3cgYW5kIHJldHVybiAnZmFsc2UnIGFzIGV4cGVjdGVkLlxuICAgICAgLy9cblxuICAgICAgYml0bWFwLmNsb3NlKCk7XG4gICAgICBjID0gbnVsbDtcbiAgICAgIHJldHVybiBzdGF0dXM7XG4gICAgfSk7XG4gIH0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy53b3JrZXJfb2Zmc2NyZWVuX2NhbnZhc19zdXBwb3J0ID0gZnVuY3Rpb24gd29ya2VyX29mZnNjcmVlbl9jYW52YXNfc3VwcG9ydCgpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBpZiAodHlwZW9mIE9mZnNjcmVlbkNhbnZhcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIC8vIGlmIE9mZnNjcmVlbkNhbnZhcyBpcyBwcmVzZW50LCB3ZSBhc3N1bWUgYnJvd3NlciBzdXBwb3J0cyBXb3JrZXIgYW5kIGJ1aWx0LWluIFByb21pc2UgYXMgd2VsbFxuICAgICAgcmVzb2x2ZShmYWxzZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gd29ya2VyUGF5bG9hZChzZWxmKSB7XG4gICAgICBpZiAodHlwZW9mIGNyZWF0ZUltYWdlQml0bWFwID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBzZWxmLnBvc3RNZXNzYWdlKGZhbHNlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNhbnZhcyA9IG5ldyBPZmZzY3JlZW5DYW52YXMoMTAsIDEwKTsgLy8gdGVzdCB0aGF0IDJkIGNvbnRleHQgY2FuIGJlIHVzZWQgaW4gd29ya2VyXG5cbiAgICAgICAgdmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgICBjdHgucmVjdCgwLCAwLCAxLCAxKTsgLy8gdGVzdCB0aGF0IGNpYiBjYW4gYmUgdXNlZCB0byByZXR1cm4gaW1hZ2UgYml0bWFwIGZyb20gd29ya2VyXG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKGNhbnZhcywgMCwgMCwgMSwgMSk7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYucG9zdE1lc3NhZ2UodHJ1ZSk7XG4gICAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBzZWxmLnBvc3RNZXNzYWdlKGZhbHNlKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHZhciBjb2RlID0gYnRvYShcIihcIi5jb25jYXQod29ya2VyUGF5bG9hZC50b1N0cmluZygpLCBcIikoc2VsZik7XCIpKTtcbiAgICB2YXIgdyA9IG5ldyBXb3JrZXIoXCJkYXRhOnRleHQvamF2YXNjcmlwdDtiYXNlNjQsXCIuY29uY2F0KGNvZGUpKTtcblxuICAgIHcub25tZXNzYWdlID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZShldi5kYXRhKTtcbiAgICB9O1xuXG4gICAgdy5vbmVycm9yID0gcmVqZWN0O1xuICB9KS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9KTtcbn07IC8vIENoZWNrIGlmIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpLmdldEltYWdlRGF0YSBjYW4gYmUgdXNlZCxcbi8vIEZpcmVGb3ggcmFuZG9taXplcyB0aGUgb3V0cHV0IG9mIHRoYXQgZnVuY3Rpb24gaW4gYHByaXZhY3kucmVzaXN0RmluZ2VycHJpbnRpbmdgIG1vZGVcblxuXG5tb2R1bGUuZXhwb3J0cy5jYW5fdXNlX2NhbnZhcyA9IGZ1bmN0aW9uIGNhbl91c2VfY2FudmFzKGNyZWF0ZUNhbnZhcykge1xuICB2YXIgdXNhYmxlID0gZmFsc2U7XG5cbiAgdHJ5IHtcbiAgICB2YXIgY2FudmFzID0gY3JlYXRlQ2FudmFzKDIsIDEpO1xuICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICB2YXIgZCA9IGN0eC5jcmVhdGVJbWFnZURhdGEoMiwgMSk7XG4gICAgZC5kYXRhWzBdID0gMTI7XG4gICAgZC5kYXRhWzFdID0gMjM7XG4gICAgZC5kYXRhWzJdID0gMzQ7XG4gICAgZC5kYXRhWzNdID0gMjU1O1xuICAgIGQuZGF0YVs0XSA9IDQ1O1xuICAgIGQuZGF0YVs1XSA9IDU2O1xuICAgIGQuZGF0YVs2XSA9IDY3O1xuICAgIGQuZGF0YVs3XSA9IDI1NTtcbiAgICBjdHgucHV0SW1hZ2VEYXRhKGQsIDAsIDApO1xuICAgIGQgPSBudWxsO1xuICAgIGQgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIDIsIDEpO1xuXG4gICAgaWYgKGQuZGF0YVswXSA9PT0gMTIgJiYgZC5kYXRhWzFdID09PSAyMyAmJiBkLmRhdGFbMl0gPT09IDM0ICYmIGQuZGF0YVszXSA9PT0gMjU1ICYmIGQuZGF0YVs0XSA9PT0gNDUgJiYgZC5kYXRhWzVdID09PSA1NiAmJiBkLmRhdGFbNl0gPT09IDY3ICYmIGQuZGF0YVs3XSA9PT0gMjU1KSB7XG4gICAgICB1c2FibGUgPSB0cnVlO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7fVxuXG4gIHJldHVybiB1c2FibGU7XG59OyAvLyBDaGVjayBpZiBjcmVhdGVJbWFnZUJpdG1hcChpbWcsIHN4LCBzeSwgc3csIHNoKSBzaWduYXR1cmUgd29ya3MgY29ycmVjdGx5XG4vLyB3aXRoIEpQRUcgaW1hZ2VzIG9yaWVudGVkIHdpdGggRXhpZjtcbi8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTEyMjA2NzFcbi8vIFRPRE86IHJlbW92ZSBhZnRlciBpdCdzIGZpeGVkIGluIGNocm9tZSBmb3IgYXQgbGVhc3QgMiByZWxlYXNlc1xuXG5cbm1vZHVsZS5leHBvcnRzLmNpYl9jYW5fdXNlX3JlZ2lvbiA9IGZ1bmN0aW9uIGNpYl9jYW5fdXNlX3JlZ2lvbigpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgaWYgKHR5cGVvZiBjcmVhdGVJbWFnZUJpdG1hcCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBpbWFnZSA9IG5ldyBJbWFnZSgpO1xuICAgIGltYWdlLnNyYyA9ICdkYXRhOmltYWdlL2pwZWc7YmFzZTY0LCcgKyAnLzlqLzRRQmlSWGhwWmdBQVRVMEFLZ0FBQUFnQUJRRVNBQU1BQUFBQkFBWUFBQUVhQUFVQUFBQUJBQUFBU2dFYkFBVUFBJyArICdBQUJBQUFBVWdFb0FBTUFBQUFCQUFJQUFBSVRBQU1BQUFBQkFBRUFBQUFBQUFBQUFBQklBQUFBQVFBQUFFZ0FBQUFCLzknICsgJ3NBUXdBRUF3TUVBd01FQkFNRUJRUUVCUVlLQndZR0JnWU5DUW9JQ2c4TkVCQVBEUThPRVJNWUZCRVNGeElPRHhVY0ZSYycgKyAnWkdSc2JHeEFVSFI4ZEdoOFlHaHNhLzlzQVF3RUVCUVVHQlFZTUJ3Y01HaEVQRVJvYUdob2FHaG9hR2hvYUdob2FHaG9hJyArICdHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYS84SUFFUWdBQVFBQ0F3RVJBQUlSQVFNUkEnICsgJ2YvRUFCUUFBUUFBQUFBQUFBQUFBQUFBQUFBQUFBZi94QUFVQVFFQUFBQUFBQUFBQUFBQUFBQUFBQUFBLzlvQURBTUJBQScgKyAnSVFBeEFBQUFGL1AvL0VBQlFRQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUQvMmdBSUFRRUFBUVVDZi8vRUFCUVJBUUFBQUFBJyArICdBQUFBQUFBQUFBQUFBQUFELzJnQUlBUU1CQVQ4QmYvL0VBQlFSQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUQvMmdBSUFRSUInICsgJ0FUOEJmLy9FQUJRUUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFELzJnQUlBUUVBQmo4Q2YvL0VBQlFRQVFBQUFBQUFBQUFBQScgKyAnQUFBQUFBQUFBRC8yZ0FJQVFFQUFUOGhmLy9hQUF3REFRQUNBQU1BQUFBUUgvL0VBQlFSQVFBQUFBQUFBQUFBQUFBQUFBJyArICdBQUFBRC8yZ0FJQVFNQkFUOFFmLy9FQUJRUkFRQUFBQUFBQUFBQUFBQUFBQUFBQUFELzJnQUlBUUlCQVQ4UWYvL0VBQlEnICsgJ1FBUUFBQUFBQUFBQUFBQUFBQUFBQUFBRC8yZ0FJQVFFQUFUOFFmLy9aJztcblxuICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGNyZWF0ZUltYWdlQml0bWFwKGltYWdlLCAwLCAwLCBpbWFnZS53aWR0aCwgaW1hZ2UuaGVpZ2h0KS50aGVuKGZ1bmN0aW9uIChiaXRtYXApIHtcbiAgICAgICAgaWYgKGJpdG1hcC53aWR0aCA9PT0gaW1hZ2Uud2lkdGggJiYgYml0bWFwLmhlaWdodCA9PT0gaW1hZ2UuaGVpZ2h0KSB7XG4gICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShmYWxzZSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgaW1hZ2Uub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiByZXNvbHZlKGZhbHNlKTtcbiAgICB9O1xuICB9KTtcbn07XG5cbn0se31dLDE3OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIFdlYiBXb3JrZXIgd3JhcHBlciBmb3IgaW1hZ2UgcmVzaXplIGZ1bmN0aW9uXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgTWF0aExpYiA9IF9kZXJlcV8oJy4vbWF0aGxpYicpO1xuXG4gIHZhciBtYXRoTGliO1xuICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bmRlZiAqL1xuXG4gIG9ubWVzc2FnZSA9IGZ1bmN0aW9uIG9ubWVzc2FnZShldikge1xuICAgIHZhciB0aWxlT3B0cyA9IGV2LmRhdGEub3B0cztcbiAgICB2YXIgcmV0dXJuQml0bWFwID0gZmFsc2U7XG5cbiAgICBpZiAoIXRpbGVPcHRzLnNyYyAmJiB0aWxlT3B0cy5zcmNCaXRtYXApIHtcbiAgICAgIHZhciBjYW52YXMgPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKHRpbGVPcHRzLndpZHRoLCB0aWxlT3B0cy5oZWlnaHQpO1xuICAgICAgdmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICAgICAgYWxwaGE6IEJvb2xlYW4odGlsZU9wdHMuYWxwaGEpXG4gICAgICB9KTtcbiAgICAgIGN0eC5kcmF3SW1hZ2UodGlsZU9wdHMuc3JjQml0bWFwLCAwLCAwKTtcbiAgICAgIHRpbGVPcHRzLnNyYyA9IGN0eC5nZXRJbWFnZURhdGEoMCwgMCwgdGlsZU9wdHMud2lkdGgsIHRpbGVPcHRzLmhlaWdodCkuZGF0YTtcbiAgICAgIGNhbnZhcy53aWR0aCA9IGNhbnZhcy5oZWlnaHQgPSAwO1xuICAgICAgY2FudmFzID0gbnVsbDtcbiAgICAgIHRpbGVPcHRzLnNyY0JpdG1hcC5jbG9zZSgpO1xuICAgICAgdGlsZU9wdHMuc3JjQml0bWFwID0gbnVsbDtcbiAgICAgIHJldHVybkJpdG1hcCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKCFtYXRoTGliKSBtYXRoTGliID0gbmV3IE1hdGhMaWIoZXYuZGF0YS5mZWF0dXJlcyk7IC8vIFVzZSBtdWx0aW1hdGgncyBzeW5jIGF1dG8taW5pdC4gQXZvaWQgUHJvbWlzZSB1c2UgaW4gb2xkIGJyb3dzZXJzLFxuICAgIC8vIGJlY2F1c2UgcG9seWZpbGxzIGFyZSBub3QgcHJvcGFnYXRlZCB0byB3ZWJ3b3JrZXIuXG5cbiAgICB2YXIgZGF0YSA9IG1hdGhMaWIucmVzaXplQW5kVW5zaGFycCh0aWxlT3B0cyk7XG5cbiAgICBpZiAocmV0dXJuQml0bWFwKSB7XG4gICAgICB2YXIgdG9JbWFnZURhdGEgPSBuZXcgSW1hZ2VEYXRhKG5ldyBVaW50OENsYW1wZWRBcnJheShkYXRhKSwgdGlsZU9wdHMudG9XaWR0aCwgdGlsZU9wdHMudG9IZWlnaHQpO1xuXG4gICAgICB2YXIgX2NhbnZhcyA9IG5ldyBPZmZzY3JlZW5DYW52YXModGlsZU9wdHMudG9XaWR0aCwgdGlsZU9wdHMudG9IZWlnaHQpO1xuXG4gICAgICB2YXIgX2N0eCA9IF9jYW52YXMuZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgICAgIGFscGhhOiBCb29sZWFuKHRpbGVPcHRzLmFscGhhKVxuICAgICAgfSk7XG5cbiAgICAgIF9jdHgucHV0SW1hZ2VEYXRhKHRvSW1hZ2VEYXRhLCAwLCAwKTtcblxuICAgICAgY3JlYXRlSW1hZ2VCaXRtYXAoX2NhbnZhcykudGhlbihmdW5jdGlvbiAoYml0bWFwKSB7XG4gICAgICAgIHBvc3RNZXNzYWdlKHtcbiAgICAgICAgICBiaXRtYXA6IGJpdG1hcFxuICAgICAgICB9LCBbYml0bWFwXSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcG9zdE1lc3NhZ2Uoe1xuICAgICAgICBkYXRhOiBkYXRhXG4gICAgICB9LCBbZGF0YS5idWZmZXJdKTtcbiAgICB9XG4gIH07XG59O1xuXG59LHtcIi4vbWF0aGxpYlwiOjF9XSwxODpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBDYWxjdWxhdGUgR2F1c3NpYW4gYmx1ciBvZiBhbiBpbWFnZSB1c2luZyBJSVIgZmlsdGVyXG4vLyBUaGUgbWV0aG9kIGlzIHRha2VuIGZyb20gSW50ZWwncyB3aGl0ZSBwYXBlciBhbmQgY29kZSBleGFtcGxlIGF0dGFjaGVkIHRvIGl0OlxuLy8gaHR0cHM6Ly9zb2Z0d2FyZS5pbnRlbC5jb20vZW4tdXMvYXJ0aWNsZXMvaWlyLWdhdXNzaWFuLWJsdXItZmlsdGVyXG4vLyAtaW1wbGVtZW50YXRpb24tdXNpbmctaW50ZWwtYWR2YW5jZWQtdmVjdG9yLWV4dGVuc2lvbnNcblxudmFyIGEwLCBhMSwgYTIsIGEzLCBiMSwgYjIsIGxlZnRfY29ybmVyLCByaWdodF9jb3JuZXI7XG5cbmZ1bmN0aW9uIGdhdXNzQ29lZihzaWdtYSkge1xuICBpZiAoc2lnbWEgPCAwLjUpIHtcbiAgICBzaWdtYSA9IDAuNTtcbiAgfVxuXG4gIHZhciBhID0gTWF0aC5leHAoMC43MjYgKiAwLjcyNikgLyBzaWdtYSxcbiAgICAgIGcxID0gTWF0aC5leHAoLWEpLFxuICAgICAgZzIgPSBNYXRoLmV4cCgtMiAqIGEpLFxuICAgICAgayA9ICgxIC0gZzEpICogKDEgLSBnMSkgLyAoMSArIDIgKiBhICogZzEgLSBnMik7XG5cbiAgYTAgPSBrO1xuICBhMSA9IGsgKiAoYSAtIDEpICogZzE7XG4gIGEyID0gayAqIChhICsgMSkgKiBnMTtcbiAgYTMgPSAtayAqIGcyO1xuICBiMSA9IDIgKiBnMTtcbiAgYjIgPSAtZzI7XG4gIGxlZnRfY29ybmVyID0gKGEwICsgYTEpIC8gKDEgLSBiMSAtIGIyKTtcbiAgcmlnaHRfY29ybmVyID0gKGEyICsgYTMpIC8gKDEgLSBiMSAtIGIyKTtcblxuICAvLyBBdHRlbXB0IHRvIGZvcmNlIHR5cGUgdG8gRlAzMi5cbiAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoWyBhMCwgYTEsIGEyLCBhMywgYjEsIGIyLCBsZWZ0X2Nvcm5lciwgcmlnaHRfY29ybmVyIF0pO1xufVxuXG5mdW5jdGlvbiBjb252b2x2ZU1vbm8xNihzcmMsIG91dCwgbGluZSwgY29lZmYsIHdpZHRoLCBoZWlnaHQpIHtcbiAgLy8gdGFrZXMgc3JjIGltYWdlIGFuZCB3cml0ZXMgdGhlIGJsdXJyZWQgYW5kIHRyYW5zcG9zZWQgcmVzdWx0IGludG8gb3V0XG5cbiAgdmFyIHByZXZfc3JjLCBjdXJyX3NyYywgY3Vycl9vdXQsIHByZXZfb3V0LCBwcmV2X3ByZXZfb3V0O1xuICB2YXIgc3JjX2luZGV4LCBvdXRfaW5kZXgsIGxpbmVfaW5kZXg7XG4gIHZhciBpLCBqO1xuICB2YXIgY29lZmZfYTAsIGNvZWZmX2ExLCBjb2VmZl9iMSwgY29lZmZfYjI7XG5cbiAgZm9yIChpID0gMDsgaSA8IGhlaWdodDsgaSsrKSB7XG4gICAgc3JjX2luZGV4ID0gaSAqIHdpZHRoO1xuICAgIG91dF9pbmRleCA9IGk7XG4gICAgbGluZV9pbmRleCA9IDA7XG5cbiAgICAvLyBsZWZ0IHRvIHJpZ2h0XG4gICAgcHJldl9zcmMgPSBzcmNbc3JjX2luZGV4XTtcbiAgICBwcmV2X3ByZXZfb3V0ID0gcHJldl9zcmMgKiBjb2VmZls2XTtcbiAgICBwcmV2X291dCA9IHByZXZfcHJldl9vdXQ7XG5cbiAgICBjb2VmZl9hMCA9IGNvZWZmWzBdO1xuICAgIGNvZWZmX2ExID0gY29lZmZbMV07XG4gICAgY29lZmZfYjEgPSBjb2VmZls0XTtcbiAgICBjb2VmZl9iMiA9IGNvZWZmWzVdO1xuXG4gICAgZm9yIChqID0gMDsgaiA8IHdpZHRoOyBqKyspIHtcbiAgICAgIGN1cnJfc3JjID0gc3JjW3NyY19pbmRleF07XG5cbiAgICAgIGN1cnJfb3V0ID0gY3Vycl9zcmMgKiBjb2VmZl9hMCArXG4gICAgICAgICAgICAgICAgIHByZXZfc3JjICogY29lZmZfYTEgK1xuICAgICAgICAgICAgICAgICBwcmV2X291dCAqIGNvZWZmX2IxICtcbiAgICAgICAgICAgICAgICAgcHJldl9wcmV2X291dCAqIGNvZWZmX2IyO1xuXG4gICAgICBwcmV2X3ByZXZfb3V0ID0gcHJldl9vdXQ7XG4gICAgICBwcmV2X291dCA9IGN1cnJfb3V0O1xuICAgICAgcHJldl9zcmMgPSBjdXJyX3NyYztcblxuICAgICAgbGluZVtsaW5lX2luZGV4XSA9IHByZXZfb3V0O1xuICAgICAgbGluZV9pbmRleCsrO1xuICAgICAgc3JjX2luZGV4Kys7XG4gICAgfVxuXG4gICAgc3JjX2luZGV4LS07XG4gICAgbGluZV9pbmRleC0tO1xuICAgIG91dF9pbmRleCArPSBoZWlnaHQgKiAod2lkdGggLSAxKTtcblxuICAgIC8vIHJpZ2h0IHRvIGxlZnRcbiAgICBwcmV2X3NyYyA9IHNyY1tzcmNfaW5kZXhdO1xuICAgIHByZXZfcHJldl9vdXQgPSBwcmV2X3NyYyAqIGNvZWZmWzddO1xuICAgIHByZXZfb3V0ID0gcHJldl9wcmV2X291dDtcbiAgICBjdXJyX3NyYyA9IHByZXZfc3JjO1xuXG4gICAgY29lZmZfYTAgPSBjb2VmZlsyXTtcbiAgICBjb2VmZl9hMSA9IGNvZWZmWzNdO1xuXG4gICAgZm9yIChqID0gd2lkdGggLSAxOyBqID49IDA7IGotLSkge1xuICAgICAgY3Vycl9vdXQgPSBjdXJyX3NyYyAqIGNvZWZmX2EwICtcbiAgICAgICAgICAgICAgICAgcHJldl9zcmMgKiBjb2VmZl9hMSArXG4gICAgICAgICAgICAgICAgIHByZXZfb3V0ICogY29lZmZfYjEgK1xuICAgICAgICAgICAgICAgICBwcmV2X3ByZXZfb3V0ICogY29lZmZfYjI7XG5cbiAgICAgIHByZXZfcHJldl9vdXQgPSBwcmV2X291dDtcbiAgICAgIHByZXZfb3V0ID0gY3Vycl9vdXQ7XG5cbiAgICAgIHByZXZfc3JjID0gY3Vycl9zcmM7XG4gICAgICBjdXJyX3NyYyA9IHNyY1tzcmNfaW5kZXhdO1xuXG4gICAgICBvdXRbb3V0X2luZGV4XSA9IGxpbmVbbGluZV9pbmRleF0gKyBwcmV2X291dDtcblxuICAgICAgc3JjX2luZGV4LS07XG4gICAgICBsaW5lX2luZGV4LS07XG4gICAgICBvdXRfaW5kZXggLT0gaGVpZ2h0O1xuICAgIH1cbiAgfVxufVxuXG5cbmZ1bmN0aW9uIGJsdXJNb25vMTYoc3JjLCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpIHtcbiAgLy8gUXVpY2sgZXhpdCBvbiB6ZXJvIHJhZGl1c1xuICBpZiAoIXJhZGl1cykgeyByZXR1cm47IH1cblxuICB2YXIgb3V0ICAgICAgPSBuZXcgVWludDE2QXJyYXkoc3JjLmxlbmd0aCksXG4gICAgICB0bXBfbGluZSA9IG5ldyBGbG9hdDMyQXJyYXkoTWF0aC5tYXgod2lkdGgsIGhlaWdodCkpO1xuXG4gIHZhciBjb2VmZiA9IGdhdXNzQ29lZihyYWRpdXMpO1xuXG4gIGNvbnZvbHZlTW9ubzE2KHNyYywgb3V0LCB0bXBfbGluZSwgY29lZmYsIHdpZHRoLCBoZWlnaHQsIHJhZGl1cyk7XG4gIGNvbnZvbHZlTW9ubzE2KG91dCwgc3JjLCB0bXBfbGluZSwgY29lZmYsIGhlaWdodCwgd2lkdGgsIHJhZGl1cyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmx1ck1vbm8xNjtcblxufSx7fV0sMTk6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICAgIH1cbiAgfVxufVxuXG59LHt9XSwyMDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cblxudmFyIGFzc2lnbiAgICAgICAgID0gX2RlcmVxXygnb2JqZWN0LWFzc2lnbicpO1xudmFyIGJhc2U2NGRlY29kZSAgID0gX2RlcmVxXygnLi9saWIvYmFzZTY0ZGVjb2RlJyk7XG52YXIgaGFzV2ViQXNzZW1ibHkgPSBfZGVyZXFfKCcuL2xpYi93YV9kZXRlY3QnKTtcblxuXG52YXIgREVGQVVMVF9PUFRJT05TID0ge1xuICBqczogdHJ1ZSxcbiAgd2FzbTogdHJ1ZVxufTtcblxuXG5mdW5jdGlvbiBNdWx0aU1hdGgob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTXVsdGlNYXRoKSkgcmV0dXJuIG5ldyBNdWx0aU1hdGgob3B0aW9ucyk7XG5cbiAgdmFyIG9wdHMgPSBhc3NpZ24oe30sIERFRkFVTFRfT1BUSU9OUywgb3B0aW9ucyB8fCB7fSk7XG5cbiAgdGhpcy5vcHRpb25zICAgICAgICAgPSBvcHRzO1xuXG4gIHRoaXMuX19jYWNoZSAgICAgICAgID0ge307XG5cbiAgdGhpcy5fX2luaXRfcHJvbWlzZSAgPSBudWxsO1xuICB0aGlzLl9fbW9kdWxlcyAgICAgICA9IG9wdHMubW9kdWxlcyB8fCB7fTtcbiAgdGhpcy5fX21lbW9yeSAgICAgICAgPSBudWxsO1xuICB0aGlzLl9fd2FzbSAgICAgICAgICA9IHt9O1xuXG4gIHRoaXMuX19pc0xFID0gKChuZXcgVWludDMyQXJyYXkoKG5ldyBVaW50OEFycmF5KFsgMSwgMCwgMCwgMCBdKSkuYnVmZmVyKSlbMF0gPT09IDEpO1xuXG4gIGlmICghdGhpcy5vcHRpb25zLmpzICYmICF0aGlzLm9wdGlvbnMud2FzbSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbWF0aGxpYjogYXQgbGVhc3QgXCJqc1wiIG9yIFwid2FzbVwiIHNob3VsZCBiZSBlbmFibGVkJyk7XG4gIH1cbn1cblxuXG5NdWx0aU1hdGgucHJvdG90eXBlLmhhc193YXNtID0gaGFzV2ViQXNzZW1ibHk7XG5cblxuTXVsdGlNYXRoLnByb3RvdHlwZS51c2UgPSBmdW5jdGlvbiAobW9kdWxlKSB7XG4gIHRoaXMuX19tb2R1bGVzW21vZHVsZS5uYW1lXSA9IG1vZHVsZTtcblxuICAvLyBQaW4gdGhlIGJlc3QgcG9zc2libGUgaW1wbGVtZW50YXRpb25cbiAgaWYgKHRoaXMub3B0aW9ucy53YXNtICYmIHRoaXMuaGFzX3dhc20oKSAmJiBtb2R1bGUud2FzbV9mbikge1xuICAgIHRoaXNbbW9kdWxlLm5hbWVdID0gbW9kdWxlLndhc21fZm47XG4gIH0gZWxzZSB7XG4gICAgdGhpc1ttb2R1bGUubmFtZV0gPSBtb2R1bGUuZm47XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cblxuTXVsdGlNYXRoLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5fX2luaXRfcHJvbWlzZSkgcmV0dXJuIHRoaXMuX19pbml0X3Byb21pc2U7XG5cbiAgaWYgKCF0aGlzLm9wdGlvbnMuanMgJiYgdGhpcy5vcHRpb25zLndhc20gJiYgIXRoaXMuaGFzX3dhc20oKSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ21hdGhsaWI6IG9ubHkgXCJ3YXNtXCIgd2FzIGVuYWJsZWQsIGJ1dCBpdFxcJ3Mgbm90IHN1cHBvcnRlZCcpKTtcbiAgfVxuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLl9faW5pdF9wcm9taXNlID0gUHJvbWlzZS5hbGwoT2JqZWN0LmtleXMoc2VsZi5fX21vZHVsZXMpLm1hcChmdW5jdGlvbiAobmFtZSkge1xuICAgIHZhciBtb2R1bGUgPSBzZWxmLl9fbW9kdWxlc1tuYW1lXTtcblxuICAgIGlmICghc2VsZi5vcHRpb25zLndhc20gfHwgIXNlbGYuaGFzX3dhc20oKSB8fCAhbW9kdWxlLndhc21fZm4pIHJldHVybiBudWxsO1xuXG4gICAgLy8gSWYgYWxyZWFkeSBjb21waWxlZCAtIGV4aXRcbiAgICBpZiAoc2VsZi5fX3dhc21bbmFtZV0pIHJldHVybiBudWxsO1xuXG4gICAgLy8gQ29tcGlsZSB3YXNtIHNvdXJjZVxuICAgIHJldHVybiBXZWJBc3NlbWJseS5jb21waWxlKHNlbGYuX19iYXNlNjRkZWNvZGUobW9kdWxlLndhc21fc3JjKSlcbiAgICAgIC50aGVuKGZ1bmN0aW9uIChtKSB7IHNlbGYuX193YXNtW25hbWVdID0gbTsgfSk7XG4gIH0pKVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlbGY7IH0pO1xuXG4gIHJldHVybiB0aGlzLl9faW5pdF9wcm9taXNlO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gTWV0aG9kcyBiZWxvdyBhcmUgZm9yIGludGVybmFsIHVzZSBmcm9tIHBsdWdpbnNcblxuXG4vLyBTaW1wbGUgZGVjb2RlIGJhc2U2NCB0byB0eXBlZCBhcnJheS4gVXNlZnVsIHRvIGxvYWQgZW1iZWRkZWQgd2ViYXNzZW1ibHlcbi8vIGNvZGUuIFlvdSBwcm9iYWJseSBkb24ndCBuZWVkIHRvIGNhbGwgdGhpcyBtZXRob2QgZGlyZWN0bHkuXG4vL1xuTXVsdGlNYXRoLnByb3RvdHlwZS5fX2Jhc2U2NGRlY29kZSA9IGJhc2U2NGRlY29kZTtcblxuXG4vLyBJbmNyZWFzZSBjdXJyZW50IG1lbW9yeSB0byBpbmNsdWRlIHNwZWNpZmllZCBudW1iZXIgb2YgYnl0ZXMuIERvIG5vdGhpbmcgaWZcbi8vIHNpemUgaXMgYWxyZWFkeSBvay4gWW91IHByb2JhYmx5IGRvbid0IG5lZWQgdG8gY2FsbCB0aGlzIG1ldGhvZCBkaXJlY3RseSxcbi8vIGJlY2F1c2UgaXQgd2lsbCBiZSBpbnZva2VkIGZyb20gYC5fX2luc3RhbmNlKClgLlxuLy9cbk11bHRpTWF0aC5wcm90b3R5cGUuX19yZWFsbG9jYXRlID0gZnVuY3Rpb24gbWVtX2dyb3dfdG8oYnl0ZXMpIHtcbiAgaWYgKCF0aGlzLl9fbWVtb3J5KSB7XG4gICAgdGhpcy5fX21lbW9yeSA9IG5ldyBXZWJBc3NlbWJseS5NZW1vcnkoe1xuICAgICAgaW5pdGlhbDogTWF0aC5jZWlsKGJ5dGVzIC8gKDY0ICogMTAyNCkpXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMuX19tZW1vcnk7XG4gIH1cblxuICB2YXIgbWVtX3NpemUgPSB0aGlzLl9fbWVtb3J5LmJ1ZmZlci5ieXRlTGVuZ3RoO1xuXG4gIGlmIChtZW1fc2l6ZSA8IGJ5dGVzKSB7XG4gICAgdGhpcy5fX21lbW9yeS5ncm93KE1hdGguY2VpbCgoYnl0ZXMgLSBtZW1fc2l6ZSkgLyAoNjQgKiAxMDI0KSkpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX19tZW1vcnk7XG59O1xuXG5cbi8vIFJldHVybnMgaW5zdGFudGluYXRlZCB3ZWJhc3NlbWJseSBpdGVtIGJ5IG5hbWUsIHdpdGggc3BlY2lmaWVkIG1lbW9yeSBzaXplXG4vLyBhbmQgZW52aXJvbm1lbnQuXG4vLyAtIHVzZSBjYWNoZSBpZiBhdmFpbGFibGVcbi8vIC0gZG8gc3luYyBtb2R1bGUgaW5pdCwgaWYgYXN5bmMgaW5pdCB3YXMgbm90IGNhbGxlZCBlYXJsaWVyXG4vLyAtIGFsbG9jYXRlIG1lbW9yeSBpZiBub3QgZW5vdWd0aFxuLy8gLSBjYW4gZXhwb3J0IGZ1bmN0aW9ucyB0byB3ZWJhc3NlbWJseSB2aWEgXCJlbnZfZXh0cmFcIixcbi8vICAgZm9yIGV4YW1wbGUsIHsgZXhwOiBNYXRoLmV4cCB9XG4vL1xuTXVsdGlNYXRoLnByb3RvdHlwZS5fX2luc3RhbmNlID0gZnVuY3Rpb24gaW5zdGFuY2UobmFtZSwgbWVtc2l6ZSwgZW52X2V4dHJhKSB7XG4gIGlmIChtZW1zaXplKSB0aGlzLl9fcmVhbGxvY2F0ZShtZW1zaXplKTtcblxuICAvLyBJZiAuaW5pdCgpIHdhcyBub3QgY2FsbGVkLCBkbyBzeW5jIGNvbXBpbGVcbiAgaWYgKCF0aGlzLl9fd2FzbVtuYW1lXSkge1xuICAgIHZhciBtb2R1bGUgPSB0aGlzLl9fbW9kdWxlc1tuYW1lXTtcbiAgICB0aGlzLl9fd2FzbVtuYW1lXSA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUodGhpcy5fX2Jhc2U2NGRlY29kZShtb2R1bGUud2FzbV9zcmMpKTtcbiAgfVxuXG4gIGlmICghdGhpcy5fX2NhY2hlW25hbWVdKSB7XG4gICAgdmFyIGVudl9iYXNlID0ge1xuICAgICAgbWVtb3J5QmFzZTogMCxcbiAgICAgIG1lbW9yeTogdGhpcy5fX21lbW9yeSxcbiAgICAgIHRhYmxlQmFzZTogMCxcbiAgICAgIHRhYmxlOiBuZXcgV2ViQXNzZW1ibHkuVGFibGUoeyBpbml0aWFsOiAwLCBlbGVtZW50OiAnYW55ZnVuYycgfSlcbiAgICB9O1xuXG4gICAgdGhpcy5fX2NhY2hlW25hbWVdID0gbmV3IFdlYkFzc2VtYmx5Lkluc3RhbmNlKHRoaXMuX193YXNtW25hbWVdLCB7XG4gICAgICBlbnY6IGFzc2lnbihlbnZfYmFzZSwgZW52X2V4dHJhIHx8IHt9KVxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX19jYWNoZVtuYW1lXTtcbn07XG5cblxuLy8gSGVscGVyIHRvIGNhbGN1bGF0ZSBtZW1vcnkgYWxpZ2ggZm9yIHBvaW50ZXJzLiBXZWJhc3NlbWJseSBkb2VzIG5vdCByZXF1aXJlXG4vLyB0aGlzLCBidXQgeW91IG1heSB3aXNoIHRvIGV4cGVyaW1lbnQuIERlZmF1bHQgYmFzZSA9IDg7XG4vL1xuTXVsdGlNYXRoLnByb3RvdHlwZS5fX2FsaWduID0gZnVuY3Rpb24gYWxpZ24obnVtYmVyLCBiYXNlKSB7XG4gIGJhc2UgPSBiYXNlIHx8IDg7XG4gIHZhciByZW1pbmRlciA9IG51bWJlciAlIGJhc2U7XG4gIHJldHVybiBudW1iZXIgKyAocmVtaW5kZXIgPyBiYXNlIC0gcmVtaW5kZXIgOiAwKTtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBNdWx0aU1hdGg7XG5cbn0se1wiLi9saWIvYmFzZTY0ZGVjb2RlXCI6MjEsXCIuL2xpYi93YV9kZXRlY3RcIjoyMixcIm9iamVjdC1hc3NpZ25cIjoyM31dLDIxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIGJhc2U2NCBkZWNvZGUgc3RyIC0+IFVpbnQ4QXJyYXksIHRvIGxvYWQgV0EgbW9kdWxlc1xuLy9cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgQkFTRTY0X01BUCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJztcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGJhc2U2NGRlY29kZShzdHIpIHtcbiAgdmFyIGlucHV0ID0gc3RyLnJlcGxhY2UoL1tcXHJcXG49XS9nLCAnJyksIC8vIHJlbW92ZSBDUi9MRiAmIHBhZGRpbmcgdG8gc2ltcGxpZnkgc2NhblxuICAgICAgbWF4ICAgPSBpbnB1dC5sZW5ndGg7XG5cbiAgdmFyIG91dCA9IG5ldyBVaW50OEFycmF5KChtYXggKiAzKSA+PiAyKTtcblxuICAvLyBDb2xsZWN0IGJ5IDYqNCBiaXRzICgzIGJ5dGVzKVxuXG4gIHZhciBiaXRzID0gMDtcbiAgdmFyIHB0ciAgPSAwO1xuXG4gIGZvciAodmFyIGlkeCA9IDA7IGlkeCA8IG1heDsgaWR4KyspIHtcbiAgICBpZiAoKGlkeCAlIDQgPT09IDApICYmIGlkeCkge1xuICAgICAgb3V0W3B0cisrXSA9IChiaXRzID4+IDE2KSAmIDB4RkY7XG4gICAgICBvdXRbcHRyKytdID0gKGJpdHMgPj4gOCkgJiAweEZGO1xuICAgICAgb3V0W3B0cisrXSA9IGJpdHMgJiAweEZGO1xuICAgIH1cblxuICAgIGJpdHMgPSAoYml0cyA8PCA2KSB8IEJBU0U2NF9NQVAuaW5kZXhPZihpbnB1dC5jaGFyQXQoaWR4KSk7XG4gIH1cblxuICAvLyBEdW1wIHRhaWxcblxuICB2YXIgdGFpbGJpdHMgPSAobWF4ICUgNCkgKiA2O1xuXG4gIGlmICh0YWlsYml0cyA9PT0gMCkge1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAxNikgJiAweEZGO1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiA4KSAmIDB4RkY7XG4gICAgb3V0W3B0cisrXSA9IGJpdHMgJiAweEZGO1xuICB9IGVsc2UgaWYgKHRhaWxiaXRzID09PSAxOCkge1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAxMCkgJiAweEZGO1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAyKSAmIDB4RkY7XG4gIH0gZWxzZSBpZiAodGFpbGJpdHMgPT09IDEyKSB7XG4gICAgb3V0W3B0cisrXSA9IChiaXRzID4+IDQpICYgMHhGRjtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59O1xuXG59LHt9XSwyMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBEZXRlY3QgV2ViQXNzZW1ibHkgc3VwcG9ydC5cbi8vIC0gQ2hlY2sgZ2xvYmFsIFdlYkFzc2VtYmx5IG9iamVjdFxuLy8gLSBUcnkgdG8gbG9hZCBzaW1wbGUgbW9kdWxlIChjYW4gYmUgZGlzYWJsZWQgdmlhIENTUClcbi8vXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIHdhO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaGFzV2ViQXNzZW1ibHkoKSB7XG4gIC8vIHVzZSBjYWNoZSBpZiBjYWxsZWQgYmVmb3JlO1xuICBpZiAodHlwZW9mIHdhICE9PSAndW5kZWZpbmVkJykgcmV0dXJuIHdhO1xuXG4gIHdhID0gZmFsc2U7XG5cbiAgaWYgKHR5cGVvZiBXZWJBc3NlbWJseSA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiB3YTtcblxuICAvLyBJZiBXZWJBc3NlbmJseSBpcyBkaXNhYmxlZCwgY29kZSBjYW4gdGhyb3cgb24gY29tcGlsZVxuICB0cnkge1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9icmlvbi9taW4td2FzbS1mYWlsL2Jsb2IvbWFzdGVyL21pbi13YXNtLWZhaWwuaW4uanNcbiAgICAvLyBBZGRpdGlvbmFsIGNoZWNrIHRoYXQgV0EgaW50ZXJuYWxzIGFyZSBjb3JyZWN0XG5cbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBjb21tYS1zcGFjaW5nLCBtYXgtbGVuICovXG4gICAgdmFyIGJpbiAgICAgID0gbmV3IFVpbnQ4QXJyYXkoWyAwLDk3LDExNSwxMDksMSwwLDAsMCwxLDYsMSw5NiwxLDEyNywxLDEyNywzLDIsMSwwLDUsMywxLDAsMSw3LDgsMSw0LDExNiwxMDEsMTE1LDExNiwwLDAsMTAsMTYsMSwxNCwwLDMyLDAsNjUsMSw1NCwyLDAsMzIsMCw0MCwyLDAsMTEgXSk7XG4gICAgdmFyIG1vZHVsZSAgID0gbmV3IFdlYkFzc2VtYmx5Lk1vZHVsZShiaW4pO1xuICAgIHZhciBpbnN0YW5jZSA9IG5ldyBXZWJBc3NlbWJseS5JbnN0YW5jZShtb2R1bGUsIHt9KTtcblxuICAgIC8vIHRlc3Qgc3RvcmluZyB0byBhbmQgbG9hZGluZyBmcm9tIGEgbm9uLXplcm8gbG9jYXRpb24gdmlhIGEgcGFyYW1ldGVyLlxuICAgIC8vIFNhZmFyaSBvbiBpT1MgMTEuMi41IHJldHVybnMgMCB1bmV4cGVjdGVkbHkgYXQgbm9uLXplcm8gbG9jYXRpb25zXG4gICAgaWYgKGluc3RhbmNlLmV4cG9ydHMudGVzdCg0KSAhPT0gMCkgd2EgPSB0cnVlO1xuXG4gICAgcmV0dXJuIHdhO1xuICB9IGNhdGNoIChfXykge31cblxuICByZXR1cm4gd2E7XG59O1xuXG59LHt9XSwyMzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxub2JqZWN0LWFzc2lnblxuKGMpIFNpbmRyZSBTb3JodXNcbkBsaWNlbnNlIE1JVFxuKi9cblxuJ3VzZSBzdHJpY3QnO1xuLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi9cbnZhciBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzO1xudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBwcm9wSXNFbnVtZXJhYmxlID0gT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuZnVuY3Rpb24gdG9PYmplY3QodmFsKSB7XG5cdGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3QuYXNzaWduIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCBudWxsIG9yIHVuZGVmaW5lZCcpO1xuXHR9XG5cblx0cmV0dXJuIE9iamVjdCh2YWwpO1xufVxuXG5mdW5jdGlvbiBzaG91bGRVc2VOYXRpdmUoKSB7XG5cdHRyeSB7XG5cdFx0aWYgKCFPYmplY3QuYXNzaWduKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gRGV0ZWN0IGJ1Z2d5IHByb3BlcnR5IGVudW1lcmF0aW9uIG9yZGVyIGluIG9sZGVyIFY4IHZlcnNpb25zLlxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9NDExOFxuXHRcdHZhciB0ZXN0MSA9IG5ldyBTdHJpbmcoJ2FiYycpOyAgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXctd3JhcHBlcnNcblx0XHR0ZXN0MVs1XSA9ICdkZSc7XG5cdFx0aWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRlc3QxKVswXSA9PT0gJzUnKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzA1NlxuXHRcdHZhciB0ZXN0MiA9IHt9O1xuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgMTA7IGkrKykge1xuXHRcdFx0dGVzdDJbJ18nICsgU3RyaW5nLmZyb21DaGFyQ29kZShpKV0gPSBpO1xuXHRcdH1cblx0XHR2YXIgb3JkZXIyID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGVzdDIpLm1hcChmdW5jdGlvbiAobikge1xuXHRcdFx0cmV0dXJuIHRlc3QyW25dO1xuXHRcdH0pO1xuXHRcdGlmIChvcmRlcjIuam9pbignJykgIT09ICcwMTIzNDU2Nzg5Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTMwNTZcblx0XHR2YXIgdGVzdDMgPSB7fTtcblx0XHQnYWJjZGVmZ2hpamtsbW5vcHFyc3QnLnNwbGl0KCcnKS5mb3JFYWNoKGZ1bmN0aW9uIChsZXR0ZXIpIHtcblx0XHRcdHRlc3QzW2xldHRlcl0gPSBsZXR0ZXI7XG5cdFx0fSk7XG5cdFx0aWYgKE9iamVjdC5rZXlzKE9iamVjdC5hc3NpZ24oe30sIHRlc3QzKSkuam9pbignJykgIT09XG5cdFx0XHRcdCdhYmNkZWZnaGlqa2xtbm9wcXJzdCcpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0Ly8gV2UgZG9uJ3QgZXhwZWN0IGFueSBvZiB0aGUgYWJvdmUgdG8gdGhyb3csIGJ1dCBiZXR0ZXIgdG8gYmUgc2FmZS5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzaG91bGRVc2VOYXRpdmUoKSA/IE9iamVjdC5hc3NpZ24gOiBmdW5jdGlvbiAodGFyZ2V0LCBzb3VyY2UpIHtcblx0dmFyIGZyb207XG5cdHZhciB0byA9IHRvT2JqZWN0KHRhcmdldCk7XG5cdHZhciBzeW1ib2xzO1xuXG5cdGZvciAodmFyIHMgPSAxOyBzIDwgYXJndW1lbnRzLmxlbmd0aDsgcysrKSB7XG5cdFx0ZnJvbSA9IE9iamVjdChhcmd1bWVudHNbc10pO1xuXG5cdFx0Zm9yICh2YXIga2V5IGluIGZyb20pIHtcblx0XHRcdGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGZyb20sIGtleSkpIHtcblx0XHRcdFx0dG9ba2V5XSA9IGZyb21ba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7XG5cdFx0XHRzeW1ib2xzID0gZ2V0T3duUHJvcGVydHlTeW1ib2xzKGZyb20pO1xuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBzeW1ib2xzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdGlmIChwcm9wSXNFbnVtZXJhYmxlLmNhbGwoZnJvbSwgc3ltYm9sc1tpXSkpIHtcblx0XHRcdFx0XHR0b1tzeW1ib2xzW2ldXSA9IGZyb21bc3ltYm9sc1tpXV07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gdG87XG59O1xuXG59LHt9XSwyNDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG52YXIgYnVuZGxlRm4gPSBhcmd1bWVudHNbM107XG52YXIgc291cmNlcyA9IGFyZ3VtZW50c1s0XTtcbnZhciBjYWNoZSA9IGFyZ3VtZW50c1s1XTtcblxudmFyIHN0cmluZ2lmeSA9IEpTT04uc3RyaW5naWZ5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChmbiwgb3B0aW9ucykge1xuICAgIHZhciB3a2V5O1xuICAgIHZhciBjYWNoZUtleXMgPSBPYmplY3Qua2V5cyhjYWNoZSk7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGNhY2hlS2V5cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgdmFyIGtleSA9IGNhY2hlS2V5c1tpXTtcbiAgICAgICAgdmFyIGV4cCA9IGNhY2hlW2tleV0uZXhwb3J0cztcbiAgICAgICAgLy8gVXNpbmcgYmFiZWwgYXMgYSB0cmFuc3BpbGVyIHRvIHVzZSBlc21vZHVsZSwgdGhlIGV4cG9ydCB3aWxsIGFsd2F5c1xuICAgICAgICAvLyBiZSBhbiBvYmplY3Qgd2l0aCB0aGUgZGVmYXVsdCBleHBvcnQgYXMgYSBwcm9wZXJ0eSBvZiBpdC4gVG8gZW5zdXJlXG4gICAgICAgIC8vIHRoZSBleGlzdGluZyBhcGkgYW5kIGJhYmVsIGVzbW9kdWxlIGV4cG9ydHMgYXJlIGJvdGggc3VwcG9ydGVkIHdlXG4gICAgICAgIC8vIGNoZWNrIGZvciBib3RoXG4gICAgICAgIGlmIChleHAgPT09IGZuIHx8IGV4cCAmJiBleHAuZGVmYXVsdCA9PT0gZm4pIHtcbiAgICAgICAgICAgIHdrZXkgPSBrZXk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICghd2tleSkge1xuICAgICAgICB3a2V5ID0gTWF0aC5mbG9vcihNYXRoLnBvdygxNiwgOCkgKiBNYXRoLnJhbmRvbSgpKS50b1N0cmluZygxNik7XG4gICAgICAgIHZhciB3Y2FjaGUgPSB7fTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjYWNoZUtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0gY2FjaGVLZXlzW2ldO1xuICAgICAgICAgICAgd2NhY2hlW2tleV0gPSBrZXk7XG4gICAgICAgIH1cbiAgICAgICAgc291cmNlc1t3a2V5XSA9IFtcbiAgICAgICAgICAgICdmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsnICsgZm4gKyAnKHNlbGYpOyB9JyxcbiAgICAgICAgICAgIHdjYWNoZVxuICAgICAgICBdO1xuICAgIH1cbiAgICB2YXIgc2tleSA9IE1hdGguZmxvb3IoTWF0aC5wb3coMTYsIDgpICogTWF0aC5yYW5kb20oKSkudG9TdHJpbmcoMTYpO1xuXG4gICAgdmFyIHNjYWNoZSA9IHt9OyBzY2FjaGVbd2tleV0gPSB3a2V5O1xuICAgIHNvdXJjZXNbc2tleV0gPSBbXG4gICAgICAgICdmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsnICtcbiAgICAgICAgICAgIC8vIHRyeSB0byBjYWxsIGRlZmF1bHQgaWYgZGVmaW5lZCB0byBhbHNvIHN1cHBvcnQgYmFiZWwgZXNtb2R1bGUgZXhwb3J0c1xuICAgICAgICAgICAgJ3ZhciBmID0gcmVxdWlyZSgnICsgc3RyaW5naWZ5KHdrZXkpICsgJyk7JyArXG4gICAgICAgICAgICAnKGYuZGVmYXVsdCA/IGYuZGVmYXVsdCA6IGYpKHNlbGYpOycgK1xuICAgICAgICAnfScsXG4gICAgICAgIHNjYWNoZVxuICAgIF07XG5cbiAgICB2YXIgd29ya2VyU291cmNlcyA9IHt9O1xuICAgIHJlc29sdmVTb3VyY2VzKHNrZXkpO1xuXG4gICAgZnVuY3Rpb24gcmVzb2x2ZVNvdXJjZXMoa2V5KSB7XG4gICAgICAgIHdvcmtlclNvdXJjZXNba2V5XSA9IHRydWU7XG5cbiAgICAgICAgZm9yICh2YXIgZGVwUGF0aCBpbiBzb3VyY2VzW2tleV1bMV0pIHtcbiAgICAgICAgICAgIHZhciBkZXBLZXkgPSBzb3VyY2VzW2tleV1bMV1bZGVwUGF0aF07XG4gICAgICAgICAgICBpZiAoIXdvcmtlclNvdXJjZXNbZGVwS2V5XSkge1xuICAgICAgICAgICAgICAgIHJlc29sdmVTb3VyY2VzKGRlcEtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgc3JjID0gJygnICsgYnVuZGxlRm4gKyAnKSh7J1xuICAgICAgICArIE9iamVjdC5rZXlzKHdvcmtlclNvdXJjZXMpLm1hcChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICByZXR1cm4gc3RyaW5naWZ5KGtleSkgKyAnOlsnXG4gICAgICAgICAgICAgICAgKyBzb3VyY2VzW2tleV1bMF1cbiAgICAgICAgICAgICAgICArICcsJyArIHN0cmluZ2lmeShzb3VyY2VzW2tleV1bMV0pICsgJ10nXG4gICAgICAgICAgICA7XG4gICAgICAgIH0pLmpvaW4oJywnKVxuICAgICAgICArICd9LHt9LFsnICsgc3RyaW5naWZ5KHNrZXkpICsgJ10pJ1xuICAgIDtcblxuICAgIHZhciBVUkwgPSB3aW5kb3cuVVJMIHx8IHdpbmRvdy53ZWJraXRVUkwgfHwgd2luZG93Lm1velVSTCB8fCB3aW5kb3cubXNVUkw7XG5cbiAgICB2YXIgYmxvYiA9IG5ldyBCbG9iKFtzcmNdLCB7IHR5cGU6ICd0ZXh0L2phdmFzY3JpcHQnIH0pO1xuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuYmFyZSkgeyByZXR1cm4gYmxvYjsgfVxuICAgIHZhciB3b3JrZXJVcmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgIHZhciB3b3JrZXIgPSBuZXcgV29ya2VyKHdvcmtlclVybCk7XG4gICAgd29ya2VyLm9iamVjdFVSTCA9IHdvcmtlclVybDtcbiAgICByZXR1cm4gd29ya2VyO1xufTtcblxufSx7fV0sXCIvaW5kZXguanNcIjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIF9zbGljZWRUb0FycmF5KGFyciwgaSkgeyByZXR1cm4gX2FycmF5V2l0aEhvbGVzKGFycikgfHwgX2l0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkgfHwgX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KGFyciwgaSkgfHwgX25vbkl0ZXJhYmxlUmVzdCgpOyB9XG5cbmZ1bmN0aW9uIF9ub25JdGVyYWJsZVJlc3QoKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGF0dGVtcHQgdG8gZGVzdHJ1Y3R1cmUgbm9uLWl0ZXJhYmxlIGluc3RhbmNlLlxcbkluIG9yZGVyIHRvIGJlIGl0ZXJhYmxlLCBub24tYXJyYXkgb2JqZWN0cyBtdXN0IGhhdmUgYSBbU3ltYm9sLml0ZXJhdG9yXSgpIG1ldGhvZC5cIik7IH1cblxuZnVuY3Rpb24gX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KG8sIG1pbkxlbikgeyBpZiAoIW8pIHJldHVybjsgaWYgKHR5cGVvZiBvID09PSBcInN0cmluZ1wiKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkobywgbWluTGVuKTsgdmFyIG4gPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobykuc2xpY2UoOCwgLTEpOyBpZiAobiA9PT0gXCJPYmplY3RcIiAmJiBvLmNvbnN0cnVjdG9yKSBuID0gby5jb25zdHJ1Y3Rvci5uYW1lOyBpZiAobiA9PT0gXCJNYXBcIiB8fCBuID09PSBcIlNldFwiKSByZXR1cm4gQXJyYXkuZnJvbShvKTsgaWYgKG4gPT09IFwiQXJndW1lbnRzXCIgfHwgL14oPzpVaXxJKW50KD86OHwxNnwzMikoPzpDbGFtcGVkKT9BcnJheSQvLnRlc3QobikpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pOyB9XG5cbmZ1bmN0aW9uIF9hcnJheUxpa2VUb0FycmF5KGFyciwgbGVuKSB7IGlmIChsZW4gPT0gbnVsbCB8fCBsZW4gPiBhcnIubGVuZ3RoKSBsZW4gPSBhcnIubGVuZ3RoOyBmb3IgKHZhciBpID0gMCwgYXJyMiA9IG5ldyBBcnJheShsZW4pOyBpIDwgbGVuOyBpKyspIHsgYXJyMltpXSA9IGFycltpXTsgfSByZXR1cm4gYXJyMjsgfVxuXG5mdW5jdGlvbiBfaXRlcmFibGVUb0FycmF5TGltaXQoYXJyLCBpKSB7IHZhciBfaSA9IGFyciA9PSBudWxsID8gbnVsbCA6IHR5cGVvZiBTeW1ib2wgIT09IFwidW5kZWZpbmVkXCIgJiYgYXJyW1N5bWJvbC5pdGVyYXRvcl0gfHwgYXJyW1wiQEBpdGVyYXRvclwiXTsgaWYgKF9pID09IG51bGwpIHJldHVybjsgdmFyIF9hcnIgPSBbXTsgdmFyIF9uID0gdHJ1ZTsgdmFyIF9kID0gZmFsc2U7IHZhciBfcywgX2U7IHRyeSB7IGZvciAoX2kgPSBfaS5jYWxsKGFycik7ICEoX24gPSAoX3MgPSBfaS5uZXh0KCkpLmRvbmUpOyBfbiA9IHRydWUpIHsgX2Fyci5wdXNoKF9zLnZhbHVlKTsgaWYgKGkgJiYgX2Fyci5sZW5ndGggPT09IGkpIGJyZWFrOyB9IH0gY2F0Y2ggKGVycikgeyBfZCA9IHRydWU7IF9lID0gZXJyOyB9IGZpbmFsbHkgeyB0cnkgeyBpZiAoIV9uICYmIF9pW1wicmV0dXJuXCJdICE9IG51bGwpIF9pW1wicmV0dXJuXCJdKCk7IH0gZmluYWxseSB7IGlmIChfZCkgdGhyb3cgX2U7IH0gfSByZXR1cm4gX2FycjsgfVxuXG5mdW5jdGlvbiBfYXJyYXlXaXRoSG9sZXMoYXJyKSB7IGlmIChBcnJheS5pc0FycmF5KGFycikpIHJldHVybiBhcnI7IH1cblxudmFyIGFzc2lnbiA9IF9kZXJlcV8oJ29iamVjdC1hc3NpZ24nKTtcblxudmFyIHdlYndvcmtpZnkgPSBfZGVyZXFfKCd3ZWJ3b3JraWZ5Jyk7XG5cbnZhciBNYXRoTGliID0gX2RlcmVxXygnLi9saWIvbWF0aGxpYicpO1xuXG52YXIgUG9vbCA9IF9kZXJlcV8oJy4vbGliL3Bvb2wnKTtcblxudmFyIHV0aWxzID0gX2RlcmVxXygnLi9saWIvdXRpbHMnKTtcblxudmFyIHdvcmtlciA9IF9kZXJlcV8oJy4vbGliL3dvcmtlcicpO1xuXG52YXIgY3JlYXRlU3RhZ2VzID0gX2RlcmVxXygnLi9saWIvc3RlcHBlcicpO1xuXG52YXIgY3JlYXRlUmVnaW9ucyA9IF9kZXJlcV8oJy4vbGliL3RpbGVyJyk7IC8vIERlZHVwbGljYXRlIHBvb2xzICYgbGltaXRlcnMgd2l0aCB0aGUgc2FtZSBjb25maWdzXG4vLyB3aGVuIHVzZXIgY3JlYXRlcyBtdWx0aXBsZSBwaWNhIGluc3RhbmNlcy5cblxuXG52YXIgc2luZ2xldG9uZXMgPSB7fTtcbnZhciBORUVEX1NBRkFSSV9GSVggPSBmYWxzZTtcblxudHJ5IHtcbiAgaWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmIG5hdmlnYXRvci51c2VyQWdlbnQpIHtcbiAgICBORUVEX1NBRkFSSV9GSVggPSBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ1NhZmFyaScpID49IDA7XG4gIH1cbn0gY2F0Y2ggKGUpIHt9XG5cbnZhciBjb25jdXJyZW5jeSA9IDE7XG5cbmlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJykge1xuICBjb25jdXJyZW5jeSA9IE1hdGgubWluKG5hdmlnYXRvci5oYXJkd2FyZUNvbmN1cnJlbmN5IHx8IDEsIDQpO1xufVxuXG52YXIgREVGQVVMVF9QSUNBX09QVFMgPSB7XG4gIHRpbGU6IDEwMjQsXG4gIGNvbmN1cnJlbmN5OiBjb25jdXJyZW5jeSxcbiAgZmVhdHVyZXM6IFsnanMnLCAnd2FzbScsICd3dyddLFxuICBpZGxlOiAyMDAwLFxuICBjcmVhdGVDYW52YXM6IGZ1bmN0aW9uIGNyZWF0ZUNhbnZhcyh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgdmFyIHRtcENhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIHRtcENhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgIHRtcENhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgcmV0dXJuIHRtcENhbnZhcztcbiAgfVxufTtcbnZhciBERUZBVUxUX1JFU0laRV9PUFRTID0ge1xuICBxdWFsaXR5OiAzLFxuICBhbHBoYTogZmFsc2UsXG4gIHVuc2hhcnBBbW91bnQ6IDAsXG4gIHVuc2hhcnBSYWRpdXM6IDAuMCxcbiAgdW5zaGFycFRocmVzaG9sZDogMFxufTtcbnZhciBDQU5fTkVXX0lNQUdFX0RBVEEgPSBmYWxzZTtcbnZhciBDQU5fQ1JFQVRFX0lNQUdFX0JJVE1BUCA9IGZhbHNlO1xudmFyIENBTl9VU0VfQ0FOVkFTX0dFVF9JTUFHRV9EQVRBID0gZmFsc2U7XG52YXIgQ0FOX1VTRV9PRkZTQ1JFRU5fQ0FOVkFTID0gZmFsc2U7XG52YXIgQ0FOX1VTRV9DSUJfUkVHSU9OX0ZPUl9JTUFHRSA9IGZhbHNlO1xuXG5mdW5jdGlvbiB3b3JrZXJGYWJyaWMoKSB7XG4gIHJldHVybiB7XG4gICAgdmFsdWU6IHdlYndvcmtpZnkod29ya2VyKSxcbiAgICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgICAgdGhpcy52YWx1ZS50ZXJtaW5hdGUoKTtcblxuICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHZhciB1cmwgPSB3aW5kb3cuVVJMIHx8IHdpbmRvdy53ZWJraXRVUkwgfHwgd2luZG93Lm1velVSTCB8fCB3aW5kb3cubXNVUkw7XG5cbiAgICAgICAgaWYgKHVybCAmJiB1cmwucmV2b2tlT2JqZWN0VVJMICYmIHRoaXMudmFsdWUub2JqZWN0VVJMKSB7XG4gICAgICAgICAgdXJsLnJldm9rZU9iamVjdFVSTCh0aGlzLnZhbHVlLm9iamVjdFVSTCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG59IC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBBUEkgbWV0aG9kc1xuXG5cbmZ1bmN0aW9uIFBpY2Eob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUGljYSkpIHJldHVybiBuZXcgUGljYShvcHRpb25zKTtcbiAgdGhpcy5vcHRpb25zID0gYXNzaWduKHt9LCBERUZBVUxUX1BJQ0FfT1BUUywgb3B0aW9ucyB8fCB7fSk7XG4gIHZhciBsaW1pdGVyX2tleSA9IFwibGtfXCIuY29uY2F0KHRoaXMub3B0aW9ucy5jb25jdXJyZW5jeSk7IC8vIFNoYXJlIGxpbWl0ZXJzIHRvIGF2b2lkIG11bHRpcGxlIHBhcmFsbGVsIHdvcmtlcnMgd2hlbiB1c2VyIGNyZWF0ZXNcbiAgLy8gbXVsdGlwbGUgcGljYSBpbnN0YW5jZXMuXG5cbiAgdGhpcy5fX2xpbWl0ID0gc2luZ2xldG9uZXNbbGltaXRlcl9rZXldIHx8IHV0aWxzLmxpbWl0ZXIodGhpcy5vcHRpb25zLmNvbmN1cnJlbmN5KTtcbiAgaWYgKCFzaW5nbGV0b25lc1tsaW1pdGVyX2tleV0pIHNpbmdsZXRvbmVzW2xpbWl0ZXJfa2V5XSA9IHRoaXMuX19saW1pdDsgLy8gTGlzdCBvZiBzdXBwb3J0ZWQgZmVhdHVyZXMsIGFjY29yZGluZyB0byBvcHRpb25zICYgYnJvd3Nlci9ub2RlLmpzXG5cbiAgdGhpcy5mZWF0dXJlcyA9IHtcbiAgICBqczogZmFsc2UsXG4gICAgLy8gcHVyZSBKUyBpbXBsZW1lbnRhdGlvbiwgY2FuIGJlIGRpc2FibGVkIGZvciB0ZXN0aW5nXG4gICAgd2FzbTogZmFsc2UsXG4gICAgLy8gd2ViYXNzZW1ibHkgaW1wbGVtZW50YXRpb24gZm9yIGhlYXZ5IGZ1bmN0aW9uc1xuICAgIGNpYjogZmFsc2UsXG4gICAgLy8gcmVzaXplIHZpYSBjcmVhdGVJbWFnZUJpdG1hcCAob25seSBGRiBhdCB0aGlzIG1vbWVudClcbiAgICB3dzogZmFsc2UgLy8gd2Vid29ya2Vyc1xuXG4gIH07XG4gIHRoaXMuX193b3JrZXJzUG9vbCA9IG51bGw7IC8vIFN0b3JlIHJlcXVlc3RlZCBmZWF0dXJlcyBmb3Igd2Vid29ya2Vyc1xuXG4gIHRoaXMuX19yZXF1ZXN0ZWRfZmVhdHVyZXMgPSBbXTtcbiAgdGhpcy5fX21hdGhsaWIgPSBudWxsO1xufVxuXG5QaWNhLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gIGlmICh0aGlzLl9faW5pdFByb21pc2UpIHJldHVybiB0aGlzLl9faW5pdFByb21pc2U7IC8vIFRlc3QgaWYgd2UgY2FuIGNyZWF0ZSBJbWFnZURhdGEgd2l0aG91dCBjYW52YXMgYW5kIG1lbW9yeSBjb3B5XG5cbiAgaWYgKHR5cGVvZiBJbWFnZURhdGEgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBVaW50OENsYW1wZWRBcnJheSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0cnkge1xuICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tbmV3ICovXG4gICAgICBuZXcgSW1hZ2VEYXRhKG5ldyBVaW50OENsYW1wZWRBcnJheSg0MDApLCAxMCwgMTApO1xuICAgICAgQ0FOX05FV19JTUFHRV9EQVRBID0gdHJ1ZTtcbiAgICB9IGNhdGNoIChfXykge31cbiAgfSAvLyBJbWFnZUJpdG1hcCBjYW4gYmUgZWZmZWN0aXZlIGluIDIgcGxhY2VzOlxuICAvL1xuICAvLyAxLiBUaHJlYWRlZCBqcGVnIHVucGFjayAoYmFzaWMpXG4gIC8vIDIuIEJ1aWx0LWluIHJlc2l6ZSAoYmxvY2tlZCBkdWUgcHJvYmxlbSBpbiBjaHJvbWUsIHNlZSBpc3N1ZSAjODkpXG4gIC8vXG4gIC8vIEZvciBiYXNpYyB1c2Ugd2UgYWxzbyBuZWVkIEltYWdlQml0bWFwIHdvIHN1cHBvcnQgLmNsb3NlKCkgbWV0aG9kLFxuICAvLyBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvcnUvZG9jcy9XZWIvQVBJL0ltYWdlQml0bWFwXG5cblxuICBpZiAodHlwZW9mIEltYWdlQml0bWFwICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmIChJbWFnZUJpdG1hcC5wcm90b3R5cGUgJiYgSW1hZ2VCaXRtYXAucHJvdG90eXBlLmNsb3NlKSB7XG4gICAgICBDQU5fQ1JFQVRFX0lNQUdFX0JJVE1BUCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGVidWcoJ0ltYWdlQml0bWFwIGRvZXMgbm90IHN1cHBvcnQgLmNsb3NlKCksIGRpc2FibGVkJyk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGZlYXR1cmVzID0gdGhpcy5vcHRpb25zLmZlYXR1cmVzLnNsaWNlKCk7XG5cbiAgaWYgKGZlYXR1cmVzLmluZGV4T2YoJ2FsbCcpID49IDApIHtcbiAgICBmZWF0dXJlcyA9IFsnY2liJywgJ3dhc20nLCAnanMnLCAnd3cnXTtcbiAgfVxuXG4gIHRoaXMuX19yZXF1ZXN0ZWRfZmVhdHVyZXMgPSBmZWF0dXJlcztcbiAgdGhpcy5fX21hdGhsaWIgPSBuZXcgTWF0aExpYihmZWF0dXJlcyk7IC8vIENoZWNrIFdlYldvcmtlciBzdXBwb3J0IGlmIHJlcXVlc3RlZFxuXG4gIGlmIChmZWF0dXJlcy5pbmRleE9mKCd3dycpID49IDApIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgJ1dvcmtlcicgaW4gd2luZG93KSB7XG4gICAgICAvLyBJRSA8PSAxMSBkb24ndCBhbGxvdyB0byBjcmVhdGUgd2Vid29ya2VycyBmcm9tIHN0cmluZy4gV2Ugc2hvdWxkIGNoZWNrIGl0LlxuICAgICAgLy8gaHR0cHM6Ly9jb25uZWN0Lm1pY3Jvc29mdC5jb20vSUUvZmVlZGJhY2svZGV0YWlscy84MDE4MTAvd2ViLXdvcmtlcnMtZnJvbS1ibG9iLXVybHMtaW4taWUtMTAtYW5kLTExXG4gICAgICB0cnkge1xuICAgICAgICB2YXIgd2tyID0gX2RlcmVxXygnd2Vid29ya2lmeScpKGZ1bmN0aW9uICgpIHt9KTtcblxuICAgICAgICB3a3IudGVybWluYXRlKCk7XG4gICAgICAgIHRoaXMuZmVhdHVyZXMud3cgPSB0cnVlOyAvLyBwb29sIHVuaXF1ZW5lc3MgZGVwZW5kcyBvbiBwb29sIGNvbmZpZyArIHdlYndvcmtlciBjb25maWdcblxuICAgICAgICB2YXIgd3Bvb2xfa2V5ID0gXCJ3cF9cIi5jb25jYXQoSlNPTi5zdHJpbmdpZnkodGhpcy5vcHRpb25zKSk7XG5cbiAgICAgICAgaWYgKHNpbmdsZXRvbmVzW3dwb29sX2tleV0pIHtcbiAgICAgICAgICB0aGlzLl9fd29ya2Vyc1Bvb2wgPSBzaW5nbGV0b25lc1t3cG9vbF9rZXldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuX193b3JrZXJzUG9vbCA9IG5ldyBQb29sKHdvcmtlckZhYnJpYywgdGhpcy5vcHRpb25zLmlkbGUpO1xuICAgICAgICAgIHNpbmdsZXRvbmVzW3dwb29sX2tleV0gPSB0aGlzLl9fd29ya2Vyc1Bvb2w7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKF9fKSB7fVxuICAgIH1cbiAgfVxuXG4gIHZhciBpbml0TWF0aCA9IHRoaXMuX19tYXRobGliLmluaXQoKS50aGVuKGZ1bmN0aW9uIChtYXRobGliKSB7XG4gICAgLy8gQ29weSBkZXRlY3RlZCBmZWF0dXJlc1xuICAgIGFzc2lnbihfdGhpcy5mZWF0dXJlcywgbWF0aGxpYi5mZWF0dXJlcyk7XG4gIH0pO1xuXG4gIHZhciBjaGVja0NpYlJlc2l6ZTtcblxuICBpZiAoIUNBTl9DUkVBVEVfSU1BR0VfQklUTUFQKSB7XG4gICAgY2hlY2tDaWJSZXNpemUgPSBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xuICB9IGVsc2Uge1xuICAgIGNoZWNrQ2liUmVzaXplID0gdXRpbHMuY2liX3N1cHBvcnQodGhpcy5vcHRpb25zLmNyZWF0ZUNhbnZhcykudGhlbihmdW5jdGlvbiAoc3RhdHVzKSB7XG4gICAgICBpZiAoX3RoaXMuZmVhdHVyZXMuY2liICYmIGZlYXR1cmVzLmluZGV4T2YoJ2NpYicpIDwgMCkge1xuICAgICAgICBfdGhpcy5kZWJ1ZygnY3JlYXRlSW1hZ2VCaXRtYXAoKSByZXNpemUgc3VwcG9ydGVkLCBidXQgZGlzYWJsZWQgYnkgY29uZmlnJyk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZmVhdHVyZXMuaW5kZXhPZignY2liJykgPj0gMCkgX3RoaXMuZmVhdHVyZXMuY2liID0gc3RhdHVzO1xuICAgIH0pO1xuICB9XG5cbiAgQ0FOX1VTRV9DQU5WQVNfR0VUX0lNQUdFX0RBVEEgPSB1dGlscy5jYW5fdXNlX2NhbnZhcyh0aGlzLm9wdGlvbnMuY3JlYXRlQ2FudmFzKTtcbiAgdmFyIGNoZWNrT2Zmc2NyZWVuQ2FudmFzO1xuXG4gIGlmIChDQU5fQ1JFQVRFX0lNQUdFX0JJVE1BUCAmJiBDQU5fTkVXX0lNQUdFX0RBVEEgJiYgZmVhdHVyZXMuaW5kZXhPZignd3cnKSAhPT0gLTEpIHtcbiAgICBjaGVja09mZnNjcmVlbkNhbnZhcyA9IHV0aWxzLndvcmtlcl9vZmZzY3JlZW5fY2FudmFzX3N1cHBvcnQoKTtcbiAgfSBlbHNlIHtcbiAgICBjaGVja09mZnNjcmVlbkNhbnZhcyA9IFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gIH1cblxuICBjaGVja09mZnNjcmVlbkNhbnZhcyA9IGNoZWNrT2Zmc2NyZWVuQ2FudmFzLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgIENBTl9VU0VfT0ZGU0NSRUVOX0NBTlZBUyA9IHJlc3VsdDtcbiAgfSk7IC8vIHdlIHVzZSBjcmVhdGVJbWFnZUJpdG1hcCB0byBjcm9wIGltYWdlIGRhdGEgYW5kIHBhc3MgaXQgdG8gd29ya2VycyxcbiAgLy8gc28gbmVlZCB0byBjaGVjayB3aGV0aGVyIGZ1bmN0aW9uIHdvcmtzIGNvcnJlY3RseTtcbiAgLy8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9MTIyMDY3MVxuXG4gIHZhciBjaGVja0NpYlJlZ2lvbiA9IHV0aWxzLmNpYl9jYW5fdXNlX3JlZ2lvbigpLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgIENBTl9VU0VfQ0lCX1JFR0lPTl9GT1JfSU1BR0UgPSByZXN1bHQ7XG4gIH0pOyAvLyBJbml0IG1hdGggbGliLiBUaGF0J3MgYXN5bmMgYmVjYXVzZSBjYW4gbG9hZCBzb21lXG5cbiAgdGhpcy5fX2luaXRQcm9taXNlID0gUHJvbWlzZS5hbGwoW2luaXRNYXRoLCBjaGVja0NpYlJlc2l6ZSwgY2hlY2tPZmZzY3JlZW5DYW52YXMsIGNoZWNrQ2liUmVnaW9uXSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9KTtcbiAgcmV0dXJuIHRoaXMuX19pbml0UHJvbWlzZTtcbn07IC8vIENhbGwgcmVzaXplciBpbiB3ZWJ3b3JrZXIgb3IgbG9jYWxseSwgZGVwZW5kaW5nIG9uIGNvbmZpZ1xuXG5cblBpY2EucHJvdG90eXBlLl9faW52b2tlUmVzaXplID0gZnVuY3Rpb24gKHRpbGVPcHRzLCBvcHRzKSB7XG4gIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gIC8vIFNoYXJlIGNhY2hlIGJldHdlZW4gY2FsbHM6XG4gIC8vXG4gIC8vIC0gd2FzbSBpbnN0YW5jZVxuICAvLyAtIHdhc20gbWVtb3J5IG9iamVjdFxuICAvL1xuICBvcHRzLl9fbWF0aENhY2hlID0gb3B0cy5fX21hdGhDYWNoZSB8fCB7fTtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIGlmICghX3RoaXMyLmZlYXR1cmVzLnd3KSB7XG4gICAgICAvLyBub3QgcG9zc2libGUgdG8gaGF2ZSBJbWFnZUJpdG1hcCBoZXJlIGlmIHVzZXIgZGlzYWJsZWQgV1dcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRhdGE6IF90aGlzMi5fX21hdGhsaWIucmVzaXplQW5kVW5zaGFycCh0aWxlT3B0cywgb3B0cy5fX21hdGhDYWNoZSlcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciB3ID0gX3RoaXMyLl9fd29ya2Vyc1Bvb2wuYWNxdWlyZSgpO1xuXG4gICAgICBpZiAob3B0cy5jYW5jZWxUb2tlbikgb3B0cy5jYW5jZWxUb2tlbltcImNhdGNoXCJdKGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgfSk7XG5cbiAgICAgIHcudmFsdWUub25tZXNzYWdlID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgIHcucmVsZWFzZSgpO1xuICAgICAgICBpZiAoZXYuZGF0YS5lcnIpIHJlamVjdChldi5kYXRhLmVycik7ZWxzZSByZXNvbHZlKGV2LmRhdGEpO1xuICAgICAgfTtcblxuICAgICAgdmFyIHRyYW5zZmVyID0gW107XG4gICAgICBpZiAodGlsZU9wdHMuc3JjKSB0cmFuc2Zlci5wdXNoKHRpbGVPcHRzLnNyYy5idWZmZXIpO1xuICAgICAgaWYgKHRpbGVPcHRzLnNyY0JpdG1hcCkgdHJhbnNmZXIucHVzaCh0aWxlT3B0cy5zcmNCaXRtYXApO1xuICAgICAgdy52YWx1ZS5wb3N0TWVzc2FnZSh7XG4gICAgICAgIG9wdHM6IHRpbGVPcHRzLFxuICAgICAgICBmZWF0dXJlczogX3RoaXMyLl9fcmVxdWVzdGVkX2ZlYXR1cmVzLFxuICAgICAgICBwcmVsb2FkOiB7XG4gICAgICAgICAgd2FzbV9ub2R1bGU6IF90aGlzMi5fX21hdGhsaWIuX19cbiAgICAgICAgfVxuICAgICAgfSwgdHJhbnNmZXIpO1xuICAgIH0pO1xuICB9KTtcbn07IC8vIHRoaXMgZnVuY3Rpb24gY2FuIHJldHVybiBwcm9taXNlIGlmIGNyZWF0ZUltYWdlQml0bWFwIGlzIHVzZWRcblxuXG5QaWNhLnByb3RvdHlwZS5fX2V4dHJhY3RUaWxlRGF0YSA9IGZ1bmN0aW9uICh0aWxlLCBmcm9tLCBvcHRzLCBzdGFnZUVudiwgZXh0cmFjdFRvKSB7XG4gIGlmICh0aGlzLmZlYXR1cmVzLnd3ICYmIENBTl9VU0VfT0ZGU0NSRUVOX0NBTlZBUyAmJiAoIC8vIGNyZWF0ZUltYWdlQml0bWFwIGRvZXNuJ3Qgd29yayBmb3IgaW1hZ2VzIChJbWFnZSwgSW1hZ2VCaXRtYXApIHdpdGggRXhpZiBvcmllbnRhdGlvbiBpbiBDaHJvbWUsXG4gIC8vIGNhbiB1c2UgY2FudmFzIGJlY2F1c2UgY2FudmFzIGRvZXNuJ3QgaGF2ZSBvcmllbnRhdGlvbjtcbiAgLy8gc2VlIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTEyMjA2NzFcbiAgdXRpbHMuaXNDYW52YXMoZnJvbSkgfHwgQ0FOX1VTRV9DSUJfUkVHSU9OX0ZPUl9JTUFHRSkpIHtcbiAgICB0aGlzLmRlYnVnKCdDcmVhdGUgdGlsZSBmb3IgT2Zmc2NyZWVuQ2FudmFzJyk7XG4gICAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKHN0YWdlRW52LnNyY0ltYWdlQml0bWFwIHx8IGZyb20sIHRpbGUueCwgdGlsZS55LCB0aWxlLndpZHRoLCB0aWxlLmhlaWdodCkudGhlbihmdW5jdGlvbiAoYml0bWFwKSB7XG4gICAgICBleHRyYWN0VG8uc3JjQml0bWFwID0gYml0bWFwO1xuICAgICAgcmV0dXJuIGV4dHJhY3RUbztcbiAgICB9KTtcbiAgfSAvLyBFeHRyYWN0IHRpbGUgUkdCQSBidWZmZXIsIGRlcGVuZGluZyBvbiBpbnB1dCB0eXBlXG5cblxuICBpZiAodXRpbHMuaXNDYW52YXMoZnJvbSkpIHtcbiAgICBpZiAoIXN0YWdlRW52LnNyY0N0eCkgc3RhZ2VFbnYuc3JjQ3R4ID0gZnJvbS5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICAgIGFscGhhOiBCb29sZWFuKG9wdHMuYWxwaGEpXG4gICAgfSk7IC8vIElmIGlucHV0IGlzIENhbnZhcyAtIGV4dHJhY3QgcmVnaW9uIGRhdGEgZGlyZWN0bHlcblxuICAgIHRoaXMuZGVidWcoJ0dldCB0aWxlIHBpeGVsIGRhdGEnKTtcbiAgICBleHRyYWN0VG8uc3JjID0gc3RhZ2VFbnYuc3JjQ3R4LmdldEltYWdlRGF0YSh0aWxlLngsIHRpbGUueSwgdGlsZS53aWR0aCwgdGlsZS5oZWlnaHQpLmRhdGE7XG4gICAgcmV0dXJuIGV4dHJhY3RUbztcbiAgfSAvLyBJZiBpbnB1dCBpcyBJbWFnZSBvciBkZWNvZGVkIHRvIEltYWdlQml0bWFwLFxuICAvLyBkcmF3IHJlZ2lvbiB0byB0ZW1wb3JhcnkgY2FudmFzIGFuZCBleHRyYWN0IGRhdGEgZnJvbSBpdFxuICAvL1xuICAvLyBOb3RlISBBdHRlbXB0IHRvIHJldXNlIHRoaXMgY2FudmFzIGNhdXNlcyBzaWduaWZpY2FudCBzbG93ZG93biBpbiBjaHJvbWVcbiAgLy9cblxuXG4gIHRoaXMuZGVidWcoJ0RyYXcgdGlsZSBpbWFnZUJpdG1hcC9pbWFnZSB0byB0ZW1wb3JhcnkgY2FudmFzJyk7XG4gIHZhciB0bXBDYW52YXMgPSB0aGlzLm9wdGlvbnMuY3JlYXRlQ2FudmFzKHRpbGUud2lkdGgsIHRpbGUuaGVpZ2h0KTtcbiAgdmFyIHRtcEN0eCA9IHRtcENhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICBhbHBoYTogQm9vbGVhbihvcHRzLmFscGhhKVxuICB9KTtcbiAgdG1wQ3R4Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICdjb3B5JztcbiAgdG1wQ3R4LmRyYXdJbWFnZShzdGFnZUVudi5zcmNJbWFnZUJpdG1hcCB8fCBmcm9tLCB0aWxlLngsIHRpbGUueSwgdGlsZS53aWR0aCwgdGlsZS5oZWlnaHQsIDAsIDAsIHRpbGUud2lkdGgsIHRpbGUuaGVpZ2h0KTtcbiAgdGhpcy5kZWJ1ZygnR2V0IHRpbGUgcGl4ZWwgZGF0YScpO1xuICBleHRyYWN0VG8uc3JjID0gdG1wQ3R4LmdldEltYWdlRGF0YSgwLCAwLCB0aWxlLndpZHRoLCB0aWxlLmhlaWdodCkuZGF0YTsgLy8gU2FmYXJpIDEyIHdvcmthcm91bmRcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhL2lzc3Vlcy8xOTlcblxuICB0bXBDYW52YXMud2lkdGggPSB0bXBDYW52YXMuaGVpZ2h0ID0gMDtcbiAgcmV0dXJuIGV4dHJhY3RUbztcbn07XG5cblBpY2EucHJvdG90eXBlLl9fbGFuZFRpbGVEYXRhID0gZnVuY3Rpb24gKHRpbGUsIHJlc3VsdCwgc3RhZ2VFbnYpIHtcbiAgdmFyIHRvSW1hZ2VEYXRhO1xuICB0aGlzLmRlYnVnKCdDb252ZXJ0IHJhdyByZ2JhIHRpbGUgcmVzdWx0IHRvIEltYWdlRGF0YScpO1xuXG4gIGlmIChyZXN1bHQuYml0bWFwKSB7XG4gICAgc3RhZ2VFbnYudG9DdHguZHJhd0ltYWdlKHJlc3VsdC5iaXRtYXAsIHRpbGUudG9YLCB0aWxlLnRvWSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoQ0FOX05FV19JTUFHRV9EQVRBKSB7XG4gICAgLy8gdGhpcyBicmFuY2ggaXMgZm9yIG1vZGVybiBicm93c2Vyc1xuICAgIC8vIElmIGBuZXcgSW1hZ2VEYXRhKClgICYgVWludDhDbGFtcGVkQXJyYXkgc3Vwb3J0ZWRcbiAgICB0b0ltYWdlRGF0YSA9IG5ldyBJbWFnZURhdGEobmV3IFVpbnQ4Q2xhbXBlZEFycmF5KHJlc3VsdC5kYXRhKSwgdGlsZS50b1dpZHRoLCB0aWxlLnRvSGVpZ2h0KTtcbiAgfSBlbHNlIHtcbiAgICAvLyBmYWxsYmFjayBmb3IgYG5vZGUtY2FudmFzYCBhbmQgb2xkIGJyb3dzZXJzXG4gICAgLy8gKElFMTEgaGFzIEltYWdlRGF0YSBidXQgZG9lcyBub3Qgc3VwcG9ydCBgbmV3IEltYWdlRGF0YSgpYClcbiAgICB0b0ltYWdlRGF0YSA9IHN0YWdlRW52LnRvQ3R4LmNyZWF0ZUltYWdlRGF0YSh0aWxlLnRvV2lkdGgsIHRpbGUudG9IZWlnaHQpO1xuXG4gICAgaWYgKHRvSW1hZ2VEYXRhLmRhdGEuc2V0KSB7XG4gICAgICB0b0ltYWdlRGF0YS5kYXRhLnNldChyZXN1bHQuZGF0YSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElFOSBkb24ndCBoYXZlIGAuc2V0KClgXG4gICAgICBmb3IgKHZhciBpID0gdG9JbWFnZURhdGEuZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICB0b0ltYWdlRGF0YS5kYXRhW2ldID0gcmVzdWx0LmRhdGFbaV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdGhpcy5kZWJ1ZygnRHJhdyB0aWxlJyk7XG5cbiAgaWYgKE5FRURfU0FGQVJJX0ZJWCkge1xuICAgIC8vIFNhZmFyaSBkcmF3cyB0aGluIHdoaXRlIHN0cmlwZXMgYmV0d2VlbiB0aWxlcyB3aXRob3V0IHRoaXMgZml4XG4gICAgc3RhZ2VFbnYudG9DdHgucHV0SW1hZ2VEYXRhKHRvSW1hZ2VEYXRhLCB0aWxlLnRvWCwgdGlsZS50b1ksIHRpbGUudG9Jbm5lclggLSB0aWxlLnRvWCwgdGlsZS50b0lubmVyWSAtIHRpbGUudG9ZLCB0aWxlLnRvSW5uZXJXaWR0aCArIDFlLTUsIHRpbGUudG9Jbm5lckhlaWdodCArIDFlLTUpO1xuICB9IGVsc2Uge1xuICAgIHN0YWdlRW52LnRvQ3R4LnB1dEltYWdlRGF0YSh0b0ltYWdlRGF0YSwgdGlsZS50b1gsIHRpbGUudG9ZLCB0aWxlLnRvSW5uZXJYIC0gdGlsZS50b1gsIHRpbGUudG9Jbm5lclkgLSB0aWxlLnRvWSwgdGlsZS50b0lubmVyV2lkdGgsIHRpbGUudG9Jbm5lckhlaWdodCk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn07XG5cblBpY2EucHJvdG90eXBlLl9fdGlsZUFuZFJlc2l6ZSA9IGZ1bmN0aW9uIChmcm9tLCB0bywgb3B0cykge1xuICB2YXIgX3RoaXMzID0gdGhpcztcblxuICB2YXIgc3RhZ2VFbnYgPSB7XG4gICAgc3JjQ3R4OiBudWxsLFxuICAgIHNyY0ltYWdlQml0bWFwOiBudWxsLFxuICAgIGlzSW1hZ2VCaXRtYXBSZXVzZWQ6IGZhbHNlLFxuICAgIHRvQ3R4OiBudWxsXG4gIH07XG5cbiAgdmFyIHByb2Nlc3NUaWxlID0gZnVuY3Rpb24gcHJvY2Vzc1RpbGUodGlsZSkge1xuICAgIHJldHVybiBfdGhpczMuX19saW1pdChmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAob3B0cy5jYW5jZWxlZCkgcmV0dXJuIG9wdHMuY2FuY2VsVG9rZW47XG4gICAgICB2YXIgdGlsZU9wdHMgPSB7XG4gICAgICAgIHdpZHRoOiB0aWxlLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IHRpbGUuaGVpZ2h0LFxuICAgICAgICB0b1dpZHRoOiB0aWxlLnRvV2lkdGgsXG4gICAgICAgIHRvSGVpZ2h0OiB0aWxlLnRvSGVpZ2h0LFxuICAgICAgICBzY2FsZVg6IHRpbGUuc2NhbGVYLFxuICAgICAgICBzY2FsZVk6IHRpbGUuc2NhbGVZLFxuICAgICAgICBvZmZzZXRYOiB0aWxlLm9mZnNldFgsXG4gICAgICAgIG9mZnNldFk6IHRpbGUub2Zmc2V0WSxcbiAgICAgICAgcXVhbGl0eTogb3B0cy5xdWFsaXR5LFxuICAgICAgICBhbHBoYTogb3B0cy5hbHBoYSxcbiAgICAgICAgdW5zaGFycEFtb3VudDogb3B0cy51bnNoYXJwQW1vdW50LFxuICAgICAgICB1bnNoYXJwUmFkaXVzOiBvcHRzLnVuc2hhcnBSYWRpdXMsXG4gICAgICAgIHVuc2hhcnBUaHJlc2hvbGQ6IG9wdHMudW5zaGFycFRocmVzaG9sZFxuICAgICAgfTtcblxuICAgICAgX3RoaXMzLmRlYnVnKCdJbnZva2UgcmVzaXplIG1hdGgnKTtcblxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aWxlT3B0cykudGhlbihmdW5jdGlvbiAodGlsZU9wdHMpIHtcbiAgICAgICAgcmV0dXJuIF90aGlzMy5fX2V4dHJhY3RUaWxlRGF0YSh0aWxlLCBmcm9tLCBvcHRzLCBzdGFnZUVudiwgdGlsZU9wdHMpO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAodGlsZU9wdHMpIHtcbiAgICAgICAgX3RoaXMzLmRlYnVnKCdJbnZva2UgcmVzaXplIG1hdGgnKTtcblxuICAgICAgICByZXR1cm4gX3RoaXMzLl9faW52b2tlUmVzaXplKHRpbGVPcHRzLCBvcHRzKTtcbiAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICBpZiAob3B0cy5jYW5jZWxlZCkgcmV0dXJuIG9wdHMuY2FuY2VsVG9rZW47XG4gICAgICAgIHN0YWdlRW52LnNyY0ltYWdlRGF0YSA9IG51bGw7XG4gICAgICAgIHJldHVybiBfdGhpczMuX19sYW5kVGlsZURhdGEodGlsZSwgcmVzdWx0LCBzdGFnZUVudik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfTsgLy8gTmVlZCB0byBub3JtYWxpemUgZGF0YSBzb3VyY2UgZmlyc3QuIEl0IGNhbiBiZSBjYW52YXMgb3IgaW1hZ2UuXG4gIC8vIElmIGltYWdlIC0gdHJ5IHRvIGRlY29kZSBpbiBiYWNrZ3JvdW5kIGlmIHBvc3NpYmxlXG5cblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgc3RhZ2VFbnYudG9DdHggPSB0by5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICAgIGFscGhhOiBCb29sZWFuKG9wdHMuYWxwaGEpXG4gICAgfSk7XG4gICAgaWYgKHV0aWxzLmlzQ2FudmFzKGZyb20pKSByZXR1cm4gbnVsbDtcblxuICAgIGlmICh1dGlscy5pc0ltYWdlQml0bWFwKGZyb20pKSB7XG4gICAgICBzdGFnZUVudi5zcmNJbWFnZUJpdG1hcCA9IGZyb207XG4gICAgICBzdGFnZUVudi5pc0ltYWdlQml0bWFwUmV1c2VkID0gdHJ1ZTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmICh1dGlscy5pc0ltYWdlKGZyb20pKSB7XG4gICAgICAvLyB0cnkgZG8gZGVjb2RlIGltYWdlIGluIGJhY2tncm91bmQgZm9yIGZhc3RlciBuZXh0IG9wZXJhdGlvbnM7XG4gICAgICAvLyBpZiB3ZSdyZSB1c2luZyBvZmZzY3JlZW4gY2FudmFzLCBjaWIgaXMgY2FsbGVkIHBlciB0aWxlLCBzbyBub3QgbmVlZGVkIGhlcmVcbiAgICAgIGlmICghQ0FOX0NSRUFURV9JTUFHRV9CSVRNQVApIHJldHVybiBudWxsO1xuXG4gICAgICBfdGhpczMuZGVidWcoJ0RlY29kZSBpbWFnZSB2aWEgY3JlYXRlSW1hZ2VCaXRtYXAnKTtcblxuICAgICAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKGZyb20pLnRoZW4oZnVuY3Rpb24gKGltYWdlQml0bWFwKSB7XG4gICAgICAgIHN0YWdlRW52LnNyY0ltYWdlQml0bWFwID0gaW1hZ2VCaXRtYXA7XG4gICAgICB9KSAvLyBTdXBwcmVzcyBlcnJvciB0byB1c2UgZmFsbGJhY2ssIGlmIG1ldGhvZCBmYWlsc1xuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhL2lzc3Vlcy8xOTBcblxuICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi9cbiAgICAgIFtcImNhdGNoXCJdKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKCdQaWNhOiBcIi5mcm9tXCIgc2hvdWxkIGJlIEltYWdlLCBDYW52YXMgb3IgSW1hZ2VCaXRtYXAnKTtcbiAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgaWYgKG9wdHMuY2FuY2VsZWQpIHJldHVybiBvcHRzLmNhbmNlbFRva2VuO1xuXG4gICAgX3RoaXMzLmRlYnVnKCdDYWxjdWxhdGUgdGlsZXMnKTsgLy9cbiAgICAvLyBIZXJlIHdlIGFyZSB3aXRoIFwibm9ybWFsaXplZFwiIHNvdXJjZSxcbiAgICAvLyBmb2xsb3cgdG8gdGlsaW5nXG4gICAgLy9cblxuXG4gICAgdmFyIHJlZ2lvbnMgPSBjcmVhdGVSZWdpb25zKHtcbiAgICAgIHdpZHRoOiBvcHRzLndpZHRoLFxuICAgICAgaGVpZ2h0OiBvcHRzLmhlaWdodCxcbiAgICAgIHNyY1RpbGVTaXplOiBfdGhpczMub3B0aW9ucy50aWxlLFxuICAgICAgdG9XaWR0aDogb3B0cy50b1dpZHRoLFxuICAgICAgdG9IZWlnaHQ6IG9wdHMudG9IZWlnaHQsXG4gICAgICBkZXN0VGlsZUJvcmRlcjogb3B0cy5fX2Rlc3RUaWxlQm9yZGVyXG4gICAgfSk7XG4gICAgdmFyIGpvYnMgPSByZWdpb25zLm1hcChmdW5jdGlvbiAodGlsZSkge1xuICAgICAgcmV0dXJuIHByb2Nlc3NUaWxlKHRpbGUpO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gY2xlYW51cChzdGFnZUVudikge1xuICAgICAgaWYgKHN0YWdlRW52LnNyY0ltYWdlQml0bWFwKSB7XG4gICAgICAgIGlmICghc3RhZ2VFbnYuaXNJbWFnZUJpdG1hcFJldXNlZCkgc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXAuY2xvc2UoKTtcbiAgICAgICAgc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXAgPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIF90aGlzMy5kZWJ1ZygnUHJvY2VzcyB0aWxlcycpO1xuXG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGpvYnMpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgX3RoaXMzLmRlYnVnKCdGaW5pc2hlZCEnKTtcblxuICAgICAgY2xlYW51cChzdGFnZUVudik7XG4gICAgICByZXR1cm4gdG87XG4gICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgY2xlYW51cChzdGFnZUVudik7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfSk7XG4gIH0pO1xufTtcblxuUGljYS5wcm90b3R5cGUuX19wcm9jZXNzU3RhZ2VzID0gZnVuY3Rpb24gKHN0YWdlcywgZnJvbSwgdG8sIG9wdHMpIHtcbiAgdmFyIF90aGlzNCA9IHRoaXM7XG5cbiAgaWYgKG9wdHMuY2FuY2VsZWQpIHJldHVybiBvcHRzLmNhbmNlbFRva2VuO1xuXG4gIHZhciBfc3RhZ2VzJHNoaWZ0ID0gc3RhZ2VzLnNoaWZ0KCksXG4gICAgICBfc3RhZ2VzJHNoaWZ0MiA9IF9zbGljZWRUb0FycmF5KF9zdGFnZXMkc2hpZnQsIDIpLFxuICAgICAgdG9XaWR0aCA9IF9zdGFnZXMkc2hpZnQyWzBdLFxuICAgICAgdG9IZWlnaHQgPSBfc3RhZ2VzJHNoaWZ0MlsxXTtcblxuICB2YXIgaXNMYXN0U3RhZ2UgPSBzdGFnZXMubGVuZ3RoID09PSAwO1xuICBvcHRzID0gYXNzaWduKHt9LCBvcHRzLCB7XG4gICAgdG9XaWR0aDogdG9XaWR0aCxcbiAgICB0b0hlaWdodDogdG9IZWlnaHQsXG4gICAgLy8gb25seSB1c2UgdXNlci1kZWZpbmVkIHF1YWxpdHkgZm9yIHRoZSBsYXN0IHN0YWdlLFxuICAgIC8vIHVzZSBzaW1wbGVyIChIYW1taW5nKSBmaWx0ZXIgZm9yIHRoZSBmaXJzdCBzdGFnZXMgd2hlcmVcbiAgICAvLyBzY2FsZSBmYWN0b3IgaXMgbGFyZ2UgZW5vdWdoIChtb3JlIHRoYW4gMi0zKVxuICAgIHF1YWxpdHk6IGlzTGFzdFN0YWdlID8gb3B0cy5xdWFsaXR5IDogTWF0aC5taW4oMSwgb3B0cy5xdWFsaXR5KVxuICB9KTtcbiAgdmFyIHRtcENhbnZhcztcblxuICBpZiAoIWlzTGFzdFN0YWdlKSB7XG4gICAgLy8gY3JlYXRlIHRlbXBvcmFyeSBjYW52YXNcbiAgICB0bXBDYW52YXMgPSB0aGlzLm9wdGlvbnMuY3JlYXRlQ2FudmFzKHRvV2lkdGgsIHRvSGVpZ2h0KTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9fdGlsZUFuZFJlc2l6ZShmcm9tLCBpc0xhc3RTdGFnZSA/IHRvIDogdG1wQ2FudmFzLCBvcHRzKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoaXNMYXN0U3RhZ2UpIHJldHVybiB0bztcbiAgICBvcHRzLndpZHRoID0gdG9XaWR0aDtcbiAgICBvcHRzLmhlaWdodCA9IHRvSGVpZ2h0O1xuICAgIHJldHVybiBfdGhpczQuX19wcm9jZXNzU3RhZ2VzKHN0YWdlcywgdG1wQ2FudmFzLCB0bywgb3B0cyk7XG4gIH0pLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgIGlmICh0bXBDYW52YXMpIHtcbiAgICAgIC8vIFNhZmFyaSAxMiB3b3JrYXJvdW5kXG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbm9kZWNhL3BpY2EvaXNzdWVzLzE5OVxuICAgICAgdG1wQ2FudmFzLndpZHRoID0gdG1wQ2FudmFzLmhlaWdodCA9IDA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfSk7XG59O1xuXG5QaWNhLnByb3RvdHlwZS5fX3Jlc2l6ZVZpYUNyZWF0ZUltYWdlQml0bWFwID0gZnVuY3Rpb24gKGZyb20sIHRvLCBvcHRzKSB7XG4gIHZhciBfdGhpczUgPSB0aGlzO1xuXG4gIHZhciB0b0N0eCA9IHRvLmdldENvbnRleHQoJzJkJywge1xuICAgIGFscGhhOiBCb29sZWFuKG9wdHMuYWxwaGEpXG4gIH0pO1xuICB0aGlzLmRlYnVnKCdSZXNpemUgdmlhIGNyZWF0ZUltYWdlQml0bWFwKCknKTtcbiAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKGZyb20sIHtcbiAgICByZXNpemVXaWR0aDogb3B0cy50b1dpZHRoLFxuICAgIHJlc2l6ZUhlaWdodDogb3B0cy50b0hlaWdodCxcbiAgICByZXNpemVRdWFsaXR5OiB1dGlscy5jaWJfcXVhbGl0eV9uYW1lKG9wdHMucXVhbGl0eSlcbiAgfSkudGhlbihmdW5jdGlvbiAoaW1hZ2VCaXRtYXApIHtcbiAgICBpZiAob3B0cy5jYW5jZWxlZCkgcmV0dXJuIG9wdHMuY2FuY2VsVG9rZW47IC8vIGlmIG5vIHVuc2hhcnAgLSBkcmF3IGRpcmVjdGx5IHRvIG91dHB1dCBjYW52YXNcblxuICAgIGlmICghb3B0cy51bnNoYXJwQW1vdW50KSB7XG4gICAgICB0b0N0eC5kcmF3SW1hZ2UoaW1hZ2VCaXRtYXAsIDAsIDApO1xuICAgICAgaW1hZ2VCaXRtYXAuY2xvc2UoKTtcbiAgICAgIHRvQ3R4ID0gbnVsbDtcblxuICAgICAgX3RoaXM1LmRlYnVnKCdGaW5pc2hlZCEnKTtcblxuICAgICAgcmV0dXJuIHRvO1xuICAgIH1cblxuICAgIF90aGlzNS5kZWJ1ZygnVW5zaGFycCByZXN1bHQnKTtcblxuICAgIHZhciB0bXBDYW52YXMgPSBfdGhpczUub3B0aW9ucy5jcmVhdGVDYW52YXMob3B0cy50b1dpZHRoLCBvcHRzLnRvSGVpZ2h0KTtcblxuICAgIHZhciB0bXBDdHggPSB0bXBDYW52YXMuZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgICBhbHBoYTogQm9vbGVhbihvcHRzLmFscGhhKVxuICAgIH0pO1xuICAgIHRtcEN0eC5kcmF3SW1hZ2UoaW1hZ2VCaXRtYXAsIDAsIDApO1xuICAgIGltYWdlQml0bWFwLmNsb3NlKCk7XG4gICAgdmFyIGlEYXRhID0gdG1wQ3R4LmdldEltYWdlRGF0YSgwLCAwLCBvcHRzLnRvV2lkdGgsIG9wdHMudG9IZWlnaHQpO1xuXG4gICAgX3RoaXM1Ll9fbWF0aGxpYi51bnNoYXJwX21hc2soaURhdGEuZGF0YSwgb3B0cy50b1dpZHRoLCBvcHRzLnRvSGVpZ2h0LCBvcHRzLnVuc2hhcnBBbW91bnQsIG9wdHMudW5zaGFycFJhZGl1cywgb3B0cy51bnNoYXJwVGhyZXNob2xkKTtcblxuICAgIHRvQ3R4LnB1dEltYWdlRGF0YShpRGF0YSwgMCwgMCk7IC8vIFNhZmFyaSAxMiB3b3JrYXJvdW5kXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhL2lzc3Vlcy8xOTlcblxuICAgIHRtcENhbnZhcy53aWR0aCA9IHRtcENhbnZhcy5oZWlnaHQgPSAwO1xuICAgIGlEYXRhID0gdG1wQ3R4ID0gdG1wQ2FudmFzID0gdG9DdHggPSBudWxsO1xuXG4gICAgX3RoaXM1LmRlYnVnKCdGaW5pc2hlZCEnKTtcblxuICAgIHJldHVybiB0bztcbiAgfSk7XG59O1xuXG5QaWNhLnByb3RvdHlwZS5yZXNpemUgPSBmdW5jdGlvbiAoZnJvbSwgdG8sIG9wdGlvbnMpIHtcbiAgdmFyIF90aGlzNiA9IHRoaXM7XG5cbiAgdGhpcy5kZWJ1ZygnU3RhcnQgcmVzaXplLi4uJyk7XG4gIHZhciBvcHRzID0gYXNzaWduKHt9LCBERUZBVUxUX1JFU0laRV9PUFRTKTtcblxuICBpZiAoIWlzTmFOKG9wdGlvbnMpKSB7XG4gICAgb3B0cyA9IGFzc2lnbihvcHRzLCB7XG4gICAgICBxdWFsaXR5OiBvcHRpb25zXG4gICAgfSk7XG4gIH0gZWxzZSBpZiAob3B0aW9ucykge1xuICAgIG9wdHMgPSBhc3NpZ24ob3B0cywgb3B0aW9ucyk7XG4gIH1cblxuICBvcHRzLnRvV2lkdGggPSB0by53aWR0aDtcbiAgb3B0cy50b0hlaWdodCA9IHRvLmhlaWdodDtcbiAgb3B0cy53aWR0aCA9IGZyb20ubmF0dXJhbFdpZHRoIHx8IGZyb20ud2lkdGg7XG4gIG9wdHMuaGVpZ2h0ID0gZnJvbS5uYXR1cmFsSGVpZ2h0IHx8IGZyb20uaGVpZ2h0OyAvLyBQcmV2ZW50IHN0ZXBwZXIgZnJvbSBpbmZpbml0ZSBsb29wXG5cbiAgaWYgKHRvLndpZHRoID09PSAwIHx8IHRvLmhlaWdodCA9PT0gMCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJJbnZhbGlkIG91dHB1dCBzaXplOiBcIi5jb25jYXQodG8ud2lkdGgsIFwieFwiKS5jb25jYXQodG8uaGVpZ2h0KSkpO1xuICB9XG5cbiAgaWYgKG9wdHMudW5zaGFycFJhZGl1cyA+IDIpIG9wdHMudW5zaGFycFJhZGl1cyA9IDI7XG4gIG9wdHMuY2FuY2VsZWQgPSBmYWxzZTtcblxuICBpZiAob3B0cy5jYW5jZWxUb2tlbikge1xuICAgIC8vIFdyYXAgY2FuY2VsVG9rZW4gdG8gYXZvaWQgc3VjY2Vzc2l2ZSByZXNvbHZlICYgc2V0IGZsYWdcbiAgICBvcHRzLmNhbmNlbFRva2VuID0gb3B0cy5jYW5jZWxUb2tlbi50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICBvcHRzLmNhbmNlbGVkID0gdHJ1ZTtcbiAgICAgIHRocm93IGRhdGE7XG4gICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgb3B0cy5jYW5jZWxlZCA9IHRydWU7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfSk7XG4gIH1cblxuICB2YXIgREVTVF9USUxFX0JPUkRFUiA9IDM7IC8vIE1heCBwb3NzaWJsZSBmaWx0ZXIgd2luZG93IHNpemVcblxuICBvcHRzLl9fZGVzdFRpbGVCb3JkZXIgPSBNYXRoLmNlaWwoTWF0aC5tYXgoREVTVF9USUxFX0JPUkRFUiwgMi41ICogb3B0cy51bnNoYXJwUmFkaXVzIHwgMCkpO1xuICByZXR1cm4gdGhpcy5pbml0KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgaWYgKG9wdHMuY2FuY2VsZWQpIHJldHVybiBvcHRzLmNhbmNlbFRva2VuOyAvLyBpZiBjcmVhdGVJbWFnZUJpdG1hcCBzdXBwb3J0cyByZXNpemUsIGp1c3QgZG8gaXQgYW5kIHJldHVyblxuXG4gICAgaWYgKF90aGlzNi5mZWF0dXJlcy5jaWIpIHtcbiAgICAgIHJldHVybiBfdGhpczYuX19yZXNpemVWaWFDcmVhdGVJbWFnZUJpdG1hcChmcm9tLCB0bywgb3B0cyk7XG4gICAgfVxuXG4gICAgaWYgKCFDQU5fVVNFX0NBTlZBU19HRVRfSU1BR0VfREFUQSkge1xuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignUGljYTogY2Fubm90IHVzZSBnZXRJbWFnZURhdGEgb24gY2FudmFzLCAnICsgXCJtYWtlIHN1cmUgZmluZ2VycHJpbnRpbmcgcHJvdGVjdGlvbiBpc24ndCBlbmFibGVkXCIpO1xuICAgICAgZXJyLmNvZGUgPSAnRVJSX0dFVF9JTUFHRV9EQVRBJztcbiAgICAgIHRocm93IGVycjtcbiAgICB9IC8vXG4gICAgLy8gTm8gZWFzeSB3YXksIGxldCdzIHJlc2l6ZSBtYW51YWxseSB2aWEgYXJyYXlzXG4gICAgLy9cblxuXG4gICAgdmFyIHN0YWdlcyA9IGNyZWF0ZVN0YWdlcyhvcHRzLndpZHRoLCBvcHRzLmhlaWdodCwgb3B0cy50b1dpZHRoLCBvcHRzLnRvSGVpZ2h0LCBfdGhpczYub3B0aW9ucy50aWxlLCBvcHRzLl9fZGVzdFRpbGVCb3JkZXIpO1xuICAgIHJldHVybiBfdGhpczYuX19wcm9jZXNzU3RhZ2VzKHN0YWdlcywgZnJvbSwgdG8sIG9wdHMpO1xuICB9KTtcbn07IC8vIFJHQkEgYnVmZmVyIHJlc2l6ZVxuLy9cblxuXG5QaWNhLnByb3RvdHlwZS5yZXNpemVCdWZmZXIgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICB2YXIgX3RoaXM3ID0gdGhpcztcblxuICB2YXIgb3B0cyA9IGFzc2lnbih7fSwgREVGQVVMVF9SRVNJWkVfT1BUUywgb3B0aW9ucyk7XG4gIHJldHVybiB0aGlzLmluaXQoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3RoaXM3Ll9fbWF0aGxpYi5yZXNpemVBbmRVbnNoYXJwKG9wdHMpO1xuICB9KTtcbn07XG5cblBpY2EucHJvdG90eXBlLnRvQmxvYiA9IGZ1bmN0aW9uIChjYW52YXMsIG1pbWVUeXBlLCBxdWFsaXR5KSB7XG4gIG1pbWVUeXBlID0gbWltZVR5cGUgfHwgJ2ltYWdlL3BuZyc7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgIGlmIChjYW52YXMudG9CbG9iKSB7XG4gICAgICBjYW52YXMudG9CbG9iKGZ1bmN0aW9uIChibG9iKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKGJsb2IpO1xuICAgICAgfSwgbWltZVR5cGUsIHF1YWxpdHkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChjYW52YXMuY29udmVydFRvQmxvYikge1xuICAgICAgcmVzb2x2ZShjYW52YXMuY29udmVydFRvQmxvYih7XG4gICAgICAgIHR5cGU6IG1pbWVUeXBlLFxuICAgICAgICBxdWFsaXR5OiBxdWFsaXR5XG4gICAgICB9KSk7XG4gICAgICByZXR1cm47XG4gICAgfSAvLyBGYWxsYmFjayBmb3Igb2xkIGJyb3dzZXJzXG5cblxuICAgIHZhciBhc1N0cmluZyA9IGF0b2IoY2FudmFzLnRvRGF0YVVSTChtaW1lVHlwZSwgcXVhbGl0eSkuc3BsaXQoJywnKVsxXSk7XG4gICAgdmFyIGxlbiA9IGFzU3RyaW5nLmxlbmd0aDtcbiAgICB2YXIgYXNCdWZmZXIgPSBuZXcgVWludDhBcnJheShsZW4pO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgYXNCdWZmZXJbaV0gPSBhc1N0cmluZy5jaGFyQ29kZUF0KGkpO1xuICAgIH1cblxuICAgIHJlc29sdmUobmV3IEJsb2IoW2FzQnVmZmVyXSwge1xuICAgICAgdHlwZTogbWltZVR5cGVcbiAgICB9KSk7XG4gIH0pO1xufTtcblxuUGljYS5wcm90b3R5cGUuZGVidWcgPSBmdW5jdGlvbiAoKSB7fTtcblxubW9kdWxlLmV4cG9ydHMgPSBQaWNhO1xuXG59LHtcIi4vbGliL21hdGhsaWJcIjoxLFwiLi9saWIvcG9vbFwiOjEzLFwiLi9saWIvc3RlcHBlclwiOjE0LFwiLi9saWIvdGlsZXJcIjoxNSxcIi4vbGliL3V0aWxzXCI6MTYsXCIuL2xpYi93b3JrZXJcIjoxNyxcIm9iamVjdC1hc3NpZ25cIjoyMyxcIndlYndvcmtpZnlcIjoyNH1dfSx7fSxbXSkoXCIvaW5kZXguanNcIilcbn0pO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///../../../node_modules/pica/dist/pica.js\n");
17
+ eval("/*!\n\npica\nhttps://github.com/nodeca/pica\n\n*/\n\n(function(f){if(true){module.exports=f()}else { var g; }})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=undefined;if(!f&&c)return require(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=undefined,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){\n// Collection of math functions\n//\n// 1. Combine components together\n// 2. Has async init to load wasm modules\n//\n'use strict';\n\nvar inherits = _dereq_('inherits');\n\nvar Multimath = _dereq_('multimath');\n\nvar mm_unsharp_mask = _dereq_('./mm_unsharp_mask');\n\nvar mm_resize = _dereq_('./mm_resize');\n\nfunction MathLib(requested_features) {\n var __requested_features = requested_features || [];\n\n var features = {\n js: __requested_features.indexOf('js') >= 0,\n wasm: __requested_features.indexOf('wasm') >= 0\n };\n Multimath.call(this, features);\n this.features = {\n js: features.js,\n wasm: features.wasm && this.has_wasm()\n };\n this.use(mm_unsharp_mask);\n this.use(mm_resize);\n}\n\ninherits(MathLib, Multimath);\n\nMathLib.prototype.resizeAndUnsharp = function resizeAndUnsharp(options, cache) {\n var result = this.resize(options, cache);\n\n if (options.unsharpAmount) {\n this.unsharp_mask(result, options.toWidth, options.toHeight, options.unsharpAmount, options.unsharpRadius, options.unsharpThreshold);\n }\n\n return result;\n};\n\nmodule.exports = MathLib;\n\n},{\"./mm_resize\":4,\"./mm_unsharp_mask\":9,\"inherits\":19,\"multimath\":20}],2:[function(_dereq_,module,exports){\n// Resize convolvers, pure JS implementation\n//\n'use strict'; // Precision of fixed FP values\n//var FIXED_FRAC_BITS = 14;\n\nfunction clampTo8(i) {\n return i < 0 ? 0 : i > 255 ? 255 : i;\n} // Convolve image in horizontal directions and transpose output. In theory,\n// transpose allow:\n//\n// - use the same convolver for both passes (this fails due different\n// types of input array and temporary buffer)\n// - making vertical pass by horisonltal lines inprove CPU cache use.\n//\n// But in real life this doesn't work :)\n//\n\n\nfunction convolveHorizontally(src, dest, srcW, srcH, destW, filters) {\n var r, g, b, a;\n var filterPtr, filterShift, filterSize;\n var srcPtr, srcY, destX, filterVal;\n var srcOffset = 0,\n destOffset = 0; // For each row\n\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0; // Apply precomputed filters to each destination row point\n\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++];\n filterSize = filters[filterPtr++];\n srcPtr = srcOffset + filterShift * 4 | 0;\n r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a\n\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n\n a = a + filterVal * src[srcPtr + 3] | 0;\n b = b + filterVal * src[srcPtr + 2] | 0;\n g = g + filterVal * src[srcPtr + 1] | 0;\n r = r + filterVal * src[srcPtr] | 0;\n srcPtr = srcPtr + 4 | 0;\n } // Bring this value back in range. All of the filter scaling factors\n // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n //\n // (!) Add 1/2 of value before clamping to get proper rounding. In other\n // case brightness loss will be noticeable if you resize image with white\n // border and place it on white background.\n //\n\n\n dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset] = clampTo8(r + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n destOffset = destOffset + srcH * 4 | 0;\n }\n\n destOffset = (srcY + 1) * 4 | 0;\n srcOffset = (srcY + 1) * srcW * 4 | 0;\n }\n} // Technically, convolvers are the same. But input array and temporary\n// buffer can be of different type (especially, in old browsers). So,\n// keep code in separate functions to avoid deoptimizations & speed loss.\n\n\nfunction convolveVertically(src, dest, srcW, srcH, destW, filters) {\n var r, g, b, a;\n var filterPtr, filterShift, filterSize;\n var srcPtr, srcY, destX, filterVal;\n var srcOffset = 0,\n destOffset = 0; // For each row\n\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0; // Apply precomputed filters to each destination row point\n\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++];\n filterSize = filters[filterPtr++];\n srcPtr = srcOffset + filterShift * 4 | 0;\n r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a\n\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n\n a = a + filterVal * src[srcPtr + 3] | 0;\n b = b + filterVal * src[srcPtr + 2] | 0;\n g = g + filterVal * src[srcPtr + 1] | 0;\n r = r + filterVal * src[srcPtr] | 0;\n srcPtr = srcPtr + 4 | 0;\n } // Bring this value back in range. All of the filter scaling factors\n // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n //\n // (!) Add 1/2 of value before clamping to get proper rounding. In other\n // case brightness loss will be noticeable if you resize image with white\n // border and place it on white background.\n //\n\n\n dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset] = clampTo8(r + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n destOffset = destOffset + srcH * 4 | 0;\n }\n\n destOffset = (srcY + 1) * 4 | 0;\n srcOffset = (srcY + 1) * srcW * 4 | 0;\n }\n}\n\nmodule.exports = {\n convolveHorizontally: convolveHorizontally,\n convolveVertically: convolveVertically\n};\n\n},{}],3:[function(_dereq_,module,exports){\n// This is autogenerated file from math.wasm, don't edit.\n//\n'use strict';\n/* eslint-disable max-len */\n\nmodule.exports = 'AGFzbQEAAAAADAZkeWxpbmsAAAAAAAEXA2AAAGAGf39/f39/AGAHf39/f39/fwACDwEDZW52Bm1lbW9yeQIAAAMEAwABAgYGAX8AQQALB1cFEV9fd2FzbV9jYWxsX2N0b3JzAAAIY29udm9sdmUAAQpjb252b2x2ZUhWAAIMX19kc29faGFuZGxlAwAYX193YXNtX2FwcGx5X2RhdGFfcmVsb2NzAAAK7AMDAwABC8YDAQ9/AkAgA0UNACAERQ0AA0AgDCENQQAhE0EAIQcDQCAHQQJqIQYCfyAHQQF0IAVqIgcuAQIiFEUEQEGAwAAhCEGAwAAhCUGAwAAhCkGAwAAhCyAGDAELIBIgBy4BAGohCEEAIQsgFCEHQQAhDiAGIQlBACEPQQAhEANAIAUgCUEBdGouAQAiESAAIAhBAnRqKAIAIgpBGHZsIBBqIRAgCkH/AXEgEWwgC2ohCyAKQRB2Qf8BcSARbCAPaiEPIApBCHZB/wFxIBFsIA5qIQ4gCEEBaiEIIAlBAWohCSAHQQFrIgcNAAsgC0GAQGshCCAOQYBAayEJIA9BgEBrIQogEEGAQGshCyAGIBRqCyEHIAEgDUECdGogCUEOdSIGQf8BIAZB/wFIGyIGQQAgBkEAShtBCHRBgP4DcSAKQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EQdEGAgPwHcSALQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EYdHJyIAhBDnUiBkH/ASAGQf8BSBsiBkEAIAZBAEobcjYCACADIA1qIQ0gE0EBaiITIARHDQALIAxBAWoiDCACbCESIAMgDEcNAAsLCx4AQQAgAiADIAQgBSAAEAEgAkEAIAQgBSAGIAEQAQs=';\n\n},{}],4:[function(_dereq_,module,exports){\n'use strict';\n\nmodule.exports = {\n name: 'resize',\n fn: _dereq_('./resize'),\n wasm_fn: _dereq_('./resize_wasm'),\n wasm_src: _dereq_('./convolve_wasm_base64')\n};\n\n},{\"./convolve_wasm_base64\":3,\"./resize\":5,\"./resize_wasm\":8}],5:[function(_dereq_,module,exports){\n'use strict';\n\nvar createFilters = _dereq_('./resize_filter_gen');\n\nvar convolveHorizontally = _dereq_('./convolve').convolveHorizontally;\n\nvar convolveVertically = _dereq_('./convolve').convolveVertically;\n\nfunction resetAlpha(dst, width, height) {\n var ptr = 3,\n len = width * height * 4 | 0;\n\n while (ptr < len) {\n dst[ptr] = 0xFF;\n ptr = ptr + 4 | 0;\n }\n}\n\nmodule.exports = function resize(options) {\n var src = options.src;\n var srcW = options.width;\n var srcH = options.height;\n var destW = options.toWidth;\n var destH = options.toHeight;\n var scaleX = options.scaleX || options.toWidth / options.width;\n var scaleY = options.scaleY || options.toHeight / options.height;\n var offsetX = options.offsetX || 0;\n var offsetY = options.offsetY || 0;\n var dest = options.dest || new Uint8Array(destW * destH * 4);\n var quality = typeof options.quality === 'undefined' ? 3 : options.quality;\n var alpha = options.alpha || false;\n var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(quality, srcH, destH, scaleY, offsetY);\n var tmp = new Uint8Array(destW * srcH * 4); // To use single function we need src & tmp of the same type.\n // But src can be CanvasPixelArray, and tmp - Uint8Array. So, keep\n // vertical and horizontal passes separately to avoid deoptimization.\n\n convolveHorizontally(src, tmp, srcW, srcH, destW, filtersX);\n convolveVertically(tmp, dest, srcH, destW, destH, filtersY); // That's faster than doing checks in convolver.\n // !!! Note, canvas data is not premultipled. We don't need other\n // alpha corrections.\n\n if (!alpha) resetAlpha(dest, destW, destH);\n return dest;\n};\n\n},{\"./convolve\":2,\"./resize_filter_gen\":6}],6:[function(_dereq_,module,exports){\n// Calculate convolution filters for each destination point,\n// and pack data to Int16Array:\n//\n// [ shift, length, data..., shift2, length2, data..., ... ]\n//\n// - shift - offset in src image\n// - length - filter length (in src points)\n// - data - filter values sequence\n//\n'use strict';\n\nvar FILTER_INFO = _dereq_('./resize_filter_info'); // Precision of fixed FP values\n\n\nvar FIXED_FRAC_BITS = 14;\n\nfunction toFixedPoint(num) {\n return Math.round(num * ((1 << FIXED_FRAC_BITS) - 1));\n}\n\nmodule.exports = function resizeFilterGen(quality, srcSize, destSize, scale, offset) {\n var filterFunction = FILTER_INFO[quality].filter;\n var scaleInverted = 1.0 / scale;\n var scaleClamped = Math.min(1.0, scale); // For upscale\n // Filter window (averaging interval), scaled to src image\n\n var srcWindow = FILTER_INFO[quality].win / scaleClamped;\n var destPixel, srcPixel, srcFirst, srcLast, filterElementSize, floatFilter, fxpFilter, total, pxl, idx, floatVal, filterTotal, filterVal;\n var leftNotEmpty, rightNotEmpty, filterShift, filterSize;\n var maxFilterElementSize = Math.floor((srcWindow + 1) * 2);\n var packedFilter = new Int16Array((maxFilterElementSize + 2) * destSize);\n var packedFilterPtr = 0;\n var slowCopy = !packedFilter.subarray || !packedFilter.set; // For each destination pixel calculate source range and built filter values\n\n for (destPixel = 0; destPixel < destSize; destPixel++) {\n // Scaling should be done relative to central pixel point\n srcPixel = (destPixel + 0.5) * scaleInverted + offset;\n srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow));\n srcLast = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow));\n filterElementSize = srcLast - srcFirst + 1;\n floatFilter = new Float32Array(filterElementSize);\n fxpFilter = new Int16Array(filterElementSize);\n total = 0.0; // Fill filter values for calculated range\n\n for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {\n floatVal = filterFunction((pxl + 0.5 - srcPixel) * scaleClamped);\n total += floatVal;\n floatFilter[idx] = floatVal;\n } // Normalize filter, convert to fixed point and accumulate conversion error\n\n\n filterTotal = 0;\n\n for (idx = 0; idx < floatFilter.length; idx++) {\n filterVal = floatFilter[idx] / total;\n filterTotal += filterVal;\n fxpFilter[idx] = toFixedPoint(filterVal);\n } // Compensate normalization error, to minimize brightness drift\n\n\n fxpFilter[destSize >> 1] += toFixedPoint(1.0 - filterTotal); //\n // Now pack filter to useable form\n //\n // 1. Trim heading and tailing zero values, and compensate shitf/length\n // 2. Put all to single array in this format:\n //\n // [ pos shift, data length, value1, value2, value3, ... ]\n //\n\n leftNotEmpty = 0;\n\n while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) {\n leftNotEmpty++;\n }\n\n if (leftNotEmpty < fxpFilter.length) {\n rightNotEmpty = fxpFilter.length - 1;\n\n while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) {\n rightNotEmpty--;\n }\n\n filterShift = srcFirst + leftNotEmpty;\n filterSize = rightNotEmpty - leftNotEmpty + 1;\n packedFilter[packedFilterPtr++] = filterShift; // shift\n\n packedFilter[packedFilterPtr++] = filterSize; // size\n\n if (!slowCopy) {\n packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr);\n packedFilterPtr += filterSize;\n } else {\n // fallback for old IE < 11, without subarray/set methods\n for (idx = leftNotEmpty; idx <= rightNotEmpty; idx++) {\n packedFilter[packedFilterPtr++] = fxpFilter[idx];\n }\n }\n } else {\n // zero data, write header only\n packedFilter[packedFilterPtr++] = 0; // shift\n\n packedFilter[packedFilterPtr++] = 0; // size\n }\n }\n\n return packedFilter;\n};\n\n},{\"./resize_filter_info\":7}],7:[function(_dereq_,module,exports){\n// Filter definitions to build tables for\n// resizing convolvers.\n//\n// Presets for quality 0..3. Filter functions + window size\n//\n'use strict';\n\nmodule.exports = [{\n // Nearest neibor (Box)\n win: 0.5,\n filter: function filter(x) {\n return x >= -0.5 && x < 0.5 ? 1.0 : 0.0;\n }\n}, {\n // Hamming\n win: 1.0,\n filter: function filter(x) {\n if (x <= -1.0 || x >= 1.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * (0.54 + 0.46 * Math.cos(xpi / 1.0));\n }\n}, {\n // Lanczos, win = 2\n win: 2.0,\n filter: function filter(x) {\n if (x <= -2.0 || x >= 2.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * Math.sin(xpi / 2.0) / (xpi / 2.0);\n }\n}, {\n // Lanczos, win = 3\n win: 3.0,\n filter: function filter(x) {\n if (x <= -3.0 || x >= 3.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * Math.sin(xpi / 3.0) / (xpi / 3.0);\n }\n}];\n\n},{}],8:[function(_dereq_,module,exports){\n'use strict';\n\nvar createFilters = _dereq_('./resize_filter_gen');\n\nfunction resetAlpha(dst, width, height) {\n var ptr = 3,\n len = width * height * 4 | 0;\n\n while (ptr < len) {\n dst[ptr] = 0xFF;\n ptr = ptr + 4 | 0;\n }\n}\n\nfunction asUint8Array(src) {\n return new Uint8Array(src.buffer, 0, src.byteLength);\n}\n\nvar IS_LE = true; // should not crash everything on module load in old browsers\n\ntry {\n IS_LE = new Uint32Array(new Uint8Array([1, 0, 0, 0]).buffer)[0] === 1;\n} catch (__) {}\n\nfunction copyInt16asLE(src, target, target_offset) {\n if (IS_LE) {\n target.set(asUint8Array(src), target_offset);\n return;\n }\n\n for (var ptr = target_offset, i = 0; i < src.length; i++) {\n var data = src[i];\n target[ptr++] = data & 0xFF;\n target[ptr++] = data >> 8 & 0xFF;\n }\n}\n\nmodule.exports = function resize_wasm(options) {\n var src = options.src;\n var srcW = options.width;\n var srcH = options.height;\n var destW = options.toWidth;\n var destH = options.toHeight;\n var scaleX = options.scaleX || options.toWidth / options.width;\n var scaleY = options.scaleY || options.toHeight / options.height;\n var offsetX = options.offsetX || 0.0;\n var offsetY = options.offsetY || 0.0;\n var dest = options.dest || new Uint8Array(destW * destH * 4);\n var quality = typeof options.quality === 'undefined' ? 3 : options.quality;\n var alpha = options.alpha || false;\n var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(quality, srcH, destH, scaleY, offsetY); // destination is 0 too.\n\n var src_offset = 0; // buffer between convolve passes\n\n var tmp_offset = this.__align(src_offset + Math.max(src.byteLength, dest.byteLength));\n\n var filtersX_offset = this.__align(tmp_offset + srcH * destW * 4);\n\n var filtersY_offset = this.__align(filtersX_offset + filtersX.byteLength);\n\n var alloc_bytes = filtersY_offset + filtersY.byteLength;\n\n var instance = this.__instance('resize', alloc_bytes); //\n // Fill memory block with data to process\n //\n\n\n var mem = new Uint8Array(this.__memory.buffer);\n var mem32 = new Uint32Array(this.__memory.buffer); // 32-bit copy is much faster in chrome\n\n var src32 = new Uint32Array(src.buffer);\n mem32.set(src32); // We should guarantee LE bytes order. Filters are not big, so\n // speed difference is not significant vs direct .set()\n\n copyInt16asLE(filtersX, mem, filtersX_offset);\n copyInt16asLE(filtersY, mem, filtersY_offset); //\n // Now call webassembly method\n // emsdk does method names with '_'\n\n var fn = instance.exports.convolveHV || instance.exports._convolveHV;\n fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH); //\n // Copy data back to typed array\n //\n // 32-bit copy is much faster in chrome\n\n var dest32 = new Uint32Array(dest.buffer);\n dest32.set(new Uint32Array(this.__memory.buffer, 0, destH * destW)); // That's faster than doing checks in convolver.\n // !!! Note, canvas data is not premultipled. We don't need other\n // alpha corrections.\n\n if (!alpha) resetAlpha(dest, destW, destH);\n return dest;\n};\n\n},{\"./resize_filter_gen\":6}],9:[function(_dereq_,module,exports){\n'use strict';\n\nmodule.exports = {\n name: 'unsharp_mask',\n fn: _dereq_('./unsharp_mask'),\n wasm_fn: _dereq_('./unsharp_mask_wasm'),\n wasm_src: _dereq_('./unsharp_mask_wasm_base64')\n};\n\n},{\"./unsharp_mask\":10,\"./unsharp_mask_wasm\":11,\"./unsharp_mask_wasm_base64\":12}],10:[function(_dereq_,module,exports){\n// Unsharp mask filter\n//\n// http://stackoverflow.com/a/23322820/1031804\n// USM(O) = O + (2 * (Amount / 100) * (O - GB))\n// GB - gaussian blur.\n//\n// Image is converted from RGB to HSV, unsharp mask is applied to the\n// brightness channel and then image is converted back to RGB.\n//\n'use strict';\n\nvar glur_mono16 = _dereq_('glur/mono16');\n\nfunction hsv_v16(img, width, height) {\n var size = width * height;\n var out = new Uint16Array(size);\n var r, g, b, max;\n\n for (var i = 0; i < size; i++) {\n r = img[4 * i];\n g = img[4 * i + 1];\n b = img[4 * i + 2];\n max = r >= g && r >= b ? r : g >= b && g >= r ? g : b;\n out[i] = max << 8;\n }\n\n return out;\n}\n\nmodule.exports = function unsharp(img, width, height, amount, radius, threshold) {\n var v1, v2, vmul;\n var diff, iTimes4;\n\n if (amount === 0 || radius < 0.5) {\n return;\n }\n\n if (radius > 2.0) {\n radius = 2.0;\n }\n\n var brightness = hsv_v16(img, width, height);\n var blured = new Uint16Array(brightness); // copy, because blur modify src\n\n glur_mono16(blured, width, height, radius);\n var amountFp = amount / 100 * 0x1000 + 0.5 | 0;\n var thresholdFp = threshold << 8;\n var size = width * height;\n /* eslint-disable indent */\n\n for (var i = 0; i < size; i++) {\n v1 = brightness[i];\n diff = v1 - blured[i];\n\n if (Math.abs(diff) >= thresholdFp) {\n // add unsharp mask to the brightness channel\n v2 = v1 + (amountFp * diff + 0x800 >> 12); // Both v1 and v2 are within [0.0 .. 255.0] (0000-FF00) range, never going into\n // [255.003 .. 255.996] (FF01-FFFF). This allows to round this value as (x+.5)|0\n // later without overflowing.\n\n v2 = v2 > 0xff00 ? 0xff00 : v2;\n v2 = v2 < 0x0000 ? 0x0000 : v2; // Avoid division by 0. V=0 means rgb(0,0,0), unsharp with unsharpAmount>0 cannot\n // change this value (because diff between colors gets inflated), so no need to verify correctness.\n\n v1 = v1 !== 0 ? v1 : 1; // Multiplying V in HSV model by a constant is equivalent to multiplying each component\n // in RGB by the same constant (same for HSL), see also:\n // https://beesbuzz.biz/code/16-hsv-color-transforms\n\n vmul = (v2 << 12) / v1 | 0; // Result will be in [0..255] range because:\n // - all numbers are positive\n // - r,g,b <= (v1/256)\n // - r,g,b,(v1/256),(v2/256) <= 255\n // So highest this number can get is X*255/X+0.5=255.5 which is < 256 and rounds down.\n\n iTimes4 = i * 4;\n img[iTimes4] = img[iTimes4] * vmul + 0x800 >> 12; // R\n\n img[iTimes4 + 1] = img[iTimes4 + 1] * vmul + 0x800 >> 12; // G\n\n img[iTimes4 + 2] = img[iTimes4 + 2] * vmul + 0x800 >> 12; // B\n }\n }\n};\n\n},{\"glur/mono16\":18}],11:[function(_dereq_,module,exports){\n'use strict';\n\nmodule.exports = function unsharp(img, width, height, amount, radius, threshold) {\n if (amount === 0 || radius < 0.5) {\n return;\n }\n\n if (radius > 2.0) {\n radius = 2.0;\n }\n\n var pixels = width * height;\n var img_bytes_cnt = pixels * 4;\n var hsv_bytes_cnt = pixels * 2;\n var blur_bytes_cnt = pixels * 2;\n var blur_line_byte_cnt = Math.max(width, height) * 4; // float32 array\n\n var blur_coeffs_byte_cnt = 8 * 4; // float32 array\n\n var img_offset = 0;\n var hsv_offset = img_bytes_cnt;\n var blur_offset = hsv_offset + hsv_bytes_cnt;\n var blur_tmp_offset = blur_offset + blur_bytes_cnt;\n var blur_line_offset = blur_tmp_offset + blur_bytes_cnt;\n var blur_coeffs_offset = blur_line_offset + blur_line_byte_cnt;\n\n var instance = this.__instance('unsharp_mask', img_bytes_cnt + hsv_bytes_cnt + blur_bytes_cnt * 2 + blur_line_byte_cnt + blur_coeffs_byte_cnt, {\n exp: Math.exp\n }); // 32-bit copy is much faster in chrome\n\n\n var img32 = new Uint32Array(img.buffer);\n var mem32 = new Uint32Array(this.__memory.buffer);\n mem32.set(img32); // HSL\n\n var fn = instance.exports.hsv_v16 || instance.exports._hsv_v16;\n fn(img_offset, hsv_offset, width, height); // BLUR\n\n fn = instance.exports.blurMono16 || instance.exports._blurMono16;\n fn(hsv_offset, blur_offset, blur_tmp_offset, blur_line_offset, blur_coeffs_offset, width, height, radius); // UNSHARP\n\n fn = instance.exports.unsharp || instance.exports._unsharp;\n fn(img_offset, img_offset, hsv_offset, blur_offset, width, height, amount, threshold); // 32-bit copy is much faster in chrome\n\n img32.set(new Uint32Array(this.__memory.buffer, 0, pixels));\n};\n\n},{}],12:[function(_dereq_,module,exports){\n// This is autogenerated file from math.wasm, don't edit.\n//\n'use strict';\n/* eslint-disable max-len */\n\nmodule.exports = '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';\n\n},{}],13:[function(_dereq_,module,exports){\n'use strict';\n\nvar GC_INTERVAL = 100;\n\nfunction Pool(create, idle) {\n this.create = create;\n this.available = [];\n this.acquired = {};\n this.lastId = 1;\n this.timeoutId = 0;\n this.idle = idle || 2000;\n}\n\nPool.prototype.acquire = function () {\n var _this = this;\n\n var resource;\n\n if (this.available.length !== 0) {\n resource = this.available.pop();\n } else {\n resource = this.create();\n resource.id = this.lastId++;\n\n resource.release = function () {\n return _this.release(resource);\n };\n }\n\n this.acquired[resource.id] = resource;\n return resource;\n};\n\nPool.prototype.release = function (resource) {\n var _this2 = this;\n\n delete this.acquired[resource.id];\n resource.lastUsed = Date.now();\n this.available.push(resource);\n\n if (this.timeoutId === 0) {\n this.timeoutId = setTimeout(function () {\n return _this2.gc();\n }, GC_INTERVAL);\n }\n};\n\nPool.prototype.gc = function () {\n var _this3 = this;\n\n var now = Date.now();\n this.available = this.available.filter(function (resource) {\n if (now - resource.lastUsed > _this3.idle) {\n resource.destroy();\n return false;\n }\n\n return true;\n });\n\n if (this.available.length !== 0) {\n this.timeoutId = setTimeout(function () {\n return _this3.gc();\n }, GC_INTERVAL);\n } else {\n this.timeoutId = 0;\n }\n};\n\nmodule.exports = Pool;\n\n},{}],14:[function(_dereq_,module,exports){\n// Add intermediate resizing steps when scaling down by a very large factor.\n//\n// For example, when resizing 10000x10000 down to 10x10, it'll resize it to\n// 300x300 first.\n//\n// It's needed because tiler has issues when the entire tile is scaled down\n// to a few pixels (1024px source tile with border size 3 should result in\n// at least 3+3+2 = 8px target tile, so max scale factor is 128 here).\n//\n// Also, adding intermediate steps can speed up processing if we use lower\n// quality algorithms for first stages.\n//\n'use strict'; // min size = 0 results in infinite loop,\n// min size = 1 can consume large amount of memory\n\nvar MIN_INNER_TILE_SIZE = 2;\n\nmodule.exports = function createStages(fromWidth, fromHeight, toWidth, toHeight, srcTileSize, destTileBorder) {\n var scaleX = toWidth / fromWidth;\n var scaleY = toHeight / fromHeight; // derived from createRegions equation:\n // innerTileWidth = pixelFloor(srcTileSize * scaleX) - 2 * destTileBorder;\n\n var minScale = (2 * destTileBorder + MIN_INNER_TILE_SIZE + 1) / srcTileSize; // refuse to scale image multiple times by less than twice each time,\n // it could only happen because of invalid options\n\n if (minScale > 0.5) return [[toWidth, toHeight]];\n var stageCount = Math.ceil(Math.log(Math.min(scaleX, scaleY)) / Math.log(minScale)); // no additional resizes are necessary,\n // stageCount can be zero or be negative when enlarging the image\n\n if (stageCount <= 1) return [[toWidth, toHeight]];\n var result = [];\n\n for (var i = 0; i < stageCount; i++) {\n var width = Math.round(Math.pow(Math.pow(fromWidth, stageCount - i - 1) * Math.pow(toWidth, i + 1), 1 / stageCount));\n var height = Math.round(Math.pow(Math.pow(fromHeight, stageCount - i - 1) * Math.pow(toHeight, i + 1), 1 / stageCount));\n result.push([width, height]);\n }\n\n return result;\n};\n\n},{}],15:[function(_dereq_,module,exports){\n// Split original image into multiple 1024x1024 chunks to reduce memory usage\n// (images have to be unpacked into typed arrays for resizing) and allow\n// parallel processing of multiple tiles at a time.\n//\n'use strict';\n/*\n * pixelFloor and pixelCeil are modified versions of Math.floor and Math.ceil\n * functions which take into account floating point arithmetic errors.\n * Those errors can cause undesired increments/decrements of sizes and offsets:\n * Math.ceil(36 / (36 / 500)) = 501\n * pixelCeil(36 / (36 / 500)) = 500\n */\n\nvar PIXEL_EPSILON = 1e-5;\n\nfunction pixelFloor(x) {\n var nearest = Math.round(x);\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) {\n return nearest;\n }\n\n return Math.floor(x);\n}\n\nfunction pixelCeil(x) {\n var nearest = Math.round(x);\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) {\n return nearest;\n }\n\n return Math.ceil(x);\n}\n\nmodule.exports = function createRegions(options) {\n var scaleX = options.toWidth / options.width;\n var scaleY = options.toHeight / options.height;\n var innerTileWidth = pixelFloor(options.srcTileSize * scaleX) - 2 * options.destTileBorder;\n var innerTileHeight = pixelFloor(options.srcTileSize * scaleY) - 2 * options.destTileBorder; // prevent infinite loop, this should never happen\n\n if (innerTileWidth < 1 || innerTileHeight < 1) {\n throw new Error('Internal error in pica: target tile width/height is too small.');\n }\n\n var x, y;\n var innerX, innerY, toTileWidth, toTileHeight;\n var tiles = [];\n var tile; // we go top-to-down instead of left-to-right to make image displayed from top to\n // doesn in the browser\n\n for (innerY = 0; innerY < options.toHeight; innerY += innerTileHeight) {\n for (innerX = 0; innerX < options.toWidth; innerX += innerTileWidth) {\n x = innerX - options.destTileBorder;\n\n if (x < 0) {\n x = 0;\n }\n\n toTileWidth = innerX + innerTileWidth + options.destTileBorder - x;\n\n if (x + toTileWidth >= options.toWidth) {\n toTileWidth = options.toWidth - x;\n }\n\n y = innerY - options.destTileBorder;\n\n if (y < 0) {\n y = 0;\n }\n\n toTileHeight = innerY + innerTileHeight + options.destTileBorder - y;\n\n if (y + toTileHeight >= options.toHeight) {\n toTileHeight = options.toHeight - y;\n }\n\n tile = {\n toX: x,\n toY: y,\n toWidth: toTileWidth,\n toHeight: toTileHeight,\n toInnerX: innerX,\n toInnerY: innerY,\n toInnerWidth: innerTileWidth,\n toInnerHeight: innerTileHeight,\n offsetX: x / scaleX - pixelFloor(x / scaleX),\n offsetY: y / scaleY - pixelFloor(y / scaleY),\n scaleX: scaleX,\n scaleY: scaleY,\n x: pixelFloor(x / scaleX),\n y: pixelFloor(y / scaleY),\n width: pixelCeil(toTileWidth / scaleX),\n height: pixelCeil(toTileHeight / scaleY)\n };\n tiles.push(tile);\n }\n }\n\n return tiles;\n};\n\n},{}],16:[function(_dereq_,module,exports){\n'use strict';\n\nfunction objClass(obj) {\n return Object.prototype.toString.call(obj);\n}\n\nmodule.exports.isCanvas = function isCanvas(element) {\n var cname = objClass(element);\n return cname === '[object HTMLCanvasElement]'\n /* browser */\n || cname === '[object OffscreenCanvas]' || cname === '[object Canvas]'\n /* node-canvas */\n ;\n};\n\nmodule.exports.isImage = function isImage(element) {\n return objClass(element) === '[object HTMLImageElement]';\n};\n\nmodule.exports.isImageBitmap = function isImageBitmap(element) {\n return objClass(element) === '[object ImageBitmap]';\n};\n\nmodule.exports.limiter = function limiter(concurrency) {\n var active = 0,\n queue = [];\n\n function roll() {\n if (active < concurrency && queue.length) {\n active++;\n queue.shift()();\n }\n }\n\n return function limit(fn) {\n return new Promise(function (resolve, reject) {\n queue.push(function () {\n fn().then(function (result) {\n resolve(result);\n active--;\n roll();\n }, function (err) {\n reject(err);\n active--;\n roll();\n });\n });\n roll();\n });\n };\n};\n\nmodule.exports.cib_quality_name = function cib_quality_name(num) {\n switch (num) {\n case 0:\n return 'pixelated';\n\n case 1:\n return 'low';\n\n case 2:\n return 'medium';\n }\n\n return 'high';\n};\n\nmodule.exports.cib_support = function cib_support(createCanvas) {\n return Promise.resolve().then(function () {\n if (typeof createImageBitmap === 'undefined') {\n return false;\n }\n\n var c = createCanvas(100, 100);\n return createImageBitmap(c, 0, 0, 100, 100, {\n resizeWidth: 10,\n resizeHeight: 10,\n resizeQuality: 'high'\n }).then(function (bitmap) {\n var status = bitmap.width === 10; // Branch below is filtered on upper level. We do not call resize\n // detection for basic ImageBitmap.\n //\n // https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap\n // old Crome 51 has ImageBitmap without .close(). Then this code\n // will throw and return 'false' as expected.\n //\n\n bitmap.close();\n c = null;\n return status;\n });\n })[\"catch\"](function () {\n return false;\n });\n};\n\nmodule.exports.worker_offscreen_canvas_support = function worker_offscreen_canvas_support() {\n return new Promise(function (resolve, reject) {\n if (typeof OffscreenCanvas === 'undefined') {\n // if OffscreenCanvas is present, we assume browser supports Worker and built-in Promise as well\n resolve(false);\n return;\n }\n\n function workerPayload(self) {\n if (typeof createImageBitmap === 'undefined') {\n self.postMessage(false);\n return;\n }\n\n Promise.resolve().then(function () {\n var canvas = new OffscreenCanvas(10, 10); // test that 2d context can be used in worker\n\n var ctx = canvas.getContext('2d');\n ctx.rect(0, 0, 1, 1); // test that cib can be used to return image bitmap from worker\n\n return createImageBitmap(canvas, 0, 0, 1, 1);\n }).then(function () {\n return self.postMessage(true);\n }, function () {\n return self.postMessage(false);\n });\n }\n\n var code = btoa(\"(\".concat(workerPayload.toString(), \")(self);\"));\n var w = new Worker(\"data:text/javascript;base64,\".concat(code));\n\n w.onmessage = function (ev) {\n return resolve(ev.data);\n };\n\n w.onerror = reject;\n }).then(function (result) {\n return result;\n }, function () {\n return false;\n });\n}; // Check if canvas.getContext('2d').getImageData can be used,\n// FireFox randomizes the output of that function in `privacy.resistFingerprinting` mode\n\n\nmodule.exports.can_use_canvas = function can_use_canvas(createCanvas) {\n var usable = false;\n\n try {\n var canvas = createCanvas(2, 1);\n var ctx = canvas.getContext('2d');\n var d = ctx.createImageData(2, 1);\n d.data[0] = 12;\n d.data[1] = 23;\n d.data[2] = 34;\n d.data[3] = 255;\n d.data[4] = 45;\n d.data[5] = 56;\n d.data[6] = 67;\n d.data[7] = 255;\n ctx.putImageData(d, 0, 0);\n d = null;\n d = ctx.getImageData(0, 0, 2, 1);\n\n if (d.data[0] === 12 && d.data[1] === 23 && d.data[2] === 34 && d.data[3] === 255 && d.data[4] === 45 && d.data[5] === 56 && d.data[6] === 67 && d.data[7] === 255) {\n usable = true;\n }\n } catch (err) {}\n\n return usable;\n}; // Check if createImageBitmap(img, sx, sy, sw, sh) signature works correctly\n// with JPEG images oriented with Exif;\n// https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n// TODO: remove after it's fixed in chrome for at least 2 releases\n\n\nmodule.exports.cib_can_use_region = function cib_can_use_region() {\n return new Promise(function (resolve) {\n if (typeof createImageBitmap === 'undefined') {\n resolve(false);\n return;\n }\n\n var image = new Image();\n image.src = 'data:image/jpeg;base64,' + '/9j/4QBiRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAYAAAEaAAUAAAABAAAASgEbAAUAA' + 'AABAAAAUgEoAAMAAAABAAIAAAITAAMAAAABAAEAAAAAAAAAAABIAAAAAQAAAEgAAAAB/9' + 'sAQwAEAwMEAwMEBAMEBQQEBQYKBwYGBgYNCQoICg8NEBAPDQ8OERMYFBESFxIODxUcFRc' + 'ZGRsbGxAUHR8dGh8YGhsa/9sAQwEEBQUGBQYMBwcMGhEPERoaGhoaGhoaGhoaGhoaGhoa' + 'GhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoa/8IAEQgAAQACAwERAAIRAQMRA' + 'f/EABQAAQAAAAAAAAAAAAAAAAAAAAf/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAA' + 'IQAxAAAAF/P//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAQUCf//EABQRAQAAAAA' + 'AAAAAAAAAAAAAAAD/2gAIAQMBAT8Bf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIB' + 'AT8Bf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEABj8Cf//EABQQAQAAAAAAAAAAA' + 'AAAAAAAAAD/2gAIAQEAAT8hf//aAAwDAQACAAMAAAAQH//EABQRAQAAAAAAAAAAAAAAAA' + 'AAAAD/2gAIAQMBAT8Qf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Qf//EABQ' + 'QAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8Qf//Z';\n\n image.onload = function () {\n createImageBitmap(image, 0, 0, image.width, image.height).then(function (bitmap) {\n if (bitmap.width === image.width && bitmap.height === image.height) {\n resolve(true);\n } else {\n resolve(false);\n }\n }, function () {\n return resolve(false);\n });\n };\n\n image.onerror = function () {\n return resolve(false);\n };\n });\n};\n\n},{}],17:[function(_dereq_,module,exports){\n// Web Worker wrapper for image resize function\n'use strict';\n\nmodule.exports = function () {\n var MathLib = _dereq_('./mathlib');\n\n var mathLib;\n /* eslint-disable no-undef */\n\n onmessage = function onmessage(ev) {\n var tileOpts = ev.data.opts;\n var returnBitmap = false;\n\n if (!tileOpts.src && tileOpts.srcBitmap) {\n var canvas = new OffscreenCanvas(tileOpts.width, tileOpts.height);\n var ctx = canvas.getContext('2d', {\n alpha: Boolean(tileOpts.alpha)\n });\n ctx.drawImage(tileOpts.srcBitmap, 0, 0);\n tileOpts.src = ctx.getImageData(0, 0, tileOpts.width, tileOpts.height).data;\n canvas.width = canvas.height = 0;\n canvas = null;\n tileOpts.srcBitmap.close();\n tileOpts.srcBitmap = null; // Temporary force out data to typed array, because Chrome have artefacts\n // https://github.com/nodeca/pica/issues/223\n // returnBitmap = true;\n }\n\n if (!mathLib) mathLib = new MathLib(ev.data.features); // Use multimath's sync auto-init. Avoid Promise use in old browsers,\n // because polyfills are not propagated to webworker.\n\n var data = mathLib.resizeAndUnsharp(tileOpts);\n\n if (returnBitmap) {\n var toImageData = new ImageData(new Uint8ClampedArray(data), tileOpts.toWidth, tileOpts.toHeight);\n\n var _canvas = new OffscreenCanvas(tileOpts.toWidth, tileOpts.toHeight);\n\n var _ctx = _canvas.getContext('2d', {\n alpha: Boolean(tileOpts.alpha)\n });\n\n _ctx.putImageData(toImageData, 0, 0);\n\n createImageBitmap(_canvas).then(function (bitmap) {\n postMessage({\n bitmap: bitmap\n }, [bitmap]);\n });\n } else {\n postMessage({\n data: data\n }, [data.buffer]);\n }\n };\n};\n\n},{\"./mathlib\":1}],18:[function(_dereq_,module,exports){\n// Calculate Gaussian blur of an image using IIR filter\n// The method is taken from Intel's white paper and code example attached to it:\n// https://software.intel.com/en-us/articles/iir-gaussian-blur-filter\n// -implementation-using-intel-advanced-vector-extensions\n\nvar a0, a1, a2, a3, b1, b2, left_corner, right_corner;\n\nfunction gaussCoef(sigma) {\n if (sigma < 0.5) {\n sigma = 0.5;\n }\n\n var a = Math.exp(0.726 * 0.726) / sigma,\n g1 = Math.exp(-a),\n g2 = Math.exp(-2 * a),\n k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2);\n\n a0 = k;\n a1 = k * (a - 1) * g1;\n a2 = k * (a + 1) * g1;\n a3 = -k * g2;\n b1 = 2 * g1;\n b2 = -g2;\n left_corner = (a0 + a1) / (1 - b1 - b2);\n right_corner = (a2 + a3) / (1 - b1 - b2);\n\n // Attempt to force type to FP32.\n return new Float32Array([ a0, a1, a2, a3, b1, b2, left_corner, right_corner ]);\n}\n\nfunction convolveMono16(src, out, line, coeff, width, height) {\n // takes src image and writes the blurred and transposed result into out\n\n var prev_src, curr_src, curr_out, prev_out, prev_prev_out;\n var src_index, out_index, line_index;\n var i, j;\n var coeff_a0, coeff_a1, coeff_b1, coeff_b2;\n\n for (i = 0; i < height; i++) {\n src_index = i * width;\n out_index = i;\n line_index = 0;\n\n // left to right\n prev_src = src[src_index];\n prev_prev_out = prev_src * coeff[6];\n prev_out = prev_prev_out;\n\n coeff_a0 = coeff[0];\n coeff_a1 = coeff[1];\n coeff_b1 = coeff[4];\n coeff_b2 = coeff[5];\n\n for (j = 0; j < width; j++) {\n curr_src = src[src_index];\n\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2;\n\n prev_prev_out = prev_out;\n prev_out = curr_out;\n prev_src = curr_src;\n\n line[line_index] = prev_out;\n line_index++;\n src_index++;\n }\n\n src_index--;\n line_index--;\n out_index += height * (width - 1);\n\n // right to left\n prev_src = src[src_index];\n prev_prev_out = prev_src * coeff[7];\n prev_out = prev_prev_out;\n curr_src = prev_src;\n\n coeff_a0 = coeff[2];\n coeff_a1 = coeff[3];\n\n for (j = width - 1; j >= 0; j--) {\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2;\n\n prev_prev_out = prev_out;\n prev_out = curr_out;\n\n prev_src = curr_src;\n curr_src = src[src_index];\n\n out[out_index] = line[line_index] + prev_out;\n\n src_index--;\n line_index--;\n out_index -= height;\n }\n }\n}\n\n\nfunction blurMono16(src, width, height, radius) {\n // Quick exit on zero radius\n if (!radius) { return; }\n\n var out = new Uint16Array(src.length),\n tmp_line = new Float32Array(Math.max(width, height));\n\n var coeff = gaussCoef(radius);\n\n convolveMono16(src, out, tmp_line, coeff, width, height, radius);\n convolveMono16(out, src, tmp_line, coeff, height, width, radius);\n}\n\nmodule.exports = blurMono16;\n\n},{}],19:[function(_dereq_,module,exports){\nif (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n })\n }\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n }\n}\n\n},{}],20:[function(_dereq_,module,exports){\n'use strict';\n\n\nvar assign = _dereq_('object-assign');\nvar base64decode = _dereq_('./lib/base64decode');\nvar hasWebAssembly = _dereq_('./lib/wa_detect');\n\n\nvar DEFAULT_OPTIONS = {\n js: true,\n wasm: true\n};\n\n\nfunction MultiMath(options) {\n if (!(this instanceof MultiMath)) return new MultiMath(options);\n\n var opts = assign({}, DEFAULT_OPTIONS, options || {});\n\n this.options = opts;\n\n this.__cache = {};\n\n this.__init_promise = null;\n this.__modules = opts.modules || {};\n this.__memory = null;\n this.__wasm = {};\n\n this.__isLE = ((new Uint32Array((new Uint8Array([ 1, 0, 0, 0 ])).buffer))[0] === 1);\n\n if (!this.options.js && !this.options.wasm) {\n throw new Error('mathlib: at least \"js\" or \"wasm\" should be enabled');\n }\n}\n\n\nMultiMath.prototype.has_wasm = hasWebAssembly;\n\n\nMultiMath.prototype.use = function (module) {\n this.__modules[module.name] = module;\n\n // Pin the best possible implementation\n if (this.options.wasm && this.has_wasm() && module.wasm_fn) {\n this[module.name] = module.wasm_fn;\n } else {\n this[module.name] = module.fn;\n }\n\n return this;\n};\n\n\nMultiMath.prototype.init = function () {\n if (this.__init_promise) return this.__init_promise;\n\n if (!this.options.js && this.options.wasm && !this.has_wasm()) {\n return Promise.reject(new Error('mathlib: only \"wasm\" was enabled, but it\\'s not supported'));\n }\n\n var self = this;\n\n this.__init_promise = Promise.all(Object.keys(self.__modules).map(function (name) {\n var module = self.__modules[name];\n\n if (!self.options.wasm || !self.has_wasm() || !module.wasm_fn) return null;\n\n // If already compiled - exit\n if (self.__wasm[name]) return null;\n\n // Compile wasm source\n return WebAssembly.compile(self.__base64decode(module.wasm_src))\n .then(function (m) { self.__wasm[name] = m; });\n }))\n .then(function () { return self; });\n\n return this.__init_promise;\n};\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Methods below are for internal use from plugins\n\n\n// Simple decode base64 to typed array. Useful to load embedded webassembly\n// code. You probably don't need to call this method directly.\n//\nMultiMath.prototype.__base64decode = base64decode;\n\n\n// Increase current memory to include specified number of bytes. Do nothing if\n// size is already ok. You probably don't need to call this method directly,\n// because it will be invoked from `.__instance()`.\n//\nMultiMath.prototype.__reallocate = function mem_grow_to(bytes) {\n if (!this.__memory) {\n this.__memory = new WebAssembly.Memory({\n initial: Math.ceil(bytes / (64 * 1024))\n });\n return this.__memory;\n }\n\n var mem_size = this.__memory.buffer.byteLength;\n\n if (mem_size < bytes) {\n this.__memory.grow(Math.ceil((bytes - mem_size) / (64 * 1024)));\n }\n\n return this.__memory;\n};\n\n\n// Returns instantinated webassembly item by name, with specified memory size\n// and environment.\n// - use cache if available\n// - do sync module init, if async init was not called earlier\n// - allocate memory if not enougth\n// - can export functions to webassembly via \"env_extra\",\n// for example, { exp: Math.exp }\n//\nMultiMath.prototype.__instance = function instance(name, memsize, env_extra) {\n if (memsize) this.__reallocate(memsize);\n\n // If .init() was not called, do sync compile\n if (!this.__wasm[name]) {\n var module = this.__modules[name];\n this.__wasm[name] = new WebAssembly.Module(this.__base64decode(module.wasm_src));\n }\n\n if (!this.__cache[name]) {\n var env_base = {\n memoryBase: 0,\n memory: this.__memory,\n tableBase: 0,\n table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })\n };\n\n this.__cache[name] = new WebAssembly.Instance(this.__wasm[name], {\n env: assign(env_base, env_extra || {})\n });\n }\n\n return this.__cache[name];\n};\n\n\n// Helper to calculate memory aligh for pointers. Webassembly does not require\n// this, but you may wish to experiment. Default base = 8;\n//\nMultiMath.prototype.__align = function align(number, base) {\n base = base || 8;\n var reminder = number % base;\n return number + (reminder ? base - reminder : 0);\n};\n\n\nmodule.exports = MultiMath;\n\n},{\"./lib/base64decode\":21,\"./lib/wa_detect\":22,\"object-assign\":23}],21:[function(_dereq_,module,exports){\n// base64 decode str -> Uint8Array, to load WA modules\n//\n'use strict';\n\n\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n\nmodule.exports = function base64decode(str) {\n var input = str.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length;\n\n var out = new Uint8Array((max * 3) >> 2);\n\n // Collect by 6*4 bits (3 bytes)\n\n var bits = 0;\n var ptr = 0;\n\n for (var idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n out[ptr++] = (bits >> 16) & 0xFF;\n out[ptr++] = (bits >> 8) & 0xFF;\n out[ptr++] = bits & 0xFF;\n }\n\n bits = (bits << 6) | BASE64_MAP.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n var tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n out[ptr++] = (bits >> 16) & 0xFF;\n out[ptr++] = (bits >> 8) & 0xFF;\n out[ptr++] = bits & 0xFF;\n } else if (tailbits === 18) {\n out[ptr++] = (bits >> 10) & 0xFF;\n out[ptr++] = (bits >> 2) & 0xFF;\n } else if (tailbits === 12) {\n out[ptr++] = (bits >> 4) & 0xFF;\n }\n\n return out;\n};\n\n},{}],22:[function(_dereq_,module,exports){\n// Detect WebAssembly support.\n// - Check global WebAssembly object\n// - Try to load simple module (can be disabled via CSP)\n//\n'use strict';\n\n\nvar wa;\n\n\nmodule.exports = function hasWebAssembly() {\n // use cache if called before;\n if (typeof wa !== 'undefined') return wa;\n\n wa = false;\n\n if (typeof WebAssembly === 'undefined') return wa;\n\n // If WebAssenbly is disabled, code can throw on compile\n try {\n // https://github.com/brion/min-wasm-fail/blob/master/min-wasm-fail.in.js\n // Additional check that WA internals are correct\n\n /* eslint-disable comma-spacing, max-len */\n var bin = new Uint8Array([ 0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11 ]);\n var module = new WebAssembly.Module(bin);\n var instance = new WebAssembly.Instance(module, {});\n\n // test storing to and loading from a non-zero location via a parameter.\n // Safari on iOS 11.2.5 returns 0 unexpectedly at non-zero locations\n if (instance.exports.test(4) !== 0) wa = true;\n\n return wa;\n } catch (__) {}\n\n return wa;\n};\n\n},{}],23:[function(_dereq_,module,exports){\n/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n'use strict';\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n\n},{}],24:[function(_dereq_,module,exports){\nvar bundleFn = arguments[3];\nvar sources = arguments[4];\nvar cache = arguments[5];\n\nvar stringify = JSON.stringify;\n\nmodule.exports = function (fn, options) {\n var wkey;\n var cacheKeys = Object.keys(cache);\n\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n var exp = cache[key].exports;\n // Using babel as a transpiler to use esmodule, the export will always\n // be an object with the default export as a property of it. To ensure\n // the existing api and babel esmodule exports are both supported we\n // check for both\n if (exp === fn || exp && exp.default === fn) {\n wkey = key;\n break;\n }\n }\n\n if (!wkey) {\n wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n var wcache = {};\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n wcache[key] = key;\n }\n sources[wkey] = [\n 'function(require,module,exports){' + fn + '(self); }',\n wcache\n ];\n }\n var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n\n var scache = {}; scache[wkey] = wkey;\n sources[skey] = [\n 'function(require,module,exports){' +\n // try to call default if defined to also support babel esmodule exports\n 'var f = require(' + stringify(wkey) + ');' +\n '(f.default ? f.default : f)(self);' +\n '}',\n scache\n ];\n\n var workerSources = {};\n resolveSources(skey);\n\n function resolveSources(key) {\n workerSources[key] = true;\n\n for (var depPath in sources[key][1]) {\n var depKey = sources[key][1][depPath];\n if (!workerSources[depKey]) {\n resolveSources(depKey);\n }\n }\n }\n\n var src = '(' + bundleFn + ')({'\n + Object.keys(workerSources).map(function (key) {\n return stringify(key) + ':['\n + sources[key][0]\n + ',' + stringify(sources[key][1]) + ']'\n ;\n }).join(',')\n + '},{},[' + stringify(skey) + '])'\n ;\n\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n var blob = new Blob([src], { type: 'text/javascript' });\n if (options && options.bare) { return blob; }\n var workerUrl = URL.createObjectURL(blob);\n var worker = new Worker(workerUrl);\n worker.objectURL = workerUrl;\n return worker;\n};\n\n},{}],\"/index.js\":[function(_dereq_,module,exports){\n'use strict';\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nvar assign = _dereq_('object-assign');\n\nvar webworkify = _dereq_('webworkify');\n\nvar MathLib = _dereq_('./lib/mathlib');\n\nvar Pool = _dereq_('./lib/pool');\n\nvar utils = _dereq_('./lib/utils');\n\nvar worker = _dereq_('./lib/worker');\n\nvar createStages = _dereq_('./lib/stepper');\n\nvar createRegions = _dereq_('./lib/tiler'); // Deduplicate pools & limiters with the same configs\n// when user creates multiple pica instances.\n\n\nvar singletones = {};\nvar NEED_SAFARI_FIX = false;\n\ntry {\n if (typeof navigator !== 'undefined' && navigator.userAgent) {\n NEED_SAFARI_FIX = navigator.userAgent.indexOf('Safari') >= 0;\n }\n} catch (e) {}\n\nvar concurrency = 1;\n\nif (typeof navigator !== 'undefined') {\n concurrency = Math.min(navigator.hardwareConcurrency || 1, 4);\n}\n\nvar DEFAULT_PICA_OPTS = {\n tile: 1024,\n concurrency: concurrency,\n features: ['js', 'wasm', 'ww'],\n idle: 2000,\n createCanvas: function createCanvas(width, height) {\n var tmpCanvas = document.createElement('canvas');\n tmpCanvas.width = width;\n tmpCanvas.height = height;\n return tmpCanvas;\n }\n};\nvar DEFAULT_RESIZE_OPTS = {\n quality: 3,\n alpha: false,\n unsharpAmount: 0,\n unsharpRadius: 0.0,\n unsharpThreshold: 0\n};\nvar CAN_NEW_IMAGE_DATA = false;\nvar CAN_CREATE_IMAGE_BITMAP = false;\nvar CAN_USE_CANVAS_GET_IMAGE_DATA = false;\nvar CAN_USE_OFFSCREEN_CANVAS = false;\nvar CAN_USE_CIB_REGION_FOR_IMAGE = false;\n\nfunction workerFabric() {\n return {\n value: webworkify(worker),\n destroy: function destroy() {\n this.value.terminate();\n\n if (typeof window !== 'undefined') {\n var url = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n if (url && url.revokeObjectURL && this.value.objectURL) {\n url.revokeObjectURL(this.value.objectURL);\n }\n }\n }\n };\n} ////////////////////////////////////////////////////////////////////////////////\n// API methods\n\n\nfunction Pica(options) {\n if (!(this instanceof Pica)) return new Pica(options);\n this.options = assign({}, DEFAULT_PICA_OPTS, options || {});\n var limiter_key = \"lk_\".concat(this.options.concurrency); // Share limiters to avoid multiple parallel workers when user creates\n // multiple pica instances.\n\n this.__limit = singletones[limiter_key] || utils.limiter(this.options.concurrency);\n if (!singletones[limiter_key]) singletones[limiter_key] = this.__limit; // List of supported features, according to options & browser/node.js\n\n this.features = {\n js: false,\n // pure JS implementation, can be disabled for testing\n wasm: false,\n // webassembly implementation for heavy functions\n cib: false,\n // resize via createImageBitmap (only FF at this moment)\n ww: false // webworkers\n\n };\n this.__workersPool = null; // Store requested features for webworkers\n\n this.__requested_features = [];\n this.__mathlib = null;\n}\n\nPica.prototype.init = function () {\n var _this = this;\n\n if (this.__initPromise) return this.__initPromise; // Test if we can create ImageData without canvas and memory copy\n\n if (typeof ImageData !== 'undefined' && typeof Uint8ClampedArray !== 'undefined') {\n try {\n /* eslint-disable no-new */\n new ImageData(new Uint8ClampedArray(400), 10, 10);\n CAN_NEW_IMAGE_DATA = true;\n } catch (__) {}\n } // ImageBitmap can be effective in 2 places:\n //\n // 1. Threaded jpeg unpack (basic)\n // 2. Built-in resize (blocked due problem in chrome, see issue #89)\n //\n // For basic use we also need ImageBitmap wo support .close() method,\n // see https://developer.mozilla.org/ru/docs/Web/API/ImageBitmap\n\n\n if (typeof ImageBitmap !== 'undefined') {\n if (ImageBitmap.prototype && ImageBitmap.prototype.close) {\n CAN_CREATE_IMAGE_BITMAP = true;\n } else {\n this.debug('ImageBitmap does not support .close(), disabled');\n }\n }\n\n var features = this.options.features.slice();\n\n if (features.indexOf('all') >= 0) {\n features = ['cib', 'wasm', 'js', 'ww'];\n }\n\n this.__requested_features = features;\n this.__mathlib = new MathLib(features); // Check WebWorker support if requested\n\n if (features.indexOf('ww') >= 0) {\n if (typeof window !== 'undefined' && 'Worker' in window) {\n // IE <= 11 don't allow to create webworkers from string. We should check it.\n // https://connect.microsoft.com/IE/feedback/details/801810/web-workers-from-blob-urls-in-ie-10-and-11\n try {\n var wkr = _dereq_('webworkify')(function () {});\n\n wkr.terminate();\n this.features.ww = true; // pool uniqueness depends on pool config + webworker config\n\n var wpool_key = \"wp_\".concat(JSON.stringify(this.options));\n\n if (singletones[wpool_key]) {\n this.__workersPool = singletones[wpool_key];\n } else {\n this.__workersPool = new Pool(workerFabric, this.options.idle);\n singletones[wpool_key] = this.__workersPool;\n }\n } catch (__) {}\n }\n }\n\n var initMath = this.__mathlib.init().then(function (mathlib) {\n // Copy detected features\n assign(_this.features, mathlib.features);\n });\n\n var checkCibResize;\n\n if (!CAN_CREATE_IMAGE_BITMAP) {\n checkCibResize = Promise.resolve(false);\n } else {\n checkCibResize = utils.cib_support(this.options.createCanvas).then(function (status) {\n if (_this.features.cib && features.indexOf('cib') < 0) {\n _this.debug('createImageBitmap() resize supported, but disabled by config');\n\n return;\n }\n\n if (features.indexOf('cib') >= 0) _this.features.cib = status;\n });\n }\n\n CAN_USE_CANVAS_GET_IMAGE_DATA = utils.can_use_canvas(this.options.createCanvas);\n var checkOffscreenCanvas;\n\n if (CAN_CREATE_IMAGE_BITMAP && CAN_NEW_IMAGE_DATA && features.indexOf('ww') !== -1) {\n checkOffscreenCanvas = utils.worker_offscreen_canvas_support();\n } else {\n checkOffscreenCanvas = Promise.resolve(false);\n }\n\n checkOffscreenCanvas = checkOffscreenCanvas.then(function (result) {\n CAN_USE_OFFSCREEN_CANVAS = result;\n }); // we use createImageBitmap to crop image data and pass it to workers,\n // so need to check whether function works correctly;\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n\n var checkCibRegion = utils.cib_can_use_region().then(function (result) {\n CAN_USE_CIB_REGION_FOR_IMAGE = result;\n }); // Init math lib. That's async because can load some\n\n this.__initPromise = Promise.all([initMath, checkCibResize, checkOffscreenCanvas, checkCibRegion]).then(function () {\n return _this;\n });\n return this.__initPromise;\n}; // Call resizer in webworker or locally, depending on config\n\n\nPica.prototype.__invokeResize = function (tileOpts, opts) {\n var _this2 = this;\n\n // Share cache between calls:\n //\n // - wasm instance\n // - wasm memory object\n //\n opts.__mathCache = opts.__mathCache || {};\n return Promise.resolve().then(function () {\n if (!_this2.features.ww) {\n // not possible to have ImageBitmap here if user disabled WW\n return {\n data: _this2.__mathlib.resizeAndUnsharp(tileOpts, opts.__mathCache)\n };\n }\n\n return new Promise(function (resolve, reject) {\n var w = _this2.__workersPool.acquire();\n\n if (opts.cancelToken) opts.cancelToken[\"catch\"](function (err) {\n return reject(err);\n });\n\n w.value.onmessage = function (ev) {\n w.release();\n if (ev.data.err) reject(ev.data.err);else resolve(ev.data);\n };\n\n var transfer = [];\n if (tileOpts.src) transfer.push(tileOpts.src.buffer);\n if (tileOpts.srcBitmap) transfer.push(tileOpts.srcBitmap);\n w.value.postMessage({\n opts: tileOpts,\n features: _this2.__requested_features,\n preload: {\n wasm_nodule: _this2.__mathlib.__\n }\n }, transfer);\n });\n });\n}; // this function can return promise if createImageBitmap is used\n\n\nPica.prototype.__extractTileData = function (tile, from, opts, stageEnv, extractTo) {\n if (this.features.ww && CAN_USE_OFFSCREEN_CANVAS && ( // createImageBitmap doesn't work for images (Image, ImageBitmap) with Exif orientation in Chrome,\n // can use canvas because canvas doesn't have orientation;\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n utils.isCanvas(from) || CAN_USE_CIB_REGION_FOR_IMAGE)) {\n this.debug('Create tile for OffscreenCanvas');\n return createImageBitmap(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height).then(function (bitmap) {\n extractTo.srcBitmap = bitmap;\n return extractTo;\n });\n } // Extract tile RGBA buffer, depending on input type\n\n\n if (utils.isCanvas(from)) {\n if (!stageEnv.srcCtx) stageEnv.srcCtx = from.getContext('2d', {\n alpha: Boolean(opts.alpha)\n }); // If input is Canvas - extract region data directly\n\n this.debug('Get tile pixel data');\n extractTo.src = stageEnv.srcCtx.getImageData(tile.x, tile.y, tile.width, tile.height).data;\n return extractTo;\n } // If input is Image or decoded to ImageBitmap,\n // draw region to temporary canvas and extract data from it\n //\n // Note! Attempt to reuse this canvas causes significant slowdown in chrome\n //\n\n\n this.debug('Draw tile imageBitmap/image to temporary canvas');\n var tmpCanvas = this.options.createCanvas(tile.width, tile.height);\n var tmpCtx = tmpCanvas.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n tmpCtx.globalCompositeOperation = 'copy';\n tmpCtx.drawImage(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height, 0, 0, tile.width, tile.height);\n this.debug('Get tile pixel data');\n extractTo.src = tmpCtx.getImageData(0, 0, tile.width, tile.height).data; // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n\n tmpCanvas.width = tmpCanvas.height = 0;\n return extractTo;\n};\n\nPica.prototype.__landTileData = function (tile, result, stageEnv) {\n var toImageData;\n this.debug('Convert raw rgba tile result to ImageData');\n\n if (result.bitmap) {\n stageEnv.toCtx.drawImage(result.bitmap, tile.toX, tile.toY);\n return null;\n }\n\n if (CAN_NEW_IMAGE_DATA) {\n // this branch is for modern browsers\n // If `new ImageData()` & Uint8ClampedArray suported\n toImageData = new ImageData(new Uint8ClampedArray(result.data), tile.toWidth, tile.toHeight);\n } else {\n // fallback for `node-canvas` and old browsers\n // (IE11 has ImageData but does not support `new ImageData()`)\n toImageData = stageEnv.toCtx.createImageData(tile.toWidth, tile.toHeight);\n\n if (toImageData.data.set) {\n toImageData.data.set(result.data);\n } else {\n // IE9 don't have `.set()`\n for (var i = toImageData.data.length - 1; i >= 0; i--) {\n toImageData.data[i] = result.data[i];\n }\n }\n }\n\n this.debug('Draw tile');\n\n if (NEED_SAFARI_FIX) {\n // Safari draws thin white stripes between tiles without this fix\n stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth + 1e-5, tile.toInnerHeight + 1e-5);\n } else {\n stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth, tile.toInnerHeight);\n }\n\n return null;\n};\n\nPica.prototype.__tileAndResize = function (from, to, opts) {\n var _this3 = this;\n\n var stageEnv = {\n srcCtx: null,\n srcImageBitmap: null,\n isImageBitmapReused: false,\n toCtx: null\n };\n\n var processTile = function processTile(tile) {\n return _this3.__limit(function () {\n if (opts.canceled) return opts.cancelToken;\n var tileOpts = {\n width: tile.width,\n height: tile.height,\n toWidth: tile.toWidth,\n toHeight: tile.toHeight,\n scaleX: tile.scaleX,\n scaleY: tile.scaleY,\n offsetX: tile.offsetX,\n offsetY: tile.offsetY,\n quality: opts.quality,\n alpha: opts.alpha,\n unsharpAmount: opts.unsharpAmount,\n unsharpRadius: opts.unsharpRadius,\n unsharpThreshold: opts.unsharpThreshold\n };\n\n _this3.debug('Invoke resize math');\n\n return Promise.resolve(tileOpts).then(function (tileOpts) {\n return _this3.__extractTileData(tile, from, opts, stageEnv, tileOpts);\n }).then(function (tileOpts) {\n _this3.debug('Invoke resize math');\n\n return _this3.__invokeResize(tileOpts, opts);\n }).then(function (result) {\n if (opts.canceled) return opts.cancelToken;\n stageEnv.srcImageData = null;\n return _this3.__landTileData(tile, result, stageEnv);\n });\n });\n }; // Need to normalize data source first. It can be canvas or image.\n // If image - try to decode in background if possible\n\n\n return Promise.resolve().then(function () {\n stageEnv.toCtx = to.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n if (utils.isCanvas(from)) return null;\n\n if (utils.isImageBitmap(from)) {\n stageEnv.srcImageBitmap = from;\n stageEnv.isImageBitmapReused = true;\n return null;\n }\n\n if (utils.isImage(from)) {\n // try do decode image in background for faster next operations;\n // if we're using offscreen canvas, cib is called per tile, so not needed here\n if (!CAN_CREATE_IMAGE_BITMAP) return null;\n\n _this3.debug('Decode image via createImageBitmap');\n\n return createImageBitmap(from).then(function (imageBitmap) {\n stageEnv.srcImageBitmap = imageBitmap;\n }) // Suppress error to use fallback, if method fails\n // https://github.com/nodeca/pica/issues/190\n\n /* eslint-disable no-unused-vars */\n [\"catch\"](function (e) {\n return null;\n });\n }\n\n throw new Error('Pica: \".from\" should be Image, Canvas or ImageBitmap');\n }).then(function () {\n if (opts.canceled) return opts.cancelToken;\n\n _this3.debug('Calculate tiles'); //\n // Here we are with \"normalized\" source,\n // follow to tiling\n //\n\n\n var regions = createRegions({\n width: opts.width,\n height: opts.height,\n srcTileSize: _this3.options.tile,\n toWidth: opts.toWidth,\n toHeight: opts.toHeight,\n destTileBorder: opts.__destTileBorder\n });\n var jobs = regions.map(function (tile) {\n return processTile(tile);\n });\n\n function cleanup(stageEnv) {\n if (stageEnv.srcImageBitmap) {\n if (!stageEnv.isImageBitmapReused) stageEnv.srcImageBitmap.close();\n stageEnv.srcImageBitmap = null;\n }\n }\n\n _this3.debug('Process tiles');\n\n return Promise.all(jobs).then(function () {\n _this3.debug('Finished!');\n\n cleanup(stageEnv);\n return to;\n }, function (err) {\n cleanup(stageEnv);\n throw err;\n });\n });\n};\n\nPica.prototype.__processStages = function (stages, from, to, opts) {\n var _this4 = this;\n\n if (opts.canceled) return opts.cancelToken;\n\n var _stages$shift = stages.shift(),\n _stages$shift2 = _slicedToArray(_stages$shift, 2),\n toWidth = _stages$shift2[0],\n toHeight = _stages$shift2[1];\n\n var isLastStage = stages.length === 0;\n opts = assign({}, opts, {\n toWidth: toWidth,\n toHeight: toHeight,\n // only use user-defined quality for the last stage,\n // use simpler (Hamming) filter for the first stages where\n // scale factor is large enough (more than 2-3)\n quality: isLastStage ? opts.quality : Math.min(1, opts.quality)\n });\n var tmpCanvas;\n\n if (!isLastStage) {\n // create temporary canvas\n tmpCanvas = this.options.createCanvas(toWidth, toHeight);\n }\n\n return this.__tileAndResize(from, isLastStage ? to : tmpCanvas, opts).then(function () {\n if (isLastStage) return to;\n opts.width = toWidth;\n opts.height = toHeight;\n return _this4.__processStages(stages, tmpCanvas, to, opts);\n }).then(function (res) {\n if (tmpCanvas) {\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n tmpCanvas.width = tmpCanvas.height = 0;\n }\n\n return res;\n });\n};\n\nPica.prototype.__resizeViaCreateImageBitmap = function (from, to, opts) {\n var _this5 = this;\n\n var toCtx = to.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n this.debug('Resize via createImageBitmap()');\n return createImageBitmap(from, {\n resizeWidth: opts.toWidth,\n resizeHeight: opts.toHeight,\n resizeQuality: utils.cib_quality_name(opts.quality)\n }).then(function (imageBitmap) {\n if (opts.canceled) return opts.cancelToken; // if no unsharp - draw directly to output canvas\n\n if (!opts.unsharpAmount) {\n toCtx.drawImage(imageBitmap, 0, 0);\n imageBitmap.close();\n toCtx = null;\n\n _this5.debug('Finished!');\n\n return to;\n }\n\n _this5.debug('Unsharp result');\n\n var tmpCanvas = _this5.options.createCanvas(opts.toWidth, opts.toHeight);\n\n var tmpCtx = tmpCanvas.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n tmpCtx.drawImage(imageBitmap, 0, 0);\n imageBitmap.close();\n var iData = tmpCtx.getImageData(0, 0, opts.toWidth, opts.toHeight);\n\n _this5.__mathlib.unsharp_mask(iData.data, opts.toWidth, opts.toHeight, opts.unsharpAmount, opts.unsharpRadius, opts.unsharpThreshold);\n\n toCtx.putImageData(iData, 0, 0); // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n\n tmpCanvas.width = tmpCanvas.height = 0;\n iData = tmpCtx = tmpCanvas = toCtx = null;\n\n _this5.debug('Finished!');\n\n return to;\n });\n};\n\nPica.prototype.resize = function (from, to, options) {\n var _this6 = this;\n\n this.debug('Start resize...');\n var opts = assign({}, DEFAULT_RESIZE_OPTS);\n\n if (!isNaN(options)) {\n opts = assign(opts, {\n quality: options\n });\n } else if (options) {\n opts = assign(opts, options);\n }\n\n opts.toWidth = to.width;\n opts.toHeight = to.height;\n opts.width = from.naturalWidth || from.width;\n opts.height = from.naturalHeight || from.height; // Prevent stepper from infinite loop\n\n if (to.width === 0 || to.height === 0) {\n return Promise.reject(new Error(\"Invalid output size: \".concat(to.width, \"x\").concat(to.height)));\n }\n\n if (opts.unsharpRadius > 2) opts.unsharpRadius = 2;\n opts.canceled = false;\n\n if (opts.cancelToken) {\n // Wrap cancelToken to avoid successive resolve & set flag\n opts.cancelToken = opts.cancelToken.then(function (data) {\n opts.canceled = true;\n throw data;\n }, function (err) {\n opts.canceled = true;\n throw err;\n });\n }\n\n var DEST_TILE_BORDER = 3; // Max possible filter window size\n\n opts.__destTileBorder = Math.ceil(Math.max(DEST_TILE_BORDER, 2.5 * opts.unsharpRadius | 0));\n return this.init().then(function () {\n if (opts.canceled) return opts.cancelToken; // if createImageBitmap supports resize, just do it and return\n\n if (_this6.features.cib) {\n return _this6.__resizeViaCreateImageBitmap(from, to, opts);\n }\n\n if (!CAN_USE_CANVAS_GET_IMAGE_DATA) {\n var err = new Error('Pica: cannot use getImageData on canvas, ' + \"make sure fingerprinting protection isn't enabled\");\n err.code = 'ERR_GET_IMAGE_DATA';\n throw err;\n } //\n // No easy way, let's resize manually via arrays\n //\n\n\n var stages = createStages(opts.width, opts.height, opts.toWidth, opts.toHeight, _this6.options.tile, opts.__destTileBorder);\n return _this6.__processStages(stages, from, to, opts);\n });\n}; // RGBA buffer resize\n//\n\n\nPica.prototype.resizeBuffer = function (options) {\n var _this7 = this;\n\n var opts = assign({}, DEFAULT_RESIZE_OPTS, options);\n return this.init().then(function () {\n return _this7.__mathlib.resizeAndUnsharp(opts);\n });\n};\n\nPica.prototype.toBlob = function (canvas, mimeType, quality) {\n mimeType = mimeType || 'image/png';\n return new Promise(function (resolve) {\n if (canvas.toBlob) {\n canvas.toBlob(function (blob) {\n return resolve(blob);\n }, mimeType, quality);\n return;\n }\n\n if (canvas.convertToBlob) {\n resolve(canvas.convertToBlob({\n type: mimeType,\n quality: quality\n }));\n return;\n } // Fallback for old browsers\n\n\n var asString = atob(canvas.toDataURL(mimeType, quality).split(',')[1]);\n var len = asString.length;\n var asBuffer = new Uint8Array(len);\n\n for (var i = 0; i < len; i++) {\n asBuffer[i] = asString.charCodeAt(i);\n }\n\n resolve(new Blob([asBuffer], {\n type: mimeType\n }));\n });\n};\n\nPica.prototype.debug = function () {};\n\nmodule.exports = Pica;\n\n},{\"./lib/mathlib\":1,\"./lib/pool\":13,\"./lib/stepper\":14,\"./lib/tiler\":15,\"./lib/utils\":16,\"./lib/worker\":17,\"object-assign\":23,\"webworkify\":24}]},{},[])(\"/index.js\")\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3BpY2EvZGlzdC9waWNhLmpzLmpzIiwibWFwcGluZ3MiOiJBQUFBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEsYUFBYSxHQUFHLElBQXNELEVBQUUsbUJBQW1CLEtBQUssVUFBNk4sQ0FBQyxhQUFhLDBCQUEwQixtQkFBbUIsa0JBQWtCLGdCQUFnQixVQUFVLFVBQVUsTUFBTSxTQUFtQyxDQUFDLGdCQUFnQixPQUFDLE9BQU8sb0JBQW9CLDhDQUE4QyxrQ0FBa0MsWUFBWSxZQUFZLG1DQUFtQyxpQkFBaUIsZUFBZSxzQkFBc0Isb0JBQW9CLFVBQVUsU0FBbUMsS0FBSyxXQUFXLFlBQVksU0FBUyxTQUFTLEtBQUs7QUFDenpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSxtRUFBbUU7QUFDdEU7QUFDQTtBQUNBLGNBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7O0FBRXRCLGlCQUFpQixhQUFhO0FBQzlCLG1CQUFtQjs7QUFFbkIsb0JBQW9CLGVBQWU7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7O0FBRXpCLGFBQWEsZ0JBQWdCO0FBQzdCLDBDQUEwQztBQUMxQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUVBOztBQUVBLENBQUMsRUFBRSw0SUFBNEksRUFBRSxHQUFHO0FBQ3BKLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3BpY2EvZGlzdC9waWNhLmpzP2ZmNTkiXSwic291cmNlc0NvbnRlbnQiOlsiLyohXG5cbnBpY2Fcbmh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYVxuXG4qL1xuXG4oZnVuY3Rpb24oZil7aWYodHlwZW9mIGV4cG9ydHM9PT1cIm9iamVjdFwiJiZ0eXBlb2YgbW9kdWxlIT09XCJ1bmRlZmluZWRcIil7bW9kdWxlLmV4cG9ydHM9ZigpfWVsc2UgaWYodHlwZW9mIGRlZmluZT09PVwiZnVuY3Rpb25cIiYmZGVmaW5lLmFtZCl7ZGVmaW5lKFtdLGYpfWVsc2V7dmFyIGc7aWYodHlwZW9mIHdpbmRvdyE9PVwidW5kZWZpbmVkXCIpe2c9d2luZG93fWVsc2UgaWYodHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCIpe2c9Z2xvYmFsfWVsc2UgaWYodHlwZW9mIHNlbGYhPT1cInVuZGVmaW5lZFwiKXtnPXNlbGZ9ZWxzZXtnPXRoaXN9Zy5waWNhID0gZigpfX0pKGZ1bmN0aW9uKCl7dmFyIGRlZmluZSxtb2R1bGUsZXhwb3J0cztyZXR1cm4gKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSh7MTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBDb2xsZWN0aW9uIG9mIG1hdGggZnVuY3Rpb25zXG4vL1xuLy8gMS4gQ29tYmluZSBjb21wb25lbnRzIHRvZ2V0aGVyXG4vLyAyLiBIYXMgYXN5bmMgaW5pdCB0byBsb2FkIHdhc20gbW9kdWxlc1xuLy9cbid1c2Ugc3RyaWN0JztcblxudmFyIGluaGVyaXRzID0gX2RlcmVxXygnaW5oZXJpdHMnKTtcblxudmFyIE11bHRpbWF0aCA9IF9kZXJlcV8oJ211bHRpbWF0aCcpO1xuXG52YXIgbW1fdW5zaGFycF9tYXNrID0gX2RlcmVxXygnLi9tbV91bnNoYXJwX21hc2snKTtcblxudmFyIG1tX3Jlc2l6ZSA9IF9kZXJlcV8oJy4vbW1fcmVzaXplJyk7XG5cbmZ1bmN0aW9uIE1hdGhMaWIocmVxdWVzdGVkX2ZlYXR1cmVzKSB7XG4gIHZhciBfX3JlcXVlc3RlZF9mZWF0dXJlcyA9IHJlcXVlc3RlZF9mZWF0dXJlcyB8fCBbXTtcblxuICB2YXIgZmVhdHVyZXMgPSB7XG4gICAganM6IF9fcmVxdWVzdGVkX2ZlYXR1cmVzLmluZGV4T2YoJ2pzJykgPj0gMCxcbiAgICB3YXNtOiBfX3JlcXVlc3RlZF9mZWF0dXJlcy5pbmRleE9mKCd3YXNtJykgPj0gMFxuICB9O1xuICBNdWx0aW1hdGguY2FsbCh0aGlzLCBmZWF0dXJlcyk7XG4gIHRoaXMuZmVhdHVyZXMgPSB7XG4gICAganM6IGZlYXR1cmVzLmpzLFxuICAgIHdhc206IGZlYXR1cmVzLndhc20gJiYgdGhpcy5oYXNfd2FzbSgpXG4gIH07XG4gIHRoaXMudXNlKG1tX3Vuc2hhcnBfbWFzayk7XG4gIHRoaXMudXNlKG1tX3Jlc2l6ZSk7XG59XG5cbmluaGVyaXRzKE1hdGhMaWIsIE11bHRpbWF0aCk7XG5cbk1hdGhMaWIucHJvdG90eXBlLnJlc2l6ZUFuZFVuc2hhcnAgPSBmdW5jdGlvbiByZXNpemVBbmRVbnNoYXJwKG9wdGlvbnMsIGNhY2hlKSB7XG4gIHZhciByZXN1bHQgPSB0aGlzLnJlc2l6ZShvcHRpb25zLCBjYWNoZSk7XG5cbiAgaWYgKG9wdGlvbnMudW5zaGFycEFtb3VudCkge1xuICAgIHRoaXMudW5zaGFycF9tYXNrKHJlc3VsdCwgb3B0aW9ucy50b1dpZHRoLCBvcHRpb25zLnRvSGVpZ2h0LCBvcHRpb25zLnVuc2hhcnBBbW91bnQsIG9wdGlvbnMudW5zaGFycFJhZGl1cywgb3B0aW9ucy51bnNoYXJwVGhyZXNob2xkKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGhMaWI7XG5cbn0se1wiLi9tbV9yZXNpemVcIjo0LFwiLi9tbV91bnNoYXJwX21hc2tcIjo5LFwiaW5oZXJpdHNcIjoxOSxcIm11bHRpbWF0aFwiOjIwfV0sMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBSZXNpemUgY29udm9sdmVycywgcHVyZSBKUyBpbXBsZW1lbnRhdGlvblxuLy9cbid1c2Ugc3RyaWN0JzsgLy8gUHJlY2lzaW9uIG9mIGZpeGVkIEZQIHZhbHVlc1xuLy92YXIgRklYRURfRlJBQ19CSVRTID0gMTQ7XG5cbmZ1bmN0aW9uIGNsYW1wVG84KGkpIHtcbiAgcmV0dXJuIGkgPCAwID8gMCA6IGkgPiAyNTUgPyAyNTUgOiBpO1xufSAvLyBDb252b2x2ZSBpbWFnZSBpbiBob3Jpem9udGFsIGRpcmVjdGlvbnMgYW5kIHRyYW5zcG9zZSBvdXRwdXQuIEluIHRoZW9yeSxcbi8vIHRyYW5zcG9zZSBhbGxvdzpcbi8vXG4vLyAtIHVzZSB0aGUgc2FtZSBjb252b2x2ZXIgZm9yIGJvdGggcGFzc2VzICh0aGlzIGZhaWxzIGR1ZSBkaWZmZXJlbnRcbi8vICAgdHlwZXMgb2YgaW5wdXQgYXJyYXkgYW5kIHRlbXBvcmFyeSBidWZmZXIpXG4vLyAtIG1ha2luZyB2ZXJ0aWNhbCBwYXNzIGJ5IGhvcmlzb25sdGFsIGxpbmVzIGlucHJvdmUgQ1BVIGNhY2hlIHVzZS5cbi8vXG4vLyBCdXQgaW4gcmVhbCBsaWZlIHRoaXMgZG9lc24ndCB3b3JrIDopXG4vL1xuXG5cbmZ1bmN0aW9uIGNvbnZvbHZlSG9yaXpvbnRhbGx5KHNyYywgZGVzdCwgc3JjVywgc3JjSCwgZGVzdFcsIGZpbHRlcnMpIHtcbiAgdmFyIHIsIGcsIGIsIGE7XG4gIHZhciBmaWx0ZXJQdHIsIGZpbHRlclNoaWZ0LCBmaWx0ZXJTaXplO1xuICB2YXIgc3JjUHRyLCBzcmNZLCBkZXN0WCwgZmlsdGVyVmFsO1xuICB2YXIgc3JjT2Zmc2V0ID0gMCxcbiAgICAgIGRlc3RPZmZzZXQgPSAwOyAvLyBGb3IgZWFjaCByb3dcblxuICBmb3IgKHNyY1kgPSAwOyBzcmNZIDwgc3JjSDsgc3JjWSsrKSB7XG4gICAgZmlsdGVyUHRyID0gMDsgLy8gQXBwbHkgcHJlY29tcHV0ZWQgZmlsdGVycyB0byBlYWNoIGRlc3RpbmF0aW9uIHJvdyBwb2ludFxuXG4gICAgZm9yIChkZXN0WCA9IDA7IGRlc3RYIDwgZGVzdFc7IGRlc3RYKyspIHtcbiAgICAgIC8vIEdldCB0aGUgZmlsdGVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgY3VycmVudCBvdXRwdXQgcGl4ZWwuXG4gICAgICBmaWx0ZXJTaGlmdCA9IGZpbHRlcnNbZmlsdGVyUHRyKytdO1xuICAgICAgZmlsdGVyU2l6ZSA9IGZpbHRlcnNbZmlsdGVyUHRyKytdO1xuICAgICAgc3JjUHRyID0gc3JjT2Zmc2V0ICsgZmlsdGVyU2hpZnQgKiA0IHwgMDtcbiAgICAgIHIgPSBnID0gYiA9IGEgPSAwOyAvLyBBcHBseSB0aGUgZmlsdGVyIHRvIHRoZSByb3cgdG8gZ2V0IHRoZSBkZXN0aW5hdGlvbiBwaXhlbCByLCBnLCBiLCBhXG5cbiAgICAgIGZvciAoOyBmaWx0ZXJTaXplID4gMDsgZmlsdGVyU2l6ZS0tKSB7XG4gICAgICAgIGZpbHRlclZhbCA9IGZpbHRlcnNbZmlsdGVyUHRyKytdOyAvLyBVc2UgcmV2ZXJzZSBvcmRlciB0byB3b3JrYXJvdW5kIGRlb3B0cyBpbiBvbGQgdjggKG5vZGUgdi4xMClcbiAgICAgICAgLy8gQmlnIHRoYW5rcyB0byBAbXJhbGVwaCAoVnlhY2hlc2xhdiBFZ29yb3YpIGZvciB0aGUgdGlwLlxuXG4gICAgICAgIGEgPSBhICsgZmlsdGVyVmFsICogc3JjW3NyY1B0ciArIDNdIHwgMDtcbiAgICAgICAgYiA9IGIgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyICsgMl0gfCAwO1xuICAgICAgICBnID0gZyArIGZpbHRlclZhbCAqIHNyY1tzcmNQdHIgKyAxXSB8IDA7XG4gICAgICAgIHIgPSByICsgZmlsdGVyVmFsICogc3JjW3NyY1B0cl0gfCAwO1xuICAgICAgICBzcmNQdHIgPSBzcmNQdHIgKyA0IHwgMDtcbiAgICAgIH0gLy8gQnJpbmcgdGhpcyB2YWx1ZSBiYWNrIGluIHJhbmdlLiBBbGwgb2YgdGhlIGZpbHRlciBzY2FsaW5nIGZhY3RvcnNcbiAgICAgIC8vIGFyZSBpbiBmaXhlZCBwb2ludCB3aXRoIEZJWEVEX0ZSQUNfQklUUyBiaXRzIG9mIGZyYWN0aW9uYWwgcGFydC5cbiAgICAgIC8vXG4gICAgICAvLyAoISkgQWRkIDEvMiBvZiB2YWx1ZSBiZWZvcmUgY2xhbXBpbmcgdG8gZ2V0IHByb3BlciByb3VuZGluZy4gSW4gb3RoZXJcbiAgICAgIC8vIGNhc2UgYnJpZ2h0bmVzcyBsb3NzIHdpbGwgYmUgbm90aWNlYWJsZSBpZiB5b3UgcmVzaXplIGltYWdlIHdpdGggd2hpdGVcbiAgICAgIC8vIGJvcmRlciBhbmQgcGxhY2UgaXQgb24gd2hpdGUgYmFja2dyb3VuZC5cbiAgICAgIC8vXG5cblxuICAgICAgZGVzdFtkZXN0T2Zmc2V0ICsgM10gPSBjbGFtcFRvOChhICsgKDEgPDwgMTMpID4+IDE0XG4gICAgICAvKkZJWEVEX0ZSQUNfQklUUyovXG4gICAgICApO1xuICAgICAgZGVzdFtkZXN0T2Zmc2V0ICsgMl0gPSBjbGFtcFRvOChiICsgKDEgPDwgMTMpID4+IDE0XG4gICAgICAvKkZJWEVEX0ZSQUNfQklUUyovXG4gICAgICApO1xuICAgICAgZGVzdFtkZXN0T2Zmc2V0ICsgMV0gPSBjbGFtcFRvOChnICsgKDEgPDwgMTMpID4+IDE0XG4gICAgICAvKkZJWEVEX0ZSQUNfQklUUyovXG4gICAgICApO1xuICAgICAgZGVzdFtkZXN0T2Zmc2V0XSA9IGNsYW1wVG84KHIgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0T2Zmc2V0ID0gZGVzdE9mZnNldCArIHNyY0ggKiA0IHwgMDtcbiAgICB9XG5cbiAgICBkZXN0T2Zmc2V0ID0gKHNyY1kgKyAxKSAqIDQgfCAwO1xuICAgIHNyY09mZnNldCA9IChzcmNZICsgMSkgKiBzcmNXICogNCB8IDA7XG4gIH1cbn0gLy8gVGVjaG5pY2FsbHksIGNvbnZvbHZlcnMgYXJlIHRoZSBzYW1lLiBCdXQgaW5wdXQgYXJyYXkgYW5kIHRlbXBvcmFyeVxuLy8gYnVmZmVyIGNhbiBiZSBvZiBkaWZmZXJlbnQgdHlwZSAoZXNwZWNpYWxseSwgaW4gb2xkIGJyb3dzZXJzKS4gU28sXG4vLyBrZWVwIGNvZGUgaW4gc2VwYXJhdGUgZnVuY3Rpb25zIHRvIGF2b2lkIGRlb3B0aW1pemF0aW9ucyAmIHNwZWVkIGxvc3MuXG5cblxuZnVuY3Rpb24gY29udm9sdmVWZXJ0aWNhbGx5KHNyYywgZGVzdCwgc3JjVywgc3JjSCwgZGVzdFcsIGZpbHRlcnMpIHtcbiAgdmFyIHIsIGcsIGIsIGE7XG4gIHZhciBmaWx0ZXJQdHIsIGZpbHRlclNoaWZ0LCBmaWx0ZXJTaXplO1xuICB2YXIgc3JjUHRyLCBzcmNZLCBkZXN0WCwgZmlsdGVyVmFsO1xuICB2YXIgc3JjT2Zmc2V0ID0gMCxcbiAgICAgIGRlc3RPZmZzZXQgPSAwOyAvLyBGb3IgZWFjaCByb3dcblxuICBmb3IgKHNyY1kgPSAwOyBzcmNZIDwgc3JjSDsgc3JjWSsrKSB7XG4gICAgZmlsdGVyUHRyID0gMDsgLy8gQXBwbHkgcHJlY29tcHV0ZWQgZmlsdGVycyB0byBlYWNoIGRlc3RpbmF0aW9uIHJvdyBwb2ludFxuXG4gICAgZm9yIChkZXN0WCA9IDA7IGRlc3RYIDwgZGVzdFc7IGRlc3RYKyspIHtcbiAgICAgIC8vIEdldCB0aGUgZmlsdGVyIHRoYXQgZGV0ZXJtaW5lcyB0aGUgY3VycmVudCBvdXRwdXQgcGl4ZWwuXG4gICAgICBmaWx0ZXJTaGlmdCA9IGZpbHRlcnNbZmlsdGVyUHRyKytdO1xuICAgICAgZmlsdGVyU2l6ZSA9IGZpbHRlcnNbZmlsdGVyUHRyKytdO1xuICAgICAgc3JjUHRyID0gc3JjT2Zmc2V0ICsgZmlsdGVyU2hpZnQgKiA0IHwgMDtcbiAgICAgIHIgPSBnID0gYiA9IGEgPSAwOyAvLyBBcHBseSB0aGUgZmlsdGVyIHRvIHRoZSByb3cgdG8gZ2V0IHRoZSBkZXN0aW5hdGlvbiBwaXhlbCByLCBnLCBiLCBhXG5cbiAgICAgIGZvciAoOyBmaWx0ZXJTaXplID4gMDsgZmlsdGVyU2l6ZS0tKSB7XG4gICAgICAgIGZpbHRlclZhbCA9IGZpbHRlcnNbZmlsdGVyUHRyKytdOyAvLyBVc2UgcmV2ZXJzZSBvcmRlciB0byB3b3JrYXJvdW5kIGRlb3B0cyBpbiBvbGQgdjggKG5vZGUgdi4xMClcbiAgICAgICAgLy8gQmlnIHRoYW5rcyB0byBAbXJhbGVwaCAoVnlhY2hlc2xhdiBFZ29yb3YpIGZvciB0aGUgdGlwLlxuXG4gICAgICAgIGEgPSBhICsgZmlsdGVyVmFsICogc3JjW3NyY1B0ciArIDNdIHwgMDtcbiAgICAgICAgYiA9IGIgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyICsgMl0gfCAwO1xuICAgICAgICBnID0gZyArIGZpbHRlclZhbCAqIHNyY1tzcmNQdHIgKyAxXSB8IDA7XG4gICAgICAgIHIgPSByICsgZmlsdGVyVmFsICogc3JjW3NyY1B0cl0gfCAwO1xuICAgICAgICBzcmNQdHIgPSBzcmNQdHIgKyA0IHwgMDtcbiAgICAgIH0gLy8gQnJpbmcgdGhpcyB2YWx1ZSBiYWNrIGluIHJhbmdlLiBBbGwgb2YgdGhlIGZpbHRlciBzY2FsaW5nIGZhY3RvcnNcbiAgICAgIC8vIGFyZSBpbiBmaXhlZCBwb2ludCB3aXRoIEZJWEVEX0ZSQUNfQklUUyBiaXRzIG9mIGZyYWN0aW9uYWwgcGFydC5cbiAgICAgIC8vXG4gICAgICAvLyAoISkgQWRkIDEvMiBvZiB2YWx1ZSBiZWZvcmUgY2xhbXBpbmcgdG8gZ2V0IHByb3BlciByb3VuZGluZy4gSW4gb3RoZXJcbiAgICAgIC8vIGNhc2UgYnJpZ2h0bmVzcyBsb3NzIHdpbGwgYmUgbm90aWNlYWJsZSBpZiB5b3UgcmVzaXplIGltYWdlIHdpdGggd2hpdGVcbiAgICAgIC8vIGJvcmRlciBhbmQgcGxhY2UgaXQgb24gd2hpdGUgYmFja2dyb3VuZC5cbiAgICAgIC8vXG5cblxuICAgICAgZGVzdFtkZXN0T2Zmc2V0ICsgM10gPSBjbGFtcFRvOChhICsgKDEgPDwgMTMpID4+IDE0XG4gICAgICAvKkZJWEVEX0ZSQUNfQklUUyovXG4gICAgICApO1xuICAgICAgZGVzdFtkZXN0T2Zmc2V0ICsgMl0gPSBjbGFtcFRvOChiICsgKDEgPDwgMTMpID4+IDE0XG4gICAgICAvKkZJWEVEX0ZSQUNfQklUUyovXG4gICAgICApO1xuICAgICAgZGVzdFtkZXN0T2Zmc2V0ICsgMV0gPSBjbGFtcFRvOChnICsgKDEgPDwgMTMpID4+IDE0XG4gICAgICAvKkZJWEVEX0ZSQUNfQklUUyovXG4gICAgICApO1xuICAgICAgZGVzdFtkZXN0T2Zmc2V0XSA9IGNsYW1wVG84KHIgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0T2Zmc2V0ID0gZGVzdE9mZnNldCArIHNyY0ggKiA0IHwgMDtcbiAgICB9XG5cbiAgICBkZXN0T2Zmc2V0ID0gKHNyY1kgKyAxKSAqIDQgfCAwO1xuICAgIHNyY09mZnNldCA9IChzcmNZICsgMSkgKiBzcmNXICogNCB8IDA7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGNvbnZvbHZlSG9yaXpvbnRhbGx5OiBjb252b2x2ZUhvcml6b250YWxseSxcbiAgY29udm9sdmVWZXJ0aWNhbGx5OiBjb252b2x2ZVZlcnRpY2FsbHlcbn07XG5cbn0se31dLDM6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLy8gVGhpcyBpcyBhdXRvZ2VuZXJhdGVkIGZpbGUgZnJvbSBtYXRoLndhc20sIGRvbid0IGVkaXQuXG4vL1xuJ3VzZSBzdHJpY3QnO1xuLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9ICdBR0Z6YlFFQUFBQUFEQVprZVd4cGJtc0FBQUFBQUFFWEEyQUFBR0FHZjM5L2YzOS9BR0FIZjM5L2YzOS9md0FDRHdFRFpXNTJCbTFsYlc5eWVRSUFBQU1FQXdBQkFnWUdBWDhBUVFBTEIxY0ZFVjlmZDJGemJWOWpZV3hzWDJOMGIzSnpBQUFJWTI5dWRtOXNkbVVBQVFwamIyNTJiMngyWlVoV0FBSU1YMTlrYzI5ZmFHRnVaR3hsQXdBWVgxOTNZWE50WDJGd2NHeDVYMlJoZEdGZmNtVnNiMk56QUFBSzdBTURBd0FCQzhZREFROS9Ba0FnQTBVTkFDQUVSUTBBQTBBZ0RDRU5RUUFoRTBFQUlRY0RRQ0FIUVFKcUlRWUNmeUFIUVFGMElBVnFJZ2N1QVFJaUZFVUVRRUdBd0FBaENFR0F3QUFoQ1VHQXdBQWhDa0dBd0FBaEN5QUdEQUVMSUJJZ0J5NEJBR29oQ0VFQUlRc2dGQ0VIUVFBaERpQUdJUWxCQUNFUFFRQWhFQU5BSUFVZ0NVRUJkR291QVFBaUVTQUFJQWhCQW5ScUtBSUFJZ3BCR0hac0lCQnFJUkFnQ2tIL0FYRWdFV3dnQzJvaEN5QUtRUkIyUWY4QmNTQVJiQ0FQYWlFUElBcEJDSFpCL3dGeElCRnNJQTVxSVE0Z0NFRUJhaUVJSUFsQkFXb2hDU0FIUVFGcklnY05BQXNnQzBHQVFHc2hDQ0FPUVlCQWF5RUpJQTlCZ0VCcklRb2dFRUdBUUdzaEN5QUdJQlJxQ3lFSElBRWdEVUVDZEdvZ0NVRU9kU0lHUWY4QklBWkIvd0ZJR3lJR1FRQWdCa0VBU2h0QkNIUkJnUDREY1NBS1FRNTFJZ1pCL3dFZ0JrSC9BVWdiSWdaQkFDQUdRUUJLRzBFUWRFR0FnUHdIY1NBTFFRNTFJZ1pCL3dFZ0JrSC9BVWdiSWdaQkFDQUdRUUJLRzBFWWRISnlJQWhCRG5VaUJrSC9BU0FHUWY4QlNCc2lCa0VBSUFaQkFFb2JjallDQUNBRElBMXFJUTBnRTBFQmFpSVRJQVJIRFFBTElBeEJBV29pRENBQ2JDRVNJQU1nREVjTkFBc0xDeDRBUVFBZ0FpQURJQVFnQlNBQUVBRWdBa0VBSUFRZ0JTQUdJQUVRQVFzPSc7XG5cbn0se31dLDQ6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgbmFtZTogJ3Jlc2l6ZScsXG4gIGZuOiBfZGVyZXFfKCcuL3Jlc2l6ZScpLFxuICB3YXNtX2ZuOiBfZGVyZXFfKCcuL3Jlc2l6ZV93YXNtJyksXG4gIHdhc21fc3JjOiBfZGVyZXFfKCcuL2NvbnZvbHZlX3dhc21fYmFzZTY0Jylcbn07XG5cbn0se1wiLi9jb252b2x2ZV93YXNtX2Jhc2U2NFwiOjMsXCIuL3Jlc2l6ZVwiOjUsXCIuL3Jlc2l6ZV93YXNtXCI6OH1dLDU6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3JlYXRlRmlsdGVycyA9IF9kZXJlcV8oJy4vcmVzaXplX2ZpbHRlcl9nZW4nKTtcblxudmFyIGNvbnZvbHZlSG9yaXpvbnRhbGx5ID0gX2RlcmVxXygnLi9jb252b2x2ZScpLmNvbnZvbHZlSG9yaXpvbnRhbGx5O1xuXG52YXIgY29udm9sdmVWZXJ0aWNhbGx5ID0gX2RlcmVxXygnLi9jb252b2x2ZScpLmNvbnZvbHZlVmVydGljYWxseTtcblxuZnVuY3Rpb24gcmVzZXRBbHBoYShkc3QsIHdpZHRoLCBoZWlnaHQpIHtcbiAgdmFyIHB0ciA9IDMsXG4gICAgICBsZW4gPSB3aWR0aCAqIGhlaWdodCAqIDQgfCAwO1xuXG4gIHdoaWxlIChwdHIgPCBsZW4pIHtcbiAgICBkc3RbcHRyXSA9IDB4RkY7XG4gICAgcHRyID0gcHRyICsgNCB8IDA7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiByZXNpemUob3B0aW9ucykge1xuICB2YXIgc3JjID0gb3B0aW9ucy5zcmM7XG4gIHZhciBzcmNXID0gb3B0aW9ucy53aWR0aDtcbiAgdmFyIHNyY0ggPSBvcHRpb25zLmhlaWdodDtcbiAgdmFyIGRlc3RXID0gb3B0aW9ucy50b1dpZHRoO1xuICB2YXIgZGVzdEggPSBvcHRpb25zLnRvSGVpZ2h0O1xuICB2YXIgc2NhbGVYID0gb3B0aW9ucy5zY2FsZVggfHwgb3B0aW9ucy50b1dpZHRoIC8gb3B0aW9ucy53aWR0aDtcbiAgdmFyIHNjYWxlWSA9IG9wdGlvbnMuc2NhbGVZIHx8IG9wdGlvbnMudG9IZWlnaHQgLyBvcHRpb25zLmhlaWdodDtcbiAgdmFyIG9mZnNldFggPSBvcHRpb25zLm9mZnNldFggfHwgMDtcbiAgdmFyIG9mZnNldFkgPSBvcHRpb25zLm9mZnNldFkgfHwgMDtcbiAgdmFyIGRlc3QgPSBvcHRpb25zLmRlc3QgfHwgbmV3IFVpbnQ4QXJyYXkoZGVzdFcgKiBkZXN0SCAqIDQpO1xuICB2YXIgcXVhbGl0eSA9IHR5cGVvZiBvcHRpb25zLnF1YWxpdHkgPT09ICd1bmRlZmluZWQnID8gMyA6IG9wdGlvbnMucXVhbGl0eTtcbiAgdmFyIGFscGhhID0gb3B0aW9ucy5hbHBoYSB8fCBmYWxzZTtcbiAgdmFyIGZpbHRlcnNYID0gY3JlYXRlRmlsdGVycyhxdWFsaXR5LCBzcmNXLCBkZXN0Vywgc2NhbGVYLCBvZmZzZXRYKSxcbiAgICAgIGZpbHRlcnNZID0gY3JlYXRlRmlsdGVycyhxdWFsaXR5LCBzcmNILCBkZXN0SCwgc2NhbGVZLCBvZmZzZXRZKTtcbiAgdmFyIHRtcCA9IG5ldyBVaW50OEFycmF5KGRlc3RXICogc3JjSCAqIDQpOyAvLyBUbyB1c2Ugc2luZ2xlIGZ1bmN0aW9uIHdlIG5lZWQgc3JjICYgdG1wIG9mIHRoZSBzYW1lIHR5cGUuXG4gIC8vIEJ1dCBzcmMgY2FuIGJlIENhbnZhc1BpeGVsQXJyYXksIGFuZCB0bXAgLSBVaW50OEFycmF5LiBTbywga2VlcFxuICAvLyB2ZXJ0aWNhbCBhbmQgaG9yaXpvbnRhbCBwYXNzZXMgc2VwYXJhdGVseSB0byBhdm9pZCBkZW9wdGltaXphdGlvbi5cblxuICBjb252b2x2ZUhvcml6b250YWxseShzcmMsIHRtcCwgc3JjVywgc3JjSCwgZGVzdFcsIGZpbHRlcnNYKTtcbiAgY29udm9sdmVWZXJ0aWNhbGx5KHRtcCwgZGVzdCwgc3JjSCwgZGVzdFcsIGRlc3RILCBmaWx0ZXJzWSk7IC8vIFRoYXQncyBmYXN0ZXIgdGhhbiBkb2luZyBjaGVja3MgaW4gY29udm9sdmVyLlxuICAvLyAhISEgTm90ZSwgY2FudmFzIGRhdGEgaXMgbm90IHByZW11bHRpcGxlZC4gV2UgZG9uJ3QgbmVlZCBvdGhlclxuICAvLyBhbHBoYSBjb3JyZWN0aW9ucy5cblxuICBpZiAoIWFscGhhKSByZXNldEFscGhhKGRlc3QsIGRlc3RXLCBkZXN0SCk7XG4gIHJldHVybiBkZXN0O1xufTtcblxufSx7XCIuL2NvbnZvbHZlXCI6MixcIi4vcmVzaXplX2ZpbHRlcl9nZW5cIjo2fV0sNjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBDYWxjdWxhdGUgY29udm9sdXRpb24gZmlsdGVycyBmb3IgZWFjaCBkZXN0aW5hdGlvbiBwb2ludCxcbi8vIGFuZCBwYWNrIGRhdGEgdG8gSW50MTZBcnJheTpcbi8vXG4vLyBbIHNoaWZ0LCBsZW5ndGgsIGRhdGEuLi4sIHNoaWZ0MiwgbGVuZ3RoMiwgZGF0YS4uLiwgLi4uIF1cbi8vXG4vLyAtIHNoaWZ0IC0gb2Zmc2V0IGluIHNyYyBpbWFnZVxuLy8gLSBsZW5ndGggLSBmaWx0ZXIgbGVuZ3RoIChpbiBzcmMgcG9pbnRzKVxuLy8gLSBkYXRhIC0gZmlsdGVyIHZhbHVlcyBzZXF1ZW5jZVxuLy9cbid1c2Ugc3RyaWN0JztcblxudmFyIEZJTFRFUl9JTkZPID0gX2RlcmVxXygnLi9yZXNpemVfZmlsdGVyX2luZm8nKTsgLy8gUHJlY2lzaW9uIG9mIGZpeGVkIEZQIHZhbHVlc1xuXG5cbnZhciBGSVhFRF9GUkFDX0JJVFMgPSAxNDtcblxuZnVuY3Rpb24gdG9GaXhlZFBvaW50KG51bSkge1xuICByZXR1cm4gTWF0aC5yb3VuZChudW0gKiAoKDEgPDwgRklYRURfRlJBQ19CSVRTKSAtIDEpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiByZXNpemVGaWx0ZXJHZW4ocXVhbGl0eSwgc3JjU2l6ZSwgZGVzdFNpemUsIHNjYWxlLCBvZmZzZXQpIHtcbiAgdmFyIGZpbHRlckZ1bmN0aW9uID0gRklMVEVSX0lORk9bcXVhbGl0eV0uZmlsdGVyO1xuICB2YXIgc2NhbGVJbnZlcnRlZCA9IDEuMCAvIHNjYWxlO1xuICB2YXIgc2NhbGVDbGFtcGVkID0gTWF0aC5taW4oMS4wLCBzY2FsZSk7IC8vIEZvciB1cHNjYWxlXG4gIC8vIEZpbHRlciB3aW5kb3cgKGF2ZXJhZ2luZyBpbnRlcnZhbCksIHNjYWxlZCB0byBzcmMgaW1hZ2VcblxuICB2YXIgc3JjV2luZG93ID0gRklMVEVSX0lORk9bcXVhbGl0eV0ud2luIC8gc2NhbGVDbGFtcGVkO1xuICB2YXIgZGVzdFBpeGVsLCBzcmNQaXhlbCwgc3JjRmlyc3QsIHNyY0xhc3QsIGZpbHRlckVsZW1lbnRTaXplLCBmbG9hdEZpbHRlciwgZnhwRmlsdGVyLCB0b3RhbCwgcHhsLCBpZHgsIGZsb2F0VmFsLCBmaWx0ZXJUb3RhbCwgZmlsdGVyVmFsO1xuICB2YXIgbGVmdE5vdEVtcHR5LCByaWdodE5vdEVtcHR5LCBmaWx0ZXJTaGlmdCwgZmlsdGVyU2l6ZTtcbiAgdmFyIG1heEZpbHRlckVsZW1lbnRTaXplID0gTWF0aC5mbG9vcigoc3JjV2luZG93ICsgMSkgKiAyKTtcbiAgdmFyIHBhY2tlZEZpbHRlciA9IG5ldyBJbnQxNkFycmF5KChtYXhGaWx0ZXJFbGVtZW50U2l6ZSArIDIpICogZGVzdFNpemUpO1xuICB2YXIgcGFja2VkRmlsdGVyUHRyID0gMDtcbiAgdmFyIHNsb3dDb3B5ID0gIXBhY2tlZEZpbHRlci5zdWJhcnJheSB8fCAhcGFja2VkRmlsdGVyLnNldDsgLy8gRm9yIGVhY2ggZGVzdGluYXRpb24gcGl4ZWwgY2FsY3VsYXRlIHNvdXJjZSByYW5nZSBhbmQgYnVpbHQgZmlsdGVyIHZhbHVlc1xuXG4gIGZvciAoZGVzdFBpeGVsID0gMDsgZGVzdFBpeGVsIDwgZGVzdFNpemU7IGRlc3RQaXhlbCsrKSB7XG4gICAgLy8gU2NhbGluZyBzaG91bGQgYmUgZG9uZSByZWxhdGl2ZSB0byBjZW50cmFsIHBpeGVsIHBvaW50XG4gICAgc3JjUGl4ZWwgPSAoZGVzdFBpeGVsICsgMC41KSAqIHNjYWxlSW52ZXJ0ZWQgKyBvZmZzZXQ7XG4gICAgc3JjRmlyc3QgPSBNYXRoLm1heCgwLCBNYXRoLmZsb29yKHNyY1BpeGVsIC0gc3JjV2luZG93KSk7XG4gICAgc3JjTGFzdCA9IE1hdGgubWluKHNyY1NpemUgLSAxLCBNYXRoLmNlaWwoc3JjUGl4ZWwgKyBzcmNXaW5kb3cpKTtcbiAgICBmaWx0ZXJFbGVtZW50U2l6ZSA9IHNyY0xhc3QgLSBzcmNGaXJzdCArIDE7XG4gICAgZmxvYXRGaWx0ZXIgPSBuZXcgRmxvYXQzMkFycmF5KGZpbHRlckVsZW1lbnRTaXplKTtcbiAgICBmeHBGaWx0ZXIgPSBuZXcgSW50MTZBcnJheShmaWx0ZXJFbGVtZW50U2l6ZSk7XG4gICAgdG90YWwgPSAwLjA7IC8vIEZpbGwgZmlsdGVyIHZhbHVlcyBmb3IgY2FsY3VsYXRlZCByYW5nZVxuXG4gICAgZm9yIChweGwgPSBzcmNGaXJzdCwgaWR4ID0gMDsgcHhsIDw9IHNyY0xhc3Q7IHB4bCsrLCBpZHgrKykge1xuICAgICAgZmxvYXRWYWwgPSBmaWx0ZXJGdW5jdGlvbigocHhsICsgMC41IC0gc3JjUGl4ZWwpICogc2NhbGVDbGFtcGVkKTtcbiAgICAgIHRvdGFsICs9IGZsb2F0VmFsO1xuICAgICAgZmxvYXRGaWx0ZXJbaWR4XSA9IGZsb2F0VmFsO1xuICAgIH0gLy8gTm9ybWFsaXplIGZpbHRlciwgY29udmVydCB0byBmaXhlZCBwb2ludCBhbmQgYWNjdW11bGF0ZSBjb252ZXJzaW9uIGVycm9yXG5cblxuICAgIGZpbHRlclRvdGFsID0gMDtcblxuICAgIGZvciAoaWR4ID0gMDsgaWR4IDwgZmxvYXRGaWx0ZXIubGVuZ3RoOyBpZHgrKykge1xuICAgICAgZmlsdGVyVmFsID0gZmxvYXRGaWx0ZXJbaWR4XSAvIHRvdGFsO1xuICAgICAgZmlsdGVyVG90YWwgKz0gZmlsdGVyVmFsO1xuICAgICAgZnhwRmlsdGVyW2lkeF0gPSB0b0ZpeGVkUG9pbnQoZmlsdGVyVmFsKTtcbiAgICB9IC8vIENvbXBlbnNhdGUgbm9ybWFsaXphdGlvbiBlcnJvciwgdG8gbWluaW1pemUgYnJpZ2h0bmVzcyBkcmlmdFxuXG5cbiAgICBmeHBGaWx0ZXJbZGVzdFNpemUgPj4gMV0gKz0gdG9GaXhlZFBvaW50KDEuMCAtIGZpbHRlclRvdGFsKTsgLy9cbiAgICAvLyBOb3cgcGFjayBmaWx0ZXIgdG8gdXNlYWJsZSBmb3JtXG4gICAgLy9cbiAgICAvLyAxLiBUcmltIGhlYWRpbmcgYW5kIHRhaWxpbmcgemVybyB2YWx1ZXMsIGFuZCBjb21wZW5zYXRlIHNoaXRmL2xlbmd0aFxuICAgIC8vIDIuIFB1dCBhbGwgdG8gc2luZ2xlIGFycmF5IGluIHRoaXMgZm9ybWF0OlxuICAgIC8vXG4gICAgLy8gICAgWyBwb3Mgc2hpZnQsIGRhdGEgbGVuZ3RoLCB2YWx1ZTEsIHZhbHVlMiwgdmFsdWUzLCAuLi4gXVxuICAgIC8vXG5cbiAgICBsZWZ0Tm90RW1wdHkgPSAwO1xuXG4gICAgd2hpbGUgKGxlZnROb3RFbXB0eSA8IGZ4cEZpbHRlci5sZW5ndGggJiYgZnhwRmlsdGVyW2xlZnROb3RFbXB0eV0gPT09IDApIHtcbiAgICAgIGxlZnROb3RFbXB0eSsrO1xuICAgIH1cblxuICAgIGlmIChsZWZ0Tm90RW1wdHkgPCBmeHBGaWx0ZXIubGVuZ3RoKSB7XG4gICAgICByaWdodE5vdEVtcHR5ID0gZnhwRmlsdGVyLmxlbmd0aCAtIDE7XG5cbiAgICAgIHdoaWxlIChyaWdodE5vdEVtcHR5ID4gMCAmJiBmeHBGaWx0ZXJbcmlnaHROb3RFbXB0eV0gPT09IDApIHtcbiAgICAgICAgcmlnaHROb3RFbXB0eS0tO1xuICAgICAgfVxuXG4gICAgICBmaWx0ZXJTaGlmdCA9IHNyY0ZpcnN0ICsgbGVmdE5vdEVtcHR5O1xuICAgICAgZmlsdGVyU2l6ZSA9IHJpZ2h0Tm90RW1wdHkgLSBsZWZ0Tm90RW1wdHkgKyAxO1xuICAgICAgcGFja2VkRmlsdGVyW3BhY2tlZEZpbHRlclB0cisrXSA9IGZpbHRlclNoaWZ0OyAvLyBzaGlmdFxuXG4gICAgICBwYWNrZWRGaWx0ZXJbcGFja2VkRmlsdGVyUHRyKytdID0gZmlsdGVyU2l6ZTsgLy8gc2l6ZVxuXG4gICAgICBpZiAoIXNsb3dDb3B5KSB7XG4gICAgICAgIHBhY2tlZEZpbHRlci5zZXQoZnhwRmlsdGVyLnN1YmFycmF5KGxlZnROb3RFbXB0eSwgcmlnaHROb3RFbXB0eSArIDEpLCBwYWNrZWRGaWx0ZXJQdHIpO1xuICAgICAgICBwYWNrZWRGaWx0ZXJQdHIgKz0gZmlsdGVyU2l6ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGZhbGxiYWNrIGZvciBvbGQgSUUgPCAxMSwgd2l0aG91dCBzdWJhcnJheS9zZXQgbWV0aG9kc1xuICAgICAgICBmb3IgKGlkeCA9IGxlZnROb3RFbXB0eTsgaWR4IDw9IHJpZ2h0Tm90RW1wdHk7IGlkeCsrKSB7XG4gICAgICAgICAgcGFja2VkRmlsdGVyW3BhY2tlZEZpbHRlclB0cisrXSA9IGZ4cEZpbHRlcltpZHhdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHplcm8gZGF0YSwgd3JpdGUgaGVhZGVyIG9ubHlcbiAgICAgIHBhY2tlZEZpbHRlcltwYWNrZWRGaWx0ZXJQdHIrK10gPSAwOyAvLyBzaGlmdFxuXG4gICAgICBwYWNrZWRGaWx0ZXJbcGFja2VkRmlsdGVyUHRyKytdID0gMDsgLy8gc2l6ZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYWNrZWRGaWx0ZXI7XG59O1xuXG59LHtcIi4vcmVzaXplX2ZpbHRlcl9pbmZvXCI6N31dLDc6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLy8gRmlsdGVyIGRlZmluaXRpb25zIHRvIGJ1aWxkIHRhYmxlcyBmb3Jcbi8vIHJlc2l6aW5nIGNvbnZvbHZlcnMuXG4vL1xuLy8gUHJlc2V0cyBmb3IgcXVhbGl0eSAwLi4zLiBGaWx0ZXIgZnVuY3Rpb25zICsgd2luZG93IHNpemVcbi8vXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gW3tcbiAgLy8gTmVhcmVzdCBuZWlib3IgKEJveClcbiAgd2luOiAwLjUsXG4gIGZpbHRlcjogZnVuY3Rpb24gZmlsdGVyKHgpIHtcbiAgICByZXR1cm4geCA+PSAtMC41ICYmIHggPCAwLjUgPyAxLjAgOiAwLjA7XG4gIH1cbn0sIHtcbiAgLy8gSGFtbWluZ1xuICB3aW46IDEuMCxcbiAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoeCkge1xuICAgIGlmICh4IDw9IC0xLjAgfHwgeCA+PSAxLjApIHtcbiAgICAgIHJldHVybiAwLjA7XG4gICAgfVxuXG4gICAgaWYgKHggPiAtMS4xOTIwOTI5MEUtMDcgJiYgeCA8IDEuMTkyMDkyOTBFLTA3KSB7XG4gICAgICByZXR1cm4gMS4wO1xuICAgIH1cblxuICAgIHZhciB4cGkgPSB4ICogTWF0aC5QSTtcbiAgICByZXR1cm4gTWF0aC5zaW4oeHBpKSAvIHhwaSAqICgwLjU0ICsgMC40NiAqIE1hdGguY29zKHhwaSAvIDEuMCkpO1xuICB9XG59LCB7XG4gIC8vIExhbmN6b3MsIHdpbiA9IDJcbiAgd2luOiAyLjAsXG4gIGZpbHRlcjogZnVuY3Rpb24gZmlsdGVyKHgpIHtcbiAgICBpZiAoeCA8PSAtMi4wIHx8IHggPj0gMi4wKSB7XG4gICAgICByZXR1cm4gMC4wO1xuICAgIH1cblxuICAgIGlmICh4ID4gLTEuMTkyMDkyOTBFLTA3ICYmIHggPCAxLjE5MjA5MjkwRS0wNykge1xuICAgICAgcmV0dXJuIDEuMDtcbiAgICB9XG5cbiAgICB2YXIgeHBpID0geCAqIE1hdGguUEk7XG4gICAgcmV0dXJuIE1hdGguc2luKHhwaSkgLyB4cGkgKiBNYXRoLnNpbih4cGkgLyAyLjApIC8gKHhwaSAvIDIuMCk7XG4gIH1cbn0sIHtcbiAgLy8gTGFuY3pvcywgd2luID0gM1xuICB3aW46IDMuMCxcbiAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoeCkge1xuICAgIGlmICh4IDw9IC0zLjAgfHwgeCA+PSAzLjApIHtcbiAgICAgIHJldHVybiAwLjA7XG4gICAgfVxuXG4gICAgaWYgKHggPiAtMS4xOTIwOTI5MEUtMDcgJiYgeCA8IDEuMTkyMDkyOTBFLTA3KSB7XG4gICAgICByZXR1cm4gMS4wO1xuICAgIH1cblxuICAgIHZhciB4cGkgPSB4ICogTWF0aC5QSTtcbiAgICByZXR1cm4gTWF0aC5zaW4oeHBpKSAvIHhwaSAqIE1hdGguc2luKHhwaSAvIDMuMCkgLyAoeHBpIC8gMy4wKTtcbiAgfVxufV07XG5cbn0se31dLDg6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3JlYXRlRmlsdGVycyA9IF9kZXJlcV8oJy4vcmVzaXplX2ZpbHRlcl9nZW4nKTtcblxuZnVuY3Rpb24gcmVzZXRBbHBoYShkc3QsIHdpZHRoLCBoZWlnaHQpIHtcbiAgdmFyIHB0ciA9IDMsXG4gICAgICBsZW4gPSB3aWR0aCAqIGhlaWdodCAqIDQgfCAwO1xuXG4gIHdoaWxlIChwdHIgPCBsZW4pIHtcbiAgICBkc3RbcHRyXSA9IDB4RkY7XG4gICAgcHRyID0gcHRyICsgNCB8IDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gYXNVaW50OEFycmF5KHNyYykge1xuICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoc3JjLmJ1ZmZlciwgMCwgc3JjLmJ5dGVMZW5ndGgpO1xufVxuXG52YXIgSVNfTEUgPSB0cnVlOyAvLyBzaG91bGQgbm90IGNyYXNoIGV2ZXJ5dGhpbmcgb24gbW9kdWxlIGxvYWQgaW4gb2xkIGJyb3dzZXJzXG5cbnRyeSB7XG4gIElTX0xFID0gbmV3IFVpbnQzMkFycmF5KG5ldyBVaW50OEFycmF5KFsxLCAwLCAwLCAwXSkuYnVmZmVyKVswXSA9PT0gMTtcbn0gY2F0Y2ggKF9fKSB7fVxuXG5mdW5jdGlvbiBjb3B5SW50MTZhc0xFKHNyYywgdGFyZ2V0LCB0YXJnZXRfb2Zmc2V0KSB7XG4gIGlmIChJU19MRSkge1xuICAgIHRhcmdldC5zZXQoYXNVaW50OEFycmF5KHNyYyksIHRhcmdldF9vZmZzZXQpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvciAodmFyIHB0ciA9IHRhcmdldF9vZmZzZXQsIGkgPSAwOyBpIDwgc3JjLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGRhdGEgPSBzcmNbaV07XG4gICAgdGFyZ2V0W3B0cisrXSA9IGRhdGEgJiAweEZGO1xuICAgIHRhcmdldFtwdHIrK10gPSBkYXRhID4+IDggJiAweEZGO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcmVzaXplX3dhc20ob3B0aW9ucykge1xuICB2YXIgc3JjID0gb3B0aW9ucy5zcmM7XG4gIHZhciBzcmNXID0gb3B0aW9ucy53aWR0aDtcbiAgdmFyIHNyY0ggPSBvcHRpb25zLmhlaWdodDtcbiAgdmFyIGRlc3RXID0gb3B0aW9ucy50b1dpZHRoO1xuICB2YXIgZGVzdEggPSBvcHRpb25zLnRvSGVpZ2h0O1xuICB2YXIgc2NhbGVYID0gb3B0aW9ucy5zY2FsZVggfHwgb3B0aW9ucy50b1dpZHRoIC8gb3B0aW9ucy53aWR0aDtcbiAgdmFyIHNjYWxlWSA9IG9wdGlvbnMuc2NhbGVZIHx8IG9wdGlvbnMudG9IZWlnaHQgLyBvcHRpb25zLmhlaWdodDtcbiAgdmFyIG9mZnNldFggPSBvcHRpb25zLm9mZnNldFggfHwgMC4wO1xuICB2YXIgb2Zmc2V0WSA9IG9wdGlvbnMub2Zmc2V0WSB8fCAwLjA7XG4gIHZhciBkZXN0ID0gb3B0aW9ucy5kZXN0IHx8IG5ldyBVaW50OEFycmF5KGRlc3RXICogZGVzdEggKiA0KTtcbiAgdmFyIHF1YWxpdHkgPSB0eXBlb2Ygb3B0aW9ucy5xdWFsaXR5ID09PSAndW5kZWZpbmVkJyA/IDMgOiBvcHRpb25zLnF1YWxpdHk7XG4gIHZhciBhbHBoYSA9IG9wdGlvbnMuYWxwaGEgfHwgZmFsc2U7XG4gIHZhciBmaWx0ZXJzWCA9IGNyZWF0ZUZpbHRlcnMocXVhbGl0eSwgc3JjVywgZGVzdFcsIHNjYWxlWCwgb2Zmc2V0WCksXG4gICAgICBmaWx0ZXJzWSA9IGNyZWF0ZUZpbHRlcnMocXVhbGl0eSwgc3JjSCwgZGVzdEgsIHNjYWxlWSwgb2Zmc2V0WSk7IC8vIGRlc3RpbmF0aW9uIGlzIDAgdG9vLlxuXG4gIHZhciBzcmNfb2Zmc2V0ID0gMDsgLy8gYnVmZmVyIGJldHdlZW4gY29udm9sdmUgcGFzc2VzXG5cbiAgdmFyIHRtcF9vZmZzZXQgPSB0aGlzLl9fYWxpZ24oc3JjX29mZnNldCArIE1hdGgubWF4KHNyYy5ieXRlTGVuZ3RoLCBkZXN0LmJ5dGVMZW5ndGgpKTtcblxuICB2YXIgZmlsdGVyc1hfb2Zmc2V0ID0gdGhpcy5fX2FsaWduKHRtcF9vZmZzZXQgKyBzcmNIICogZGVzdFcgKiA0KTtcblxuICB2YXIgZmlsdGVyc1lfb2Zmc2V0ID0gdGhpcy5fX2FsaWduKGZpbHRlcnNYX29mZnNldCArIGZpbHRlcnNYLmJ5dGVMZW5ndGgpO1xuXG4gIHZhciBhbGxvY19ieXRlcyA9IGZpbHRlcnNZX29mZnNldCArIGZpbHRlcnNZLmJ5dGVMZW5ndGg7XG5cbiAgdmFyIGluc3RhbmNlID0gdGhpcy5fX2luc3RhbmNlKCdyZXNpemUnLCBhbGxvY19ieXRlcyk7IC8vXG4gIC8vIEZpbGwgbWVtb3J5IGJsb2NrIHdpdGggZGF0YSB0byBwcm9jZXNzXG4gIC8vXG5cblxuICB2YXIgbWVtID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5fX21lbW9yeS5idWZmZXIpO1xuICB2YXIgbWVtMzIgPSBuZXcgVWludDMyQXJyYXkodGhpcy5fX21lbW9yeS5idWZmZXIpOyAvLyAzMi1iaXQgY29weSBpcyBtdWNoIGZhc3RlciBpbiBjaHJvbWVcblxuICB2YXIgc3JjMzIgPSBuZXcgVWludDMyQXJyYXkoc3JjLmJ1ZmZlcik7XG4gIG1lbTMyLnNldChzcmMzMik7IC8vIFdlIHNob3VsZCBndWFyYW50ZWUgTEUgYnl0ZXMgb3JkZXIuIEZpbHRlcnMgYXJlIG5vdCBiaWcsIHNvXG4gIC8vIHNwZWVkIGRpZmZlcmVuY2UgaXMgbm90IHNpZ25pZmljYW50IHZzIGRpcmVjdCAuc2V0KClcblxuICBjb3B5SW50MTZhc0xFKGZpbHRlcnNYLCBtZW0sIGZpbHRlcnNYX29mZnNldCk7XG4gIGNvcHlJbnQxNmFzTEUoZmlsdGVyc1ksIG1lbSwgZmlsdGVyc1lfb2Zmc2V0KTsgLy9cbiAgLy8gTm93IGNhbGwgd2ViYXNzZW1ibHkgbWV0aG9kXG4gIC8vIGVtc2RrIGRvZXMgbWV0aG9kIG5hbWVzIHdpdGggJ18nXG5cbiAgdmFyIGZuID0gaW5zdGFuY2UuZXhwb3J0cy5jb252b2x2ZUhWIHx8IGluc3RhbmNlLmV4cG9ydHMuX2NvbnZvbHZlSFY7XG4gIGZuKGZpbHRlcnNYX29mZnNldCwgZmlsdGVyc1lfb2Zmc2V0LCB0bXBfb2Zmc2V0LCBzcmNXLCBzcmNILCBkZXN0VywgZGVzdEgpOyAvL1xuICAvLyBDb3B5IGRhdGEgYmFjayB0byB0eXBlZCBhcnJheVxuICAvL1xuICAvLyAzMi1iaXQgY29weSBpcyBtdWNoIGZhc3RlciBpbiBjaHJvbWVcblxuICB2YXIgZGVzdDMyID0gbmV3IFVpbnQzMkFycmF5KGRlc3QuYnVmZmVyKTtcbiAgZGVzdDMyLnNldChuZXcgVWludDMyQXJyYXkodGhpcy5fX21lbW9yeS5idWZmZXIsIDAsIGRlc3RIICogZGVzdFcpKTsgLy8gVGhhdCdzIGZhc3RlciB0aGFuIGRvaW5nIGNoZWNrcyBpbiBjb252b2x2ZXIuXG4gIC8vICEhISBOb3RlLCBjYW52YXMgZGF0YSBpcyBub3QgcHJlbXVsdGlwbGVkLiBXZSBkb24ndCBuZWVkIG90aGVyXG4gIC8vIGFscGhhIGNvcnJlY3Rpb25zLlxuXG4gIGlmICghYWxwaGEpIHJlc2V0QWxwaGEoZGVzdCwgZGVzdFcsIGRlc3RIKTtcbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG59LHtcIi4vcmVzaXplX2ZpbHRlcl9nZW5cIjo2fV0sOTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBuYW1lOiAndW5zaGFycF9tYXNrJyxcbiAgZm46IF9kZXJlcV8oJy4vdW5zaGFycF9tYXNrJyksXG4gIHdhc21fZm46IF9kZXJlcV8oJy4vdW5zaGFycF9tYXNrX3dhc20nKSxcbiAgd2FzbV9zcmM6IF9kZXJlcV8oJy4vdW5zaGFycF9tYXNrX3dhc21fYmFzZTY0Jylcbn07XG5cbn0se1wiLi91bnNoYXJwX21hc2tcIjoxMCxcIi4vdW5zaGFycF9tYXNrX3dhc21cIjoxMSxcIi4vdW5zaGFycF9tYXNrX3dhc21fYmFzZTY0XCI6MTJ9XSwxMDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBVbnNoYXJwIG1hc2sgZmlsdGVyXG4vL1xuLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjMzMjI4MjAvMTAzMTgwNFxuLy8gVVNNKE8pID0gTyArICgyICogKEFtb3VudCAvIDEwMCkgKiAoTyAtIEdCKSlcbi8vIEdCIC0gZ2F1c3NpYW4gYmx1ci5cbi8vXG4vLyBJbWFnZSBpcyBjb252ZXJ0ZWQgZnJvbSBSR0IgdG8gSFNWLCB1bnNoYXJwIG1hc2sgaXMgYXBwbGllZCB0byB0aGVcbi8vIGJyaWdodG5lc3MgY2hhbm5lbCBhbmQgdGhlbiBpbWFnZSBpcyBjb252ZXJ0ZWQgYmFjayB0byBSR0IuXG4vL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgZ2x1cl9tb25vMTYgPSBfZGVyZXFfKCdnbHVyL21vbm8xNicpO1xuXG5mdW5jdGlvbiBoc3ZfdjE2KGltZywgd2lkdGgsIGhlaWdodCkge1xuICB2YXIgc2l6ZSA9IHdpZHRoICogaGVpZ2h0O1xuICB2YXIgb3V0ID0gbmV3IFVpbnQxNkFycmF5KHNpemUpO1xuICB2YXIgciwgZywgYiwgbWF4O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgciA9IGltZ1s0ICogaV07XG4gICAgZyA9IGltZ1s0ICogaSArIDFdO1xuICAgIGIgPSBpbWdbNCAqIGkgKyAyXTtcbiAgICBtYXggPSByID49IGcgJiYgciA+PSBiID8gciA6IGcgPj0gYiAmJiBnID49IHIgPyBnIDogYjtcbiAgICBvdXRbaV0gPSBtYXggPDwgODtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gdW5zaGFycChpbWcsIHdpZHRoLCBoZWlnaHQsIGFtb3VudCwgcmFkaXVzLCB0aHJlc2hvbGQpIHtcbiAgdmFyIHYxLCB2Miwgdm11bDtcbiAgdmFyIGRpZmYsIGlUaW1lczQ7XG5cbiAgaWYgKGFtb3VudCA9PT0gMCB8fCByYWRpdXMgPCAwLjUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAocmFkaXVzID4gMi4wKSB7XG4gICAgcmFkaXVzID0gMi4wO1xuICB9XG5cbiAgdmFyIGJyaWdodG5lc3MgPSBoc3ZfdjE2KGltZywgd2lkdGgsIGhlaWdodCk7XG4gIHZhciBibHVyZWQgPSBuZXcgVWludDE2QXJyYXkoYnJpZ2h0bmVzcyk7IC8vIGNvcHksIGJlY2F1c2UgYmx1ciBtb2RpZnkgc3JjXG5cbiAgZ2x1cl9tb25vMTYoYmx1cmVkLCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpO1xuICB2YXIgYW1vdW50RnAgPSBhbW91bnQgLyAxMDAgKiAweDEwMDAgKyAwLjUgfCAwO1xuICB2YXIgdGhyZXNob2xkRnAgPSB0aHJlc2hvbGQgPDwgODtcbiAgdmFyIHNpemUgPSB3aWR0aCAqIGhlaWdodDtcbiAgLyogZXNsaW50LWRpc2FibGUgaW5kZW50ICovXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICB2MSA9IGJyaWdodG5lc3NbaV07XG4gICAgZGlmZiA9IHYxIC0gYmx1cmVkW2ldO1xuXG4gICAgaWYgKE1hdGguYWJzKGRpZmYpID49IHRocmVzaG9sZEZwKSB7XG4gICAgICAvLyBhZGQgdW5zaGFycCBtYXNrIHRvIHRoZSBicmlnaHRuZXNzIGNoYW5uZWxcbiAgICAgIHYyID0gdjEgKyAoYW1vdW50RnAgKiBkaWZmICsgMHg4MDAgPj4gMTIpOyAvLyBCb3RoIHYxIGFuZCB2MiBhcmUgd2l0aGluIFswLjAgLi4gMjU1LjBdICgwMDAwLUZGMDApIHJhbmdlLCBuZXZlciBnb2luZyBpbnRvXG4gICAgICAvLyBbMjU1LjAwMyAuLiAyNTUuOTk2XSAoRkYwMS1GRkZGKS4gVGhpcyBhbGxvd3MgdG8gcm91bmQgdGhpcyB2YWx1ZSBhcyAoeCsuNSl8MFxuICAgICAgLy8gbGF0ZXIgd2l0aG91dCBvdmVyZmxvd2luZy5cblxuICAgICAgdjIgPSB2MiA+IDB4ZmYwMCA/IDB4ZmYwMCA6IHYyO1xuICAgICAgdjIgPSB2MiA8IDB4MDAwMCA/IDB4MDAwMCA6IHYyOyAvLyBBdm9pZCBkaXZpc2lvbiBieSAwLiBWPTAgbWVhbnMgcmdiKDAsMCwwKSwgdW5zaGFycCB3aXRoIHVuc2hhcnBBbW91bnQ+MCBjYW5ub3RcbiAgICAgIC8vIGNoYW5nZSB0aGlzIHZhbHVlIChiZWNhdXNlIGRpZmYgYmV0d2VlbiBjb2xvcnMgZ2V0cyBpbmZsYXRlZCksIHNvIG5vIG5lZWQgdG8gdmVyaWZ5IGNvcnJlY3RuZXNzLlxuXG4gICAgICB2MSA9IHYxICE9PSAwID8gdjEgOiAxOyAvLyBNdWx0aXBseWluZyBWIGluIEhTViBtb2RlbCBieSBhIGNvbnN0YW50IGlzIGVxdWl2YWxlbnQgdG8gbXVsdGlwbHlpbmcgZWFjaCBjb21wb25lbnRcbiAgICAgIC8vIGluIFJHQiBieSB0aGUgc2FtZSBjb25zdGFudCAoc2FtZSBmb3IgSFNMKSwgc2VlIGFsc286XG4gICAgICAvLyBodHRwczovL2JlZXNidXp6LmJpei9jb2RlLzE2LWhzdi1jb2xvci10cmFuc2Zvcm1zXG5cbiAgICAgIHZtdWwgPSAodjIgPDwgMTIpIC8gdjEgfCAwOyAvLyBSZXN1bHQgd2lsbCBiZSBpbiBbMC4uMjU1XSByYW5nZSBiZWNhdXNlOlxuICAgICAgLy8gIC0gYWxsIG51bWJlcnMgYXJlIHBvc2l0aXZlXG4gICAgICAvLyAgLSByLGcsYiA8PSAodjEvMjU2KVxuICAgICAgLy8gIC0gcixnLGIsKHYxLzI1NiksKHYyLzI1NikgPD0gMjU1XG4gICAgICAvLyBTbyBoaWdoZXN0IHRoaXMgbnVtYmVyIGNhbiBnZXQgaXMgWCoyNTUvWCswLjU9MjU1LjUgd2hpY2ggaXMgPCAyNTYgYW5kIHJvdW5kcyBkb3duLlxuXG4gICAgICBpVGltZXM0ID0gaSAqIDQ7XG4gICAgICBpbWdbaVRpbWVzNF0gPSBpbWdbaVRpbWVzNF0gKiB2bXVsICsgMHg4MDAgPj4gMTI7IC8vIFJcblxuICAgICAgaW1nW2lUaW1lczQgKyAxXSA9IGltZ1tpVGltZXM0ICsgMV0gKiB2bXVsICsgMHg4MDAgPj4gMTI7IC8vIEdcblxuICAgICAgaW1nW2lUaW1lczQgKyAyXSA9IGltZ1tpVGltZXM0ICsgMl0gKiB2bXVsICsgMHg4MDAgPj4gMTI7IC8vIEJcbiAgICB9XG4gIH1cbn07XG5cbn0se1wiZ2x1ci9tb25vMTZcIjoxOH1dLDExOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB1bnNoYXJwKGltZywgd2lkdGgsIGhlaWdodCwgYW1vdW50LCByYWRpdXMsIHRocmVzaG9sZCkge1xuICBpZiAoYW1vdW50ID09PSAwIHx8IHJhZGl1cyA8IDAuNSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChyYWRpdXMgPiAyLjApIHtcbiAgICByYWRpdXMgPSAyLjA7XG4gIH1cblxuICB2YXIgcGl4ZWxzID0gd2lkdGggKiBoZWlnaHQ7XG4gIHZhciBpbWdfYnl0ZXNfY250ID0gcGl4ZWxzICogNDtcbiAgdmFyIGhzdl9ieXRlc19jbnQgPSBwaXhlbHMgKiAyO1xuICB2YXIgYmx1cl9ieXRlc19jbnQgPSBwaXhlbHMgKiAyO1xuICB2YXIgYmx1cl9saW5lX2J5dGVfY250ID0gTWF0aC5tYXgod2lkdGgsIGhlaWdodCkgKiA0OyAvLyBmbG9hdDMyIGFycmF5XG5cbiAgdmFyIGJsdXJfY29lZmZzX2J5dGVfY250ID0gOCAqIDQ7IC8vIGZsb2F0MzIgYXJyYXlcblxuICB2YXIgaW1nX29mZnNldCA9IDA7XG4gIHZhciBoc3Zfb2Zmc2V0ID0gaW1nX2J5dGVzX2NudDtcbiAgdmFyIGJsdXJfb2Zmc2V0ID0gaHN2X29mZnNldCArIGhzdl9ieXRlc19jbnQ7XG4gIHZhciBibHVyX3RtcF9vZmZzZXQgPSBibHVyX29mZnNldCArIGJsdXJfYnl0ZXNfY250O1xuICB2YXIgYmx1cl9saW5lX29mZnNldCA9IGJsdXJfdG1wX29mZnNldCArIGJsdXJfYnl0ZXNfY250O1xuICB2YXIgYmx1cl9jb2VmZnNfb2Zmc2V0ID0gYmx1cl9saW5lX29mZnNldCArIGJsdXJfbGluZV9ieXRlX2NudDtcblxuICB2YXIgaW5zdGFuY2UgPSB0aGlzLl9faW5zdGFuY2UoJ3Vuc2hhcnBfbWFzaycsIGltZ19ieXRlc19jbnQgKyBoc3ZfYnl0ZXNfY250ICsgYmx1cl9ieXRlc19jbnQgKiAyICsgYmx1cl9saW5lX2J5dGVfY250ICsgYmx1cl9jb2VmZnNfYnl0ZV9jbnQsIHtcbiAgICBleHA6IE1hdGguZXhwXG4gIH0pOyAvLyAzMi1iaXQgY29weSBpcyBtdWNoIGZhc3RlciBpbiBjaHJvbWVcblxuXG4gIHZhciBpbWczMiA9IG5ldyBVaW50MzJBcnJheShpbWcuYnVmZmVyKTtcbiAgdmFyIG1lbTMyID0gbmV3IFVpbnQzMkFycmF5KHRoaXMuX19tZW1vcnkuYnVmZmVyKTtcbiAgbWVtMzIuc2V0KGltZzMyKTsgLy8gSFNMXG5cbiAgdmFyIGZuID0gaW5zdGFuY2UuZXhwb3J0cy5oc3ZfdjE2IHx8IGluc3RhbmNlLmV4cG9ydHMuX2hzdl92MTY7XG4gIGZuKGltZ19vZmZzZXQsIGhzdl9vZmZzZXQsIHdpZHRoLCBoZWlnaHQpOyAvLyBCTFVSXG5cbiAgZm4gPSBpbnN0YW5jZS5leHBvcnRzLmJsdXJNb25vMTYgfHwgaW5zdGFuY2UuZXhwb3J0cy5fYmx1ck1vbm8xNjtcbiAgZm4oaHN2X29mZnNldCwgYmx1cl9vZmZzZXQsIGJsdXJfdG1wX29mZnNldCwgYmx1cl9saW5lX29mZnNldCwgYmx1cl9jb2VmZnNfb2Zmc2V0LCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpOyAvLyBVTlNIQVJQXG5cbiAgZm4gPSBpbnN0YW5jZS5leHBvcnRzLnVuc2hhcnAgfHwgaW5zdGFuY2UuZXhwb3J0cy5fdW5zaGFycDtcbiAgZm4oaW1nX29mZnNldCwgaW1nX29mZnNldCwgaHN2X29mZnNldCwgYmx1cl9vZmZzZXQsIHdpZHRoLCBoZWlnaHQsIGFtb3VudCwgdGhyZXNob2xkKTsgLy8gMzItYml0IGNvcHkgaXMgbXVjaCBmYXN0ZXIgaW4gY2hyb21lXG5cbiAgaW1nMzIuc2V0KG5ldyBVaW50MzJBcnJheSh0aGlzLl9fbWVtb3J5LmJ1ZmZlciwgMCwgcGl4ZWxzKSk7XG59O1xuXG59LHt9XSwxMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBUaGlzIGlzIGF1dG9nZW5lcmF0ZWQgZmlsZSBmcm9tIG1hdGgud2FzbSwgZG9uJ3QgZWRpdC5cbi8vXG4ndXNlIHN0cmljdCc7XG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cbm1vZHVsZS5leHBvcnRzID0gJ0FHRnpiUUVBQUFBQURBWmtlV3hwYm1zQUFBQUFBQUUwQjJBQUFHQUVmMzkvZndCZ0JuOS9mMzkvZndCZ0NIOS9mMzkvZjM5L0FHQUlmMzkvZjM5L2YzMEFZQUo5ZndCZ0FYd0JmQUlaQWdObGJuWURaWGh3QUFZRFpXNTJCbTFsYlc5eWVRSUFBQU1IQmdBRkFnUUJBd1lHQVg4QVFRQUxCNG9CQ0JGZlgzZGhjMjFmWTJGc2JGOWpkRzl5Y3dBQkZsOWZZblZwYkdSZloyRjFjM05wWVc1ZlkyOWxabk1BQWc1ZlgyZGhkWE56TVRaZmJHbHVaUUFEQ21Kc2RYSk5iMjV2TVRZQUJBZG9jM1pmZGpFMkFBVUhkVzV6YUdGeWNBQUdERjlmWkhOdlgyaGhibVJzWlFNQUdGOWZkMkZ6YlY5aGNIQnNlVjlrWVhSaFgzSmxiRzlqY3dBQkNzVU1CZ01BQVF2V0FRRUhmQ0FCUk51R3VrT0NHdnMvSUFDN295SUNSQUFBQUFBQUFBREFvaEFBSWdXMmpEZ0NGQ0FCSUFLYUVBQWlBeUFEb0NJR3RqZ0NFQ0FCUkFBQUFBQUFBUEEvSUFPaElnUWdCS0lnQXlBQ0lBS2dva1FBQUFBQUFBRHdQNkFnQmFHaklnUzJPQUlBSUFFZ0JTQUVtcUlpQjdZNEFnd2dBU0FESUFKRUFBQUFBQUFBOEQrZ0lBU2lvaUlJdGpnQ0NDQUJJQU1nQWtRQUFBQUFBQUR3djZBZ0JLS2lJZ0syT0FJRUlBRWdCeUFJb0NBRlJBQUFBQUFBQVBBL0lBYWhvQ0lEbzdZNEFod2dBU0FFSUFLZ0lBT2p0amdDR0F1R0JRTUdmd2w4QW4wZ0F5b0NEQ0VWSUFNcUFnZ2hGaUFES2dJVXV5RVJJQU1xQWhDN0lSQUNRQ0FFUVFGcklnaEJBRWdpQ1FSQUlBSWhCeUFBSVFZTUFRc2dBaUFBTHdFQXVDSVBJQU1xQWhpN29pSU1JQkdpSWcwZ0RDQVFvaUFQSUFNcUFnUzdJaE9pSWhRZ0F5b0NBTHNpRWlBUG9xQ2dvQ0lPdGpnQ0FDQUNRUVJxSVFjZ0FFRUNhaUVHSUFoRkRRQWdDRUVCSUFoQkFVZ2JJZ3BCZjNNaEN3Si9JQVFnQ210QkFYRkZCRUFnRGlFTklBZ01BUXNnQWlBTklBNGdFS0lnRkNBU0lBQXZBUUs0SWcraW9LQ2dJZzIyT0FJRUlBSkJDR29oQnlBQVFRUnFJUVlnRGlFTUlBUkJBbXNMSVFJZ0MwRUFJQVJyUmcwQUEwQWdCeUFNSUJHaUlBMGdFS0lnRHlBVG9pQVNJQVl2QVFDNElnNmlvS0NnSWd5Mk9BSUFJQWNnRFNBUm9pQU1JQkNpSUE0Z0U2SWdFaUFHTHdFQ3VDSVBvcUNnb0NJTnRqZ0NCQ0FIUVFocUlRY2dCa0VFYWlFR0lBSkJBa29oQUNBQ1FRSnJJUUlnQUEwQUN3c0NRQ0FKRFFBZ0FTQUZJQWhzUVFGMGFpSUFBbjhnQmtFQ2F5OEJBQ0lDdUNJTklCVzdJaEtpSUEwZ0Zyc2lFNktnSUEwZ0F5b0NITHVpSWd3Z0VLS2dJQXdnRWFLZ0lnOGdCMEVFYXlJSEtnSUF1NkFpRGtRQUFBQUFBQUR3UVdNZ0RrUUFBQUFBQUFBQUFHWnhCRUFnRHFzTUFRdEJBQXM3QVFBZ0NFVU5BQ0FHUVFScklRWkJBQ0FGYTBFQmRDRUJBMEFDZnlBTklCS2lJQUpCLy84RGNiZ2lEU0FUb3FBZ0R5SU9JQkNpb0NBTUlCR2lvQ0lQSUFkQkJHc2lCeW9DQUx1Z0lneEVBQUFBQUFBQThFRmpJQXhFQUFBQUFBQUFBQUJtY1FSQUlBeXJEQUVMUVFBTElRTWdCaThCQUNFQ0lBQWdBV29pQUNBRE93RUFJQVpCQW1zaEJpQUlRUUZLSVFNZ0RpRU1JQWhCQVdzaENDQUREUUFMQ3d2UkFnSUJmd2Q4QWtBZ0IwTUFBQUFBV3cwQUlBUkUyNGE2UTRJYSt6OGdCME1BQUFBL2w3dWpJZ2xFQUFBQUFBQUFBTUNpRUFBaURMYU1PQUlVSUFRZ0Nab1FBQ0lLSUFxZ0lnMjJPQUlRSUFSRUFBQUFBQUFBOEQ4Z0NxRWlDeUFMb2lBS0lBa2dDYUNpUkFBQUFBQUFBUEEvb0NBTW9hTWlDN1k0QWdBZ0JDQU1JQXVhb2lJT3RqZ0NEQ0FFSUFvZ0NVUUFBQUFBQUFEd1A2QWdDNktpSWcrMk9BSUlJQVFnQ2lBSlJBQUFBQUFBQVBDL29DQUxvcUlpQ2JZNEFnUWdCQ0FPSUErZ0lBeEVBQUFBQUFBQThEOGdEYUdnSWdxanRqZ0NIQ0FFSUFzZ0NhQWdDcU8yT0FJWUlBWUVRQU5BSUFBZ0JTQUliRUVCZEdvZ0FpQUlRUUYwYWlBRElBUWdCU0FHRUFNZ0NFRUJhaUlJSUFaSERRQUxDeUFGUlEwQVFRQWhDQU5BSUFJZ0JpQUliRUVCZEdvZ0FTQUlRUUYwYWlBRElBUWdCaUFGRUFNZ0NFRUJhaUlJSUFWSERRQUxDd3R4QVFOL0lBSWdBMndpQlFSQUEwQWdBU0FBS0FJQUlnUkJFSFpCL3dGeElnSWdBaUFFUVFoMlFmOEJjU0lESUFNZ0JFSC9BWEVpQkVrYklBSWdBMHNiSWdZZ0JpQUVJQUlnQkVzYklBTWdCRXNiUVFoME93RUFJQUZCQW1vaEFTQUFRUVJxSVFBZ0JVRUJheUlGRFFBTEN3dVpBZ0lEZndGOElBUWdCV3doQkFKL0lBYXpRd0FBZ0VXVVF3QUF5RUtWdTBRQUFBQUFBQURnUDZBaUM1bEVBQUFBQUFBQTRFRmpCRUFnQzZvTUFRdEJnSUNBZ0hnTElRVWdCQVJBSUFkQkNIUWhDVUVBSVFZRFFDQUpJQUlnQmtFQmRDSUhhaThCQUNJQklBTWdCMm92QVFCcklnY2dCMEVmZFNJSWFpQUljMDBFUUNBQUlBWkJBblFpQ0dvaUNpQUZJQWRzUVlBUWFrRU1kU0FCYWlJSFFZRCtBeUFIUVlEK0EwZ2JJZ2RCQUNBSFFRQktHMEVNZENBQlFRRWdBUnR1SWdFZ0NpMEFBR3hCZ0JCcVFReDJPZ0FBSUFBZ0NFRUJjbW9pQnlBQklBY3RBQUJzUVlBUWFrRU1kam9BQUNBQUlBaEJBbkpxSWdjZ0FTQUhMUUFBYkVHQUVHcEJESFk2QUFBTElBWkJBV29pQmlBRVJ3MEFDd3NMJztcblxufSx7fV0sMTM6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgR0NfSU5URVJWQUwgPSAxMDA7XG5cbmZ1bmN0aW9uIFBvb2woY3JlYXRlLCBpZGxlKSB7XG4gIHRoaXMuY3JlYXRlID0gY3JlYXRlO1xuICB0aGlzLmF2YWlsYWJsZSA9IFtdO1xuICB0aGlzLmFjcXVpcmVkID0ge307XG4gIHRoaXMubGFzdElkID0gMTtcbiAgdGhpcy50aW1lb3V0SWQgPSAwO1xuICB0aGlzLmlkbGUgPSBpZGxlIHx8IDIwMDA7XG59XG5cblBvb2wucHJvdG90eXBlLmFjcXVpcmUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgdmFyIHJlc291cmNlO1xuXG4gIGlmICh0aGlzLmF2YWlsYWJsZS5sZW5ndGggIT09IDApIHtcbiAgICByZXNvdXJjZSA9IHRoaXMuYXZhaWxhYmxlLnBvcCgpO1xuICB9IGVsc2Uge1xuICAgIHJlc291cmNlID0gdGhpcy5jcmVhdGUoKTtcbiAgICByZXNvdXJjZS5pZCA9IHRoaXMubGFzdElkKys7XG5cbiAgICByZXNvdXJjZS5yZWxlYXNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIF90aGlzLnJlbGVhc2UocmVzb3VyY2UpO1xuICAgIH07XG4gIH1cblxuICB0aGlzLmFjcXVpcmVkW3Jlc291cmNlLmlkXSA9IHJlc291cmNlO1xuICByZXR1cm4gcmVzb3VyY2U7XG59O1xuXG5Qb29sLnByb3RvdHlwZS5yZWxlYXNlID0gZnVuY3Rpb24gKHJlc291cmNlKSB7XG4gIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gIGRlbGV0ZSB0aGlzLmFjcXVpcmVkW3Jlc291cmNlLmlkXTtcbiAgcmVzb3VyY2UubGFzdFVzZWQgPSBEYXRlLm5vdygpO1xuICB0aGlzLmF2YWlsYWJsZS5wdXNoKHJlc291cmNlKTtcblxuICBpZiAodGhpcy50aW1lb3V0SWQgPT09IDApIHtcbiAgICB0aGlzLnRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIF90aGlzMi5nYygpO1xuICAgIH0sIEdDX0lOVEVSVkFMKTtcbiAgfVxufTtcblxuUG9vbC5wcm90b3R5cGUuZ2MgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gIHZhciBub3cgPSBEYXRlLm5vdygpO1xuICB0aGlzLmF2YWlsYWJsZSA9IHRoaXMuYXZhaWxhYmxlLmZpbHRlcihmdW5jdGlvbiAocmVzb3VyY2UpIHtcbiAgICBpZiAobm93IC0gcmVzb3VyY2UubGFzdFVzZWQgPiBfdGhpczMuaWRsZSkge1xuICAgICAgcmVzb3VyY2UuZGVzdHJveSgpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9KTtcblxuICBpZiAodGhpcy5hdmFpbGFibGUubGVuZ3RoICE9PSAwKSB7XG4gICAgdGhpcy50aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBfdGhpczMuZ2MoKTtcbiAgICB9LCBHQ19JTlRFUlZBTCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy50aW1lb3V0SWQgPSAwO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBvb2w7XG5cbn0se31dLDE0OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIEFkZCBpbnRlcm1lZGlhdGUgcmVzaXppbmcgc3RlcHMgd2hlbiBzY2FsaW5nIGRvd24gYnkgYSB2ZXJ5IGxhcmdlIGZhY3Rvci5cbi8vXG4vLyBGb3IgZXhhbXBsZSwgd2hlbiByZXNpemluZyAxMDAwMHgxMDAwMCBkb3duIHRvIDEweDEwLCBpdCdsbCByZXNpemUgaXQgdG9cbi8vIDMwMHgzMDAgZmlyc3QuXG4vL1xuLy8gSXQncyBuZWVkZWQgYmVjYXVzZSB0aWxlciBoYXMgaXNzdWVzIHdoZW4gdGhlIGVudGlyZSB0aWxlIGlzIHNjYWxlZCBkb3duXG4vLyB0byBhIGZldyBwaXhlbHMgKDEwMjRweCBzb3VyY2UgdGlsZSB3aXRoIGJvcmRlciBzaXplIDMgc2hvdWxkIHJlc3VsdCBpblxuLy8gYXQgbGVhc3QgMyszKzIgPSA4cHggdGFyZ2V0IHRpbGUsIHNvIG1heCBzY2FsZSBmYWN0b3IgaXMgMTI4IGhlcmUpLlxuLy9cbi8vIEFsc28sIGFkZGluZyBpbnRlcm1lZGlhdGUgc3RlcHMgY2FuIHNwZWVkIHVwIHByb2Nlc3NpbmcgaWYgd2UgdXNlIGxvd2VyXG4vLyBxdWFsaXR5IGFsZ29yaXRobXMgZm9yIGZpcnN0IHN0YWdlcy5cbi8vXG4ndXNlIHN0cmljdCc7IC8vIG1pbiBzaXplID0gMCByZXN1bHRzIGluIGluZmluaXRlIGxvb3AsXG4vLyBtaW4gc2l6ZSA9IDEgY2FuIGNvbnN1bWUgbGFyZ2UgYW1vdW50IG9mIG1lbW9yeVxuXG52YXIgTUlOX0lOTkVSX1RJTEVfU0laRSA9IDI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlU3RhZ2VzKGZyb21XaWR0aCwgZnJvbUhlaWdodCwgdG9XaWR0aCwgdG9IZWlnaHQsIHNyY1RpbGVTaXplLCBkZXN0VGlsZUJvcmRlcikge1xuICB2YXIgc2NhbGVYID0gdG9XaWR0aCAvIGZyb21XaWR0aDtcbiAgdmFyIHNjYWxlWSA9IHRvSGVpZ2h0IC8gZnJvbUhlaWdodDsgLy8gZGVyaXZlZCBmcm9tIGNyZWF0ZVJlZ2lvbnMgZXF1YXRpb246XG4gIC8vIGlubmVyVGlsZVdpZHRoID0gcGl4ZWxGbG9vcihzcmNUaWxlU2l6ZSAqIHNjYWxlWCkgLSAyICogZGVzdFRpbGVCb3JkZXI7XG5cbiAgdmFyIG1pblNjYWxlID0gKDIgKiBkZXN0VGlsZUJvcmRlciArIE1JTl9JTk5FUl9USUxFX1NJWkUgKyAxKSAvIHNyY1RpbGVTaXplOyAvLyByZWZ1c2UgdG8gc2NhbGUgaW1hZ2UgbXVsdGlwbGUgdGltZXMgYnkgbGVzcyB0aGFuIHR3aWNlIGVhY2ggdGltZSxcbiAgLy8gaXQgY291bGQgb25seSBoYXBwZW4gYmVjYXVzZSBvZiBpbnZhbGlkIG9wdGlvbnNcblxuICBpZiAobWluU2NhbGUgPiAwLjUpIHJldHVybiBbW3RvV2lkdGgsIHRvSGVpZ2h0XV07XG4gIHZhciBzdGFnZUNvdW50ID0gTWF0aC5jZWlsKE1hdGgubG9nKE1hdGgubWluKHNjYWxlWCwgc2NhbGVZKSkgLyBNYXRoLmxvZyhtaW5TY2FsZSkpOyAvLyBubyBhZGRpdGlvbmFsIHJlc2l6ZXMgYXJlIG5lY2Vzc2FyeSxcbiAgLy8gc3RhZ2VDb3VudCBjYW4gYmUgemVybyBvciBiZSBuZWdhdGl2ZSB3aGVuIGVubGFyZ2luZyB0aGUgaW1hZ2VcblxuICBpZiAoc3RhZ2VDb3VudCA8PSAxKSByZXR1cm4gW1t0b1dpZHRoLCB0b0hlaWdodF1dO1xuICB2YXIgcmVzdWx0ID0gW107XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdGFnZUNvdW50OyBpKyspIHtcbiAgICB2YXIgd2lkdGggPSBNYXRoLnJvdW5kKE1hdGgucG93KE1hdGgucG93KGZyb21XaWR0aCwgc3RhZ2VDb3VudCAtIGkgLSAxKSAqIE1hdGgucG93KHRvV2lkdGgsIGkgKyAxKSwgMSAvIHN0YWdlQ291bnQpKTtcbiAgICB2YXIgaGVpZ2h0ID0gTWF0aC5yb3VuZChNYXRoLnBvdyhNYXRoLnBvdyhmcm9tSGVpZ2h0LCBzdGFnZUNvdW50IC0gaSAtIDEpICogTWF0aC5wb3codG9IZWlnaHQsIGkgKyAxKSwgMSAvIHN0YWdlQ291bnQpKTtcbiAgICByZXN1bHQucHVzaChbd2lkdGgsIGhlaWdodF0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbn0se31dLDE1OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIFNwbGl0IG9yaWdpbmFsIGltYWdlIGludG8gbXVsdGlwbGUgMTAyNHgxMDI0IGNodW5rcyB0byByZWR1Y2UgbWVtb3J5IHVzYWdlXG4vLyAoaW1hZ2VzIGhhdmUgdG8gYmUgdW5wYWNrZWQgaW50byB0eXBlZCBhcnJheXMgZm9yIHJlc2l6aW5nKSBhbmQgYWxsb3dcbi8vIHBhcmFsbGVsIHByb2Nlc3Npbmcgb2YgbXVsdGlwbGUgdGlsZXMgYXQgYSB0aW1lLlxuLy9cbid1c2Ugc3RyaWN0Jztcbi8qXG4gKiBwaXhlbEZsb29yIGFuZCBwaXhlbENlaWwgYXJlIG1vZGlmaWVkIHZlcnNpb25zIG9mIE1hdGguZmxvb3IgYW5kIE1hdGguY2VpbFxuICogZnVuY3Rpb25zIHdoaWNoIHRha2UgaW50byBhY2NvdW50IGZsb2F0aW5nIHBvaW50IGFyaXRobWV0aWMgZXJyb3JzLlxuICogVGhvc2UgZXJyb3JzIGNhbiBjYXVzZSB1bmRlc2lyZWQgaW5jcmVtZW50cy9kZWNyZW1lbnRzIG9mIHNpemVzIGFuZCBvZmZzZXRzOlxuICogTWF0aC5jZWlsKDM2IC8gKDM2IC8gNTAwKSkgPSA1MDFcbiAqIHBpeGVsQ2VpbCgzNiAvICgzNiAvIDUwMCkpID0gNTAwXG4gKi9cblxudmFyIFBJWEVMX0VQU0lMT04gPSAxZS01O1xuXG5mdW5jdGlvbiBwaXhlbEZsb29yKHgpIHtcbiAgdmFyIG5lYXJlc3QgPSBNYXRoLnJvdW5kKHgpO1xuXG4gIGlmIChNYXRoLmFicyh4IC0gbmVhcmVzdCkgPCBQSVhFTF9FUFNJTE9OKSB7XG4gICAgcmV0dXJuIG5lYXJlc3Q7XG4gIH1cblxuICByZXR1cm4gTWF0aC5mbG9vcih4KTtcbn1cblxuZnVuY3Rpb24gcGl4ZWxDZWlsKHgpIHtcbiAgdmFyIG5lYXJlc3QgPSBNYXRoLnJvdW5kKHgpO1xuXG4gIGlmIChNYXRoLmFicyh4IC0gbmVhcmVzdCkgPCBQSVhFTF9FUFNJTE9OKSB7XG4gICAgcmV0dXJuIG5lYXJlc3Q7XG4gIH1cblxuICByZXR1cm4gTWF0aC5jZWlsKHgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZVJlZ2lvbnMob3B0aW9ucykge1xuICB2YXIgc2NhbGVYID0gb3B0aW9ucy50b1dpZHRoIC8gb3B0aW9ucy53aWR0aDtcbiAgdmFyIHNjYWxlWSA9IG9wdGlvbnMudG9IZWlnaHQgLyBvcHRpb25zLmhlaWdodDtcbiAgdmFyIGlubmVyVGlsZVdpZHRoID0gcGl4ZWxGbG9vcihvcHRpb25zLnNyY1RpbGVTaXplICogc2NhbGVYKSAtIDIgKiBvcHRpb25zLmRlc3RUaWxlQm9yZGVyO1xuICB2YXIgaW5uZXJUaWxlSGVpZ2h0ID0gcGl4ZWxGbG9vcihvcHRpb25zLnNyY1RpbGVTaXplICogc2NhbGVZKSAtIDIgKiBvcHRpb25zLmRlc3RUaWxlQm9yZGVyOyAvLyBwcmV2ZW50IGluZmluaXRlIGxvb3AsIHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlblxuXG4gIGlmIChpbm5lclRpbGVXaWR0aCA8IDEgfHwgaW5uZXJUaWxlSGVpZ2h0IDwgMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW50ZXJuYWwgZXJyb3IgaW4gcGljYTogdGFyZ2V0IHRpbGUgd2lkdGgvaGVpZ2h0IGlzIHRvbyBzbWFsbC4nKTtcbiAgfVxuXG4gIHZhciB4LCB5O1xuICB2YXIgaW5uZXJYLCBpbm5lclksIHRvVGlsZVdpZHRoLCB0b1RpbGVIZWlnaHQ7XG4gIHZhciB0aWxlcyA9IFtdO1xuICB2YXIgdGlsZTsgLy8gd2UgZ28gdG9wLXRvLWRvd24gaW5zdGVhZCBvZiBsZWZ0LXRvLXJpZ2h0IHRvIG1ha2UgaW1hZ2UgZGlzcGxheWVkIGZyb20gdG9wIHRvXG4gIC8vIGRvZXNuIGluIHRoZSBicm93c2VyXG5cbiAgZm9yIChpbm5lclkgPSAwOyBpbm5lclkgPCBvcHRpb25zLnRvSGVpZ2h0OyBpbm5lclkgKz0gaW5uZXJUaWxlSGVpZ2h0KSB7XG4gICAgZm9yIChpbm5lclggPSAwOyBpbm5lclggPCBvcHRpb25zLnRvV2lkdGg7IGlubmVyWCArPSBpbm5lclRpbGVXaWR0aCkge1xuICAgICAgeCA9IGlubmVyWCAtIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7XG5cbiAgICAgIGlmICh4IDwgMCkge1xuICAgICAgICB4ID0gMDtcbiAgICAgIH1cblxuICAgICAgdG9UaWxlV2lkdGggPSBpbm5lclggKyBpbm5lclRpbGVXaWR0aCArIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXIgLSB4O1xuXG4gICAgICBpZiAoeCArIHRvVGlsZVdpZHRoID49IG9wdGlvbnMudG9XaWR0aCkge1xuICAgICAgICB0b1RpbGVXaWR0aCA9IG9wdGlvbnMudG9XaWR0aCAtIHg7XG4gICAgICB9XG5cbiAgICAgIHkgPSBpbm5lclkgLSBvcHRpb25zLmRlc3RUaWxlQm9yZGVyO1xuXG4gICAgICBpZiAoeSA8IDApIHtcbiAgICAgICAgeSA9IDA7XG4gICAgICB9XG5cbiAgICAgIHRvVGlsZUhlaWdodCA9IGlubmVyWSArIGlubmVyVGlsZUhlaWdodCArIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXIgLSB5O1xuXG4gICAgICBpZiAoeSArIHRvVGlsZUhlaWdodCA+PSBvcHRpb25zLnRvSGVpZ2h0KSB7XG4gICAgICAgIHRvVGlsZUhlaWdodCA9IG9wdGlvbnMudG9IZWlnaHQgLSB5O1xuICAgICAgfVxuXG4gICAgICB0aWxlID0ge1xuICAgICAgICB0b1g6IHgsXG4gICAgICAgIHRvWTogeSxcbiAgICAgICAgdG9XaWR0aDogdG9UaWxlV2lkdGgsXG4gICAgICAgIHRvSGVpZ2h0OiB0b1RpbGVIZWlnaHQsXG4gICAgICAgIHRvSW5uZXJYOiBpbm5lclgsXG4gICAgICAgIHRvSW5uZXJZOiBpbm5lclksXG4gICAgICAgIHRvSW5uZXJXaWR0aDogaW5uZXJUaWxlV2lkdGgsXG4gICAgICAgIHRvSW5uZXJIZWlnaHQ6IGlubmVyVGlsZUhlaWdodCxcbiAgICAgICAgb2Zmc2V0WDogeCAvIHNjYWxlWCAtIHBpeGVsRmxvb3IoeCAvIHNjYWxlWCksXG4gICAgICAgIG9mZnNldFk6IHkgLyBzY2FsZVkgLSBwaXhlbEZsb29yKHkgLyBzY2FsZVkpLFxuICAgICAgICBzY2FsZVg6IHNjYWxlWCxcbiAgICAgICAgc2NhbGVZOiBzY2FsZVksXG4gICAgICAgIHg6IHBpeGVsRmxvb3IoeCAvIHNjYWxlWCksXG4gICAgICAgIHk6IHBpeGVsRmxvb3IoeSAvIHNjYWxlWSksXG4gICAgICAgIHdpZHRoOiBwaXhlbENlaWwodG9UaWxlV2lkdGggLyBzY2FsZVgpLFxuICAgICAgICBoZWlnaHQ6IHBpeGVsQ2VpbCh0b1RpbGVIZWlnaHQgLyBzY2FsZVkpXG4gICAgICB9O1xuICAgICAgdGlsZXMucHVzaCh0aWxlKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGlsZXM7XG59O1xuXG59LHt9XSwxNjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIG9iakNsYXNzKG9iaikge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaik7XG59XG5cbm1vZHVsZS5leHBvcnRzLmlzQ2FudmFzID0gZnVuY3Rpb24gaXNDYW52YXMoZWxlbWVudCkge1xuICB2YXIgY25hbWUgPSBvYmpDbGFzcyhlbGVtZW50KTtcbiAgcmV0dXJuIGNuYW1lID09PSAnW29iamVjdCBIVE1MQ2FudmFzRWxlbWVudF0nXG4gIC8qIGJyb3dzZXIgKi9cbiAgfHwgY25hbWUgPT09ICdbb2JqZWN0IE9mZnNjcmVlbkNhbnZhc10nIHx8IGNuYW1lID09PSAnW29iamVjdCBDYW52YXNdJ1xuICAvKiBub2RlLWNhbnZhcyAqL1xuICA7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5pc0ltYWdlID0gZnVuY3Rpb24gaXNJbWFnZShlbGVtZW50KSB7XG4gIHJldHVybiBvYmpDbGFzcyhlbGVtZW50KSA9PT0gJ1tvYmplY3QgSFRNTEltYWdlRWxlbWVudF0nO1xufTtcblxubW9kdWxlLmV4cG9ydHMuaXNJbWFnZUJpdG1hcCA9IGZ1bmN0aW9uIGlzSW1hZ2VCaXRtYXAoZWxlbWVudCkge1xuICByZXR1cm4gb2JqQ2xhc3MoZWxlbWVudCkgPT09ICdbb2JqZWN0IEltYWdlQml0bWFwXSc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5saW1pdGVyID0gZnVuY3Rpb24gbGltaXRlcihjb25jdXJyZW5jeSkge1xuICB2YXIgYWN0aXZlID0gMCxcbiAgICAgIHF1ZXVlID0gW107XG5cbiAgZnVuY3Rpb24gcm9sbCgpIHtcbiAgICBpZiAoYWN0aXZlIDwgY29uY3VycmVuY3kgJiYgcXVldWUubGVuZ3RoKSB7XG4gICAgICBhY3RpdmUrKztcbiAgICAgIHF1ZXVlLnNoaWZ0KCkoKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gbGltaXQoZm4pIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgcXVldWUucHVzaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGZuKCkudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgIGFjdGl2ZS0tO1xuICAgICAgICAgIHJvbGwoKTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgIGFjdGl2ZS0tO1xuICAgICAgICAgIHJvbGwoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHJvbGwoKTtcbiAgICB9KTtcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzLmNpYl9xdWFsaXR5X25hbWUgPSBmdW5jdGlvbiBjaWJfcXVhbGl0eV9uYW1lKG51bSkge1xuICBzd2l0Y2ggKG51bSkge1xuICAgIGNhc2UgMDpcbiAgICAgIHJldHVybiAncGl4ZWxhdGVkJztcblxuICAgIGNhc2UgMTpcbiAgICAgIHJldHVybiAnbG93JztcblxuICAgIGNhc2UgMjpcbiAgICAgIHJldHVybiAnbWVkaXVtJztcbiAgfVxuXG4gIHJldHVybiAnaGlnaCc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5jaWJfc3VwcG9ydCA9IGZ1bmN0aW9uIGNpYl9zdXBwb3J0KGNyZWF0ZUNhbnZhcykge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHR5cGVvZiBjcmVhdGVJbWFnZUJpdG1hcCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgYyA9IGNyZWF0ZUNhbnZhcygxMDAsIDEwMCk7XG4gICAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKGMsIDAsIDAsIDEwMCwgMTAwLCB7XG4gICAgICByZXNpemVXaWR0aDogMTAsXG4gICAgICByZXNpemVIZWlnaHQ6IDEwLFxuICAgICAgcmVzaXplUXVhbGl0eTogJ2hpZ2gnXG4gICAgfSkudGhlbihmdW5jdGlvbiAoYml0bWFwKSB7XG4gICAgICB2YXIgc3RhdHVzID0gYml0bWFwLndpZHRoID09PSAxMDsgLy8gQnJhbmNoIGJlbG93IGlzIGZpbHRlcmVkIG9uIHVwcGVyIGxldmVsLiBXZSBkbyBub3QgY2FsbCByZXNpemVcbiAgICAgIC8vIGRldGVjdGlvbiBmb3IgYmFzaWMgSW1hZ2VCaXRtYXAuXG4gICAgICAvL1xuICAgICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0ltYWdlQml0bWFwXG4gICAgICAvLyBvbGQgQ3JvbWUgNTEgaGFzIEltYWdlQml0bWFwIHdpdGhvdXQgLmNsb3NlKCkuIFRoZW4gdGhpcyBjb2RlXG4gICAgICAvLyB3aWxsIHRocm93IGFuZCByZXR1cm4gJ2ZhbHNlJyBhcyBleHBlY3RlZC5cbiAgICAgIC8vXG5cbiAgICAgIGJpdG1hcC5jbG9zZSgpO1xuICAgICAgYyA9IG51bGw7XG4gICAgICByZXR1cm4gc3RhdHVzO1xuICAgIH0pO1xuICB9KVtcImNhdGNoXCJdKGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMud29ya2VyX29mZnNjcmVlbl9jYW52YXNfc3VwcG9ydCA9IGZ1bmN0aW9uIHdvcmtlcl9vZmZzY3JlZW5fY2FudmFzX3N1cHBvcnQoKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgaWYgKHR5cGVvZiBPZmZzY3JlZW5DYW52YXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAvLyBpZiBPZmZzY3JlZW5DYW52YXMgaXMgcHJlc2VudCwgd2UgYXNzdW1lIGJyb3dzZXIgc3VwcG9ydHMgV29ya2VyIGFuZCBidWlsdC1pbiBQcm9taXNlIGFzIHdlbGxcbiAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHdvcmtlclBheWxvYWQoc2VsZikge1xuICAgICAgaWYgKHR5cGVvZiBjcmVhdGVJbWFnZUJpdG1hcCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgc2VsZi5wb3N0TWVzc2FnZShmYWxzZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjYW52YXMgPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKDEwLCAxMCk7IC8vIHRlc3QgdGhhdCAyZCBjb250ZXh0IGNhbiBiZSB1c2VkIGluIHdvcmtlclxuXG4gICAgICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgY3R4LnJlY3QoMCwgMCwgMSwgMSk7IC8vIHRlc3QgdGhhdCBjaWIgY2FuIGJlIHVzZWQgdG8gcmV0dXJuIGltYWdlIGJpdG1hcCBmcm9tIHdvcmtlclxuXG4gICAgICAgIHJldHVybiBjcmVhdGVJbWFnZUJpdG1hcChjYW52YXMsIDAsIDAsIDEsIDEpO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBzZWxmLnBvc3RNZXNzYWdlKHRydWUpO1xuICAgICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gc2VsZi5wb3N0TWVzc2FnZShmYWxzZSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB2YXIgY29kZSA9IGJ0b2EoXCIoXCIuY29uY2F0KHdvcmtlclBheWxvYWQudG9TdHJpbmcoKSwgXCIpKHNlbGYpO1wiKSk7XG4gICAgdmFyIHcgPSBuZXcgV29ya2VyKFwiZGF0YTp0ZXh0L2phdmFzY3JpcHQ7YmFzZTY0LFwiLmNvbmNhdChjb2RlKSk7XG5cbiAgICB3Lm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChldikge1xuICAgICAgcmV0dXJuIHJlc29sdmUoZXYuZGF0YSk7XG4gICAgfTtcblxuICAgIHcub25lcnJvciA9IHJlamVjdDtcbiAgfSkudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSwgZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSk7XG59OyAvLyBDaGVjayBpZiBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKS5nZXRJbWFnZURhdGEgY2FuIGJlIHVzZWQsXG4vLyBGaXJlRm94IHJhbmRvbWl6ZXMgdGhlIG91dHB1dCBvZiB0aGF0IGZ1bmN0aW9uIGluIGBwcml2YWN5LnJlc2lzdEZpbmdlcnByaW50aW5nYCBtb2RlXG5cblxubW9kdWxlLmV4cG9ydHMuY2FuX3VzZV9jYW52YXMgPSBmdW5jdGlvbiBjYW5fdXNlX2NhbnZhcyhjcmVhdGVDYW52YXMpIHtcbiAgdmFyIHVzYWJsZSA9IGZhbHNlO1xuXG4gIHRyeSB7XG4gICAgdmFyIGNhbnZhcyA9IGNyZWF0ZUNhbnZhcygyLCAxKTtcbiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgdmFyIGQgPSBjdHguY3JlYXRlSW1hZ2VEYXRhKDIsIDEpO1xuICAgIGQuZGF0YVswXSA9IDEyO1xuICAgIGQuZGF0YVsxXSA9IDIzO1xuICAgIGQuZGF0YVsyXSA9IDM0O1xuICAgIGQuZGF0YVszXSA9IDI1NTtcbiAgICBkLmRhdGFbNF0gPSA0NTtcbiAgICBkLmRhdGFbNV0gPSA1NjtcbiAgICBkLmRhdGFbNl0gPSA2NztcbiAgICBkLmRhdGFbN10gPSAyNTU7XG4gICAgY3R4LnB1dEltYWdlRGF0YShkLCAwLCAwKTtcbiAgICBkID0gbnVsbDtcbiAgICBkID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCAyLCAxKTtcblxuICAgIGlmIChkLmRhdGFbMF0gPT09IDEyICYmIGQuZGF0YVsxXSA9PT0gMjMgJiYgZC5kYXRhWzJdID09PSAzNCAmJiBkLmRhdGFbM10gPT09IDI1NSAmJiBkLmRhdGFbNF0gPT09IDQ1ICYmIGQuZGF0YVs1XSA9PT0gNTYgJiYgZC5kYXRhWzZdID09PSA2NyAmJiBkLmRhdGFbN10gPT09IDI1NSkge1xuICAgICAgdXNhYmxlID0gdHJ1ZTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycikge31cblxuICByZXR1cm4gdXNhYmxlO1xufTsgLy8gQ2hlY2sgaWYgY3JlYXRlSW1hZ2VCaXRtYXAoaW1nLCBzeCwgc3ksIHN3LCBzaCkgc2lnbmF0dXJlIHdvcmtzIGNvcnJlY3RseVxuLy8gd2l0aCBKUEVHIGltYWdlcyBvcmllbnRlZCB3aXRoIEV4aWY7XG4vLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0xMjIwNjcxXG4vLyBUT0RPOiByZW1vdmUgYWZ0ZXIgaXQncyBmaXhlZCBpbiBjaHJvbWUgZm9yIGF0IGxlYXN0IDIgcmVsZWFzZXNcblxuXG5tb2R1bGUuZXhwb3J0cy5jaWJfY2FuX3VzZV9yZWdpb24gPSBmdW5jdGlvbiBjaWJfY2FuX3VzZV9yZWdpb24oKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgIGlmICh0eXBlb2YgY3JlYXRlSW1hZ2VCaXRtYXAgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICBpbWFnZS5zcmMgPSAnZGF0YTppbWFnZS9qcGVnO2Jhc2U2NCwnICsgJy85ai80UUJpUlhocFpnQUFUVTBBS2dBQUFBZ0FCUUVTQUFNQUFBQUJBQVlBQUFFYUFBVUFBQUFCQUFBQVNnRWJBQVVBQScgKyAnQUFCQUFBQVVnRW9BQU1BQUFBQkFBSUFBQUlUQUFNQUFBQUJBQUVBQUFBQUFBQUFBQUJJQUFBQUFRQUFBRWdBQUFBQi85JyArICdzQVF3QUVBd01FQXdNRUJBTUVCUVFFQlFZS0J3WUdCZ1lOQ1FvSUNnOE5FQkFQRFE4T0VSTVlGQkVTRnhJT0R4VWNGUmMnICsgJ1pHUnNiR3hBVUhSOGRHaDhZR2hzYS85c0FRd0VFQlFVR0JRWU1Cd2NNR2hFUEVSb2FHaG9hR2hvYUdob2FHaG9hR2hvYScgKyAnR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2EvOElBRVFnQUFRQUNBd0VSQUFJUkFRTVJBJyArICdmL0VBQlFBQVFBQUFBQUFBQUFBQUFBQUFBQUFBQWYveEFBVUFRRUFBQUFBQUFBQUFBQUFBQUFBQUFBQS85b0FEQU1CQUEnICsgJ0lRQXhBQUFBRi9QLy9FQUJRUUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFELzJnQUlBUUVBQVFVQ2YvL0VBQlFSQVFBQUFBQScgKyAnQUFBQUFBQUFBQUFBQUFBRC8yZ0FJQVFNQkFUOEJmLy9FQUJRUkFRQUFBQUFBQUFBQUFBQUFBQUFBQUFELzJnQUlBUUlCJyArICdBVDhCZi8vRUFCUVFBUUFBQUFBQUFBQUFBQUFBQUFBQUFBRC8yZ0FJQVFFQUJqOENmLy9FQUJRUUFRQUFBQUFBQUFBQUEnICsgJ0FBQUFBQUFBQUQvMmdBSUFRRUFBVDhoZi8vYUFBd0RBUUFDQUFNQUFBQVFILy9FQUJRUkFRQUFBQUFBQUFBQUFBQUFBQScgKyAnQUFBQUQvMmdBSUFRTUJBVDhRZi8vRUFCUVJBUUFBQUFBQUFBQUFBQUFBQUFBQUFBRC8yZ0FJQVFJQkFUOFFmLy9FQUJRJyArICdRQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUQvMmdBSUFRRUFBVDhRZi8vWic7XG5cbiAgICBpbWFnZS5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBjcmVhdGVJbWFnZUJpdG1hcChpbWFnZSwgMCwgMCwgaW1hZ2Uud2lkdGgsIGltYWdlLmhlaWdodCkudGhlbihmdW5jdGlvbiAoYml0bWFwKSB7XG4gICAgICAgIGlmIChiaXRtYXAud2lkdGggPT09IGltYWdlLndpZHRoICYmIGJpdG1hcC5oZWlnaHQgPT09IGltYWdlLmhlaWdodCkge1xuICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZShmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgIH0sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoZmFsc2UpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGltYWdlLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZShmYWxzZSk7XG4gICAgfTtcbiAgfSk7XG59O1xuXG59LHt9XSwxNzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBXZWIgV29ya2VyIHdyYXBwZXIgZm9yIGltYWdlIHJlc2l6ZSBmdW5jdGlvblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIE1hdGhMaWIgPSBfZGVyZXFfKCcuL21hdGhsaWInKTtcblxuICB2YXIgbWF0aExpYjtcbiAgLyogZXNsaW50LWRpc2FibGUgbm8tdW5kZWYgKi9cblxuICBvbm1lc3NhZ2UgPSBmdW5jdGlvbiBvbm1lc3NhZ2UoZXYpIHtcbiAgICB2YXIgdGlsZU9wdHMgPSBldi5kYXRhLm9wdHM7XG4gICAgdmFyIHJldHVybkJpdG1hcCA9IGZhbHNlO1xuXG4gICAgaWYgKCF0aWxlT3B0cy5zcmMgJiYgdGlsZU9wdHMuc3JjQml0bWFwKSB7XG4gICAgICB2YXIgY2FudmFzID0gbmV3IE9mZnNjcmVlbkNhbnZhcyh0aWxlT3B0cy53aWR0aCwgdGlsZU9wdHMuaGVpZ2h0KTtcbiAgICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgICAgIGFscGhhOiBCb29sZWFuKHRpbGVPcHRzLmFscGhhKVxuICAgICAgfSk7XG4gICAgICBjdHguZHJhd0ltYWdlKHRpbGVPcHRzLnNyY0JpdG1hcCwgMCwgMCk7XG4gICAgICB0aWxlT3B0cy5zcmMgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIHRpbGVPcHRzLndpZHRoLCB0aWxlT3B0cy5oZWlnaHQpLmRhdGE7XG4gICAgICBjYW52YXMud2lkdGggPSBjYW52YXMuaGVpZ2h0ID0gMDtcbiAgICAgIGNhbnZhcyA9IG51bGw7XG4gICAgICB0aWxlT3B0cy5zcmNCaXRtYXAuY2xvc2UoKTtcbiAgICAgIHRpbGVPcHRzLnNyY0JpdG1hcCA9IG51bGw7IC8vIFRlbXBvcmFyeSBmb3JjZSBvdXQgZGF0YSB0byB0eXBlZCBhcnJheSwgYmVjYXVzZSBDaHJvbWUgaGF2ZSBhcnRlZmFjdHNcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYS9pc3N1ZXMvMjIzXG4gICAgICAvLyByZXR1cm5CaXRtYXAgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICghbWF0aExpYikgbWF0aExpYiA9IG5ldyBNYXRoTGliKGV2LmRhdGEuZmVhdHVyZXMpOyAvLyBVc2UgbXVsdGltYXRoJ3Mgc3luYyBhdXRvLWluaXQuIEF2b2lkIFByb21pc2UgdXNlIGluIG9sZCBicm93c2VycyxcbiAgICAvLyBiZWNhdXNlIHBvbHlmaWxscyBhcmUgbm90IHByb3BhZ2F0ZWQgdG8gd2Vid29ya2VyLlxuXG4gICAgdmFyIGRhdGEgPSBtYXRoTGliLnJlc2l6ZUFuZFVuc2hhcnAodGlsZU9wdHMpO1xuXG4gICAgaWYgKHJldHVybkJpdG1hcCkge1xuICAgICAgdmFyIHRvSW1hZ2VEYXRhID0gbmV3IEltYWdlRGF0YShuZXcgVWludDhDbGFtcGVkQXJyYXkoZGF0YSksIHRpbGVPcHRzLnRvV2lkdGgsIHRpbGVPcHRzLnRvSGVpZ2h0KTtcblxuICAgICAgdmFyIF9jYW52YXMgPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKHRpbGVPcHRzLnRvV2lkdGgsIHRpbGVPcHRzLnRvSGVpZ2h0KTtcblxuICAgICAgdmFyIF9jdHggPSBfY2FudmFzLmdldENvbnRleHQoJzJkJywge1xuICAgICAgICBhbHBoYTogQm9vbGVhbih0aWxlT3B0cy5hbHBoYSlcbiAgICAgIH0pO1xuXG4gICAgICBfY3R4LnB1dEltYWdlRGF0YSh0b0ltYWdlRGF0YSwgMCwgMCk7XG5cbiAgICAgIGNyZWF0ZUltYWdlQml0bWFwKF9jYW52YXMpLnRoZW4oZnVuY3Rpb24gKGJpdG1hcCkge1xuICAgICAgICBwb3N0TWVzc2FnZSh7XG4gICAgICAgICAgYml0bWFwOiBiaXRtYXBcbiAgICAgICAgfSwgW2JpdG1hcF0pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBvc3RNZXNzYWdlKHtcbiAgICAgICAgZGF0YTogZGF0YVxuICAgICAgfSwgW2RhdGEuYnVmZmVyXSk7XG4gICAgfVxuICB9O1xufTtcblxufSx7XCIuL21hdGhsaWJcIjoxfV0sMTg6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLy8gQ2FsY3VsYXRlIEdhdXNzaWFuIGJsdXIgb2YgYW4gaW1hZ2UgdXNpbmcgSUlSIGZpbHRlclxuLy8gVGhlIG1ldGhvZCBpcyB0YWtlbiBmcm9tIEludGVsJ3Mgd2hpdGUgcGFwZXIgYW5kIGNvZGUgZXhhbXBsZSBhdHRhY2hlZCB0byBpdDpcbi8vIGh0dHBzOi8vc29mdHdhcmUuaW50ZWwuY29tL2VuLXVzL2FydGljbGVzL2lpci1nYXVzc2lhbi1ibHVyLWZpbHRlclxuLy8gLWltcGxlbWVudGF0aW9uLXVzaW5nLWludGVsLWFkdmFuY2VkLXZlY3Rvci1leHRlbnNpb25zXG5cbnZhciBhMCwgYTEsIGEyLCBhMywgYjEsIGIyLCBsZWZ0X2Nvcm5lciwgcmlnaHRfY29ybmVyO1xuXG5mdW5jdGlvbiBnYXVzc0NvZWYoc2lnbWEpIHtcbiAgaWYgKHNpZ21hIDwgMC41KSB7XG4gICAgc2lnbWEgPSAwLjU7XG4gIH1cblxuICB2YXIgYSA9IE1hdGguZXhwKDAuNzI2ICogMC43MjYpIC8gc2lnbWEsXG4gICAgICBnMSA9IE1hdGguZXhwKC1hKSxcbiAgICAgIGcyID0gTWF0aC5leHAoLTIgKiBhKSxcbiAgICAgIGsgPSAoMSAtIGcxKSAqICgxIC0gZzEpIC8gKDEgKyAyICogYSAqIGcxIC0gZzIpO1xuXG4gIGEwID0gaztcbiAgYTEgPSBrICogKGEgLSAxKSAqIGcxO1xuICBhMiA9IGsgKiAoYSArIDEpICogZzE7XG4gIGEzID0gLWsgKiBnMjtcbiAgYjEgPSAyICogZzE7XG4gIGIyID0gLWcyO1xuICBsZWZ0X2Nvcm5lciA9IChhMCArIGExKSAvICgxIC0gYjEgLSBiMik7XG4gIHJpZ2h0X2Nvcm5lciA9IChhMiArIGEzKSAvICgxIC0gYjEgLSBiMik7XG5cbiAgLy8gQXR0ZW1wdCB0byBmb3JjZSB0eXBlIHRvIEZQMzIuXG4gIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KFsgYTAsIGExLCBhMiwgYTMsIGIxLCBiMiwgbGVmdF9jb3JuZXIsIHJpZ2h0X2Nvcm5lciBdKTtcbn1cblxuZnVuY3Rpb24gY29udm9sdmVNb25vMTYoc3JjLCBvdXQsIGxpbmUsIGNvZWZmLCB3aWR0aCwgaGVpZ2h0KSB7XG4gIC8vIHRha2VzIHNyYyBpbWFnZSBhbmQgd3JpdGVzIHRoZSBibHVycmVkIGFuZCB0cmFuc3Bvc2VkIHJlc3VsdCBpbnRvIG91dFxuXG4gIHZhciBwcmV2X3NyYywgY3Vycl9zcmMsIGN1cnJfb3V0LCBwcmV2X291dCwgcHJldl9wcmV2X291dDtcbiAgdmFyIHNyY19pbmRleCwgb3V0X2luZGV4LCBsaW5lX2luZGV4O1xuICB2YXIgaSwgajtcbiAgdmFyIGNvZWZmX2EwLCBjb2VmZl9hMSwgY29lZmZfYjEsIGNvZWZmX2IyO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBoZWlnaHQ7IGkrKykge1xuICAgIHNyY19pbmRleCA9IGkgKiB3aWR0aDtcbiAgICBvdXRfaW5kZXggPSBpO1xuICAgIGxpbmVfaW5kZXggPSAwO1xuXG4gICAgLy8gbGVmdCB0byByaWdodFxuICAgIHByZXZfc3JjID0gc3JjW3NyY19pbmRleF07XG4gICAgcHJldl9wcmV2X291dCA9IHByZXZfc3JjICogY29lZmZbNl07XG4gICAgcHJldl9vdXQgPSBwcmV2X3ByZXZfb3V0O1xuXG4gICAgY29lZmZfYTAgPSBjb2VmZlswXTtcbiAgICBjb2VmZl9hMSA9IGNvZWZmWzFdO1xuICAgIGNvZWZmX2IxID0gY29lZmZbNF07XG4gICAgY29lZmZfYjIgPSBjb2VmZls1XTtcblxuICAgIGZvciAoaiA9IDA7IGogPCB3aWR0aDsgaisrKSB7XG4gICAgICBjdXJyX3NyYyA9IHNyY1tzcmNfaW5kZXhdO1xuXG4gICAgICBjdXJyX291dCA9IGN1cnJfc3JjICogY29lZmZfYTAgK1xuICAgICAgICAgICAgICAgICBwcmV2X3NyYyAqIGNvZWZmX2ExICtcbiAgICAgICAgICAgICAgICAgcHJldl9vdXQgKiBjb2VmZl9iMSArXG4gICAgICAgICAgICAgICAgIHByZXZfcHJldl9vdXQgKiBjb2VmZl9iMjtcblxuICAgICAgcHJldl9wcmV2X291dCA9IHByZXZfb3V0O1xuICAgICAgcHJldl9vdXQgPSBjdXJyX291dDtcbiAgICAgIHByZXZfc3JjID0gY3Vycl9zcmM7XG5cbiAgICAgIGxpbmVbbGluZV9pbmRleF0gPSBwcmV2X291dDtcbiAgICAgIGxpbmVfaW5kZXgrKztcbiAgICAgIHNyY19pbmRleCsrO1xuICAgIH1cblxuICAgIHNyY19pbmRleC0tO1xuICAgIGxpbmVfaW5kZXgtLTtcbiAgICBvdXRfaW5kZXggKz0gaGVpZ2h0ICogKHdpZHRoIC0gMSk7XG5cbiAgICAvLyByaWdodCB0byBsZWZ0XG4gICAgcHJldl9zcmMgPSBzcmNbc3JjX2luZGV4XTtcbiAgICBwcmV2X3ByZXZfb3V0ID0gcHJldl9zcmMgKiBjb2VmZls3XTtcbiAgICBwcmV2X291dCA9IHByZXZfcHJldl9vdXQ7XG4gICAgY3Vycl9zcmMgPSBwcmV2X3NyYztcblxuICAgIGNvZWZmX2EwID0gY29lZmZbMl07XG4gICAgY29lZmZfYTEgPSBjb2VmZlszXTtcblxuICAgIGZvciAoaiA9IHdpZHRoIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgIGN1cnJfb3V0ID0gY3Vycl9zcmMgKiBjb2VmZl9hMCArXG4gICAgICAgICAgICAgICAgIHByZXZfc3JjICogY29lZmZfYTEgK1xuICAgICAgICAgICAgICAgICBwcmV2X291dCAqIGNvZWZmX2IxICtcbiAgICAgICAgICAgICAgICAgcHJldl9wcmV2X291dCAqIGNvZWZmX2IyO1xuXG4gICAgICBwcmV2X3ByZXZfb3V0ID0gcHJldl9vdXQ7XG4gICAgICBwcmV2X291dCA9IGN1cnJfb3V0O1xuXG4gICAgICBwcmV2X3NyYyA9IGN1cnJfc3JjO1xuICAgICAgY3Vycl9zcmMgPSBzcmNbc3JjX2luZGV4XTtcblxuICAgICAgb3V0W291dF9pbmRleF0gPSBsaW5lW2xpbmVfaW5kZXhdICsgcHJldl9vdXQ7XG5cbiAgICAgIHNyY19pbmRleC0tO1xuICAgICAgbGluZV9pbmRleC0tO1xuICAgICAgb3V0X2luZGV4IC09IGhlaWdodDtcbiAgICB9XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBibHVyTW9ubzE2KHNyYywgd2lkdGgsIGhlaWdodCwgcmFkaXVzKSB7XG4gIC8vIFF1aWNrIGV4aXQgb24gemVybyByYWRpdXNcbiAgaWYgKCFyYWRpdXMpIHsgcmV0dXJuOyB9XG5cbiAgdmFyIG91dCAgICAgID0gbmV3IFVpbnQxNkFycmF5KHNyYy5sZW5ndGgpLFxuICAgICAgdG1wX2xpbmUgPSBuZXcgRmxvYXQzMkFycmF5KE1hdGgubWF4KHdpZHRoLCBoZWlnaHQpKTtcblxuICB2YXIgY29lZmYgPSBnYXVzc0NvZWYocmFkaXVzKTtcblxuICBjb252b2x2ZU1vbm8xNihzcmMsIG91dCwgdG1wX2xpbmUsIGNvZWZmLCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpO1xuICBjb252b2x2ZU1vbm8xNihvdXQsIHNyYywgdG1wX2xpbmUsIGNvZWZmLCBoZWlnaHQsIHdpZHRoLCByYWRpdXMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJsdXJNb25vMTY7XG5cbn0se31dLDE5OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbmlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9XG4gICAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3JcbiAgICB9XG4gIH1cbn1cblxufSx7fV0sMjA6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBhc3NpZ24gICAgICAgICA9IF9kZXJlcV8oJ29iamVjdC1hc3NpZ24nKTtcbnZhciBiYXNlNjRkZWNvZGUgICA9IF9kZXJlcV8oJy4vbGliL2Jhc2U2NGRlY29kZScpO1xudmFyIGhhc1dlYkFzc2VtYmx5ID0gX2RlcmVxXygnLi9saWIvd2FfZGV0ZWN0Jyk7XG5cblxudmFyIERFRkFVTFRfT1BUSU9OUyA9IHtcbiAganM6IHRydWUsXG4gIHdhc206IHRydWVcbn07XG5cblxuZnVuY3Rpb24gTXVsdGlNYXRoKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIE11bHRpTWF0aCkpIHJldHVybiBuZXcgTXVsdGlNYXRoKG9wdGlvbnMpO1xuXG4gIHZhciBvcHRzID0gYXNzaWduKHt9LCBERUZBVUxUX09QVElPTlMsIG9wdGlvbnMgfHwge30pO1xuXG4gIHRoaXMub3B0aW9ucyAgICAgICAgID0gb3B0cztcblxuICB0aGlzLl9fY2FjaGUgICAgICAgICA9IHt9O1xuXG4gIHRoaXMuX19pbml0X3Byb21pc2UgID0gbnVsbDtcbiAgdGhpcy5fX21vZHVsZXMgICAgICAgPSBvcHRzLm1vZHVsZXMgfHwge307XG4gIHRoaXMuX19tZW1vcnkgICAgICAgID0gbnVsbDtcbiAgdGhpcy5fX3dhc20gICAgICAgICAgPSB7fTtcblxuICB0aGlzLl9faXNMRSA9ICgobmV3IFVpbnQzMkFycmF5KChuZXcgVWludDhBcnJheShbIDEsIDAsIDAsIDAgXSkpLmJ1ZmZlcikpWzBdID09PSAxKTtcblxuICBpZiAoIXRoaXMub3B0aW9ucy5qcyAmJiAhdGhpcy5vcHRpb25zLndhc20pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ21hdGhsaWI6IGF0IGxlYXN0IFwianNcIiBvciBcIndhc21cIiBzaG91bGQgYmUgZW5hYmxlZCcpO1xuICB9XG59XG5cblxuTXVsdGlNYXRoLnByb3RvdHlwZS5oYXNfd2FzbSA9IGhhc1dlYkFzc2VtYmx5O1xuXG5cbk11bHRpTWF0aC5wcm90b3R5cGUudXNlID0gZnVuY3Rpb24gKG1vZHVsZSkge1xuICB0aGlzLl9fbW9kdWxlc1ttb2R1bGUubmFtZV0gPSBtb2R1bGU7XG5cbiAgLy8gUGluIHRoZSBiZXN0IHBvc3NpYmxlIGltcGxlbWVudGF0aW9uXG4gIGlmICh0aGlzLm9wdGlvbnMud2FzbSAmJiB0aGlzLmhhc193YXNtKCkgJiYgbW9kdWxlLndhc21fZm4pIHtcbiAgICB0aGlzW21vZHVsZS5uYW1lXSA9IG1vZHVsZS53YXNtX2ZuO1xuICB9IGVsc2Uge1xuICAgIHRoaXNbbW9kdWxlLm5hbWVdID0gbW9kdWxlLmZuO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5cbk11bHRpTWF0aC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuX19pbml0X3Byb21pc2UpIHJldHVybiB0aGlzLl9faW5pdF9wcm9taXNlO1xuXG4gIGlmICghdGhpcy5vcHRpb25zLmpzICYmIHRoaXMub3B0aW9ucy53YXNtICYmICF0aGlzLmhhc193YXNtKCkpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdtYXRobGliOiBvbmx5IFwid2FzbVwiIHdhcyBlbmFibGVkLCBidXQgaXRcXCdzIG5vdCBzdXBwb3J0ZWQnKSk7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5fX2luaXRfcHJvbWlzZSA9IFByb21pc2UuYWxsKE9iamVjdC5rZXlzKHNlbGYuX19tb2R1bGVzKS5tYXAoZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB2YXIgbW9kdWxlID0gc2VsZi5fX21vZHVsZXNbbmFtZV07XG5cbiAgICBpZiAoIXNlbGYub3B0aW9ucy53YXNtIHx8ICFzZWxmLmhhc193YXNtKCkgfHwgIW1vZHVsZS53YXNtX2ZuKSByZXR1cm4gbnVsbDtcblxuICAgIC8vIElmIGFscmVhZHkgY29tcGlsZWQgLSBleGl0XG4gICAgaWYgKHNlbGYuX193YXNtW25hbWVdKSByZXR1cm4gbnVsbDtcblxuICAgIC8vIENvbXBpbGUgd2FzbSBzb3VyY2VcbiAgICByZXR1cm4gV2ViQXNzZW1ibHkuY29tcGlsZShzZWxmLl9fYmFzZTY0ZGVjb2RlKG1vZHVsZS53YXNtX3NyYykpXG4gICAgICAudGhlbihmdW5jdGlvbiAobSkgeyBzZWxmLl9fd2FzbVtuYW1lXSA9IG07IH0pO1xuICB9KSlcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBzZWxmOyB9KTtcblxuICByZXR1cm4gdGhpcy5fX2luaXRfcHJvbWlzZTtcbn07XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIE1ldGhvZHMgYmVsb3cgYXJlIGZvciBpbnRlcm5hbCB1c2UgZnJvbSBwbHVnaW5zXG5cblxuLy8gU2ltcGxlIGRlY29kZSBiYXNlNjQgdG8gdHlwZWQgYXJyYXkuIFVzZWZ1bCB0byBsb2FkIGVtYmVkZGVkIHdlYmFzc2VtYmx5XG4vLyBjb2RlLiBZb3UgcHJvYmFibHkgZG9uJ3QgbmVlZCB0byBjYWxsIHRoaXMgbWV0aG9kIGRpcmVjdGx5LlxuLy9cbk11bHRpTWF0aC5wcm90b3R5cGUuX19iYXNlNjRkZWNvZGUgPSBiYXNlNjRkZWNvZGU7XG5cblxuLy8gSW5jcmVhc2UgY3VycmVudCBtZW1vcnkgdG8gaW5jbHVkZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ5dGVzLiBEbyBub3RoaW5nIGlmXG4vLyBzaXplIGlzIGFscmVhZHkgb2suIFlvdSBwcm9iYWJseSBkb24ndCBuZWVkIHRvIGNhbGwgdGhpcyBtZXRob2QgZGlyZWN0bHksXG4vLyBiZWNhdXNlIGl0IHdpbGwgYmUgaW52b2tlZCBmcm9tIGAuX19pbnN0YW5jZSgpYC5cbi8vXG5NdWx0aU1hdGgucHJvdG90eXBlLl9fcmVhbGxvY2F0ZSA9IGZ1bmN0aW9uIG1lbV9ncm93X3RvKGJ5dGVzKSB7XG4gIGlmICghdGhpcy5fX21lbW9yeSkge1xuICAgIHRoaXMuX19tZW1vcnkgPSBuZXcgV2ViQXNzZW1ibHkuTWVtb3J5KHtcbiAgICAgIGluaXRpYWw6IE1hdGguY2VpbChieXRlcyAvICg2NCAqIDEwMjQpKVxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzLl9fbWVtb3J5O1xuICB9XG5cbiAgdmFyIG1lbV9zaXplID0gdGhpcy5fX21lbW9yeS5idWZmZXIuYnl0ZUxlbmd0aDtcblxuICBpZiAobWVtX3NpemUgPCBieXRlcykge1xuICAgIHRoaXMuX19tZW1vcnkuZ3JvdyhNYXRoLmNlaWwoKGJ5dGVzIC0gbWVtX3NpemUpIC8gKDY0ICogMTAyNCkpKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9fbWVtb3J5O1xufTtcblxuXG4vLyBSZXR1cm5zIGluc3RhbnRpbmF0ZWQgd2ViYXNzZW1ibHkgaXRlbSBieSBuYW1lLCB3aXRoIHNwZWNpZmllZCBtZW1vcnkgc2l6ZVxuLy8gYW5kIGVudmlyb25tZW50LlxuLy8gLSB1c2UgY2FjaGUgaWYgYXZhaWxhYmxlXG4vLyAtIGRvIHN5bmMgbW9kdWxlIGluaXQsIGlmIGFzeW5jIGluaXQgd2FzIG5vdCBjYWxsZWQgZWFybGllclxuLy8gLSBhbGxvY2F0ZSBtZW1vcnkgaWYgbm90IGVub3VndGhcbi8vIC0gY2FuIGV4cG9ydCBmdW5jdGlvbnMgdG8gd2ViYXNzZW1ibHkgdmlhIFwiZW52X2V4dHJhXCIsXG4vLyAgIGZvciBleGFtcGxlLCB7IGV4cDogTWF0aC5leHAgfVxuLy9cbk11bHRpTWF0aC5wcm90b3R5cGUuX19pbnN0YW5jZSA9IGZ1bmN0aW9uIGluc3RhbmNlKG5hbWUsIG1lbXNpemUsIGVudl9leHRyYSkge1xuICBpZiAobWVtc2l6ZSkgdGhpcy5fX3JlYWxsb2NhdGUobWVtc2l6ZSk7XG5cbiAgLy8gSWYgLmluaXQoKSB3YXMgbm90IGNhbGxlZCwgZG8gc3luYyBjb21waWxlXG4gIGlmICghdGhpcy5fX3dhc21bbmFtZV0pIHtcbiAgICB2YXIgbW9kdWxlID0gdGhpcy5fX21vZHVsZXNbbmFtZV07XG4gICAgdGhpcy5fX3dhc21bbmFtZV0gPSBuZXcgV2ViQXNzZW1ibHkuTW9kdWxlKHRoaXMuX19iYXNlNjRkZWNvZGUobW9kdWxlLndhc21fc3JjKSk7XG4gIH1cblxuICBpZiAoIXRoaXMuX19jYWNoZVtuYW1lXSkge1xuICAgIHZhciBlbnZfYmFzZSA9IHtcbiAgICAgIG1lbW9yeUJhc2U6IDAsXG4gICAgICBtZW1vcnk6IHRoaXMuX19tZW1vcnksXG4gICAgICB0YWJsZUJhc2U6IDAsXG4gICAgICB0YWJsZTogbmV3IFdlYkFzc2VtYmx5LlRhYmxlKHsgaW5pdGlhbDogMCwgZWxlbWVudDogJ2FueWZ1bmMnIH0pXG4gICAgfTtcblxuICAgIHRoaXMuX19jYWNoZVtuYW1lXSA9IG5ldyBXZWJBc3NlbWJseS5JbnN0YW5jZSh0aGlzLl9fd2FzbVtuYW1lXSwge1xuICAgICAgZW52OiBhc3NpZ24oZW52X2Jhc2UsIGVudl9leHRyYSB8fCB7fSlcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9fY2FjaGVbbmFtZV07XG59O1xuXG5cbi8vIEhlbHBlciB0byBjYWxjdWxhdGUgbWVtb3J5IGFsaWdoIGZvciBwb2ludGVycy4gV2ViYXNzZW1ibHkgZG9lcyBub3QgcmVxdWlyZVxuLy8gdGhpcywgYnV0IHlvdSBtYXkgd2lzaCB0byBleHBlcmltZW50LiBEZWZhdWx0IGJhc2UgPSA4O1xuLy9cbk11bHRpTWF0aC5wcm90b3R5cGUuX19hbGlnbiA9IGZ1bmN0aW9uIGFsaWduKG51bWJlciwgYmFzZSkge1xuICBiYXNlID0gYmFzZSB8fCA4O1xuICB2YXIgcmVtaW5kZXIgPSBudW1iZXIgJSBiYXNlO1xuICByZXR1cm4gbnVtYmVyICsgKHJlbWluZGVyID8gYmFzZSAtIHJlbWluZGVyIDogMCk7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gTXVsdGlNYXRoO1xuXG59LHtcIi4vbGliL2Jhc2U2NGRlY29kZVwiOjIxLFwiLi9saWIvd2FfZGV0ZWN0XCI6MjIsXCJvYmplY3QtYXNzaWduXCI6MjN9XSwyMTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vLyBiYXNlNjQgZGVjb2RlIHN0ciAtPiBVaW50OEFycmF5LCB0byBsb2FkIFdBIG1vZHVsZXNcbi8vXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIEJBU0U2NF9NQVAgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyc7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiYXNlNjRkZWNvZGUoc3RyKSB7XG4gIHZhciBpbnB1dCA9IHN0ci5yZXBsYWNlKC9bXFxyXFxuPV0vZywgJycpLCAvLyByZW1vdmUgQ1IvTEYgJiBwYWRkaW5nIHRvIHNpbXBsaWZ5IHNjYW5cbiAgICAgIG1heCAgID0gaW5wdXQubGVuZ3RoO1xuXG4gIHZhciBvdXQgPSBuZXcgVWludDhBcnJheSgobWF4ICogMykgPj4gMik7XG5cbiAgLy8gQ29sbGVjdCBieSA2KjQgYml0cyAoMyBieXRlcylcblxuICB2YXIgYml0cyA9IDA7XG4gIHZhciBwdHIgID0gMDtcblxuICBmb3IgKHZhciBpZHggPSAwOyBpZHggPCBtYXg7IGlkeCsrKSB7XG4gICAgaWYgKChpZHggJSA0ID09PSAwKSAmJiBpZHgpIHtcbiAgICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAxNikgJiAweEZGO1xuICAgICAgb3V0W3B0cisrXSA9IChiaXRzID4+IDgpICYgMHhGRjtcbiAgICAgIG91dFtwdHIrK10gPSBiaXRzICYgMHhGRjtcbiAgICB9XG5cbiAgICBiaXRzID0gKGJpdHMgPDwgNikgfCBCQVNFNjRfTUFQLmluZGV4T2YoaW5wdXQuY2hhckF0KGlkeCkpO1xuICB9XG5cbiAgLy8gRHVtcCB0YWlsXG5cbiAgdmFyIHRhaWxiaXRzID0gKG1heCAlIDQpICogNjtcblxuICBpZiAodGFpbGJpdHMgPT09IDApIHtcbiAgICBvdXRbcHRyKytdID0gKGJpdHMgPj4gMTYpICYgMHhGRjtcbiAgICBvdXRbcHRyKytdID0gKGJpdHMgPj4gOCkgJiAweEZGO1xuICAgIG91dFtwdHIrK10gPSBiaXRzICYgMHhGRjtcbiAgfSBlbHNlIGlmICh0YWlsYml0cyA9PT0gMTgpIHtcbiAgICBvdXRbcHRyKytdID0gKGJpdHMgPj4gMTApICYgMHhGRjtcbiAgICBvdXRbcHRyKytdID0gKGJpdHMgPj4gMikgJiAweEZGO1xuICB9IGVsc2UgaWYgKHRhaWxiaXRzID09PSAxMikge1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiA0KSAmIDB4RkY7XG4gIH1cblxuICByZXR1cm4gb3V0O1xufTtcblxufSx7fV0sMjI6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLy8gRGV0ZWN0IFdlYkFzc2VtYmx5IHN1cHBvcnQuXG4vLyAtIENoZWNrIGdsb2JhbCBXZWJBc3NlbWJseSBvYmplY3Rcbi8vIC0gVHJ5IHRvIGxvYWQgc2ltcGxlIG1vZHVsZSAoY2FuIGJlIGRpc2FibGVkIHZpYSBDU1ApXG4vL1xuJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB3YTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGhhc1dlYkFzc2VtYmx5KCkge1xuICAvLyB1c2UgY2FjaGUgaWYgY2FsbGVkIGJlZm9yZTtcbiAgaWYgKHR5cGVvZiB3YSAhPT0gJ3VuZGVmaW5lZCcpIHJldHVybiB3YTtcblxuICB3YSA9IGZhbHNlO1xuXG4gIGlmICh0eXBlb2YgV2ViQXNzZW1ibHkgPT09ICd1bmRlZmluZWQnKSByZXR1cm4gd2E7XG5cbiAgLy8gSWYgV2ViQXNzZW5ibHkgaXMgZGlzYWJsZWQsIGNvZGUgY2FuIHRocm93IG9uIGNvbXBpbGVcbiAgdHJ5IHtcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vYnJpb24vbWluLXdhc20tZmFpbC9ibG9iL21hc3Rlci9taW4td2FzbS1mYWlsLmluLmpzXG4gICAgLy8gQWRkaXRpb25hbCBjaGVjayB0aGF0IFdBIGludGVybmFscyBhcmUgY29ycmVjdFxuXG4gICAgLyogZXNsaW50LWRpc2FibGUgY29tbWEtc3BhY2luZywgbWF4LWxlbiAqL1xuICAgIHZhciBiaW4gICAgICA9IG5ldyBVaW50OEFycmF5KFsgMCw5NywxMTUsMTA5LDEsMCwwLDAsMSw2LDEsOTYsMSwxMjcsMSwxMjcsMywyLDEsMCw1LDMsMSwwLDEsNyw4LDEsNCwxMTYsMTAxLDExNSwxMTYsMCwwLDEwLDE2LDEsMTQsMCwzMiwwLDY1LDEsNTQsMiwwLDMyLDAsNDAsMiwwLDExIF0pO1xuICAgIHZhciBtb2R1bGUgICA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUoYmluKTtcbiAgICB2YXIgaW5zdGFuY2UgPSBuZXcgV2ViQXNzZW1ibHkuSW5zdGFuY2UobW9kdWxlLCB7fSk7XG5cbiAgICAvLyB0ZXN0IHN0b3JpbmcgdG8gYW5kIGxvYWRpbmcgZnJvbSBhIG5vbi16ZXJvIGxvY2F0aW9uIHZpYSBhIHBhcmFtZXRlci5cbiAgICAvLyBTYWZhcmkgb24gaU9TIDExLjIuNSByZXR1cm5zIDAgdW5leHBlY3RlZGx5IGF0IG5vbi16ZXJvIGxvY2F0aW9uc1xuICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLnRlc3QoNCkgIT09IDApIHdhID0gdHJ1ZTtcblxuICAgIHJldHVybiB3YTtcbiAgfSBjYXRjaCAoX18pIHt9XG5cbiAgcmV0dXJuIHdhO1xufTtcblxufSx7fV0sMjM6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLypcbm9iamVjdC1hc3NpZ25cbihjKSBTaW5kcmUgU29yaHVzXG5AbGljZW5zZSBNSVRcbiovXG5cbid1c2Ugc3RyaWN0Jztcbi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG52YXIgZ2V0T3duUHJvcGVydHlTeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scztcbnZhciBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgcHJvcElzRW51bWVyYWJsZSA9IE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbmZ1bmN0aW9uIHRvT2JqZWN0KHZhbCkge1xuXHRpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignT2JqZWN0LmFzc2lnbiBjYW5ub3QgYmUgY2FsbGVkIHdpdGggbnVsbCBvciB1bmRlZmluZWQnKTtcblx0fVxuXG5cdHJldHVybiBPYmplY3QodmFsKTtcbn1cblxuZnVuY3Rpb24gc2hvdWxkVXNlTmF0aXZlKCkge1xuXHR0cnkge1xuXHRcdGlmICghT2JqZWN0LmFzc2lnbikge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIERldGVjdCBidWdneSBwcm9wZXJ0eSBlbnVtZXJhdGlvbiBvcmRlciBpbiBvbGRlciBWOCB2ZXJzaW9ucy5cblxuXHRcdC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTQxMThcblx0XHR2YXIgdGVzdDEgPSBuZXcgU3RyaW5nKCdhYmMnKTsgIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3LXdyYXBwZXJzXG5cdFx0dGVzdDFbNV0gPSAnZGUnO1xuXHRcdGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0ZXN0MSlbMF0gPT09ICc1Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTMwNTZcblx0XHR2YXIgdGVzdDIgPSB7fTtcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IDEwOyBpKyspIHtcblx0XHRcdHRlc3QyWydfJyArIFN0cmluZy5mcm9tQ2hhckNvZGUoaSldID0gaTtcblx0XHR9XG5cdFx0dmFyIG9yZGVyMiA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRlc3QyKS5tYXAoZnVuY3Rpb24gKG4pIHtcblx0XHRcdHJldHVybiB0ZXN0MltuXTtcblx0XHR9KTtcblx0XHRpZiAob3JkZXIyLmpvaW4oJycpICE9PSAnMDEyMzQ1Njc4OScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMDU2XG5cdFx0dmFyIHRlc3QzID0ge307XG5cdFx0J2FiY2RlZmdoaWprbG1ub3BxcnN0Jy5zcGxpdCgnJykuZm9yRWFjaChmdW5jdGlvbiAobGV0dGVyKSB7XG5cdFx0XHR0ZXN0M1tsZXR0ZXJdID0gbGV0dGVyO1xuXHRcdH0pO1xuXHRcdGlmIChPYmplY3Qua2V5cyhPYmplY3QuYXNzaWduKHt9LCB0ZXN0MykpLmpvaW4oJycpICE9PVxuXHRcdFx0XHQnYWJjZGVmZ2hpamtsbW5vcHFyc3QnKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRydWU7XG5cdH0gY2F0Y2ggKGVycikge1xuXHRcdC8vIFdlIGRvbid0IGV4cGVjdCBhbnkgb2YgdGhlIGFib3ZlIHRvIHRocm93LCBidXQgYmV0dGVyIHRvIGJlIHNhZmUuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2hvdWxkVXNlTmF0aXZlKCkgPyBPYmplY3QuYXNzaWduIDogZnVuY3Rpb24gKHRhcmdldCwgc291cmNlKSB7XG5cdHZhciBmcm9tO1xuXHR2YXIgdG8gPSB0b09iamVjdCh0YXJnZXQpO1xuXHR2YXIgc3ltYm9scztcblxuXHRmb3IgKHZhciBzID0gMTsgcyA8IGFyZ3VtZW50cy5sZW5ndGg7IHMrKykge1xuXHRcdGZyb20gPSBPYmplY3QoYXJndW1lbnRzW3NdKTtcblxuXHRcdGZvciAodmFyIGtleSBpbiBmcm9tKSB7XG5cdFx0XHRpZiAoaGFzT3duUHJvcGVydHkuY2FsbChmcm9tLCBrZXkpKSB7XG5cdFx0XHRcdHRvW2tleV0gPSBmcm9tW2tleV07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGdldE93blByb3BlcnR5U3ltYm9scykge1xuXHRcdFx0c3ltYm9scyA9IGdldE93blByb3BlcnR5U3ltYm9scyhmcm9tKTtcblx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgc3ltYm9scy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRpZiAocHJvcElzRW51bWVyYWJsZS5jYWxsKGZyb20sIHN5bWJvbHNbaV0pKSB7XG5cdFx0XHRcdFx0dG9bc3ltYm9sc1tpXV0gPSBmcm9tW3N5bWJvbHNbaV1dO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHRvO1xufTtcblxufSx7fV0sMjQ6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xudmFyIGJ1bmRsZUZuID0gYXJndW1lbnRzWzNdO1xudmFyIHNvdXJjZXMgPSBhcmd1bWVudHNbNF07XG52YXIgY2FjaGUgPSBhcmd1bWVudHNbNV07XG5cbnZhciBzdHJpbmdpZnkgPSBKU09OLnN0cmluZ2lmeTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZm4sIG9wdGlvbnMpIHtcbiAgICB2YXIgd2tleTtcbiAgICB2YXIgY2FjaGVLZXlzID0gT2JqZWN0LmtleXMoY2FjaGUpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjYWNoZUtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBjYWNoZUtleXNbaV07XG4gICAgICAgIHZhciBleHAgPSBjYWNoZVtrZXldLmV4cG9ydHM7XG4gICAgICAgIC8vIFVzaW5nIGJhYmVsIGFzIGEgdHJhbnNwaWxlciB0byB1c2UgZXNtb2R1bGUsIHRoZSBleHBvcnQgd2lsbCBhbHdheXNcbiAgICAgICAgLy8gYmUgYW4gb2JqZWN0IHdpdGggdGhlIGRlZmF1bHQgZXhwb3J0IGFzIGEgcHJvcGVydHkgb2YgaXQuIFRvIGVuc3VyZVxuICAgICAgICAvLyB0aGUgZXhpc3RpbmcgYXBpIGFuZCBiYWJlbCBlc21vZHVsZSBleHBvcnRzIGFyZSBib3RoIHN1cHBvcnRlZCB3ZVxuICAgICAgICAvLyBjaGVjayBmb3IgYm90aFxuICAgICAgICBpZiAoZXhwID09PSBmbiB8fCBleHAgJiYgZXhwLmRlZmF1bHQgPT09IGZuKSB7XG4gICAgICAgICAgICB3a2V5ID0ga2V5O1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXdrZXkpIHtcbiAgICAgICAgd2tleSA9IE1hdGguZmxvb3IoTWF0aC5wb3coMTYsIDgpICogTWF0aC5yYW5kb20oKSkudG9TdHJpbmcoMTYpO1xuICAgICAgICB2YXIgd2NhY2hlID0ge307XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gY2FjaGVLZXlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgdmFyIGtleSA9IGNhY2hlS2V5c1tpXTtcbiAgICAgICAgICAgIHdjYWNoZVtrZXldID0ga2V5O1xuICAgICAgICB9XG4gICAgICAgIHNvdXJjZXNbd2tleV0gPSBbXG4gICAgICAgICAgICAnZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7JyArIGZuICsgJyhzZWxmKTsgfScsXG4gICAgICAgICAgICB3Y2FjaGVcbiAgICAgICAgXTtcbiAgICB9XG4gICAgdmFyIHNrZXkgPSBNYXRoLmZsb29yKE1hdGgucG93KDE2LCA4KSAqIE1hdGgucmFuZG9tKCkpLnRvU3RyaW5nKDE2KTtcblxuICAgIHZhciBzY2FjaGUgPSB7fTsgc2NhY2hlW3drZXldID0gd2tleTtcbiAgICBzb3VyY2VzW3NrZXldID0gW1xuICAgICAgICAnZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7JyArXG4gICAgICAgICAgICAvLyB0cnkgdG8gY2FsbCBkZWZhdWx0IGlmIGRlZmluZWQgdG8gYWxzbyBzdXBwb3J0IGJhYmVsIGVzbW9kdWxlIGV4cG9ydHNcbiAgICAgICAgICAgICd2YXIgZiA9IHJlcXVpcmUoJyArIHN0cmluZ2lmeSh3a2V5KSArICcpOycgK1xuICAgICAgICAgICAgJyhmLmRlZmF1bHQgPyBmLmRlZmF1bHQgOiBmKShzZWxmKTsnICtcbiAgICAgICAgJ30nLFxuICAgICAgICBzY2FjaGVcbiAgICBdO1xuXG4gICAgdmFyIHdvcmtlclNvdXJjZXMgPSB7fTtcbiAgICByZXNvbHZlU291cmNlcyhza2V5KTtcblxuICAgIGZ1bmN0aW9uIHJlc29sdmVTb3VyY2VzKGtleSkge1xuICAgICAgICB3b3JrZXJTb3VyY2VzW2tleV0gPSB0cnVlO1xuXG4gICAgICAgIGZvciAodmFyIGRlcFBhdGggaW4gc291cmNlc1trZXldWzFdKSB7XG4gICAgICAgICAgICB2YXIgZGVwS2V5ID0gc291cmNlc1trZXldWzFdW2RlcFBhdGhdO1xuICAgICAgICAgICAgaWYgKCF3b3JrZXJTb3VyY2VzW2RlcEtleV0pIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlU291cmNlcyhkZXBLZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHNyYyA9ICcoJyArIGJ1bmRsZUZuICsgJykoeydcbiAgICAgICAgKyBPYmplY3Qua2V5cyh3b3JrZXJTb3VyY2VzKS5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgcmV0dXJuIHN0cmluZ2lmeShrZXkpICsgJzpbJ1xuICAgICAgICAgICAgICAgICsgc291cmNlc1trZXldWzBdXG4gICAgICAgICAgICAgICAgKyAnLCcgKyBzdHJpbmdpZnkoc291cmNlc1trZXldWzFdKSArICddJ1xuICAgICAgICAgICAgO1xuICAgICAgICB9KS5qb2luKCcsJylcbiAgICAgICAgKyAnfSx7fSxbJyArIHN0cmluZ2lmeShza2V5KSArICddKSdcbiAgICA7XG5cbiAgICB2YXIgVVJMID0gd2luZG93LlVSTCB8fCB3aW5kb3cud2Via2l0VVJMIHx8IHdpbmRvdy5tb3pVUkwgfHwgd2luZG93Lm1zVVJMO1xuXG4gICAgdmFyIGJsb2IgPSBuZXcgQmxvYihbc3JjXSwgeyB0eXBlOiAndGV4dC9qYXZhc2NyaXB0JyB9KTtcbiAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmJhcmUpIHsgcmV0dXJuIGJsb2I7IH1cbiAgICB2YXIgd29ya2VyVXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICB2YXIgd29ya2VyID0gbmV3IFdvcmtlcih3b3JrZXJVcmwpO1xuICAgIHdvcmtlci5vYmplY3RVUkwgPSB3b3JrZXJVcmw7XG4gICAgcmV0dXJuIHdvcmtlcjtcbn07XG5cbn0se31dLFwiL2luZGV4LmpzXCI6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBfc2xpY2VkVG9BcnJheShhcnIsIGkpIHsgcmV0dXJuIF9hcnJheVdpdGhIb2xlcyhhcnIpIHx8IF9pdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHx8IF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShhcnIsIGkpIHx8IF9ub25JdGVyYWJsZVJlc3QoKTsgfVxuXG5mdW5jdGlvbiBfbm9uSXRlcmFibGVSZXN0KCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIGRlc3RydWN0dXJlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpOyB9XG5cbmZ1bmN0aW9uIF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShvLCBtaW5MZW4pIHsgaWYgKCFvKSByZXR1cm47IGlmICh0eXBlb2YgbyA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIF9hcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7IHZhciBuID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pLnNsaWNlKDgsIC0xKTsgaWYgKG4gPT09IFwiT2JqZWN0XCIgJiYgby5jb25zdHJ1Y3RvcikgbiA9IG8uY29uc3RydWN0b3IubmFtZTsgaWYgKG4gPT09IFwiTWFwXCIgfHwgbiA9PT0gXCJTZXRcIikgcmV0dXJuIEFycmF5LmZyb20obyk7IGlmIChuID09PSBcIkFyZ3VtZW50c1wiIHx8IC9eKD86VWl8SSludCg/Ojh8MTZ8MzIpKD86Q2xhbXBlZCk/QXJyYXkkLy50ZXN0KG4pKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkobywgbWluTGVuKTsgfVxuXG5mdW5jdGlvbiBfYXJyYXlMaWtlVG9BcnJheShhcnIsIGxlbikgeyBpZiAobGVuID09IG51bGwgfHwgbGVuID4gYXJyLmxlbmd0aCkgbGVuID0gYXJyLmxlbmd0aDsgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBuZXcgQXJyYXkobGVuKTsgaSA8IGxlbjsgaSsrKSB7IGFycjJbaV0gPSBhcnJbaV07IH0gcmV0dXJuIGFycjI7IH1cblxuZnVuY3Rpb24gX2l0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkgeyB2YXIgX2kgPSBhcnIgPT0gbnVsbCA/IG51bGwgOiB0eXBlb2YgU3ltYm9sICE9PSBcInVuZGVmaW5lZFwiICYmIGFycltTeW1ib2wuaXRlcmF0b3JdIHx8IGFycltcIkBAaXRlcmF0b3JcIl07IGlmIChfaSA9PSBudWxsKSByZXR1cm47IHZhciBfYXJyID0gW107IHZhciBfbiA9IHRydWU7IHZhciBfZCA9IGZhbHNlOyB2YXIgX3MsIF9lOyB0cnkgeyBmb3IgKF9pID0gX2kuY2FsbChhcnIpOyAhKF9uID0gKF9zID0gX2kubmV4dCgpKS5kb25lKTsgX24gPSB0cnVlKSB7IF9hcnIucHVzaChfcy52YWx1ZSk7IGlmIChpICYmIF9hcnIubGVuZ3RoID09PSBpKSBicmVhazsgfSB9IGNhdGNoIChlcnIpIHsgX2QgPSB0cnVlOyBfZSA9IGVycjsgfSBmaW5hbGx5IHsgdHJ5IHsgaWYgKCFfbiAmJiBfaVtcInJldHVyblwiXSAhPSBudWxsKSBfaVtcInJldHVyblwiXSgpOyB9IGZpbmFsbHkgeyBpZiAoX2QpIHRocm93IF9lOyB9IH0gcmV0dXJuIF9hcnI7IH1cblxuZnVuY3Rpb24gX2FycmF5V2l0aEhvbGVzKGFycikgeyBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSByZXR1cm4gYXJyOyB9XG5cbnZhciBhc3NpZ24gPSBfZGVyZXFfKCdvYmplY3QtYXNzaWduJyk7XG5cbnZhciB3ZWJ3b3JraWZ5ID0gX2RlcmVxXygnd2Vid29ya2lmeScpO1xuXG52YXIgTWF0aExpYiA9IF9kZXJlcV8oJy4vbGliL21hdGhsaWInKTtcblxudmFyIFBvb2wgPSBfZGVyZXFfKCcuL2xpYi9wb29sJyk7XG5cbnZhciB1dGlscyA9IF9kZXJlcV8oJy4vbGliL3V0aWxzJyk7XG5cbnZhciB3b3JrZXIgPSBfZGVyZXFfKCcuL2xpYi93b3JrZXInKTtcblxudmFyIGNyZWF0ZVN0YWdlcyA9IF9kZXJlcV8oJy4vbGliL3N0ZXBwZXInKTtcblxudmFyIGNyZWF0ZVJlZ2lvbnMgPSBfZGVyZXFfKCcuL2xpYi90aWxlcicpOyAvLyBEZWR1cGxpY2F0ZSBwb29scyAmIGxpbWl0ZXJzIHdpdGggdGhlIHNhbWUgY29uZmlnc1xuLy8gd2hlbiB1c2VyIGNyZWF0ZXMgbXVsdGlwbGUgcGljYSBpbnN0YW5jZXMuXG5cblxudmFyIHNpbmdsZXRvbmVzID0ge307XG52YXIgTkVFRF9TQUZBUklfRklYID0gZmFsc2U7XG5cbnRyeSB7XG4gIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJyAmJiBuYXZpZ2F0b3IudXNlckFnZW50KSB7XG4gICAgTkVFRF9TQUZBUklfRklYID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdTYWZhcmknKSA+PSAwO1xuICB9XG59IGNhdGNoIChlKSB7fVxuXG52YXIgY29uY3VycmVuY3kgPSAxO1xuXG5pZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgY29uY3VycmVuY3kgPSBNYXRoLm1pbihuYXZpZ2F0b3IuaGFyZHdhcmVDb25jdXJyZW5jeSB8fCAxLCA0KTtcbn1cblxudmFyIERFRkFVTFRfUElDQV9PUFRTID0ge1xuICB0aWxlOiAxMDI0LFxuICBjb25jdXJyZW5jeTogY29uY3VycmVuY3ksXG4gIGZlYXR1cmVzOiBbJ2pzJywgJ3dhc20nLCAnd3cnXSxcbiAgaWRsZTogMjAwMCxcbiAgY3JlYXRlQ2FudmFzOiBmdW5jdGlvbiBjcmVhdGVDYW52YXMod2lkdGgsIGhlaWdodCkge1xuICAgIHZhciB0bXBDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICB0bXBDYW52YXMud2lkdGggPSB3aWR0aDtcbiAgICB0bXBDYW52YXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIHJldHVybiB0bXBDYW52YXM7XG4gIH1cbn07XG52YXIgREVGQVVMVF9SRVNJWkVfT1BUUyA9IHtcbiAgcXVhbGl0eTogMyxcbiAgYWxwaGE6IGZhbHNlLFxuICB1bnNoYXJwQW1vdW50OiAwLFxuICB1bnNoYXJwUmFkaXVzOiAwLjAsXG4gIHVuc2hhcnBUaHJlc2hvbGQ6IDBcbn07XG52YXIgQ0FOX05FV19JTUFHRV9EQVRBID0gZmFsc2U7XG52YXIgQ0FOX0NSRUFURV9JTUFHRV9CSVRNQVAgPSBmYWxzZTtcbnZhciBDQU5fVVNFX0NBTlZBU19HRVRfSU1BR0VfREFUQSA9IGZhbHNlO1xudmFyIENBTl9VU0VfT0ZGU0NSRUVOX0NBTlZBUyA9IGZhbHNlO1xudmFyIENBTl9VU0VfQ0lCX1JFR0lPTl9GT1JfSU1BR0UgPSBmYWxzZTtcblxuZnVuY3Rpb24gd29ya2VyRmFicmljKCkge1xuICByZXR1cm4ge1xuICAgIHZhbHVlOiB3ZWJ3b3JraWZ5KHdvcmtlciksXG4gICAgZGVzdHJveTogZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICAgIHRoaXMudmFsdWUudGVybWluYXRlKCk7XG5cbiAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB2YXIgdXJsID0gd2luZG93LlVSTCB8fCB3aW5kb3cud2Via2l0VVJMIHx8IHdpbmRvdy5tb3pVUkwgfHwgd2luZG93Lm1zVVJMO1xuXG4gICAgICAgIGlmICh1cmwgJiYgdXJsLnJldm9rZU9iamVjdFVSTCAmJiB0aGlzLnZhbHVlLm9iamVjdFVSTCkge1xuICAgICAgICAgIHVybC5yZXZva2VPYmplY3RVUkwodGhpcy52YWx1ZS5vYmplY3RVUkwpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xufSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gQVBJIG1ldGhvZHNcblxuXG5mdW5jdGlvbiBQaWNhKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFBpY2EpKSByZXR1cm4gbmV3IFBpY2Eob3B0aW9ucyk7XG4gIHRoaXMub3B0aW9ucyA9IGFzc2lnbih7fSwgREVGQVVMVF9QSUNBX09QVFMsIG9wdGlvbnMgfHwge30pO1xuICB2YXIgbGltaXRlcl9rZXkgPSBcImxrX1wiLmNvbmNhdCh0aGlzLm9wdGlvbnMuY29uY3VycmVuY3kpOyAvLyBTaGFyZSBsaW1pdGVycyB0byBhdm9pZCBtdWx0aXBsZSBwYXJhbGxlbCB3b3JrZXJzIHdoZW4gdXNlciBjcmVhdGVzXG4gIC8vIG11bHRpcGxlIHBpY2EgaW5zdGFuY2VzLlxuXG4gIHRoaXMuX19saW1pdCA9IHNpbmdsZXRvbmVzW2xpbWl0ZXJfa2V5XSB8fCB1dGlscy5saW1pdGVyKHRoaXMub3B0aW9ucy5jb25jdXJyZW5jeSk7XG4gIGlmICghc2luZ2xldG9uZXNbbGltaXRlcl9rZXldKSBzaW5nbGV0b25lc1tsaW1pdGVyX2tleV0gPSB0aGlzLl9fbGltaXQ7IC8vIExpc3Qgb2Ygc3VwcG9ydGVkIGZlYXR1cmVzLCBhY2NvcmRpbmcgdG8gb3B0aW9ucyAmIGJyb3dzZXIvbm9kZS5qc1xuXG4gIHRoaXMuZmVhdHVyZXMgPSB7XG4gICAganM6IGZhbHNlLFxuICAgIC8vIHB1cmUgSlMgaW1wbGVtZW50YXRpb24sIGNhbiBiZSBkaXNhYmxlZCBmb3IgdGVzdGluZ1xuICAgIHdhc206IGZhbHNlLFxuICAgIC8vIHdlYmFzc2VtYmx5IGltcGxlbWVudGF0aW9uIGZvciBoZWF2eSBmdW5jdGlvbnNcbiAgICBjaWI6IGZhbHNlLFxuICAgIC8vIHJlc2l6ZSB2aWEgY3JlYXRlSW1hZ2VCaXRtYXAgKG9ubHkgRkYgYXQgdGhpcyBtb21lbnQpXG4gICAgd3c6IGZhbHNlIC8vIHdlYndvcmtlcnNcblxuICB9O1xuICB0aGlzLl9fd29ya2Vyc1Bvb2wgPSBudWxsOyAvLyBTdG9yZSByZXF1ZXN0ZWQgZmVhdHVyZXMgZm9yIHdlYndvcmtlcnNcblxuICB0aGlzLl9fcmVxdWVzdGVkX2ZlYXR1cmVzID0gW107XG4gIHRoaXMuX19tYXRobGliID0gbnVsbDtcbn1cblxuUGljYS5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcblxuICBpZiAodGhpcy5fX2luaXRQcm9taXNlKSByZXR1cm4gdGhpcy5fX2luaXRQcm9taXNlOyAvLyBUZXN0IGlmIHdlIGNhbiBjcmVhdGUgSW1hZ2VEYXRhIHdpdGhvdXQgY2FudmFzIGFuZCBtZW1vcnkgY29weVxuXG4gIGlmICh0eXBlb2YgSW1hZ2VEYXRhICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgVWludDhDbGFtcGVkQXJyYXkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLW5ldyAqL1xuICAgICAgbmV3IEltYWdlRGF0YShuZXcgVWludDhDbGFtcGVkQXJyYXkoNDAwKSwgMTAsIDEwKTtcbiAgICAgIENBTl9ORVdfSU1BR0VfREFUQSA9IHRydWU7XG4gICAgfSBjYXRjaCAoX18pIHt9XG4gIH0gLy8gSW1hZ2VCaXRtYXAgY2FuIGJlIGVmZmVjdGl2ZSBpbiAyIHBsYWNlczpcbiAgLy9cbiAgLy8gMS4gVGhyZWFkZWQganBlZyB1bnBhY2sgKGJhc2ljKVxuICAvLyAyLiBCdWlsdC1pbiByZXNpemUgKGJsb2NrZWQgZHVlIHByb2JsZW0gaW4gY2hyb21lLCBzZWUgaXNzdWUgIzg5KVxuICAvL1xuICAvLyBGb3IgYmFzaWMgdXNlIHdlIGFsc28gbmVlZCBJbWFnZUJpdG1hcCB3byBzdXBwb3J0IC5jbG9zZSgpIG1ldGhvZCxcbiAgLy8gc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL3J1L2RvY3MvV2ViL0FQSS9JbWFnZUJpdG1hcFxuXG5cbiAgaWYgKHR5cGVvZiBJbWFnZUJpdG1hcCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAoSW1hZ2VCaXRtYXAucHJvdG90eXBlICYmIEltYWdlQml0bWFwLnByb3RvdHlwZS5jbG9zZSkge1xuICAgICAgQ0FOX0NSRUFURV9JTUFHRV9CSVRNQVAgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlYnVnKCdJbWFnZUJpdG1hcCBkb2VzIG5vdCBzdXBwb3J0IC5jbG9zZSgpLCBkaXNhYmxlZCcpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBmZWF0dXJlcyA9IHRoaXMub3B0aW9ucy5mZWF0dXJlcy5zbGljZSgpO1xuXG4gIGlmIChmZWF0dXJlcy5pbmRleE9mKCdhbGwnKSA+PSAwKSB7XG4gICAgZmVhdHVyZXMgPSBbJ2NpYicsICd3YXNtJywgJ2pzJywgJ3d3J107XG4gIH1cblxuICB0aGlzLl9fcmVxdWVzdGVkX2ZlYXR1cmVzID0gZmVhdHVyZXM7XG4gIHRoaXMuX19tYXRobGliID0gbmV3IE1hdGhMaWIoZmVhdHVyZXMpOyAvLyBDaGVjayBXZWJXb3JrZXIgc3VwcG9ydCBpZiByZXF1ZXN0ZWRcblxuICBpZiAoZmVhdHVyZXMuaW5kZXhPZignd3cnKSA+PSAwKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmICdXb3JrZXInIGluIHdpbmRvdykge1xuICAgICAgLy8gSUUgPD0gMTEgZG9uJ3QgYWxsb3cgdG8gY3JlYXRlIHdlYndvcmtlcnMgZnJvbSBzdHJpbmcuIFdlIHNob3VsZCBjaGVjayBpdC5cbiAgICAgIC8vIGh0dHBzOi8vY29ubmVjdC5taWNyb3NvZnQuY29tL0lFL2ZlZWRiYWNrL2RldGFpbHMvODAxODEwL3dlYi13b3JrZXJzLWZyb20tYmxvYi11cmxzLWluLWllLTEwLWFuZC0xMVxuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIHdrciA9IF9kZXJlcV8oJ3dlYndvcmtpZnknKShmdW5jdGlvbiAoKSB7fSk7XG5cbiAgICAgICAgd2tyLnRlcm1pbmF0ZSgpO1xuICAgICAgICB0aGlzLmZlYXR1cmVzLnd3ID0gdHJ1ZTsgLy8gcG9vbCB1bmlxdWVuZXNzIGRlcGVuZHMgb24gcG9vbCBjb25maWcgKyB3ZWJ3b3JrZXIgY29uZmlnXG5cbiAgICAgICAgdmFyIHdwb29sX2tleSA9IFwid3BfXCIuY29uY2F0KEpTT04uc3RyaW5naWZ5KHRoaXMub3B0aW9ucykpO1xuXG4gICAgICAgIGlmIChzaW5nbGV0b25lc1t3cG9vbF9rZXldKSB7XG4gICAgICAgICAgdGhpcy5fX3dvcmtlcnNQb29sID0gc2luZ2xldG9uZXNbd3Bvb2xfa2V5XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl9fd29ya2Vyc1Bvb2wgPSBuZXcgUG9vbCh3b3JrZXJGYWJyaWMsIHRoaXMub3B0aW9ucy5pZGxlKTtcbiAgICAgICAgICBzaW5nbGV0b25lc1t3cG9vbF9rZXldID0gdGhpcy5fX3dvcmtlcnNQb29sO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChfXykge31cbiAgICB9XG4gIH1cblxuICB2YXIgaW5pdE1hdGggPSB0aGlzLl9fbWF0aGxpYi5pbml0KCkudGhlbihmdW5jdGlvbiAobWF0aGxpYikge1xuICAgIC8vIENvcHkgZGV0ZWN0ZWQgZmVhdHVyZXNcbiAgICBhc3NpZ24oX3RoaXMuZmVhdHVyZXMsIG1hdGhsaWIuZmVhdHVyZXMpO1xuICB9KTtcblxuICB2YXIgY2hlY2tDaWJSZXNpemU7XG5cbiAgaWYgKCFDQU5fQ1JFQVRFX0lNQUdFX0JJVE1BUCkge1xuICAgIGNoZWNrQ2liUmVzaXplID0gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgfSBlbHNlIHtcbiAgICBjaGVja0NpYlJlc2l6ZSA9IHV0aWxzLmNpYl9zdXBwb3J0KHRoaXMub3B0aW9ucy5jcmVhdGVDYW52YXMpLnRoZW4oZnVuY3Rpb24gKHN0YXR1cykge1xuICAgICAgaWYgKF90aGlzLmZlYXR1cmVzLmNpYiAmJiBmZWF0dXJlcy5pbmRleE9mKCdjaWInKSA8IDApIHtcbiAgICAgICAgX3RoaXMuZGVidWcoJ2NyZWF0ZUltYWdlQml0bWFwKCkgcmVzaXplIHN1cHBvcnRlZCwgYnV0IGRpc2FibGVkIGJ5IGNvbmZpZycpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGZlYXR1cmVzLmluZGV4T2YoJ2NpYicpID49IDApIF90aGlzLmZlYXR1cmVzLmNpYiA9IHN0YXR1cztcbiAgICB9KTtcbiAgfVxuXG4gIENBTl9VU0VfQ0FOVkFTX0dFVF9JTUFHRV9EQVRBID0gdXRpbHMuY2FuX3VzZV9jYW52YXModGhpcy5vcHRpb25zLmNyZWF0ZUNhbnZhcyk7XG4gIHZhciBjaGVja09mZnNjcmVlbkNhbnZhcztcblxuICBpZiAoQ0FOX0NSRUFURV9JTUFHRV9CSVRNQVAgJiYgQ0FOX05FV19JTUFHRV9EQVRBICYmIGZlYXR1cmVzLmluZGV4T2YoJ3d3JykgIT09IC0xKSB7XG4gICAgY2hlY2tPZmZzY3JlZW5DYW52YXMgPSB1dGlscy53b3JrZXJfb2Zmc2NyZWVuX2NhbnZhc19zdXBwb3J0KCk7XG4gIH0gZWxzZSB7XG4gICAgY2hlY2tPZmZzY3JlZW5DYW52YXMgPSBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xuICB9XG5cbiAgY2hlY2tPZmZzY3JlZW5DYW52YXMgPSBjaGVja09mZnNjcmVlbkNhbnZhcy50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICBDQU5fVVNFX09GRlNDUkVFTl9DQU5WQVMgPSByZXN1bHQ7XG4gIH0pOyAvLyB3ZSB1c2UgY3JlYXRlSW1hZ2VCaXRtYXAgdG8gY3JvcCBpbWFnZSBkYXRhIGFuZCBwYXNzIGl0IHRvIHdvcmtlcnMsXG4gIC8vIHNvIG5lZWQgdG8gY2hlY2sgd2hldGhlciBmdW5jdGlvbiB3b3JrcyBjb3JyZWN0bHk7XG4gIC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTEyMjA2NzFcblxuICB2YXIgY2hlY2tDaWJSZWdpb24gPSB1dGlscy5jaWJfY2FuX3VzZV9yZWdpb24oKS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICBDQU5fVVNFX0NJQl9SRUdJT05fRk9SX0lNQUdFID0gcmVzdWx0O1xuICB9KTsgLy8gSW5pdCBtYXRoIGxpYi4gVGhhdCdzIGFzeW5jIGJlY2F1c2UgY2FuIGxvYWQgc29tZVxuXG4gIHRoaXMuX19pbml0UHJvbWlzZSA9IFByb21pc2UuYWxsKFtpbml0TWF0aCwgY2hlY2tDaWJSZXNpemUsIGNoZWNrT2Zmc2NyZWVuQ2FudmFzLCBjaGVja0NpYlJlZ2lvbl0pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdGhpcztcbiAgfSk7XG4gIHJldHVybiB0aGlzLl9faW5pdFByb21pc2U7XG59OyAvLyBDYWxsIHJlc2l6ZXIgaW4gd2Vid29ya2VyIG9yIGxvY2FsbHksIGRlcGVuZGluZyBvbiBjb25maWdcblxuXG5QaWNhLnByb3RvdHlwZS5fX2ludm9rZVJlc2l6ZSA9IGZ1bmN0aW9uICh0aWxlT3B0cywgb3B0cykge1xuICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAvLyBTaGFyZSBjYWNoZSBiZXR3ZWVuIGNhbGxzOlxuICAvL1xuICAvLyAtIHdhc20gaW5zdGFuY2VcbiAgLy8gLSB3YXNtIG1lbW9yeSBvYmplY3RcbiAgLy9cbiAgb3B0cy5fX21hdGhDYWNoZSA9IG9wdHMuX19tYXRoQ2FjaGUgfHwge307XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIV90aGlzMi5mZWF0dXJlcy53dykge1xuICAgICAgLy8gbm90IHBvc3NpYmxlIHRvIGhhdmUgSW1hZ2VCaXRtYXAgaGVyZSBpZiB1c2VyIGRpc2FibGVkIFdXXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkYXRhOiBfdGhpczIuX19tYXRobGliLnJlc2l6ZUFuZFVuc2hhcnAodGlsZU9wdHMsIG9wdHMuX19tYXRoQ2FjaGUpXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgdyA9IF90aGlzMi5fX3dvcmtlcnNQb29sLmFjcXVpcmUoKTtcblxuICAgICAgaWYgKG9wdHMuY2FuY2VsVG9rZW4pIG9wdHMuY2FuY2VsVG9rZW5bXCJjYXRjaFwiXShmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgIH0pO1xuXG4gICAgICB3LnZhbHVlLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICB3LnJlbGVhc2UoKTtcbiAgICAgICAgaWYgKGV2LmRhdGEuZXJyKSByZWplY3QoZXYuZGF0YS5lcnIpO2Vsc2UgcmVzb2x2ZShldi5kYXRhKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciB0cmFuc2ZlciA9IFtdO1xuICAgICAgaWYgKHRpbGVPcHRzLnNyYykgdHJhbnNmZXIucHVzaCh0aWxlT3B0cy5zcmMuYnVmZmVyKTtcbiAgICAgIGlmICh0aWxlT3B0cy5zcmNCaXRtYXApIHRyYW5zZmVyLnB1c2godGlsZU9wdHMuc3JjQml0bWFwKTtcbiAgICAgIHcudmFsdWUucG9zdE1lc3NhZ2Uoe1xuICAgICAgICBvcHRzOiB0aWxlT3B0cyxcbiAgICAgICAgZmVhdHVyZXM6IF90aGlzMi5fX3JlcXVlc3RlZF9mZWF0dXJlcyxcbiAgICAgICAgcHJlbG9hZDoge1xuICAgICAgICAgIHdhc21fbm9kdWxlOiBfdGhpczIuX19tYXRobGliLl9fXG4gICAgICAgIH1cbiAgICAgIH0sIHRyYW5zZmVyKTtcbiAgICB9KTtcbiAgfSk7XG59OyAvLyB0aGlzIGZ1bmN0aW9uIGNhbiByZXR1cm4gcHJvbWlzZSBpZiBjcmVhdGVJbWFnZUJpdG1hcCBpcyB1c2VkXG5cblxuUGljYS5wcm90b3R5cGUuX19leHRyYWN0VGlsZURhdGEgPSBmdW5jdGlvbiAodGlsZSwgZnJvbSwgb3B0cywgc3RhZ2VFbnYsIGV4dHJhY3RUbykge1xuICBpZiAodGhpcy5mZWF0dXJlcy53dyAmJiBDQU5fVVNFX09GRlNDUkVFTl9DQU5WQVMgJiYgKCAvLyBjcmVhdGVJbWFnZUJpdG1hcCBkb2Vzbid0IHdvcmsgZm9yIGltYWdlcyAoSW1hZ2UsIEltYWdlQml0bWFwKSB3aXRoIEV4aWYgb3JpZW50YXRpb24gaW4gQ2hyb21lLFxuICAvLyBjYW4gdXNlIGNhbnZhcyBiZWNhdXNlIGNhbnZhcyBkb2Vzbid0IGhhdmUgb3JpZW50YXRpb247XG4gIC8vIHNlZSBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0xMjIwNjcxXG4gIHV0aWxzLmlzQ2FudmFzKGZyb20pIHx8IENBTl9VU0VfQ0lCX1JFR0lPTl9GT1JfSU1BR0UpKSB7XG4gICAgdGhpcy5kZWJ1ZygnQ3JlYXRlIHRpbGUgZm9yIE9mZnNjcmVlbkNhbnZhcycpO1xuICAgIHJldHVybiBjcmVhdGVJbWFnZUJpdG1hcChzdGFnZUVudi5zcmNJbWFnZUJpdG1hcCB8fCBmcm9tLCB0aWxlLngsIHRpbGUueSwgdGlsZS53aWR0aCwgdGlsZS5oZWlnaHQpLnRoZW4oZnVuY3Rpb24gKGJpdG1hcCkge1xuICAgICAgZXh0cmFjdFRvLnNyY0JpdG1hcCA9IGJpdG1hcDtcbiAgICAgIHJldHVybiBleHRyYWN0VG87XG4gICAgfSk7XG4gIH0gLy8gRXh0cmFjdCB0aWxlIFJHQkEgYnVmZmVyLCBkZXBlbmRpbmcgb24gaW5wdXQgdHlwZVxuXG5cbiAgaWYgKHV0aWxzLmlzQ2FudmFzKGZyb20pKSB7XG4gICAgaWYgKCFzdGFnZUVudi5zcmNDdHgpIHN0YWdlRW52LnNyY0N0eCA9IGZyb20uZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgICBhbHBoYTogQm9vbGVhbihvcHRzLmFscGhhKVxuICAgIH0pOyAvLyBJZiBpbnB1dCBpcyBDYW52YXMgLSBleHRyYWN0IHJlZ2lvbiBkYXRhIGRpcmVjdGx5XG5cbiAgICB0aGlzLmRlYnVnKCdHZXQgdGlsZSBwaXhlbCBkYXRhJyk7XG4gICAgZXh0cmFjdFRvLnNyYyA9IHN0YWdlRW52LnNyY0N0eC5nZXRJbWFnZURhdGEodGlsZS54LCB0aWxlLnksIHRpbGUud2lkdGgsIHRpbGUuaGVpZ2h0KS5kYXRhO1xuICAgIHJldHVybiBleHRyYWN0VG87XG4gIH0gLy8gSWYgaW5wdXQgaXMgSW1hZ2Ugb3IgZGVjb2RlZCB0byBJbWFnZUJpdG1hcCxcbiAgLy8gZHJhdyByZWdpb24gdG8gdGVtcG9yYXJ5IGNhbnZhcyBhbmQgZXh0cmFjdCBkYXRhIGZyb20gaXRcbiAgLy9cbiAgLy8gTm90ZSEgQXR0ZW1wdCB0byByZXVzZSB0aGlzIGNhbnZhcyBjYXVzZXMgc2lnbmlmaWNhbnQgc2xvd2Rvd24gaW4gY2hyb21lXG4gIC8vXG5cblxuICB0aGlzLmRlYnVnKCdEcmF3IHRpbGUgaW1hZ2VCaXRtYXAvaW1hZ2UgdG8gdGVtcG9yYXJ5IGNhbnZhcycpO1xuICB2YXIgdG1wQ2FudmFzID0gdGhpcy5vcHRpb25zLmNyZWF0ZUNhbnZhcyh0aWxlLndpZHRoLCB0aWxlLmhlaWdodCk7XG4gIHZhciB0bXBDdHggPSB0bXBDYW52YXMuZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgYWxwaGE6IEJvb2xlYW4ob3B0cy5hbHBoYSlcbiAgfSk7XG4gIHRtcEN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSAnY29weSc7XG4gIHRtcEN0eC5kcmF3SW1hZ2Uoc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXAgfHwgZnJvbSwgdGlsZS54LCB0aWxlLnksIHRpbGUud2lkdGgsIHRpbGUuaGVpZ2h0LCAwLCAwLCB0aWxlLndpZHRoLCB0aWxlLmhlaWdodCk7XG4gIHRoaXMuZGVidWcoJ0dldCB0aWxlIHBpeGVsIGRhdGEnKTtcbiAgZXh0cmFjdFRvLnNyYyA9IHRtcEN0eC5nZXRJbWFnZURhdGEoMCwgMCwgdGlsZS53aWR0aCwgdGlsZS5oZWlnaHQpLmRhdGE7IC8vIFNhZmFyaSAxMiB3b3JrYXJvdW5kXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYS9pc3N1ZXMvMTk5XG5cbiAgdG1wQ2FudmFzLndpZHRoID0gdG1wQ2FudmFzLmhlaWdodCA9IDA7XG4gIHJldHVybiBleHRyYWN0VG87XG59O1xuXG5QaWNhLnByb3RvdHlwZS5fX2xhbmRUaWxlRGF0YSA9IGZ1bmN0aW9uICh0aWxlLCByZXN1bHQsIHN0YWdlRW52KSB7XG4gIHZhciB0b0ltYWdlRGF0YTtcbiAgdGhpcy5kZWJ1ZygnQ29udmVydCByYXcgcmdiYSB0aWxlIHJlc3VsdCB0byBJbWFnZURhdGEnKTtcblxuICBpZiAocmVzdWx0LmJpdG1hcCkge1xuICAgIHN0YWdlRW52LnRvQ3R4LmRyYXdJbWFnZShyZXN1bHQuYml0bWFwLCB0aWxlLnRvWCwgdGlsZS50b1kpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKENBTl9ORVdfSU1BR0VfREFUQSkge1xuICAgIC8vIHRoaXMgYnJhbmNoIGlzIGZvciBtb2Rlcm4gYnJvd3NlcnNcbiAgICAvLyBJZiBgbmV3IEltYWdlRGF0YSgpYCAmIFVpbnQ4Q2xhbXBlZEFycmF5IHN1cG9ydGVkXG4gICAgdG9JbWFnZURhdGEgPSBuZXcgSW1hZ2VEYXRhKG5ldyBVaW50OENsYW1wZWRBcnJheShyZXN1bHQuZGF0YSksIHRpbGUudG9XaWR0aCwgdGlsZS50b0hlaWdodCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gZmFsbGJhY2sgZm9yIGBub2RlLWNhbnZhc2AgYW5kIG9sZCBicm93c2Vyc1xuICAgIC8vIChJRTExIGhhcyBJbWFnZURhdGEgYnV0IGRvZXMgbm90IHN1cHBvcnQgYG5ldyBJbWFnZURhdGEoKWApXG4gICAgdG9JbWFnZURhdGEgPSBzdGFnZUVudi50b0N0eC5jcmVhdGVJbWFnZURhdGEodGlsZS50b1dpZHRoLCB0aWxlLnRvSGVpZ2h0KTtcblxuICAgIGlmICh0b0ltYWdlRGF0YS5kYXRhLnNldCkge1xuICAgICAgdG9JbWFnZURhdGEuZGF0YS5zZXQocmVzdWx0LmRhdGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJRTkgZG9uJ3QgaGF2ZSBgLnNldCgpYFxuICAgICAgZm9yICh2YXIgaSA9IHRvSW1hZ2VEYXRhLmRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgdG9JbWFnZURhdGEuZGF0YVtpXSA9IHJlc3VsdC5kYXRhW2ldO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRoaXMuZGVidWcoJ0RyYXcgdGlsZScpO1xuXG4gIGlmIChORUVEX1NBRkFSSV9GSVgpIHtcbiAgICAvLyBTYWZhcmkgZHJhd3MgdGhpbiB3aGl0ZSBzdHJpcGVzIGJldHdlZW4gdGlsZXMgd2l0aG91dCB0aGlzIGZpeFxuICAgIHN0YWdlRW52LnRvQ3R4LnB1dEltYWdlRGF0YSh0b0ltYWdlRGF0YSwgdGlsZS50b1gsIHRpbGUudG9ZLCB0aWxlLnRvSW5uZXJYIC0gdGlsZS50b1gsIHRpbGUudG9Jbm5lclkgLSB0aWxlLnRvWSwgdGlsZS50b0lubmVyV2lkdGggKyAxZS01LCB0aWxlLnRvSW5uZXJIZWlnaHQgKyAxZS01KTtcbiAgfSBlbHNlIHtcbiAgICBzdGFnZUVudi50b0N0eC5wdXRJbWFnZURhdGEodG9JbWFnZURhdGEsIHRpbGUudG9YLCB0aWxlLnRvWSwgdGlsZS50b0lubmVyWCAtIHRpbGUudG9YLCB0aWxlLnRvSW5uZXJZIC0gdGlsZS50b1ksIHRpbGUudG9Jbm5lcldpZHRoLCB0aWxlLnRvSW5uZXJIZWlnaHQpO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5QaWNhLnByb3RvdHlwZS5fX3RpbGVBbmRSZXNpemUgPSBmdW5jdGlvbiAoZnJvbSwgdG8sIG9wdHMpIHtcbiAgdmFyIF90aGlzMyA9IHRoaXM7XG5cbiAgdmFyIHN0YWdlRW52ID0ge1xuICAgIHNyY0N0eDogbnVsbCxcbiAgICBzcmNJbWFnZUJpdG1hcDogbnVsbCxcbiAgICBpc0ltYWdlQml0bWFwUmV1c2VkOiBmYWxzZSxcbiAgICB0b0N0eDogbnVsbFxuICB9O1xuXG4gIHZhciBwcm9jZXNzVGlsZSA9IGZ1bmN0aW9uIHByb2Nlc3NUaWxlKHRpbGUpIHtcbiAgICByZXR1cm4gX3RoaXMzLl9fbGltaXQoZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKG9wdHMuY2FuY2VsZWQpIHJldHVybiBvcHRzLmNhbmNlbFRva2VuO1xuICAgICAgdmFyIHRpbGVPcHRzID0ge1xuICAgICAgICB3aWR0aDogdGlsZS53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiB0aWxlLmhlaWdodCxcbiAgICAgICAgdG9XaWR0aDogdGlsZS50b1dpZHRoLFxuICAgICAgICB0b0hlaWdodDogdGlsZS50b0hlaWdodCxcbiAgICAgICAgc2NhbGVYOiB0aWxlLnNjYWxlWCxcbiAgICAgICAgc2NhbGVZOiB0aWxlLnNjYWxlWSxcbiAgICAgICAgb2Zmc2V0WDogdGlsZS5vZmZzZXRYLFxuICAgICAgICBvZmZzZXRZOiB0aWxlLm9mZnNldFksXG4gICAgICAgIHF1YWxpdHk6IG9wdHMucXVhbGl0eSxcbiAgICAgICAgYWxwaGE6IG9wdHMuYWxwaGEsXG4gICAgICAgIHVuc2hhcnBBbW91bnQ6IG9wdHMudW5zaGFycEFtb3VudCxcbiAgICAgICAgdW5zaGFycFJhZGl1czogb3B0cy51bnNoYXJwUmFkaXVzLFxuICAgICAgICB1bnNoYXJwVGhyZXNob2xkOiBvcHRzLnVuc2hhcnBUaHJlc2hvbGRcbiAgICAgIH07XG5cbiAgICAgIF90aGlzMy5kZWJ1ZygnSW52b2tlIHJlc2l6ZSBtYXRoJyk7XG5cbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGlsZU9wdHMpLnRoZW4oZnVuY3Rpb24gKHRpbGVPcHRzKSB7XG4gICAgICAgIHJldHVybiBfdGhpczMuX19leHRyYWN0VGlsZURhdGEodGlsZSwgZnJvbSwgb3B0cywgc3RhZ2VFbnYsIHRpbGVPcHRzKTtcbiAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHRpbGVPcHRzKSB7XG4gICAgICAgIF90aGlzMy5kZWJ1ZygnSW52b2tlIHJlc2l6ZSBtYXRoJyk7XG5cbiAgICAgICAgcmV0dXJuIF90aGlzMy5fX2ludm9rZVJlc2l6ZSh0aWxlT3B0cywgb3B0cyk7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgaWYgKG9wdHMuY2FuY2VsZWQpIHJldHVybiBvcHRzLmNhbmNlbFRva2VuO1xuICAgICAgICBzdGFnZUVudi5zcmNJbWFnZURhdGEgPSBudWxsO1xuICAgICAgICByZXR1cm4gX3RoaXMzLl9fbGFuZFRpbGVEYXRhKHRpbGUsIHJlc3VsdCwgc3RhZ2VFbnYpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07IC8vIE5lZWQgdG8gbm9ybWFsaXplIGRhdGEgc291cmNlIGZpcnN0LiBJdCBjYW4gYmUgY2FudmFzIG9yIGltYWdlLlxuICAvLyBJZiBpbWFnZSAtIHRyeSB0byBkZWNvZGUgaW4gYmFja2dyb3VuZCBpZiBwb3NzaWJsZVxuXG5cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIHN0YWdlRW52LnRvQ3R4ID0gdG8uZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgICBhbHBoYTogQm9vbGVhbihvcHRzLmFscGhhKVxuICAgIH0pO1xuICAgIGlmICh1dGlscy5pc0NhbnZhcyhmcm9tKSkgcmV0dXJuIG51bGw7XG5cbiAgICBpZiAodXRpbHMuaXNJbWFnZUJpdG1hcChmcm9tKSkge1xuICAgICAgc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXAgPSBmcm9tO1xuICAgICAgc3RhZ2VFbnYuaXNJbWFnZUJpdG1hcFJldXNlZCA9IHRydWU7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodXRpbHMuaXNJbWFnZShmcm9tKSkge1xuICAgICAgLy8gdHJ5IGRvIGRlY29kZSBpbWFnZSBpbiBiYWNrZ3JvdW5kIGZvciBmYXN0ZXIgbmV4dCBvcGVyYXRpb25zO1xuICAgICAgLy8gaWYgd2UncmUgdXNpbmcgb2Zmc2NyZWVuIGNhbnZhcywgY2liIGlzIGNhbGxlZCBwZXIgdGlsZSwgc28gbm90IG5lZWRlZCBoZXJlXG4gICAgICBpZiAoIUNBTl9DUkVBVEVfSU1BR0VfQklUTUFQKSByZXR1cm4gbnVsbDtcblxuICAgICAgX3RoaXMzLmRlYnVnKCdEZWNvZGUgaW1hZ2UgdmlhIGNyZWF0ZUltYWdlQml0bWFwJyk7XG5cbiAgICAgIHJldHVybiBjcmVhdGVJbWFnZUJpdG1hcChmcm9tKS50aGVuKGZ1bmN0aW9uIChpbWFnZUJpdG1hcCkge1xuICAgICAgICBzdGFnZUVudi5zcmNJbWFnZUJpdG1hcCA9IGltYWdlQml0bWFwO1xuICAgICAgfSkgLy8gU3VwcHJlc3MgZXJyb3IgdG8gdXNlIGZhbGxiYWNrLCBpZiBtZXRob2QgZmFpbHNcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYS9pc3N1ZXMvMTkwXG5cbiAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG4gICAgICBbXCJjYXRjaFwiXShmdW5jdGlvbiAoZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcignUGljYTogXCIuZnJvbVwiIHNob3VsZCBiZSBJbWFnZSwgQ2FudmFzIG9yIEltYWdlQml0bWFwJyk7XG4gIH0pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIGlmIChvcHRzLmNhbmNlbGVkKSByZXR1cm4gb3B0cy5jYW5jZWxUb2tlbjtcblxuICAgIF90aGlzMy5kZWJ1ZygnQ2FsY3VsYXRlIHRpbGVzJyk7IC8vXG4gICAgLy8gSGVyZSB3ZSBhcmUgd2l0aCBcIm5vcm1hbGl6ZWRcIiBzb3VyY2UsXG4gICAgLy8gZm9sbG93IHRvIHRpbGluZ1xuICAgIC8vXG5cblxuICAgIHZhciByZWdpb25zID0gY3JlYXRlUmVnaW9ucyh7XG4gICAgICB3aWR0aDogb3B0cy53aWR0aCxcbiAgICAgIGhlaWdodDogb3B0cy5oZWlnaHQsXG4gICAgICBzcmNUaWxlU2l6ZTogX3RoaXMzLm9wdGlvbnMudGlsZSxcbiAgICAgIHRvV2lkdGg6IG9wdHMudG9XaWR0aCxcbiAgICAgIHRvSGVpZ2h0OiBvcHRzLnRvSGVpZ2h0LFxuICAgICAgZGVzdFRpbGVCb3JkZXI6IG9wdHMuX19kZXN0VGlsZUJvcmRlclxuICAgIH0pO1xuICAgIHZhciBqb2JzID0gcmVnaW9ucy5tYXAoZnVuY3Rpb24gKHRpbGUpIHtcbiAgICAgIHJldHVybiBwcm9jZXNzVGlsZSh0aWxlKTtcbiAgICB9KTtcblxuICAgIGZ1bmN0aW9uIGNsZWFudXAoc3RhZ2VFbnYpIHtcbiAgICAgIGlmIChzdGFnZUVudi5zcmNJbWFnZUJpdG1hcCkge1xuICAgICAgICBpZiAoIXN0YWdlRW52LmlzSW1hZ2VCaXRtYXBSZXVzZWQpIHN0YWdlRW52LnNyY0ltYWdlQml0bWFwLmNsb3NlKCk7XG4gICAgICAgIHN0YWdlRW52LnNyY0ltYWdlQml0bWFwID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBfdGhpczMuZGVidWcoJ1Byb2Nlc3MgdGlsZXMnKTtcblxuICAgIHJldHVybiBQcm9taXNlLmFsbChqb2JzKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIF90aGlzMy5kZWJ1ZygnRmluaXNoZWQhJyk7XG5cbiAgICAgIGNsZWFudXAoc3RhZ2VFbnYpO1xuICAgICAgcmV0dXJuIHRvO1xuICAgIH0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIGNsZWFudXAoc3RhZ2VFbnYpO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH0pO1xuICB9KTtcbn07XG5cblBpY2EucHJvdG90eXBlLl9fcHJvY2Vzc1N0YWdlcyA9IGZ1bmN0aW9uIChzdGFnZXMsIGZyb20sIHRvLCBvcHRzKSB7XG4gIHZhciBfdGhpczQgPSB0aGlzO1xuXG4gIGlmIChvcHRzLmNhbmNlbGVkKSByZXR1cm4gb3B0cy5jYW5jZWxUb2tlbjtcblxuICB2YXIgX3N0YWdlcyRzaGlmdCA9IHN0YWdlcy5zaGlmdCgpLFxuICAgICAgX3N0YWdlcyRzaGlmdDIgPSBfc2xpY2VkVG9BcnJheShfc3RhZ2VzJHNoaWZ0LCAyKSxcbiAgICAgIHRvV2lkdGggPSBfc3RhZ2VzJHNoaWZ0MlswXSxcbiAgICAgIHRvSGVpZ2h0ID0gX3N0YWdlcyRzaGlmdDJbMV07XG5cbiAgdmFyIGlzTGFzdFN0YWdlID0gc3RhZ2VzLmxlbmd0aCA9PT0gMDtcbiAgb3B0cyA9IGFzc2lnbih7fSwgb3B0cywge1xuICAgIHRvV2lkdGg6IHRvV2lkdGgsXG4gICAgdG9IZWlnaHQ6IHRvSGVpZ2h0LFxuICAgIC8vIG9ubHkgdXNlIHVzZXItZGVmaW5lZCBxdWFsaXR5IGZvciB0aGUgbGFzdCBzdGFnZSxcbiAgICAvLyB1c2Ugc2ltcGxlciAoSGFtbWluZykgZmlsdGVyIGZvciB0aGUgZmlyc3Qgc3RhZ2VzIHdoZXJlXG4gICAgLy8gc2NhbGUgZmFjdG9yIGlzIGxhcmdlIGVub3VnaCAobW9yZSB0aGFuIDItMylcbiAgICBxdWFsaXR5OiBpc0xhc3RTdGFnZSA/IG9wdHMucXVhbGl0eSA6IE1hdGgubWluKDEsIG9wdHMucXVhbGl0eSlcbiAgfSk7XG4gIHZhciB0bXBDYW52YXM7XG5cbiAgaWYgKCFpc0xhc3RTdGFnZSkge1xuICAgIC8vIGNyZWF0ZSB0ZW1wb3JhcnkgY2FudmFzXG4gICAgdG1wQ2FudmFzID0gdGhpcy5vcHRpb25zLmNyZWF0ZUNhbnZhcyh0b1dpZHRoLCB0b0hlaWdodCk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fX3RpbGVBbmRSZXNpemUoZnJvbSwgaXNMYXN0U3RhZ2UgPyB0byA6IHRtcENhbnZhcywgb3B0cykudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGlzTGFzdFN0YWdlKSByZXR1cm4gdG87XG4gICAgb3B0cy53aWR0aCA9IHRvV2lkdGg7XG4gICAgb3B0cy5oZWlnaHQgPSB0b0hlaWdodDtcbiAgICByZXR1cm4gX3RoaXM0Ll9fcHJvY2Vzc1N0YWdlcyhzdGFnZXMsIHRtcENhbnZhcywgdG8sIG9wdHMpO1xuICB9KS50aGVuKGZ1bmN0aW9uIChyZXMpIHtcbiAgICBpZiAodG1wQ2FudmFzKSB7XG4gICAgICAvLyBTYWZhcmkgMTIgd29ya2Fyb3VuZFxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhL2lzc3Vlcy8xOTlcbiAgICAgIHRtcENhbnZhcy53aWR0aCA9IHRtcENhbnZhcy5oZWlnaHQgPSAwO1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH0pO1xufTtcblxuUGljYS5wcm90b3R5cGUuX19yZXNpemVWaWFDcmVhdGVJbWFnZUJpdG1hcCA9IGZ1bmN0aW9uIChmcm9tLCB0bywgb3B0cykge1xuICB2YXIgX3RoaXM1ID0gdGhpcztcblxuICB2YXIgdG9DdHggPSB0by5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICBhbHBoYTogQm9vbGVhbihvcHRzLmFscGhhKVxuICB9KTtcbiAgdGhpcy5kZWJ1ZygnUmVzaXplIHZpYSBjcmVhdGVJbWFnZUJpdG1hcCgpJyk7XG4gIHJldHVybiBjcmVhdGVJbWFnZUJpdG1hcChmcm9tLCB7XG4gICAgcmVzaXplV2lkdGg6IG9wdHMudG9XaWR0aCxcbiAgICByZXNpemVIZWlnaHQ6IG9wdHMudG9IZWlnaHQsXG4gICAgcmVzaXplUXVhbGl0eTogdXRpbHMuY2liX3F1YWxpdHlfbmFtZShvcHRzLnF1YWxpdHkpXG4gIH0pLnRoZW4oZnVuY3Rpb24gKGltYWdlQml0bWFwKSB7XG4gICAgaWYgKG9wdHMuY2FuY2VsZWQpIHJldHVybiBvcHRzLmNhbmNlbFRva2VuOyAvLyBpZiBubyB1bnNoYXJwIC0gZHJhdyBkaXJlY3RseSB0byBvdXRwdXQgY2FudmFzXG5cbiAgICBpZiAoIW9wdHMudW5zaGFycEFtb3VudCkge1xuICAgICAgdG9DdHguZHJhd0ltYWdlKGltYWdlQml0bWFwLCAwLCAwKTtcbiAgICAgIGltYWdlQml0bWFwLmNsb3NlKCk7XG4gICAgICB0b0N0eCA9IG51bGw7XG5cbiAgICAgIF90aGlzNS5kZWJ1ZygnRmluaXNoZWQhJyk7XG5cbiAgICAgIHJldHVybiB0bztcbiAgICB9XG5cbiAgICBfdGhpczUuZGVidWcoJ1Vuc2hhcnAgcmVzdWx0Jyk7XG5cbiAgICB2YXIgdG1wQ2FudmFzID0gX3RoaXM1Lm9wdGlvbnMuY3JlYXRlQ2FudmFzKG9wdHMudG9XaWR0aCwgb3B0cy50b0hlaWdodCk7XG5cbiAgICB2YXIgdG1wQ3R4ID0gdG1wQ2FudmFzLmdldENvbnRleHQoJzJkJywge1xuICAgICAgYWxwaGE6IEJvb2xlYW4ob3B0cy5hbHBoYSlcbiAgICB9KTtcbiAgICB0bXBDdHguZHJhd0ltYWdlKGltYWdlQml0bWFwLCAwLCAwKTtcbiAgICBpbWFnZUJpdG1hcC5jbG9zZSgpO1xuICAgIHZhciBpRGF0YSA9IHRtcEN0eC5nZXRJbWFnZURhdGEoMCwgMCwgb3B0cy50b1dpZHRoLCBvcHRzLnRvSGVpZ2h0KTtcblxuICAgIF90aGlzNS5fX21hdGhsaWIudW5zaGFycF9tYXNrKGlEYXRhLmRhdGEsIG9wdHMudG9XaWR0aCwgb3B0cy50b0hlaWdodCwgb3B0cy51bnNoYXJwQW1vdW50LCBvcHRzLnVuc2hhcnBSYWRpdXMsIG9wdHMudW5zaGFycFRocmVzaG9sZCk7XG5cbiAgICB0b0N0eC5wdXRJbWFnZURhdGEoaURhdGEsIDAsIDApOyAvLyBTYWZhcmkgMTIgd29ya2Fyb3VuZFxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYS9pc3N1ZXMvMTk5XG5cbiAgICB0bXBDYW52YXMud2lkdGggPSB0bXBDYW52YXMuaGVpZ2h0ID0gMDtcbiAgICBpRGF0YSA9IHRtcEN0eCA9IHRtcENhbnZhcyA9IHRvQ3R4ID0gbnVsbDtcblxuICAgIF90aGlzNS5kZWJ1ZygnRmluaXNoZWQhJyk7XG5cbiAgICByZXR1cm4gdG87XG4gIH0pO1xufTtcblxuUGljYS5wcm90b3R5cGUucmVzaXplID0gZnVuY3Rpb24gKGZyb20sIHRvLCBvcHRpb25zKSB7XG4gIHZhciBfdGhpczYgPSB0aGlzO1xuXG4gIHRoaXMuZGVidWcoJ1N0YXJ0IHJlc2l6ZS4uLicpO1xuICB2YXIgb3B0cyA9IGFzc2lnbih7fSwgREVGQVVMVF9SRVNJWkVfT1BUUyk7XG5cbiAgaWYgKCFpc05hTihvcHRpb25zKSkge1xuICAgIG9wdHMgPSBhc3NpZ24ob3B0cywge1xuICAgICAgcXVhbGl0eTogb3B0aW9uc1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKG9wdGlvbnMpIHtcbiAgICBvcHRzID0gYXNzaWduKG9wdHMsIG9wdGlvbnMpO1xuICB9XG5cbiAgb3B0cy50b1dpZHRoID0gdG8ud2lkdGg7XG4gIG9wdHMudG9IZWlnaHQgPSB0by5oZWlnaHQ7XG4gIG9wdHMud2lkdGggPSBmcm9tLm5hdHVyYWxXaWR0aCB8fCBmcm9tLndpZHRoO1xuICBvcHRzLmhlaWdodCA9IGZyb20ubmF0dXJhbEhlaWdodCB8fCBmcm9tLmhlaWdodDsgLy8gUHJldmVudCBzdGVwcGVyIGZyb20gaW5maW5pdGUgbG9vcFxuXG4gIGlmICh0by53aWR0aCA9PT0gMCB8fCB0by5oZWlnaHQgPT09IDApIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiSW52YWxpZCBvdXRwdXQgc2l6ZTogXCIuY29uY2F0KHRvLndpZHRoLCBcInhcIikuY29uY2F0KHRvLmhlaWdodCkpKTtcbiAgfVxuXG4gIGlmIChvcHRzLnVuc2hhcnBSYWRpdXMgPiAyKSBvcHRzLnVuc2hhcnBSYWRpdXMgPSAyO1xuICBvcHRzLmNhbmNlbGVkID0gZmFsc2U7XG5cbiAgaWYgKG9wdHMuY2FuY2VsVG9rZW4pIHtcbiAgICAvLyBXcmFwIGNhbmNlbFRva2VuIHRvIGF2b2lkIHN1Y2Nlc3NpdmUgcmVzb2x2ZSAmIHNldCBmbGFnXG4gICAgb3B0cy5jYW5jZWxUb2tlbiA9IG9wdHMuY2FuY2VsVG9rZW4udGhlbihmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgb3B0cy5jYW5jZWxlZCA9IHRydWU7XG4gICAgICB0aHJvdyBkYXRhO1xuICAgIH0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIG9wdHMuY2FuY2VsZWQgPSB0cnVlO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH0pO1xuICB9XG5cbiAgdmFyIERFU1RfVElMRV9CT1JERVIgPSAzOyAvLyBNYXggcG9zc2libGUgZmlsdGVyIHdpbmRvdyBzaXplXG5cbiAgb3B0cy5fX2Rlc3RUaWxlQm9yZGVyID0gTWF0aC5jZWlsKE1hdGgubWF4KERFU1RfVElMRV9CT1JERVIsIDIuNSAqIG9wdHMudW5zaGFycFJhZGl1cyB8IDApKTtcbiAgcmV0dXJuIHRoaXMuaW5pdCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIGlmIChvcHRzLmNhbmNlbGVkKSByZXR1cm4gb3B0cy5jYW5jZWxUb2tlbjsgLy8gaWYgY3JlYXRlSW1hZ2VCaXRtYXAgc3VwcG9ydHMgcmVzaXplLCBqdXN0IGRvIGl0IGFuZCByZXR1cm5cblxuICAgIGlmIChfdGhpczYuZmVhdHVyZXMuY2liKSB7XG4gICAgICByZXR1cm4gX3RoaXM2Ll9fcmVzaXplVmlhQ3JlYXRlSW1hZ2VCaXRtYXAoZnJvbSwgdG8sIG9wdHMpO1xuICAgIH1cblxuICAgIGlmICghQ0FOX1VTRV9DQU5WQVNfR0VUX0lNQUdFX0RBVEEpIHtcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1BpY2E6IGNhbm5vdCB1c2UgZ2V0SW1hZ2VEYXRhIG9uIGNhbnZhcywgJyArIFwibWFrZSBzdXJlIGZpbmdlcnByaW50aW5nIHByb3RlY3Rpb24gaXNuJ3QgZW5hYmxlZFwiKTtcbiAgICAgIGVyci5jb2RlID0gJ0VSUl9HRVRfSU1BR0VfREFUQSc7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfSAvL1xuICAgIC8vIE5vIGVhc3kgd2F5LCBsZXQncyByZXNpemUgbWFudWFsbHkgdmlhIGFycmF5c1xuICAgIC8vXG5cblxuICAgIHZhciBzdGFnZXMgPSBjcmVhdGVTdGFnZXMob3B0cy53aWR0aCwgb3B0cy5oZWlnaHQsIG9wdHMudG9XaWR0aCwgb3B0cy50b0hlaWdodCwgX3RoaXM2Lm9wdGlvbnMudGlsZSwgb3B0cy5fX2Rlc3RUaWxlQm9yZGVyKTtcbiAgICByZXR1cm4gX3RoaXM2Ll9fcHJvY2Vzc1N0YWdlcyhzdGFnZXMsIGZyb20sIHRvLCBvcHRzKTtcbiAgfSk7XG59OyAvLyBSR0JBIGJ1ZmZlciByZXNpemVcbi8vXG5cblxuUGljYS5wcm90b3R5cGUucmVzaXplQnVmZmVyID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgdmFyIF90aGlzNyA9IHRoaXM7XG5cbiAgdmFyIG9wdHMgPSBhc3NpZ24oe30sIERFRkFVTFRfUkVTSVpFX09QVFMsIG9wdGlvbnMpO1xuICByZXR1cm4gdGhpcy5pbml0KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF90aGlzNy5fX21hdGhsaWIucmVzaXplQW5kVW5zaGFycChvcHRzKTtcbiAgfSk7XG59O1xuXG5QaWNhLnByb3RvdHlwZS50b0Jsb2IgPSBmdW5jdGlvbiAoY2FudmFzLCBtaW1lVHlwZSwgcXVhbGl0eSkge1xuICBtaW1lVHlwZSA9IG1pbWVUeXBlIHx8ICdpbWFnZS9wbmcnO1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICBpZiAoY2FudmFzLnRvQmxvYikge1xuICAgICAgY2FudmFzLnRvQmxvYihmdW5jdGlvbiAoYmxvYikge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShibG9iKTtcbiAgICAgIH0sIG1pbWVUeXBlLCBxdWFsaXR5KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY2FudmFzLmNvbnZlcnRUb0Jsb2IpIHtcbiAgICAgIHJlc29sdmUoY2FudmFzLmNvbnZlcnRUb0Jsb2Ioe1xuICAgICAgICB0eXBlOiBtaW1lVHlwZSxcbiAgICAgICAgcXVhbGl0eTogcXVhbGl0eVxuICAgICAgfSkpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gRmFsbGJhY2sgZm9yIG9sZCBicm93c2Vyc1xuXG5cbiAgICB2YXIgYXNTdHJpbmcgPSBhdG9iKGNhbnZhcy50b0RhdGFVUkwobWltZVR5cGUsIHF1YWxpdHkpLnNwbGl0KCcsJylbMV0pO1xuICAgIHZhciBsZW4gPSBhc1N0cmluZy5sZW5ndGg7XG4gICAgdmFyIGFzQnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkobGVuKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGFzQnVmZmVyW2ldID0gYXNTdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICB9XG5cbiAgICByZXNvbHZlKG5ldyBCbG9iKFthc0J1ZmZlcl0sIHtcbiAgICAgIHR5cGU6IG1pbWVUeXBlXG4gICAgfSkpO1xuICB9KTtcbn07XG5cblBpY2EucHJvdG90eXBlLmRlYnVnID0gZnVuY3Rpb24gKCkge307XG5cbm1vZHVsZS5leHBvcnRzID0gUGljYTtcblxufSx7XCIuL2xpYi9tYXRobGliXCI6MSxcIi4vbGliL3Bvb2xcIjoxMyxcIi4vbGliL3N0ZXBwZXJcIjoxNCxcIi4vbGliL3RpbGVyXCI6MTUsXCIuL2xpYi91dGlsc1wiOjE2LFwiLi9saWIvd29ya2VyXCI6MTcsXCJvYmplY3QtYXNzaWduXCI6MjMsXCJ3ZWJ3b3JraWZ5XCI6MjR9XX0se30sW10pKFwiL2luZGV4LmpzXCIpXG59KTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///../../../node_modules/pica/dist/pica.js\n");
18
18
 
19
19
  /***/ }),
20
20
 
@@ -25,7 +25,7 @@ eval("/*!\n\npica\nhttps://github.com/nodeca/pica\n\n*/\n\n(function(f){if(true)
25
25
  /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
26
26
 
27
27
  "use strict";
28
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n\n/*! image-blob-reduce 3.0.1 https://github.com/nodeca/image-blob-reduce @license MIT */\nvar assign$1 = function assign(to) {\n var from;\n\n for (var s = 1; s < arguments.length; s++) {\n from = Object(arguments[s]);\n\n for (var key in from) {\n if (Object.prototype.hasOwnProperty.call(from, key)) to[key] = from[key];\n }\n }\n\n return to;\n};\n\n\nfunction pick(from, props) {\n var to = {};\n\n props.forEach(function (key) {\n if (Object.prototype.hasOwnProperty.call(from, key)) to[key] = from[key];\n });\n\n return to;\n}\n\n\nfunction pick_pica_resize_options(from) {\n return pick(from, [\n 'alpha',\n 'unsharpAmount',\n 'unsharpRadius',\n 'unsharpThreshold',\n 'cancelToken'\n ]);\n}\n\n\nvar pick_1 = pick;\nvar pick_pica_resize_options_1 = pick_pica_resize_options;\n\nvar utils = {\n\tassign: assign$1,\n\tpick: pick_1,\n\tpick_pica_resize_options: pick_pica_resize_options_1\n};\n\nfunction createCommonjsModule(fn) {\n var module = { exports: {} };\n\treturn fn(module, module.exports), module.exports;\n}\n\nfunction commonjsRequire (target) {\n\tthrow new Error('Could not dynamically require \"' + target + '\". Please configure the dynamicRequireTargets option of @rollup/plugin-commonjs appropriately for this require call to behave properly.');\n}\n\n/*!\n\npica\nhttps://github.com/nodeca/pica\n\n*/\n\nvar pica = createCommonjsModule(function (module, exports) {\n(function(f){{module.exports=f();}})(function(){return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof commonjsRequire&&commonjsRequire;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t);}return n[i].exports}for(var u=\"function\"==typeof commonjsRequire&&commonjsRequire,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){\n\nvar inherits = _dereq_('inherits');\n\nvar Multimath = _dereq_('multimath');\n\nvar mm_unsharp_mask = _dereq_('./mm_unsharp_mask');\n\nvar mm_resize = _dereq_('./mm_resize');\n\nfunction MathLib(requested_features) {\n var __requested_features = requested_features || [];\n\n var features = {\n js: __requested_features.indexOf('js') >= 0,\n wasm: __requested_features.indexOf('wasm') >= 0\n };\n Multimath.call(this, features);\n this.features = {\n js: features.js,\n wasm: features.wasm && this.has_wasm()\n };\n this.use(mm_unsharp_mask);\n this.use(mm_resize);\n}\n\ninherits(MathLib, Multimath);\n\nMathLib.prototype.resizeAndUnsharp = function resizeAndUnsharp(options, cache) {\n var result = this.resize(options, cache);\n\n if (options.unsharpAmount) {\n this.unsharp_mask(result, options.toWidth, options.toHeight, options.unsharpAmount, options.unsharpRadius, options.unsharpThreshold);\n }\n\n return result;\n};\n\nmodule.exports = MathLib;\n\n},{\"./mm_resize\":4,\"./mm_unsharp_mask\":9,\"inherits\":19,\"multimath\":20}],2:[function(_dereq_,module,exports){\n//var FIXED_FRAC_BITS = 14;\n\nfunction clampTo8(i) {\n return i < 0 ? 0 : i > 255 ? 255 : i;\n} // Convolve image in horizontal directions and transpose output. In theory,\n// transpose allow:\n//\n// - use the same convolver for both passes (this fails due different\n// types of input array and temporary buffer)\n// - making vertical pass by horisonltal lines inprove CPU cache use.\n//\n// But in real life this doesn't work :)\n//\n\n\nfunction convolveHorizontally(src, dest, srcW, srcH, destW, filters) {\n var r, g, b, a;\n var filterPtr, filterShift, filterSize;\n var srcPtr, srcY, destX, filterVal;\n var srcOffset = 0,\n destOffset = 0; // For each row\n\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0; // Apply precomputed filters to each destination row point\n\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++];\n filterSize = filters[filterPtr++];\n srcPtr = srcOffset + filterShift * 4 | 0;\n r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a\n\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n\n a = a + filterVal * src[srcPtr + 3] | 0;\n b = b + filterVal * src[srcPtr + 2] | 0;\n g = g + filterVal * src[srcPtr + 1] | 0;\n r = r + filterVal * src[srcPtr] | 0;\n srcPtr = srcPtr + 4 | 0;\n } // Bring this value back in range. All of the filter scaling factors\n // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n //\n // (!) Add 1/2 of value before clamping to get proper rounding. In other\n // case brightness loss will be noticeable if you resize image with white\n // border and place it on white background.\n //\n\n\n dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset] = clampTo8(r + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n destOffset = destOffset + srcH * 4 | 0;\n }\n\n destOffset = (srcY + 1) * 4 | 0;\n srcOffset = (srcY + 1) * srcW * 4 | 0;\n }\n} // Technically, convolvers are the same. But input array and temporary\n// buffer can be of different type (especially, in old browsers). So,\n// keep code in separate functions to avoid deoptimizations & speed loss.\n\n\nfunction convolveVertically(src, dest, srcW, srcH, destW, filters) {\n var r, g, b, a;\n var filterPtr, filterShift, filterSize;\n var srcPtr, srcY, destX, filterVal;\n var srcOffset = 0,\n destOffset = 0; // For each row\n\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0; // Apply precomputed filters to each destination row point\n\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++];\n filterSize = filters[filterPtr++];\n srcPtr = srcOffset + filterShift * 4 | 0;\n r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a\n\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n\n a = a + filterVal * src[srcPtr + 3] | 0;\n b = b + filterVal * src[srcPtr + 2] | 0;\n g = g + filterVal * src[srcPtr + 1] | 0;\n r = r + filterVal * src[srcPtr] | 0;\n srcPtr = srcPtr + 4 | 0;\n } // Bring this value back in range. All of the filter scaling factors\n // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n //\n // (!) Add 1/2 of value before clamping to get proper rounding. In other\n // case brightness loss will be noticeable if you resize image with white\n // border and place it on white background.\n //\n\n\n dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset] = clampTo8(r + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n destOffset = destOffset + srcH * 4 | 0;\n }\n\n destOffset = (srcY + 1) * 4 | 0;\n srcOffset = (srcY + 1) * srcW * 4 | 0;\n }\n}\n\nmodule.exports = {\n convolveHorizontally: convolveHorizontally,\n convolveVertically: convolveVertically\n};\n\n},{}],3:[function(_dereq_,module,exports){\n/* eslint-disable max-len */\n\nmodule.exports = 'AGFzbQEAAAAADAZkeWxpbmsAAAAAAAEXA2AAAGAGf39/f39/AGAHf39/f39/fwACDwEDZW52Bm1lbW9yeQIAAAMEAwABAgYGAX8AQQALB1cFEV9fd2FzbV9jYWxsX2N0b3JzAAAIY29udm9sdmUAAQpjb252b2x2ZUhWAAIMX19kc29faGFuZGxlAwAYX193YXNtX2FwcGx5X2RhdGFfcmVsb2NzAAAK7AMDAwABC8YDAQ9/AkAgA0UNACAERQ0AA0AgDCENQQAhE0EAIQcDQCAHQQJqIQYCfyAHQQF0IAVqIgcuAQIiFEUEQEGAwAAhCEGAwAAhCUGAwAAhCkGAwAAhCyAGDAELIBIgBy4BAGohCEEAIQsgFCEHQQAhDiAGIQlBACEPQQAhEANAIAUgCUEBdGouAQAiESAAIAhBAnRqKAIAIgpBGHZsIBBqIRAgCkH/AXEgEWwgC2ohCyAKQRB2Qf8BcSARbCAPaiEPIApBCHZB/wFxIBFsIA5qIQ4gCEEBaiEIIAlBAWohCSAHQQFrIgcNAAsgC0GAQGshCCAOQYBAayEJIA9BgEBrIQogEEGAQGshCyAGIBRqCyEHIAEgDUECdGogCUEOdSIGQf8BIAZB/wFIGyIGQQAgBkEAShtBCHRBgP4DcSAKQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EQdEGAgPwHcSALQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EYdHJyIAhBDnUiBkH/ASAGQf8BSBsiBkEAIAZBAEobcjYCACADIA1qIQ0gE0EBaiITIARHDQALIAxBAWoiDCACbCESIAMgDEcNAAsLCx4AQQAgAiADIAQgBSAAEAEgAkEAIAQgBSAGIAEQAQs=';\n\n},{}],4:[function(_dereq_,module,exports){\n\nmodule.exports = {\n name: 'resize',\n fn: _dereq_('./resize'),\n wasm_fn: _dereq_('./resize_wasm'),\n wasm_src: _dereq_('./convolve_wasm_base64')\n};\n\n},{\"./convolve_wasm_base64\":3,\"./resize\":5,\"./resize_wasm\":8}],5:[function(_dereq_,module,exports){\n\nvar createFilters = _dereq_('./resize_filter_gen');\n\nvar convolveHorizontally = _dereq_('./convolve').convolveHorizontally;\n\nvar convolveVertically = _dereq_('./convolve').convolveVertically;\n\nfunction resetAlpha(dst, width, height) {\n var ptr = 3,\n len = width * height * 4 | 0;\n\n while (ptr < len) {\n dst[ptr] = 0xFF;\n ptr = ptr + 4 | 0;\n }\n}\n\nmodule.exports = function resize(options) {\n var src = options.src;\n var srcW = options.width;\n var srcH = options.height;\n var destW = options.toWidth;\n var destH = options.toHeight;\n var scaleX = options.scaleX || options.toWidth / options.width;\n var scaleY = options.scaleY || options.toHeight / options.height;\n var offsetX = options.offsetX || 0;\n var offsetY = options.offsetY || 0;\n var dest = options.dest || new Uint8Array(destW * destH * 4);\n var quality = typeof options.quality === 'undefined' ? 3 : options.quality;\n var alpha = options.alpha || false;\n var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(quality, srcH, destH, scaleY, offsetY);\n var tmp = new Uint8Array(destW * srcH * 4); // To use single function we need src & tmp of the same type.\n // But src can be CanvasPixelArray, and tmp - Uint8Array. So, keep\n // vertical and horizontal passes separately to avoid deoptimization.\n\n convolveHorizontally(src, tmp, srcW, srcH, destW, filtersX);\n convolveVertically(tmp, dest, srcH, destW, destH, filtersY); // That's faster than doing checks in convolver.\n // !!! Note, canvas data is not premultipled. We don't need other\n // alpha corrections.\n\n if (!alpha) resetAlpha(dest, destW, destH);\n return dest;\n};\n\n},{\"./convolve\":2,\"./resize_filter_gen\":6}],6:[function(_dereq_,module,exports){\n\nvar FILTER_INFO = _dereq_('./resize_filter_info'); // Precision of fixed FP values\n\n\nvar FIXED_FRAC_BITS = 14;\n\nfunction toFixedPoint(num) {\n return Math.round(num * ((1 << FIXED_FRAC_BITS) - 1));\n}\n\nmodule.exports = function resizeFilterGen(quality, srcSize, destSize, scale, offset) {\n var filterFunction = FILTER_INFO[quality].filter;\n var scaleInverted = 1.0 / scale;\n var scaleClamped = Math.min(1.0, scale); // For upscale\n // Filter window (averaging interval), scaled to src image\n\n var srcWindow = FILTER_INFO[quality].win / scaleClamped;\n var destPixel, srcPixel, srcFirst, srcLast, filterElementSize, floatFilter, fxpFilter, total, pxl, idx, floatVal, filterTotal, filterVal;\n var leftNotEmpty, rightNotEmpty, filterShift, filterSize;\n var maxFilterElementSize = Math.floor((srcWindow + 1) * 2);\n var packedFilter = new Int16Array((maxFilterElementSize + 2) * destSize);\n var packedFilterPtr = 0;\n var slowCopy = !packedFilter.subarray || !packedFilter.set; // For each destination pixel calculate source range and built filter values\n\n for (destPixel = 0; destPixel < destSize; destPixel++) {\n // Scaling should be done relative to central pixel point\n srcPixel = (destPixel + 0.5) * scaleInverted + offset;\n srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow));\n srcLast = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow));\n filterElementSize = srcLast - srcFirst + 1;\n floatFilter = new Float32Array(filterElementSize);\n fxpFilter = new Int16Array(filterElementSize);\n total = 0.0; // Fill filter values for calculated range\n\n for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {\n floatVal = filterFunction((pxl + 0.5 - srcPixel) * scaleClamped);\n total += floatVal;\n floatFilter[idx] = floatVal;\n } // Normalize filter, convert to fixed point and accumulate conversion error\n\n\n filterTotal = 0;\n\n for (idx = 0; idx < floatFilter.length; idx++) {\n filterVal = floatFilter[idx] / total;\n filterTotal += filterVal;\n fxpFilter[idx] = toFixedPoint(filterVal);\n } // Compensate normalization error, to minimize brightness drift\n\n\n fxpFilter[destSize >> 1] += toFixedPoint(1.0 - filterTotal); //\n // Now pack filter to useable form\n //\n // 1. Trim heading and tailing zero values, and compensate shitf/length\n // 2. Put all to single array in this format:\n //\n // [ pos shift, data length, value1, value2, value3, ... ]\n //\n\n leftNotEmpty = 0;\n\n while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) {\n leftNotEmpty++;\n }\n\n if (leftNotEmpty < fxpFilter.length) {\n rightNotEmpty = fxpFilter.length - 1;\n\n while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) {\n rightNotEmpty--;\n }\n\n filterShift = srcFirst + leftNotEmpty;\n filterSize = rightNotEmpty - leftNotEmpty + 1;\n packedFilter[packedFilterPtr++] = filterShift; // shift\n\n packedFilter[packedFilterPtr++] = filterSize; // size\n\n if (!slowCopy) {\n packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr);\n packedFilterPtr += filterSize;\n } else {\n // fallback for old IE < 11, without subarray/set methods\n for (idx = leftNotEmpty; idx <= rightNotEmpty; idx++) {\n packedFilter[packedFilterPtr++] = fxpFilter[idx];\n }\n }\n } else {\n // zero data, write header only\n packedFilter[packedFilterPtr++] = 0; // shift\n\n packedFilter[packedFilterPtr++] = 0; // size\n }\n }\n\n return packedFilter;\n};\n\n},{\"./resize_filter_info\":7}],7:[function(_dereq_,module,exports){\n\nmodule.exports = [{\n // Nearest neibor (Box)\n win: 0.5,\n filter: function filter(x) {\n return x >= -0.5 && x < 0.5 ? 1.0 : 0.0;\n }\n}, {\n // Hamming\n win: 1.0,\n filter: function filter(x) {\n if (x <= -1.0 || x >= 1.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * (0.54 + 0.46 * Math.cos(xpi / 1.0));\n }\n}, {\n // Lanczos, win = 2\n win: 2.0,\n filter: function filter(x) {\n if (x <= -2.0 || x >= 2.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * Math.sin(xpi / 2.0) / (xpi / 2.0);\n }\n}, {\n // Lanczos, win = 3\n win: 3.0,\n filter: function filter(x) {\n if (x <= -3.0 || x >= 3.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * Math.sin(xpi / 3.0) / (xpi / 3.0);\n }\n}];\n\n},{}],8:[function(_dereq_,module,exports){\n\nvar createFilters = _dereq_('./resize_filter_gen');\n\nfunction resetAlpha(dst, width, height) {\n var ptr = 3,\n len = width * height * 4 | 0;\n\n while (ptr < len) {\n dst[ptr] = 0xFF;\n ptr = ptr + 4 | 0;\n }\n}\n\nfunction asUint8Array(src) {\n return new Uint8Array(src.buffer, 0, src.byteLength);\n}\n\nvar IS_LE = true; // should not crash everything on module load in old browsers\n\ntry {\n IS_LE = new Uint32Array(new Uint8Array([1, 0, 0, 0]).buffer)[0] === 1;\n} catch (__) {}\n\nfunction copyInt16asLE(src, target, target_offset) {\n if (IS_LE) {\n target.set(asUint8Array(src), target_offset);\n return;\n }\n\n for (var ptr = target_offset, i = 0; i < src.length; i++) {\n var data = src[i];\n target[ptr++] = data & 0xFF;\n target[ptr++] = data >> 8 & 0xFF;\n }\n}\n\nmodule.exports = function resize_wasm(options) {\n var src = options.src;\n var srcW = options.width;\n var srcH = options.height;\n var destW = options.toWidth;\n var destH = options.toHeight;\n var scaleX = options.scaleX || options.toWidth / options.width;\n var scaleY = options.scaleY || options.toHeight / options.height;\n var offsetX = options.offsetX || 0.0;\n var offsetY = options.offsetY || 0.0;\n var dest = options.dest || new Uint8Array(destW * destH * 4);\n var quality = typeof options.quality === 'undefined' ? 3 : options.quality;\n var alpha = options.alpha || false;\n var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(quality, srcH, destH, scaleY, offsetY); // destination is 0 too.\n\n var src_offset = 0; // buffer between convolve passes\n\n var tmp_offset = this.__align(src_offset + Math.max(src.byteLength, dest.byteLength));\n\n var filtersX_offset = this.__align(tmp_offset + srcH * destW * 4);\n\n var filtersY_offset = this.__align(filtersX_offset + filtersX.byteLength);\n\n var alloc_bytes = filtersY_offset + filtersY.byteLength;\n\n var instance = this.__instance('resize', alloc_bytes); //\n // Fill memory block with data to process\n //\n\n\n var mem = new Uint8Array(this.__memory.buffer);\n var mem32 = new Uint32Array(this.__memory.buffer); // 32-bit copy is much faster in chrome\n\n var src32 = new Uint32Array(src.buffer);\n mem32.set(src32); // We should guarantee LE bytes order. Filters are not big, so\n // speed difference is not significant vs direct .set()\n\n copyInt16asLE(filtersX, mem, filtersX_offset);\n copyInt16asLE(filtersY, mem, filtersY_offset); //\n // Now call webassembly method\n // emsdk does method names with '_'\n\n var fn = instance.exports.convolveHV || instance.exports._convolveHV;\n fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH); //\n // Copy data back to typed array\n //\n // 32-bit copy is much faster in chrome\n\n var dest32 = new Uint32Array(dest.buffer);\n dest32.set(new Uint32Array(this.__memory.buffer, 0, destH * destW)); // That's faster than doing checks in convolver.\n // !!! Note, canvas data is not premultipled. We don't need other\n // alpha corrections.\n\n if (!alpha) resetAlpha(dest, destW, destH);\n return dest;\n};\n\n},{\"./resize_filter_gen\":6}],9:[function(_dereq_,module,exports){\n\nmodule.exports = {\n name: 'unsharp_mask',\n fn: _dereq_('./unsharp_mask'),\n wasm_fn: _dereq_('./unsharp_mask_wasm'),\n wasm_src: _dereq_('./unsharp_mask_wasm_base64')\n};\n\n},{\"./unsharp_mask\":10,\"./unsharp_mask_wasm\":11,\"./unsharp_mask_wasm_base64\":12}],10:[function(_dereq_,module,exports){\n\nvar glur_mono16 = _dereq_('glur/mono16');\n\nfunction hsv_v16(img, width, height) {\n var size = width * height;\n var out = new Uint16Array(size);\n var r, g, b, max;\n\n for (var i = 0; i < size; i++) {\n r = img[4 * i];\n g = img[4 * i + 1];\n b = img[4 * i + 2];\n max = r >= g && r >= b ? r : g >= b && g >= r ? g : b;\n out[i] = max << 8;\n }\n\n return out;\n}\n\nmodule.exports = function unsharp(img, width, height, amount, radius, threshold) {\n var v1, v2, vmul;\n var diff, iTimes4;\n\n if (amount === 0 || radius < 0.5) {\n return;\n }\n\n if (radius > 2.0) {\n radius = 2.0;\n }\n\n var brightness = hsv_v16(img, width, height);\n var blured = new Uint16Array(brightness); // copy, because blur modify src\n\n glur_mono16(blured, width, height, radius);\n var amountFp = amount / 100 * 0x1000 + 0.5 | 0;\n var thresholdFp = threshold << 8;\n var size = width * height;\n /* eslint-disable indent */\n\n for (var i = 0; i < size; i++) {\n v1 = brightness[i];\n diff = v1 - blured[i];\n\n if (Math.abs(diff) >= thresholdFp) {\n // add unsharp mask to the brightness channel\n v2 = v1 + (amountFp * diff + 0x800 >> 12); // Both v1 and v2 are within [0.0 .. 255.0] (0000-FF00) range, never going into\n // [255.003 .. 255.996] (FF01-FFFF). This allows to round this value as (x+.5)|0\n // later without overflowing.\n\n v2 = v2 > 0xff00 ? 0xff00 : v2;\n v2 = v2 < 0x0000 ? 0x0000 : v2; // Avoid division by 0. V=0 means rgb(0,0,0), unsharp with unsharpAmount>0 cannot\n // change this value (because diff between colors gets inflated), so no need to verify correctness.\n\n v1 = v1 !== 0 ? v1 : 1; // Multiplying V in HSV model by a constant is equivalent to multiplying each component\n // in RGB by the same constant (same for HSL), see also:\n // https://beesbuzz.biz/code/16-hsv-color-transforms\n\n vmul = (v2 << 12) / v1 | 0; // Result will be in [0..255] range because:\n // - all numbers are positive\n // - r,g,b <= (v1/256)\n // - r,g,b,(v1/256),(v2/256) <= 255\n // So highest this number can get is X*255/X+0.5=255.5 which is < 256 and rounds down.\n\n iTimes4 = i * 4;\n img[iTimes4] = img[iTimes4] * vmul + 0x800 >> 12; // R\n\n img[iTimes4 + 1] = img[iTimes4 + 1] * vmul + 0x800 >> 12; // G\n\n img[iTimes4 + 2] = img[iTimes4 + 2] * vmul + 0x800 >> 12; // B\n }\n }\n};\n\n},{\"glur/mono16\":18}],11:[function(_dereq_,module,exports){\n\nmodule.exports = function unsharp(img, width, height, amount, radius, threshold) {\n if (amount === 0 || radius < 0.5) {\n return;\n }\n\n if (radius > 2.0) {\n radius = 2.0;\n }\n\n var pixels = width * height;\n var img_bytes_cnt = pixels * 4;\n var hsv_bytes_cnt = pixels * 2;\n var blur_bytes_cnt = pixels * 2;\n var blur_line_byte_cnt = Math.max(width, height) * 4; // float32 array\n\n var blur_coeffs_byte_cnt = 8 * 4; // float32 array\n\n var img_offset = 0;\n var hsv_offset = img_bytes_cnt;\n var blur_offset = hsv_offset + hsv_bytes_cnt;\n var blur_tmp_offset = blur_offset + blur_bytes_cnt;\n var blur_line_offset = blur_tmp_offset + blur_bytes_cnt;\n var blur_coeffs_offset = blur_line_offset + blur_line_byte_cnt;\n\n var instance = this.__instance('unsharp_mask', img_bytes_cnt + hsv_bytes_cnt + blur_bytes_cnt * 2 + blur_line_byte_cnt + blur_coeffs_byte_cnt, {\n exp: Math.exp\n }); // 32-bit copy is much faster in chrome\n\n\n var img32 = new Uint32Array(img.buffer);\n var mem32 = new Uint32Array(this.__memory.buffer);\n mem32.set(img32); // HSL\n\n var fn = instance.exports.hsv_v16 || instance.exports._hsv_v16;\n fn(img_offset, hsv_offset, width, height); // BLUR\n\n fn = instance.exports.blurMono16 || instance.exports._blurMono16;\n fn(hsv_offset, blur_offset, blur_tmp_offset, blur_line_offset, blur_coeffs_offset, width, height, radius); // UNSHARP\n\n fn = instance.exports.unsharp || instance.exports._unsharp;\n fn(img_offset, img_offset, hsv_offset, blur_offset, width, height, amount, threshold); // 32-bit copy is much faster in chrome\n\n img32.set(new Uint32Array(this.__memory.buffer, 0, pixels));\n};\n\n},{}],12:[function(_dereq_,module,exports){\n/* eslint-disable max-len */\n\nmodule.exports = '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';\n\n},{}],13:[function(_dereq_,module,exports){\n\nvar GC_INTERVAL = 100;\n\nfunction Pool(create, idle) {\n this.create = create;\n this.available = [];\n this.acquired = {};\n this.lastId = 1;\n this.timeoutId = 0;\n this.idle = idle || 2000;\n}\n\nPool.prototype.acquire = function () {\n var _this = this;\n\n var resource;\n\n if (this.available.length !== 0) {\n resource = this.available.pop();\n } else {\n resource = this.create();\n resource.id = this.lastId++;\n\n resource.release = function () {\n return _this.release(resource);\n };\n }\n\n this.acquired[resource.id] = resource;\n return resource;\n};\n\nPool.prototype.release = function (resource) {\n var _this2 = this;\n\n delete this.acquired[resource.id];\n resource.lastUsed = Date.now();\n this.available.push(resource);\n\n if (this.timeoutId === 0) {\n this.timeoutId = setTimeout(function () {\n return _this2.gc();\n }, GC_INTERVAL);\n }\n};\n\nPool.prototype.gc = function () {\n var _this3 = this;\n\n var now = Date.now();\n this.available = this.available.filter(function (resource) {\n if (now - resource.lastUsed > _this3.idle) {\n resource.destroy();\n return false;\n }\n\n return true;\n });\n\n if (this.available.length !== 0) {\n this.timeoutId = setTimeout(function () {\n return _this3.gc();\n }, GC_INTERVAL);\n } else {\n this.timeoutId = 0;\n }\n};\n\nmodule.exports = Pool;\n\n},{}],14:[function(_dereq_,module,exports){\n// min size = 1 can consume large amount of memory\n\nvar MIN_INNER_TILE_SIZE = 2;\n\nmodule.exports = function createStages(fromWidth, fromHeight, toWidth, toHeight, srcTileSize, destTileBorder) {\n var scaleX = toWidth / fromWidth;\n var scaleY = toHeight / fromHeight; // derived from createRegions equation:\n // innerTileWidth = pixelFloor(srcTileSize * scaleX) - 2 * destTileBorder;\n\n var minScale = (2 * destTileBorder + MIN_INNER_TILE_SIZE + 1) / srcTileSize; // refuse to scale image multiple times by less than twice each time,\n // it could only happen because of invalid options\n\n if (minScale > 0.5) return [[toWidth, toHeight]];\n var stageCount = Math.ceil(Math.log(Math.min(scaleX, scaleY)) / Math.log(minScale)); // no additional resizes are necessary,\n // stageCount can be zero or be negative when enlarging the image\n\n if (stageCount <= 1) return [[toWidth, toHeight]];\n var result = [];\n\n for (var i = 0; i < stageCount; i++) {\n var width = Math.round(Math.pow(Math.pow(fromWidth, stageCount - i - 1) * Math.pow(toWidth, i + 1), 1 / stageCount));\n var height = Math.round(Math.pow(Math.pow(fromHeight, stageCount - i - 1) * Math.pow(toHeight, i + 1), 1 / stageCount));\n result.push([width, height]);\n }\n\n return result;\n};\n\n},{}],15:[function(_dereq_,module,exports){\n/*\n * pixelFloor and pixelCeil are modified versions of Math.floor and Math.ceil\n * functions which take into account floating point arithmetic errors.\n * Those errors can cause undesired increments/decrements of sizes and offsets:\n * Math.ceil(36 / (36 / 500)) = 501\n * pixelCeil(36 / (36 / 500)) = 500\n */\n\nvar PIXEL_EPSILON = 1e-5;\n\nfunction pixelFloor(x) {\n var nearest = Math.round(x);\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) {\n return nearest;\n }\n\n return Math.floor(x);\n}\n\nfunction pixelCeil(x) {\n var nearest = Math.round(x);\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) {\n return nearest;\n }\n\n return Math.ceil(x);\n}\n\nmodule.exports = function createRegions(options) {\n var scaleX = options.toWidth / options.width;\n var scaleY = options.toHeight / options.height;\n var innerTileWidth = pixelFloor(options.srcTileSize * scaleX) - 2 * options.destTileBorder;\n var innerTileHeight = pixelFloor(options.srcTileSize * scaleY) - 2 * options.destTileBorder; // prevent infinite loop, this should never happen\n\n if (innerTileWidth < 1 || innerTileHeight < 1) {\n throw new Error('Internal error in pica: target tile width/height is too small.');\n }\n\n var x, y;\n var innerX, innerY, toTileWidth, toTileHeight;\n var tiles = [];\n var tile; // we go top-to-down instead of left-to-right to make image displayed from top to\n // doesn in the browser\n\n for (innerY = 0; innerY < options.toHeight; innerY += innerTileHeight) {\n for (innerX = 0; innerX < options.toWidth; innerX += innerTileWidth) {\n x = innerX - options.destTileBorder;\n\n if (x < 0) {\n x = 0;\n }\n\n toTileWidth = innerX + innerTileWidth + options.destTileBorder - x;\n\n if (x + toTileWidth >= options.toWidth) {\n toTileWidth = options.toWidth - x;\n }\n\n y = innerY - options.destTileBorder;\n\n if (y < 0) {\n y = 0;\n }\n\n toTileHeight = innerY + innerTileHeight + options.destTileBorder - y;\n\n if (y + toTileHeight >= options.toHeight) {\n toTileHeight = options.toHeight - y;\n }\n\n tile = {\n toX: x,\n toY: y,\n toWidth: toTileWidth,\n toHeight: toTileHeight,\n toInnerX: innerX,\n toInnerY: innerY,\n toInnerWidth: innerTileWidth,\n toInnerHeight: innerTileHeight,\n offsetX: x / scaleX - pixelFloor(x / scaleX),\n offsetY: y / scaleY - pixelFloor(y / scaleY),\n scaleX: scaleX,\n scaleY: scaleY,\n x: pixelFloor(x / scaleX),\n y: pixelFloor(y / scaleY),\n width: pixelCeil(toTileWidth / scaleX),\n height: pixelCeil(toTileHeight / scaleY)\n };\n tiles.push(tile);\n }\n }\n\n return tiles;\n};\n\n},{}],16:[function(_dereq_,module,exports){\n\nfunction objClass(obj) {\n return Object.prototype.toString.call(obj);\n}\n\nmodule.exports.isCanvas = function isCanvas(element) {\n var cname = objClass(element);\n return cname === '[object HTMLCanvasElement]'\n /* browser */\n || cname === '[object OffscreenCanvas]' || cname === '[object Canvas]'\n /* node-canvas */\n ;\n};\n\nmodule.exports.isImage = function isImage(element) {\n return objClass(element) === '[object HTMLImageElement]';\n};\n\nmodule.exports.isImageBitmap = function isImageBitmap(element) {\n return objClass(element) === '[object ImageBitmap]';\n};\n\nmodule.exports.limiter = function limiter(concurrency) {\n var active = 0,\n queue = [];\n\n function roll() {\n if (active < concurrency && queue.length) {\n active++;\n queue.shift()();\n }\n }\n\n return function limit(fn) {\n return new Promise(function (resolve, reject) {\n queue.push(function () {\n fn().then(function (result) {\n resolve(result);\n active--;\n roll();\n }, function (err) {\n reject(err);\n active--;\n roll();\n });\n });\n roll();\n });\n };\n};\n\nmodule.exports.cib_quality_name = function cib_quality_name(num) {\n switch (num) {\n case 0:\n return 'pixelated';\n\n case 1:\n return 'low';\n\n case 2:\n return 'medium';\n }\n\n return 'high';\n};\n\nmodule.exports.cib_support = function cib_support(createCanvas) {\n return Promise.resolve().then(function () {\n if (typeof createImageBitmap === 'undefined') {\n return false;\n }\n\n var c = createCanvas(100, 100);\n return createImageBitmap(c, 0, 0, 100, 100, {\n resizeWidth: 10,\n resizeHeight: 10,\n resizeQuality: 'high'\n }).then(function (bitmap) {\n var status = bitmap.width === 10; // Branch below is filtered on upper level. We do not call resize\n // detection for basic ImageBitmap.\n //\n // https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap\n // old Crome 51 has ImageBitmap without .close(). Then this code\n // will throw and return 'false' as expected.\n //\n\n bitmap.close();\n c = null;\n return status;\n });\n })[\"catch\"](function () {\n return false;\n });\n};\n\nmodule.exports.worker_offscreen_canvas_support = function worker_offscreen_canvas_support() {\n return new Promise(function (resolve, reject) {\n if (typeof OffscreenCanvas === 'undefined') {\n // if OffscreenCanvas is present, we assume browser supports Worker and built-in Promise as well\n resolve(false);\n return;\n }\n\n function workerPayload(self) {\n if (typeof createImageBitmap === 'undefined') {\n self.postMessage(false);\n return;\n }\n\n Promise.resolve().then(function () {\n var canvas = new OffscreenCanvas(10, 10); // test that 2d context can be used in worker\n\n var ctx = canvas.getContext('2d');\n ctx.rect(0, 0, 1, 1); // test that cib can be used to return image bitmap from worker\n\n return createImageBitmap(canvas, 0, 0, 1, 1);\n }).then(function () {\n return self.postMessage(true);\n }, function () {\n return self.postMessage(false);\n });\n }\n\n var code = btoa(\"(\".concat(workerPayload.toString(), \")(self);\"));\n var w = new Worker(\"data:text/javascript;base64,\".concat(code));\n\n w.onmessage = function (ev) {\n return resolve(ev.data);\n };\n\n w.onerror = reject;\n }).then(function (result) {\n return result;\n }, function () {\n return false;\n });\n}; // Check if canvas.getContext('2d').getImageData can be used,\n// FireFox randomizes the output of that function in `privacy.resistFingerprinting` mode\n\n\nmodule.exports.can_use_canvas = function can_use_canvas(createCanvas) {\n var usable = false;\n\n try {\n var canvas = createCanvas(2, 1);\n var ctx = canvas.getContext('2d');\n var d = ctx.createImageData(2, 1);\n d.data[0] = 12;\n d.data[1] = 23;\n d.data[2] = 34;\n d.data[3] = 255;\n d.data[4] = 45;\n d.data[5] = 56;\n d.data[6] = 67;\n d.data[7] = 255;\n ctx.putImageData(d, 0, 0);\n d = null;\n d = ctx.getImageData(0, 0, 2, 1);\n\n if (d.data[0] === 12 && d.data[1] === 23 && d.data[2] === 34 && d.data[3] === 255 && d.data[4] === 45 && d.data[5] === 56 && d.data[6] === 67 && d.data[7] === 255) {\n usable = true;\n }\n } catch (err) {}\n\n return usable;\n}; // Check if createImageBitmap(img, sx, sy, sw, sh) signature works correctly\n// with JPEG images oriented with Exif;\n// https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n// TODO: remove after it's fixed in chrome for at least 2 releases\n\n\nmodule.exports.cib_can_use_region = function cib_can_use_region() {\n return new Promise(function (resolve) {\n if (typeof createImageBitmap === 'undefined') {\n resolve(false);\n return;\n }\n\n var image = new Image();\n image.src = 'data:image/jpeg;base64,' + '/9j/4QBiRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAYAAAEaAAUAAAABAAAASgEbAAUAA' + 'AABAAAAUgEoAAMAAAABAAIAAAITAAMAAAABAAEAAAAAAAAAAABIAAAAAQAAAEgAAAAB/9' + 'sAQwAEAwMEAwMEBAMEBQQEBQYKBwYGBgYNCQoICg8NEBAPDQ8OERMYFBESFxIODxUcFRc' + 'ZGRsbGxAUHR8dGh8YGhsa/9sAQwEEBQUGBQYMBwcMGhEPERoaGhoaGhoaGhoaGhoaGhoa' + 'GhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoa/8IAEQgAAQACAwERAAIRAQMRA' + 'f/EABQAAQAAAAAAAAAAAAAAAAAAAAf/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAA' + 'IQAxAAAAF/P//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAQUCf//EABQRAQAAAAA' + 'AAAAAAAAAAAAAAAD/2gAIAQMBAT8Bf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIB' + 'AT8Bf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEABj8Cf//EABQQAQAAAAAAAAAAA' + 'AAAAAAAAAD/2gAIAQEAAT8hf//aAAwDAQACAAMAAAAQH//EABQRAQAAAAAAAAAAAAAAAA' + 'AAAAD/2gAIAQMBAT8Qf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Qf//EABQ' + 'QAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8Qf//Z';\n\n image.onload = function () {\n createImageBitmap(image, 0, 0, image.width, image.height).then(function (bitmap) {\n if (bitmap.width === image.width && bitmap.height === image.height) {\n resolve(true);\n } else {\n resolve(false);\n }\n }, function () {\n return resolve(false);\n });\n };\n\n image.onerror = function () {\n return resolve(false);\n };\n });\n};\n\n},{}],17:[function(_dereq_,module,exports){\n\nmodule.exports = function () {\n var MathLib = _dereq_('./mathlib');\n\n var mathLib;\n /* eslint-disable no-undef */\n\n onmessage = function onmessage(ev) {\n var tileOpts = ev.data.opts;\n var returnBitmap = false;\n\n if (!tileOpts.src && tileOpts.srcBitmap) {\n var canvas = new OffscreenCanvas(tileOpts.width, tileOpts.height);\n var ctx = canvas.getContext('2d', {\n alpha: Boolean(tileOpts.alpha)\n });\n ctx.drawImage(tileOpts.srcBitmap, 0, 0);\n tileOpts.src = ctx.getImageData(0, 0, tileOpts.width, tileOpts.height).data;\n canvas.width = canvas.height = 0;\n canvas = null;\n tileOpts.srcBitmap.close();\n tileOpts.srcBitmap = null;\n returnBitmap = true;\n }\n\n if (!mathLib) mathLib = new MathLib(ev.data.features); // Use multimath's sync auto-init. Avoid Promise use in old browsers,\n // because polyfills are not propagated to webworker.\n\n var data = mathLib.resizeAndUnsharp(tileOpts);\n\n if (returnBitmap) {\n var toImageData = new ImageData(new Uint8ClampedArray(data), tileOpts.toWidth, tileOpts.toHeight);\n\n var _canvas = new OffscreenCanvas(tileOpts.toWidth, tileOpts.toHeight);\n\n var _ctx = _canvas.getContext('2d', {\n alpha: Boolean(tileOpts.alpha)\n });\n\n _ctx.putImageData(toImageData, 0, 0);\n\n createImageBitmap(_canvas).then(function (bitmap) {\n postMessage({\n bitmap: bitmap\n }, [bitmap]);\n });\n } else {\n postMessage({\n data: data\n }, [data.buffer]);\n }\n };\n};\n\n},{\"./mathlib\":1}],18:[function(_dereq_,module,exports){\n// Calculate Gaussian blur of an image using IIR filter\n// The method is taken from Intel's white paper and code example attached to it:\n// https://software.intel.com/en-us/articles/iir-gaussian-blur-filter\n// -implementation-using-intel-advanced-vector-extensions\n\nvar a0, a1, a2, a3, b1, b2, left_corner, right_corner;\n\nfunction gaussCoef(sigma) {\n if (sigma < 0.5) {\n sigma = 0.5;\n }\n\n var a = Math.exp(0.726 * 0.726) / sigma,\n g1 = Math.exp(-a),\n g2 = Math.exp(-2 * a),\n k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2);\n\n a0 = k;\n a1 = k * (a - 1) * g1;\n a2 = k * (a + 1) * g1;\n a3 = -k * g2;\n b1 = 2 * g1;\n b2 = -g2;\n left_corner = (a0 + a1) / (1 - b1 - b2);\n right_corner = (a2 + a3) / (1 - b1 - b2);\n\n // Attempt to force type to FP32.\n return new Float32Array([ a0, a1, a2, a3, b1, b2, left_corner, right_corner ]);\n}\n\nfunction convolveMono16(src, out, line, coeff, width, height) {\n // takes src image and writes the blurred and transposed result into out\n\n var prev_src, curr_src, curr_out, prev_out, prev_prev_out;\n var src_index, out_index, line_index;\n var i, j;\n var coeff_a0, coeff_a1, coeff_b1, coeff_b2;\n\n for (i = 0; i < height; i++) {\n src_index = i * width;\n out_index = i;\n line_index = 0;\n\n // left to right\n prev_src = src[src_index];\n prev_prev_out = prev_src * coeff[6];\n prev_out = prev_prev_out;\n\n coeff_a0 = coeff[0];\n coeff_a1 = coeff[1];\n coeff_b1 = coeff[4];\n coeff_b2 = coeff[5];\n\n for (j = 0; j < width; j++) {\n curr_src = src[src_index];\n\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2;\n\n prev_prev_out = prev_out;\n prev_out = curr_out;\n prev_src = curr_src;\n\n line[line_index] = prev_out;\n line_index++;\n src_index++;\n }\n\n src_index--;\n line_index--;\n out_index += height * (width - 1);\n\n // right to left\n prev_src = src[src_index];\n prev_prev_out = prev_src * coeff[7];\n prev_out = prev_prev_out;\n curr_src = prev_src;\n\n coeff_a0 = coeff[2];\n coeff_a1 = coeff[3];\n\n for (j = width - 1; j >= 0; j--) {\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2;\n\n prev_prev_out = prev_out;\n prev_out = curr_out;\n\n prev_src = curr_src;\n curr_src = src[src_index];\n\n out[out_index] = line[line_index] + prev_out;\n\n src_index--;\n line_index--;\n out_index -= height;\n }\n }\n}\n\n\nfunction blurMono16(src, width, height, radius) {\n // Quick exit on zero radius\n if (!radius) { return; }\n\n var out = new Uint16Array(src.length),\n tmp_line = new Float32Array(Math.max(width, height));\n\n var coeff = gaussCoef(radius);\n\n convolveMono16(src, out, tmp_line, coeff, width, height);\n convolveMono16(out, src, tmp_line, coeff, height, width);\n}\n\nmodule.exports = blurMono16;\n\n},{}],19:[function(_dereq_,module,exports){\nif (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor;\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n }\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor;\n var TempCtor = function () {};\n TempCtor.prototype = superCtor.prototype;\n ctor.prototype = new TempCtor();\n ctor.prototype.constructor = ctor;\n }\n };\n}\n\n},{}],20:[function(_dereq_,module,exports){\n\n\nvar assign = _dereq_('object-assign');\nvar base64decode = _dereq_('./lib/base64decode');\nvar hasWebAssembly = _dereq_('./lib/wa_detect');\n\n\nvar DEFAULT_OPTIONS = {\n js: true,\n wasm: true\n};\n\n\nfunction MultiMath(options) {\n if (!(this instanceof MultiMath)) return new MultiMath(options);\n\n var opts = assign({}, DEFAULT_OPTIONS, options || {});\n\n this.options = opts;\n\n this.__cache = {};\n\n this.__init_promise = null;\n this.__modules = opts.modules || {};\n this.__memory = null;\n this.__wasm = {};\n\n this.__isLE = ((new Uint32Array((new Uint8Array([ 1, 0, 0, 0 ])).buffer))[0] === 1);\n\n if (!this.options.js && !this.options.wasm) {\n throw new Error('mathlib: at least \"js\" or \"wasm\" should be enabled');\n }\n}\n\n\nMultiMath.prototype.has_wasm = hasWebAssembly;\n\n\nMultiMath.prototype.use = function (module) {\n this.__modules[module.name] = module;\n\n // Pin the best possible implementation\n if (this.options.wasm && this.has_wasm() && module.wasm_fn) {\n this[module.name] = module.wasm_fn;\n } else {\n this[module.name] = module.fn;\n }\n\n return this;\n};\n\n\nMultiMath.prototype.init = function () {\n if (this.__init_promise) return this.__init_promise;\n\n if (!this.options.js && this.options.wasm && !this.has_wasm()) {\n return Promise.reject(new Error('mathlib: only \"wasm\" was enabled, but it\\'s not supported'));\n }\n\n var self = this;\n\n this.__init_promise = Promise.all(Object.keys(self.__modules).map(function (name) {\n var module = self.__modules[name];\n\n if (!self.options.wasm || !self.has_wasm() || !module.wasm_fn) return null;\n\n // If already compiled - exit\n if (self.__wasm[name]) return null;\n\n // Compile wasm source\n return WebAssembly.compile(self.__base64decode(module.wasm_src))\n .then(function (m) { self.__wasm[name] = m; });\n }))\n .then(function () { return self; });\n\n return this.__init_promise;\n};\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Methods below are for internal use from plugins\n\n\n// Simple decode base64 to typed array. Useful to load embedded webassembly\n// code. You probably don't need to call this method directly.\n//\nMultiMath.prototype.__base64decode = base64decode;\n\n\n// Increase current memory to include specified number of bytes. Do nothing if\n// size is already ok. You probably don't need to call this method directly,\n// because it will be invoked from `.__instance()`.\n//\nMultiMath.prototype.__reallocate = function mem_grow_to(bytes) {\n if (!this.__memory) {\n this.__memory = new WebAssembly.Memory({\n initial: Math.ceil(bytes / (64 * 1024))\n });\n return this.__memory;\n }\n\n var mem_size = this.__memory.buffer.byteLength;\n\n if (mem_size < bytes) {\n this.__memory.grow(Math.ceil((bytes - mem_size) / (64 * 1024)));\n }\n\n return this.__memory;\n};\n\n\n// Returns instantinated webassembly item by name, with specified memory size\n// and environment.\n// - use cache if available\n// - do sync module init, if async init was not called earlier\n// - allocate memory if not enougth\n// - can export functions to webassembly via \"env_extra\",\n// for example, { exp: Math.exp }\n//\nMultiMath.prototype.__instance = function instance(name, memsize, env_extra) {\n if (memsize) this.__reallocate(memsize);\n\n // If .init() was not called, do sync compile\n if (!this.__wasm[name]) {\n var module = this.__modules[name];\n this.__wasm[name] = new WebAssembly.Module(this.__base64decode(module.wasm_src));\n }\n\n if (!this.__cache[name]) {\n var env_base = {\n memoryBase: 0,\n memory: this.__memory,\n tableBase: 0,\n table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })\n };\n\n this.__cache[name] = new WebAssembly.Instance(this.__wasm[name], {\n env: assign(env_base, env_extra || {})\n });\n }\n\n return this.__cache[name];\n};\n\n\n// Helper to calculate memory aligh for pointers. Webassembly does not require\n// this, but you may wish to experiment. Default base = 8;\n//\nMultiMath.prototype.__align = function align(number, base) {\n base = base || 8;\n var reminder = number % base;\n return number + (reminder ? base - reminder : 0);\n};\n\n\nmodule.exports = MultiMath;\n\n},{\"./lib/base64decode\":21,\"./lib/wa_detect\":22,\"object-assign\":23}],21:[function(_dereq_,module,exports){\n\n\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n\nmodule.exports = function base64decode(str) {\n var input = str.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length;\n\n var out = new Uint8Array((max * 3) >> 2);\n\n // Collect by 6*4 bits (3 bytes)\n\n var bits = 0;\n var ptr = 0;\n\n for (var idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n out[ptr++] = (bits >> 16) & 0xFF;\n out[ptr++] = (bits >> 8) & 0xFF;\n out[ptr++] = bits & 0xFF;\n }\n\n bits = (bits << 6) | BASE64_MAP.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n var tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n out[ptr++] = (bits >> 16) & 0xFF;\n out[ptr++] = (bits >> 8) & 0xFF;\n out[ptr++] = bits & 0xFF;\n } else if (tailbits === 18) {\n out[ptr++] = (bits >> 10) & 0xFF;\n out[ptr++] = (bits >> 2) & 0xFF;\n } else if (tailbits === 12) {\n out[ptr++] = (bits >> 4) & 0xFF;\n }\n\n return out;\n};\n\n},{}],22:[function(_dereq_,module,exports){\n\n\nvar wa;\n\n\nmodule.exports = function hasWebAssembly() {\n // use cache if called before;\n if (typeof wa !== 'undefined') return wa;\n\n wa = false;\n\n if (typeof WebAssembly === 'undefined') return wa;\n\n // If WebAssenbly is disabled, code can throw on compile\n try {\n // https://github.com/brion/min-wasm-fail/blob/master/min-wasm-fail.in.js\n // Additional check that WA internals are correct\n\n /* eslint-disable comma-spacing, max-len */\n var bin = new Uint8Array([ 0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11 ]);\n var module = new WebAssembly.Module(bin);\n var instance = new WebAssembly.Instance(module, {});\n\n // test storing to and loading from a non-zero location via a parameter.\n // Safari on iOS 11.2.5 returns 0 unexpectedly at non-zero locations\n if (instance.exports.test(4) !== 0) wa = true;\n\n return wa;\n } catch (__) {}\n\n return wa;\n};\n\n},{}],23:[function(_dereq_,module,exports){\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n\n},{}],24:[function(_dereq_,module,exports){\nvar bundleFn = arguments[3];\nvar sources = arguments[4];\nvar cache = arguments[5];\n\nvar stringify = JSON.stringify;\n\nmodule.exports = function (fn, options) {\n var wkey;\n var cacheKeys = Object.keys(cache);\n\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n var exp = cache[key].exports;\n // Using babel as a transpiler to use esmodule, the export will always\n // be an object with the default export as a property of it. To ensure\n // the existing api and babel esmodule exports are both supported we\n // check for both\n if (exp === fn || exp && exp.default === fn) {\n wkey = key;\n break;\n }\n }\n\n if (!wkey) {\n wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n var wcache = {};\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n wcache[key] = key;\n }\n sources[wkey] = [\n 'function(require,module,exports){' + fn + '(self); }',\n wcache\n ];\n }\n var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n\n var scache = {}; scache[wkey] = wkey;\n sources[skey] = [\n 'function(require,module,exports){' +\n // try to call default if defined to also support babel esmodule exports\n 'var f = require(' + stringify(wkey) + ');' +\n '(f.default ? f.default : f)(self);' +\n '}',\n scache\n ];\n\n var workerSources = {};\n resolveSources(skey);\n\n function resolveSources(key) {\n workerSources[key] = true;\n\n for (var depPath in sources[key][1]) {\n var depKey = sources[key][1][depPath];\n if (!workerSources[depKey]) {\n resolveSources(depKey);\n }\n }\n }\n\n var src = '(' + bundleFn + ')({'\n + Object.keys(workerSources).map(function (key) {\n return stringify(key) + ':['\n + sources[key][0]\n + ',' + stringify(sources[key][1]) + ']'\n ;\n }).join(',')\n + '},{},[' + stringify(skey) + '])'\n ;\n\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n var blob = new Blob([src], { type: 'text/javascript' });\n if (options && options.bare) { return blob; }\n var workerUrl = URL.createObjectURL(blob);\n var worker = new Worker(workerUrl);\n worker.objectURL = workerUrl;\n return worker;\n};\n\n},{}],\"/index.js\":[function(_dereq_,module,exports){\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nvar assign = _dereq_('object-assign');\n\nvar webworkify = _dereq_('webworkify');\n\nvar MathLib = _dereq_('./lib/mathlib');\n\nvar Pool = _dereq_('./lib/pool');\n\nvar utils = _dereq_('./lib/utils');\n\nvar worker = _dereq_('./lib/worker');\n\nvar createStages = _dereq_('./lib/stepper');\n\nvar createRegions = _dereq_('./lib/tiler'); // Deduplicate pools & limiters with the same configs\n// when user creates multiple pica instances.\n\n\nvar singletones = {};\nvar NEED_SAFARI_FIX = false;\n\ntry {\n if (typeof navigator !== 'undefined' && navigator.userAgent) {\n NEED_SAFARI_FIX = navigator.userAgent.indexOf('Safari') >= 0;\n }\n} catch (e) {}\n\nvar concurrency = 1;\n\nif (typeof navigator !== 'undefined') {\n concurrency = Math.min(navigator.hardwareConcurrency || 1, 4);\n}\n\nvar DEFAULT_PICA_OPTS = {\n tile: 1024,\n concurrency: concurrency,\n features: ['js', 'wasm', 'ww'],\n idle: 2000,\n createCanvas: function createCanvas(width, height) {\n var tmpCanvas = document.createElement('canvas');\n tmpCanvas.width = width;\n tmpCanvas.height = height;\n return tmpCanvas;\n }\n};\nvar DEFAULT_RESIZE_OPTS = {\n quality: 3,\n alpha: false,\n unsharpAmount: 0,\n unsharpRadius: 0.0,\n unsharpThreshold: 0\n};\nvar CAN_NEW_IMAGE_DATA = false;\nvar CAN_CREATE_IMAGE_BITMAP = false;\nvar CAN_USE_CANVAS_GET_IMAGE_DATA = false;\nvar CAN_USE_OFFSCREEN_CANVAS = false;\nvar CAN_USE_CIB_REGION_FOR_IMAGE = false;\n\nfunction workerFabric() {\n return {\n value: webworkify(worker),\n destroy: function destroy() {\n this.value.terminate();\n\n if (typeof window !== 'undefined') {\n var url = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n if (url && url.revokeObjectURL && this.value.objectURL) {\n url.revokeObjectURL(this.value.objectURL);\n }\n }\n }\n };\n} ////////////////////////////////////////////////////////////////////////////////\n// API methods\n\n\nfunction Pica(options) {\n if (!(this instanceof Pica)) return new Pica(options);\n this.options = assign({}, DEFAULT_PICA_OPTS, options || {});\n var limiter_key = \"lk_\".concat(this.options.concurrency); // Share limiters to avoid multiple parallel workers when user creates\n // multiple pica instances.\n\n this.__limit = singletones[limiter_key] || utils.limiter(this.options.concurrency);\n if (!singletones[limiter_key]) singletones[limiter_key] = this.__limit; // List of supported features, according to options & browser/node.js\n\n this.features = {\n js: false,\n // pure JS implementation, can be disabled for testing\n wasm: false,\n // webassembly implementation for heavy functions\n cib: false,\n // resize via createImageBitmap (only FF at this moment)\n ww: false // webworkers\n\n };\n this.__workersPool = null; // Store requested features for webworkers\n\n this.__requested_features = [];\n this.__mathlib = null;\n}\n\nPica.prototype.init = function () {\n var _this = this;\n\n if (this.__initPromise) return this.__initPromise; // Test if we can create ImageData without canvas and memory copy\n\n if (typeof ImageData !== 'undefined' && typeof Uint8ClampedArray !== 'undefined') {\n try {\n /* eslint-disable no-new */\n new ImageData(new Uint8ClampedArray(400), 10, 10);\n CAN_NEW_IMAGE_DATA = true;\n } catch (__) {}\n } // ImageBitmap can be effective in 2 places:\n //\n // 1. Threaded jpeg unpack (basic)\n // 2. Built-in resize (blocked due problem in chrome, see issue #89)\n //\n // For basic use we also need ImageBitmap wo support .close() method,\n // see https://developer.mozilla.org/ru/docs/Web/API/ImageBitmap\n\n\n if (typeof ImageBitmap !== 'undefined') {\n if (ImageBitmap.prototype && ImageBitmap.prototype.close) {\n CAN_CREATE_IMAGE_BITMAP = true;\n } else {\n this.debug('ImageBitmap does not support .close(), disabled');\n }\n }\n\n var features = this.options.features.slice();\n\n if (features.indexOf('all') >= 0) {\n features = ['cib', 'wasm', 'js', 'ww'];\n }\n\n this.__requested_features = features;\n this.__mathlib = new MathLib(features); // Check WebWorker support if requested\n\n if (features.indexOf('ww') >= 0) {\n if (typeof window !== 'undefined' && 'Worker' in window) {\n // IE <= 11 don't allow to create webworkers from string. We should check it.\n // https://connect.microsoft.com/IE/feedback/details/801810/web-workers-from-blob-urls-in-ie-10-and-11\n try {\n var wkr = _dereq_('webworkify')(function () {});\n\n wkr.terminate();\n this.features.ww = true; // pool uniqueness depends on pool config + webworker config\n\n var wpool_key = \"wp_\".concat(JSON.stringify(this.options));\n\n if (singletones[wpool_key]) {\n this.__workersPool = singletones[wpool_key];\n } else {\n this.__workersPool = new Pool(workerFabric, this.options.idle);\n singletones[wpool_key] = this.__workersPool;\n }\n } catch (__) {}\n }\n }\n\n var initMath = this.__mathlib.init().then(function (mathlib) {\n // Copy detected features\n assign(_this.features, mathlib.features);\n });\n\n var checkCibResize;\n\n if (!CAN_CREATE_IMAGE_BITMAP) {\n checkCibResize = Promise.resolve(false);\n } else {\n checkCibResize = utils.cib_support(this.options.createCanvas).then(function (status) {\n if (_this.features.cib && features.indexOf('cib') < 0) {\n _this.debug('createImageBitmap() resize supported, but disabled by config');\n\n return;\n }\n\n if (features.indexOf('cib') >= 0) _this.features.cib = status;\n });\n }\n\n CAN_USE_CANVAS_GET_IMAGE_DATA = utils.can_use_canvas(this.options.createCanvas);\n var checkOffscreenCanvas;\n\n if (CAN_CREATE_IMAGE_BITMAP && CAN_NEW_IMAGE_DATA && features.indexOf('ww') !== -1) {\n checkOffscreenCanvas = utils.worker_offscreen_canvas_support();\n } else {\n checkOffscreenCanvas = Promise.resolve(false);\n }\n\n checkOffscreenCanvas = checkOffscreenCanvas.then(function (result) {\n CAN_USE_OFFSCREEN_CANVAS = result;\n }); // we use createImageBitmap to crop image data and pass it to workers,\n // so need to check whether function works correctly;\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n\n var checkCibRegion = utils.cib_can_use_region().then(function (result) {\n CAN_USE_CIB_REGION_FOR_IMAGE = result;\n }); // Init math lib. That's async because can load some\n\n this.__initPromise = Promise.all([initMath, checkCibResize, checkOffscreenCanvas, checkCibRegion]).then(function () {\n return _this;\n });\n return this.__initPromise;\n}; // Call resizer in webworker or locally, depending on config\n\n\nPica.prototype.__invokeResize = function (tileOpts, opts) {\n var _this2 = this;\n\n // Share cache between calls:\n //\n // - wasm instance\n // - wasm memory object\n //\n opts.__mathCache = opts.__mathCache || {};\n return Promise.resolve().then(function () {\n if (!_this2.features.ww) {\n // not possible to have ImageBitmap here if user disabled WW\n return {\n data: _this2.__mathlib.resizeAndUnsharp(tileOpts, opts.__mathCache)\n };\n }\n\n return new Promise(function (resolve, reject) {\n var w = _this2.__workersPool.acquire();\n\n if (opts.cancelToken) opts.cancelToken[\"catch\"](function (err) {\n return reject(err);\n });\n\n w.value.onmessage = function (ev) {\n w.release();\n if (ev.data.err) reject(ev.data.err);else resolve(ev.data);\n };\n\n var transfer = [];\n if (tileOpts.src) transfer.push(tileOpts.src.buffer);\n if (tileOpts.srcBitmap) transfer.push(tileOpts.srcBitmap);\n w.value.postMessage({\n opts: tileOpts,\n features: _this2.__requested_features,\n preload: {\n wasm_nodule: _this2.__mathlib.__\n }\n }, transfer);\n });\n });\n}; // this function can return promise if createImageBitmap is used\n\n\nPica.prototype.__extractTileData = function (tile, from, opts, stageEnv, extractTo) {\n if (this.features.ww && CAN_USE_OFFSCREEN_CANVAS && ( // createImageBitmap doesn't work for images (Image, ImageBitmap) with Exif orientation in Chrome,\n // can use canvas because canvas doesn't have orientation;\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n utils.isCanvas(from) || CAN_USE_CIB_REGION_FOR_IMAGE)) {\n this.debug('Create tile for OffscreenCanvas');\n return createImageBitmap(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height).then(function (bitmap) {\n extractTo.srcBitmap = bitmap;\n return extractTo;\n });\n } // Extract tile RGBA buffer, depending on input type\n\n\n if (utils.isCanvas(from)) {\n if (!stageEnv.srcCtx) stageEnv.srcCtx = from.getContext('2d', {\n alpha: Boolean(opts.alpha)\n }); // If input is Canvas - extract region data directly\n\n this.debug('Get tile pixel data');\n extractTo.src = stageEnv.srcCtx.getImageData(tile.x, tile.y, tile.width, tile.height).data;\n return extractTo;\n } // If input is Image or decoded to ImageBitmap,\n // draw region to temporary canvas and extract data from it\n //\n // Note! Attempt to reuse this canvas causes significant slowdown in chrome\n //\n\n\n this.debug('Draw tile imageBitmap/image to temporary canvas');\n var tmpCanvas = this.options.createCanvas(tile.width, tile.height);\n var tmpCtx = tmpCanvas.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n tmpCtx.globalCompositeOperation = 'copy';\n tmpCtx.drawImage(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height, 0, 0, tile.width, tile.height);\n this.debug('Get tile pixel data');\n extractTo.src = tmpCtx.getImageData(0, 0, tile.width, tile.height).data; // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n\n tmpCanvas.width = tmpCanvas.height = 0;\n return extractTo;\n};\n\nPica.prototype.__landTileData = function (tile, result, stageEnv) {\n var toImageData;\n this.debug('Convert raw rgba tile result to ImageData');\n\n if (result.bitmap) {\n stageEnv.toCtx.drawImage(result.bitmap, tile.toX, tile.toY);\n return null;\n }\n\n if (CAN_NEW_IMAGE_DATA) {\n // this branch is for modern browsers\n // If `new ImageData()` & Uint8ClampedArray suported\n toImageData = new ImageData(new Uint8ClampedArray(result.data), tile.toWidth, tile.toHeight);\n } else {\n // fallback for `node-canvas` and old browsers\n // (IE11 has ImageData but does not support `new ImageData()`)\n toImageData = stageEnv.toCtx.createImageData(tile.toWidth, tile.toHeight);\n\n if (toImageData.data.set) {\n toImageData.data.set(result.data);\n } else {\n // IE9 don't have `.set()`\n for (var i = toImageData.data.length - 1; i >= 0; i--) {\n toImageData.data[i] = result.data[i];\n }\n }\n }\n\n this.debug('Draw tile');\n\n if (NEED_SAFARI_FIX) {\n // Safari draws thin white stripes between tiles without this fix\n stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth + 1e-5, tile.toInnerHeight + 1e-5);\n } else {\n stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth, tile.toInnerHeight);\n }\n\n return null;\n};\n\nPica.prototype.__tileAndResize = function (from, to, opts) {\n var _this3 = this;\n\n var stageEnv = {\n srcCtx: null,\n srcImageBitmap: null,\n isImageBitmapReused: false,\n toCtx: null\n };\n\n var processTile = function processTile(tile) {\n return _this3.__limit(function () {\n if (opts.canceled) return opts.cancelToken;\n var tileOpts = {\n width: tile.width,\n height: tile.height,\n toWidth: tile.toWidth,\n toHeight: tile.toHeight,\n scaleX: tile.scaleX,\n scaleY: tile.scaleY,\n offsetX: tile.offsetX,\n offsetY: tile.offsetY,\n quality: opts.quality,\n alpha: opts.alpha,\n unsharpAmount: opts.unsharpAmount,\n unsharpRadius: opts.unsharpRadius,\n unsharpThreshold: opts.unsharpThreshold\n };\n\n _this3.debug('Invoke resize math');\n\n return Promise.resolve(tileOpts).then(function (tileOpts) {\n return _this3.__extractTileData(tile, from, opts, stageEnv, tileOpts);\n }).then(function (tileOpts) {\n _this3.debug('Invoke resize math');\n\n return _this3.__invokeResize(tileOpts, opts);\n }).then(function (result) {\n if (opts.canceled) return opts.cancelToken;\n stageEnv.srcImageData = null;\n return _this3.__landTileData(tile, result, stageEnv);\n });\n });\n }; // Need to normalize data source first. It can be canvas or image.\n // If image - try to decode in background if possible\n\n\n return Promise.resolve().then(function () {\n stageEnv.toCtx = to.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n if (utils.isCanvas(from)) return null;\n\n if (utils.isImageBitmap(from)) {\n stageEnv.srcImageBitmap = from;\n stageEnv.isImageBitmapReused = true;\n return null;\n }\n\n if (utils.isImage(from)) {\n // try do decode image in background for faster next operations;\n // if we're using offscreen canvas, cib is called per tile, so not needed here\n if (!CAN_CREATE_IMAGE_BITMAP) return null;\n\n _this3.debug('Decode image via createImageBitmap');\n\n return createImageBitmap(from).then(function (imageBitmap) {\n stageEnv.srcImageBitmap = imageBitmap;\n }) // Suppress error to use fallback, if method fails\n // https://github.com/nodeca/pica/issues/190\n\n /* eslint-disable no-unused-vars */\n [\"catch\"](function (e) {\n return null;\n });\n }\n\n throw new Error('Pica: \".from\" should be Image, Canvas or ImageBitmap');\n }).then(function () {\n if (opts.canceled) return opts.cancelToken;\n\n _this3.debug('Calculate tiles'); //\n // Here we are with \"normalized\" source,\n // follow to tiling\n //\n\n\n var regions = createRegions({\n width: opts.width,\n height: opts.height,\n srcTileSize: _this3.options.tile,\n toWidth: opts.toWidth,\n toHeight: opts.toHeight,\n destTileBorder: opts.__destTileBorder\n });\n var jobs = regions.map(function (tile) {\n return processTile(tile);\n });\n\n function cleanup(stageEnv) {\n if (stageEnv.srcImageBitmap) {\n if (!stageEnv.isImageBitmapReused) stageEnv.srcImageBitmap.close();\n stageEnv.srcImageBitmap = null;\n }\n }\n\n _this3.debug('Process tiles');\n\n return Promise.all(jobs).then(function () {\n _this3.debug('Finished!');\n\n cleanup(stageEnv);\n return to;\n }, function (err) {\n cleanup(stageEnv);\n throw err;\n });\n });\n};\n\nPica.prototype.__processStages = function (stages, from, to, opts) {\n var _this4 = this;\n\n if (opts.canceled) return opts.cancelToken;\n\n var _stages$shift = stages.shift(),\n _stages$shift2 = _slicedToArray(_stages$shift, 2),\n toWidth = _stages$shift2[0],\n toHeight = _stages$shift2[1];\n\n var isLastStage = stages.length === 0;\n opts = assign({}, opts, {\n toWidth: toWidth,\n toHeight: toHeight,\n // only use user-defined quality for the last stage,\n // use simpler (Hamming) filter for the first stages where\n // scale factor is large enough (more than 2-3)\n quality: isLastStage ? opts.quality : Math.min(1, opts.quality)\n });\n var tmpCanvas;\n\n if (!isLastStage) {\n // create temporary canvas\n tmpCanvas = this.options.createCanvas(toWidth, toHeight);\n }\n\n return this.__tileAndResize(from, isLastStage ? to : tmpCanvas, opts).then(function () {\n if (isLastStage) return to;\n opts.width = toWidth;\n opts.height = toHeight;\n return _this4.__processStages(stages, tmpCanvas, to, opts);\n }).then(function (res) {\n if (tmpCanvas) {\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n tmpCanvas.width = tmpCanvas.height = 0;\n }\n\n return res;\n });\n};\n\nPica.prototype.__resizeViaCreateImageBitmap = function (from, to, opts) {\n var _this5 = this;\n\n var toCtx = to.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n this.debug('Resize via createImageBitmap()');\n return createImageBitmap(from, {\n resizeWidth: opts.toWidth,\n resizeHeight: opts.toHeight,\n resizeQuality: utils.cib_quality_name(opts.quality)\n }).then(function (imageBitmap) {\n if (opts.canceled) return opts.cancelToken; // if no unsharp - draw directly to output canvas\n\n if (!opts.unsharpAmount) {\n toCtx.drawImage(imageBitmap, 0, 0);\n imageBitmap.close();\n toCtx = null;\n\n _this5.debug('Finished!');\n\n return to;\n }\n\n _this5.debug('Unsharp result');\n\n var tmpCanvas = _this5.options.createCanvas(opts.toWidth, opts.toHeight);\n\n var tmpCtx = tmpCanvas.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n tmpCtx.drawImage(imageBitmap, 0, 0);\n imageBitmap.close();\n var iData = tmpCtx.getImageData(0, 0, opts.toWidth, opts.toHeight);\n\n _this5.__mathlib.unsharp_mask(iData.data, opts.toWidth, opts.toHeight, opts.unsharpAmount, opts.unsharpRadius, opts.unsharpThreshold);\n\n toCtx.putImageData(iData, 0, 0); // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n\n tmpCanvas.width = tmpCanvas.height = 0;\n iData = tmpCtx = tmpCanvas = toCtx = null;\n\n _this5.debug('Finished!');\n\n return to;\n });\n};\n\nPica.prototype.resize = function (from, to, options) {\n var _this6 = this;\n\n this.debug('Start resize...');\n var opts = assign({}, DEFAULT_RESIZE_OPTS);\n\n if (!isNaN(options)) {\n opts = assign(opts, {\n quality: options\n });\n } else if (options) {\n opts = assign(opts, options);\n }\n\n opts.toWidth = to.width;\n opts.toHeight = to.height;\n opts.width = from.naturalWidth || from.width;\n opts.height = from.naturalHeight || from.height; // Prevent stepper from infinite loop\n\n if (to.width === 0 || to.height === 0) {\n return Promise.reject(new Error(\"Invalid output size: \".concat(to.width, \"x\").concat(to.height)));\n }\n\n if (opts.unsharpRadius > 2) opts.unsharpRadius = 2;\n opts.canceled = false;\n\n if (opts.cancelToken) {\n // Wrap cancelToken to avoid successive resolve & set flag\n opts.cancelToken = opts.cancelToken.then(function (data) {\n opts.canceled = true;\n throw data;\n }, function (err) {\n opts.canceled = true;\n throw err;\n });\n }\n\n var DEST_TILE_BORDER = 3; // Max possible filter window size\n\n opts.__destTileBorder = Math.ceil(Math.max(DEST_TILE_BORDER, 2.5 * opts.unsharpRadius | 0));\n return this.init().then(function () {\n if (opts.canceled) return opts.cancelToken; // if createImageBitmap supports resize, just do it and return\n\n if (_this6.features.cib) {\n return _this6.__resizeViaCreateImageBitmap(from, to, opts);\n }\n\n if (!CAN_USE_CANVAS_GET_IMAGE_DATA) {\n var err = new Error('Pica: cannot use getImageData on canvas, ' + \"make sure fingerprinting protection isn't enabled\");\n err.code = 'ERR_GET_IMAGE_DATA';\n throw err;\n } //\n // No easy way, let's resize manually via arrays\n //\n\n\n var stages = createStages(opts.width, opts.height, opts.toWidth, opts.toHeight, _this6.options.tile, opts.__destTileBorder);\n return _this6.__processStages(stages, from, to, opts);\n });\n}; // RGBA buffer resize\n//\n\n\nPica.prototype.resizeBuffer = function (options) {\n var _this7 = this;\n\n var opts = assign({}, DEFAULT_RESIZE_OPTS, options);\n return this.init().then(function () {\n return _this7.__mathlib.resizeAndUnsharp(opts);\n });\n};\n\nPica.prototype.toBlob = function (canvas, mimeType, quality) {\n mimeType = mimeType || 'image/png';\n return new Promise(function (resolve) {\n if (canvas.toBlob) {\n canvas.toBlob(function (blob) {\n return resolve(blob);\n }, mimeType, quality);\n return;\n }\n\n if (canvas.convertToBlob) {\n resolve(canvas.convertToBlob({\n type: mimeType,\n quality: quality\n }));\n return;\n } // Fallback for old browsers\n\n\n var asString = atob(canvas.toDataURL(mimeType, quality).split(',')[1]);\n var len = asString.length;\n var asBuffer = new Uint8Array(len);\n\n for (var i = 0; i < len; i++) {\n asBuffer[i] = asString.charCodeAt(i);\n }\n\n resolve(new Blob([asBuffer], {\n type: mimeType\n }));\n });\n};\n\nPica.prototype.debug = function () {};\n\nmodule.exports = Pica;\n\n},{\"./lib/mathlib\":1,\"./lib/pool\":13,\"./lib/stepper\":14,\"./lib/tiler\":15,\"./lib/utils\":16,\"./lib/worker\":17,\"object-assign\":23,\"webworkify\":24}]},{},[])(\"/index.js\")\n});\n});\n\nvar image_traverse = createCommonjsModule(function (module) {\n\n//////////////////////////////////////////////////////////////////////////\n// Helpers\n//\nfunction error(message, code) {\n var err = new Error(message);\n err.code = code;\n return err;\n}\n\n\n// Convert number to 0xHH string\n//\nfunction to_hex(number) {\n var n = number.toString(16).toUpperCase();\n for (var i = 2 - n.length; i > 0; i--) n = '0' + n;\n return '0x' + n;\n}\n\n\nfunction utf8_encode(str) {\n try {\n return unescape(encodeURIComponent(str));\n } catch (_) {\n return str;\n }\n}\n\n\nfunction utf8_decode(str) {\n try {\n return decodeURIComponent(escape(str));\n } catch (_) {\n return str;\n }\n}\n\n\n// Check if input is a Uint8Array\n//\nfunction is_uint8array(bin) {\n return Object.prototype.toString.call(bin) === '[object Uint8Array]';\n}\n\n\n//////////////////////////////////////////////////////////////////////////\n// Exif parser\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n// - exif_start: Number - start of TIFF header (after Exif\\0\\0)\n// - exif_end: Number - end of Exif segment\n// - on_entry: Number - callback\n//\nfunction ExifParser(jpeg_bin, exif_start, exif_end) {\n // Uint8Array, exif without signature (which isn't included in offsets)\n this.input = jpeg_bin.subarray(exif_start, exif_end);\n\n // offset correction for `on_entry` callback\n this.start = exif_start;\n\n // Check TIFF header (includes byte alignment and first IFD offset)\n var sig = String.fromCharCode.apply(null, this.input.subarray(0, 4));\n\n if (sig !== 'II\\x2A\\0' && sig !== 'MM\\0\\x2A') {\n throw error('invalid TIFF signature', 'EBADDATA');\n }\n\n // true if motorola (big endian) byte alignment, false if intel\n this.big_endian = sig[0] === 'M';\n}\n\n\nExifParser.prototype.each = function (on_entry) {\n // allow premature exit\n this.aborted = false;\n\n var offset = this.read_uint32(4);\n\n this.ifds_to_read = [ {\n id: 0,\n offset: offset\n } ];\n\n while (this.ifds_to_read.length > 0 && !this.aborted) {\n var i = this.ifds_to_read.shift();\n if (!i.offset) continue;\n this.scan_ifd(i.id, i.offset, on_entry);\n }\n};\n\n\nExifParser.prototype.filter = function (on_entry) {\n var ifds = {};\n\n // make sure IFD0 always exists\n ifds.ifd0 = { id: 0, entries: [] };\n\n this.each(function (entry) {\n if (on_entry(entry) === false && !entry.is_subifd_link) return;\n if (entry.is_subifd_link && entry.count !== 1 && entry.format !== 4) return; // filter out bogus links\n\n if (!ifds['ifd' + entry.ifd]) {\n ifds['ifd' + entry.ifd] = { id: entry.ifd, entries: [] };\n }\n\n ifds['ifd' + entry.ifd].entries.push(entry);\n });\n\n // thumbnails are not supported just yet, so delete all information related to it\n delete ifds.ifd1;\n\n // Calculate output size\n var length = 8;\n Object.keys(ifds).forEach(function (ifd_no) {\n length += 2;\n\n ifds[ifd_no].entries.forEach(function (entry) {\n length += 12 + (entry.data_length > 4 ? Math.ceil(entry.data_length / 2) * 2 : 0);\n });\n\n length += 4;\n });\n\n this.output = new Uint8Array(length);\n this.output[0] = this.output[1] = (this.big_endian ? 'M' : 'I').charCodeAt(0);\n this.write_uint16(2, 0x2A);\n\n var offset = 8;\n var self = this;\n this.write_uint32(4, offset);\n\n Object.keys(ifds).forEach(function (ifd_no) {\n ifds[ifd_no].written_offset = offset;\n\n var ifd_start = offset;\n var ifd_end = ifd_start + 2 + ifds[ifd_no].entries.length * 12 + 4;\n offset = ifd_end;\n\n self.write_uint16(ifd_start, ifds[ifd_no].entries.length);\n\n ifds[ifd_no].entries.sort(function (a, b) {\n // IFD entries must be in order of increasing tag IDs\n return a.tag - b.tag;\n }).forEach(function (entry, idx) {\n var entry_offset = ifd_start + 2 + idx * 12;\n\n self.write_uint16(entry_offset, entry.tag);\n self.write_uint16(entry_offset + 2, entry.format);\n self.write_uint32(entry_offset + 4, entry.count);\n\n if (entry.is_subifd_link) {\n // filled in later\n if (ifds['ifd' + entry.tag]) ifds['ifd' + entry.tag].link_offset = entry_offset + 8;\n } else if (entry.data_length <= 4) {\n self.output.set(\n self.input.subarray(entry.data_offset - self.start, entry.data_offset - self.start + 4),\n entry_offset + 8\n );\n } else {\n self.write_uint32(entry_offset + 8, offset);\n self.output.set(\n self.input.subarray(entry.data_offset - self.start, entry.data_offset - self.start + entry.data_length),\n offset\n );\n offset += Math.ceil(entry.data_length / 2) * 2;\n }\n });\n\n var next_ifd = ifds['ifd' + (ifds[ifd_no].id + 1)];\n if (next_ifd) next_ifd.link_offset = ifd_end - 4;\n });\n\n Object.keys(ifds).forEach(function (ifd_no) {\n if (ifds[ifd_no].written_offset && ifds[ifd_no].link_offset) {\n self.write_uint32(ifds[ifd_no].link_offset, ifds[ifd_no].written_offset);\n }\n });\n\n if (this.output.length !== offset) throw error('internal error: incorrect buffer size allocated');\n\n return this.output;\n};\n\n\nExifParser.prototype.read_uint16 = function (offset) {\n var d = this.input;\n if (offset + 2 > d.length) throw error('unexpected EOF', 'EBADDATA');\n\n return this.big_endian ?\n d[offset] * 0x100 + d[offset + 1] :\n d[offset] + d[offset + 1] * 0x100;\n};\n\n\nExifParser.prototype.read_uint32 = function (offset) {\n var d = this.input;\n if (offset + 4 > d.length) throw error('unexpected EOF', 'EBADDATA');\n\n return this.big_endian ?\n d[offset] * 0x1000000 + d[offset + 1] * 0x10000 + d[offset + 2] * 0x100 + d[offset + 3] :\n d[offset] + d[offset + 1] * 0x100 + d[offset + 2] * 0x10000 + d[offset + 3] * 0x1000000;\n};\n\n\nExifParser.prototype.write_uint16 = function (offset, value) {\n var d = this.output;\n\n if (this.big_endian) {\n d[offset] = (value >>> 8) & 0xFF;\n d[offset + 1] = value & 0xFF;\n } else {\n d[offset] = value & 0xFF;\n d[offset + 1] = (value >>> 8) & 0xFF;\n }\n};\n\n\nExifParser.prototype.write_uint32 = function (offset, value) {\n var d = this.output;\n\n if (this.big_endian) {\n d[offset] = (value >>> 24) & 0xFF;\n d[offset + 1] = (value >>> 16) & 0xFF;\n d[offset + 2] = (value >>> 8) & 0xFF;\n d[offset + 3] = value & 0xFF;\n } else {\n d[offset] = value & 0xFF;\n d[offset + 1] = (value >>> 8) & 0xFF;\n d[offset + 2] = (value >>> 16) & 0xFF;\n d[offset + 3] = (value >>> 24) & 0xFF;\n }\n};\n\n\nExifParser.prototype.is_subifd_link = function (ifd, tag) {\n return (ifd === 0 && tag === 0x8769) || // SubIFD\n (ifd === 0 && tag === 0x8825) || // GPS Info\n (ifd === 0x8769 && tag === 0xA005); // Interop IFD\n};\n\n\n// Returns byte length of a single component of a given format\n//\nExifParser.prototype.exif_format_length = function (format) {\n switch (format) {\n case 1: // byte\n case 2: // ascii\n case 6: // sbyte\n case 7: // undefined\n return 1;\n\n case 3: // short\n case 8: // sshort\n return 2;\n\n case 4: // long\n case 9: // slong\n case 11: // float\n return 4;\n\n case 5: // rational\n case 10: // srational\n case 12: // double\n return 8;\n\n default:\n // unknown type\n return 0;\n }\n};\n\n\n// Reads Exif data\n//\nExifParser.prototype.exif_format_read = function (format, offset) {\n var v;\n\n switch (format) {\n case 1: // byte\n case 2: // ascii\n v = this.input[offset];\n return v;\n\n case 6: // sbyte\n v = this.input[offset];\n return v | (v & 0x80) * 0x1fffffe;\n\n case 3: // short\n v = this.read_uint16(offset);\n return v;\n\n case 8: // sshort\n v = this.read_uint16(offset);\n return v | (v & 0x8000) * 0x1fffe;\n\n case 4: // long\n v = this.read_uint32(offset);\n return v;\n\n case 9: // slong\n v = this.read_uint32(offset);\n return v | 0;\n\n case 5: // rational\n case 10: // srational\n case 11: // float\n case 12: // double\n return null; // not implemented\n\n case 7: // undefined\n return null; // blob\n\n default:\n // unknown type\n return null;\n }\n};\n\n\nExifParser.prototype.scan_ifd = function (ifd_no, offset, on_entry) {\n var entry_count = this.read_uint16(offset);\n\n offset += 2;\n\n for (var i = 0; i < entry_count; i++) {\n var tag = this.read_uint16(offset);\n var format = this.read_uint16(offset + 2);\n var count = this.read_uint32(offset + 4);\n\n var comp_length = this.exif_format_length(format);\n var data_length = count * comp_length;\n var data_offset = data_length <= 4 ? offset + 8 : this.read_uint32(offset + 8);\n var is_subifd_link = false;\n\n if (data_offset + data_length > this.input.length) {\n throw error('unexpected EOF', 'EBADDATA');\n }\n\n var value = [];\n var comp_offset = data_offset;\n\n for (var j = 0; j < count; j++, comp_offset += comp_length) {\n var item = this.exif_format_read(format, comp_offset);\n if (item === null) {\n value = null;\n break;\n }\n value.push(item);\n }\n\n if (Array.isArray(value) && format === 2) {\n try {\n value = utf8_decode(String.fromCharCode.apply(null, value));\n } catch (_) {\n value = null;\n }\n\n if (value && value[value.length - 1] === '\\0') value = value.slice(0, -1);\n }\n\n if (this.is_subifd_link(ifd_no, tag)) {\n if (Array.isArray(value) && Number.isInteger(value[0]) && value[0] > 0) {\n this.ifds_to_read.push({\n id: tag,\n offset: value[0]\n });\n is_subifd_link = true;\n }\n }\n\n var entry = {\n is_big_endian: this.big_endian,\n ifd: ifd_no,\n tag: tag,\n format: format,\n count: count,\n entry_offset: offset + this.start,\n data_length: data_length,\n data_offset: data_offset + this.start,\n value: value,\n is_subifd_link: is_subifd_link\n };\n\n if (on_entry(entry) === false) {\n this.aborted = true;\n return;\n }\n\n offset += 12;\n }\n\n if (ifd_no === 0) {\n this.ifds_to_read.push({\n id: 1,\n offset: this.read_uint32(offset)\n });\n }\n};\n\n\n// Check whether input is a JPEG image\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n//\n// Returns true if it is and false otherwise\n//\nmodule.exports.is_jpeg = function (jpeg_bin) {\n return jpeg_bin.length >= 4 && jpeg_bin[0] === 0xFF && jpeg_bin[1] === 0xD8 && jpeg_bin[2] === 0xFF;\n};\n\n\n// Call an iterator on each segment in the given JPEG image\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n// - on_segment: Function - callback executed on each JPEG marker segment\n// - segment: Object\n// - code: Number - marker type (2nd byte, e.g. 0xE0 for APP0)\n// - offset: Number - offset of the first byte (0xFF) relative to `jpeg_bin` start\n// - length: Number - length of the entire marker segment including first two bytes and length\n// - 2 for standalone markers\n// - 4+length for markers with data\n//\n// Iteration stops when `EOI` (0xFFD9) marker is reached or if `on_segment`\n// function returns `false`.\n//\nmodule.exports.jpeg_segments_each = function (jpeg_bin, on_segment) {\n if (!is_uint8array(jpeg_bin)) {\n throw error('Invalid argument (jpeg_bin), Uint8Array expected', 'EINVAL');\n }\n\n if (typeof on_segment !== 'function') {\n throw error('Invalid argument (on_segment), Function expected', 'EINVAL');\n }\n\n if (!module.exports.is_jpeg(jpeg_bin)) {\n throw error('Unknown file format', 'ENOTJPEG');\n }\n\n var offset = 0, length = jpeg_bin.length, inside_scan = false;\n\n for (;;) {\n var segment_code, segment_length;\n\n if (offset + 1 >= length) throw error('Unexpected EOF', 'EBADDATA');\n var byte1 = jpeg_bin[offset];\n var byte2 = jpeg_bin[offset + 1];\n\n if (byte1 === 0xFF && byte2 === 0xFF) {\n // padding\n segment_code = 0xFF;\n segment_length = 1;\n\n } else if (byte1 === 0xFF && byte2 !== 0) {\n // marker\n segment_code = byte2;\n segment_length = 2;\n\n if ((0xD0 <= segment_code && segment_code <= 0xD9) || segment_code === 0x01) ; else {\n if (offset + 3 >= length) throw error('Unexpected EOF', 'EBADDATA');\n segment_length += jpeg_bin[offset + 2] * 0x100 + jpeg_bin[offset + 3];\n if (segment_length < 2) throw error('Invalid segment length', 'EBADDATA');\n if (offset + segment_length - 1 >= length) throw error('Unexpected EOF', 'EBADDATA');\n }\n\n if (inside_scan) {\n if (segment_code >= 0xD0 && segment_code <= 0xD7) ; else {\n inside_scan = false;\n }\n }\n\n if (segment_code === 0xDA /* SOS */) inside_scan = true;\n } else if (inside_scan) {\n // entropy-encoded segment\n for (var pos = offset + 1; ; pos++) {\n // scan until we find FF\n if (pos >= length) throw error('Unexpected EOF', 'EBADDATA');\n if (jpeg_bin[pos] === 0xFF) {\n if (pos + 1 >= length) throw error('Unexpected EOF', 'EBADDATA');\n if (jpeg_bin[pos + 1] !== 0) {\n segment_code = 0;\n segment_length = pos - offset;\n break;\n }\n }\n }\n } else {\n throw error('Unexpected byte at segment start: ' + to_hex(byte1) +\n ' (offset ' + to_hex(offset) + ')', 'EBADDATA');\n }\n\n if (on_segment({ code: segment_code, offset: offset, length: segment_length }) === false) break;\n if (segment_code === 0xD9 /* EOI */) break;\n offset += segment_length;\n }\n};\n\n\n// Replace or remove segments in the given JPEG image\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n// - on_segment: Function - callback executed on each JPEG marker segment\n// - segment: Object\n// - code: Number - marker type (2nd byte, e.g. 0xE0 for APP0)\n// - offset: Number - offset of the first byte (0xFF) relative to `jpeg_bin` start\n// - length: Number - length of the entire marker segment including first two bytes and length\n// - 2 for standalone markers\n// - 4+length for markers with data\n//\n// `on_segment` function should return one of the following:\n// - `false` - segment is removed from the output\n// - Uint8Array - segment is replaced with the new data\n// - [ Uint8Array ] - segment is replaced with the new data\n// - anything else - segment is copied to the output as is\n//\n// Any data after `EOI` (0xFFD9) marker is removed.\n//\nmodule.exports.jpeg_segments_filter = function (jpeg_bin, on_segment) {\n if (!is_uint8array(jpeg_bin)) {\n throw error('Invalid argument (jpeg_bin), Uint8Array expected', 'EINVAL');\n }\n\n if (typeof on_segment !== 'function') {\n throw error('Invalid argument (on_segment), Function expected', 'EINVAL');\n }\n\n var ranges = [];\n var out_length = 0;\n\n module.exports.jpeg_segments_each(jpeg_bin, function (segment) {\n var new_segment = on_segment(segment);\n\n if (is_uint8array(new_segment)) {\n ranges.push({ data: new_segment });\n out_length += new_segment.length;\n } else if (Array.isArray(new_segment)) {\n new_segment.filter(is_uint8array).forEach(function (s) {\n ranges.push({ data: s });\n out_length += s.length;\n });\n } else if (new_segment !== false) {\n var new_range = { start: segment.offset, end: segment.offset + segment.length };\n\n if (ranges.length > 0 && ranges[ranges.length - 1].end === new_range.start) {\n ranges[ranges.length - 1].end = new_range.end;\n } else {\n ranges.push(new_range);\n }\n\n out_length += segment.length;\n }\n });\n\n var result = new Uint8Array(out_length);\n var offset = 0;\n\n ranges.forEach(function (range) {\n var data = range.data || jpeg_bin.subarray(range.start, range.end);\n result.set(data, offset);\n offset += data.length;\n });\n\n return result;\n};\n\n\n// Call an iterator on each Exif entry in the given JPEG image\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n// - on_entry: Function - callback executed on each Exif entry\n// - entry: Object\n// - is_big_endian: Boolean - whether Exif uses big or little endian byte alignment\n// - ifd: Number - IFD identifier (0 for IFD0, 1 for IFD1, 0x8769 for SubIFD,\n// 0x8825 for GPS Info, 0xA005 for Interop IFD)\n// - tag: Number - exif entry tag (0x0110 - camera name, 0x0112 - orientation, etc. - see Exif spec)\n// - format: Number - exif entry format (1 - byte, 2 - ascii, 3 - short, etc. - see Exif spec)\n// - count: Number - number of components of the given format inside data\n// (usually 1, or string length for ascii format)\n// - entry_offset: Number - start of Exif entry (entry length is always 12, so not included)\n// - data_offset: Number - start of data attached to Exif entry (will overlap with entry if length <= 4)\n// - data_length: Number - length of data attached to Exif entry\n// - value: Array|String|Null - our best attempt at parsing data (not all formats supported right now)\n// - is_subifd_link: Boolean - whether this entry is recognized to be a link to subifd (can't filter these out)\n//\n// Iteration stops early if iterator returns `false`.\n//\n// If Exif wasn't found anywhere (before start of the image data, SOS),\n// iterator is never executed.\n//\nmodule.exports.jpeg_exif_tags_each = function (jpeg_bin, on_exif_entry) {\n if (!is_uint8array(jpeg_bin)) {\n throw error('Invalid argument (jpeg_bin), Uint8Array expected', 'EINVAL');\n }\n\n if (typeof on_exif_entry !== 'function') {\n throw error('Invalid argument (on_exif_entry), Function expected', 'EINVAL');\n }\n\n /* eslint-disable consistent-return */\n module.exports.jpeg_segments_each(jpeg_bin, function (segment) {\n if (segment.code === 0xDA /* SOS */) return false;\n\n // look for APP1 segment and compare header with 'Exif\\0\\0'\n if (segment.code === 0xE1 && segment.length >= 10 &&\n jpeg_bin[segment.offset + 4] === 0x45 && jpeg_bin[segment.offset + 5] === 0x78 &&\n jpeg_bin[segment.offset + 6] === 0x69 && jpeg_bin[segment.offset + 7] === 0x66 &&\n jpeg_bin[segment.offset + 8] === 0x00 && jpeg_bin[segment.offset + 9] === 0x00) {\n\n new ExifParser(jpeg_bin, segment.offset + 10, segment.offset + segment.length).each(on_exif_entry);\n return false;\n }\n });\n};\n\n\n// Remove Exif entries in the given JPEG image\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n// - on_entry: Function - callback executed on each Exif entry\n// - entry: Object\n// - is_big_endian: Boolean - whether Exif uses big or little endian byte alignment\n// - ifd: Number - IFD identifier (0 for IFD0, 1 for IFD1, 0x8769 for SubIFD,\n// 0x8825 for GPS Info, 0xA005 for Interop IFD)\n// - tag: Number - exif entry tag (0x0110 - camera name, 0x0112 - orientation, etc. - see Exif spec)\n// - format: Number - exif entry format (1 - byte, 2 - ascii, 3 - short, etc. - see Exif spec)\n// - count: Number - number of components of the given format inside data\n// (usually 1, or string length for ascii format)\n// - entry_offset: Number - start of Exif entry (entry length is always 12, so not included)\n// - data_offset: Number - start of data attached to Exif entry (will overlap with entry if length <= 4)\n// - data_length: Number - length of data attached to Exif entry\n// - value: Array|String|Null - our best attempt at parsing data (not all formats supported right now)\n// - is_subifd_link: Boolean - whether this entry is recognized to be a link to subifd (can't filter these out)\n//\n// This function removes following from Exif:\n// - all entries where iterator returned false (except subifd links which are mandatory)\n// - IFD1 and thumbnail image (the purpose of this function is to reduce file size,\n// so thumbnail is usually the first thing to go)\n// - all other data that isn't in IFD0, SubIFD, GPSIFD, InteropIFD\n// (theoretically possible proprietary extensions, I haven't seen any of these yet)\n//\n// Changing data inside Exif entries is NOT supported yet (modifying `entry` object inside callback may break stuff).\n//\n// If Exif wasn't found anywhere (before start of the image data, SOS),\n// iterator is never executed, and original JPEG is returned as is.\n//\nmodule.exports.jpeg_exif_tags_filter = function (jpeg_bin, on_exif_entry) {\n if (!is_uint8array(jpeg_bin)) {\n throw error('Invalid argument (jpeg_bin), Uint8Array expected', 'EINVAL');\n }\n\n if (typeof on_exif_entry !== 'function') {\n throw error('Invalid argument (on_exif_entry), Function expected', 'EINVAL');\n }\n\n var stop_search = false;\n\n return module.exports.jpeg_segments_filter(jpeg_bin, function (segment) {\n if (stop_search) return;\n if (segment.code === 0xDA /* SOS */) stop_search = true;\n\n // look for APP1 segment and compare header with 'Exif\\0\\0'\n if (segment.code === 0xE1 && segment.length >= 10 &&\n jpeg_bin[segment.offset + 4] === 0x45 && jpeg_bin[segment.offset + 5] === 0x78 &&\n jpeg_bin[segment.offset + 6] === 0x69 && jpeg_bin[segment.offset + 7] === 0x66 &&\n jpeg_bin[segment.offset + 8] === 0x00 && jpeg_bin[segment.offset + 9] === 0x00) {\n\n var new_exif = new ExifParser(jpeg_bin, segment.offset + 10, segment.offset + segment.length)\n .filter(on_exif_entry);\n if (!new_exif) return false;\n\n var header = new Uint8Array(10);\n\n header.set(jpeg_bin.slice(segment.offset, segment.offset + 10));\n header[2] = ((new_exif.length + 8) >>> 8) & 0xFF;\n header[3] = (new_exif.length + 8) & 0xFF;\n\n stop_search = true;\n return [ header, new_exif ];\n }\n });\n};\n\n\n// Inserts a custom comment marker segment into JPEG file.\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n// - comment: String\n//\n// Comment is inserted after first two bytes (FFD8, SOI).\n//\n// If JFIF (APP0) marker exists immediately after SOI (as mandated by the JFIF\n// spec), we insert comment after it instead.\n//\nmodule.exports.jpeg_add_comment = function (jpeg_bin, comment) {\n var comment_inserted = false, segment_count = 0;\n\n return module.exports.jpeg_segments_filter(jpeg_bin, function (segment) {\n segment_count++;\n if (segment_count === 1 && segment.code === 0xD8 /* SOI */) return;\n if (segment_count === 2 && segment.code === 0xE0 /* APP0 */) return;\n\n if (comment_inserted) return;\n comment = utf8_encode(comment);\n\n // comment segment\n var csegment = new Uint8Array(5 + comment.length);\n var offset = 0;\n\n csegment[offset++] = 0xFF;\n csegment[offset++] = 0xFE;\n csegment[offset++] = ((comment.length + 3) >>> 8) & 0xFF;\n csegment[offset++] = (comment.length + 3) & 0xFF;\n\n comment.split('').forEach(function (c) {\n csegment[offset++] = c.charCodeAt(0) & 0xFF;\n });\n\n csegment[offset++] = 0;\n comment_inserted = true;\n\n return [ csegment, jpeg_bin.subarray(segment.offset, segment.offset + segment.length) ];\n });\n};\n});\n\nfunction jpeg_patch_exif(env) {\n return this._getUint8Array(env.blob).then(function (data) {\n env.is_jpeg = image_traverse.is_jpeg(data);\n\n if (!env.is_jpeg) return Promise.resolve(env);\n\n env.orig_blob = env.blob;\n\n try {\n var exif_is_big_endian, orientation_offset;\n\n /* eslint-disable consistent-return */\n image_traverse.jpeg_exif_tags_each(data, function (entry) {\n if (entry.ifd === 0 && entry.tag === 0x112 && Array.isArray(entry.value)) {\n env.orientation = entry.value[0] || 1;\n exif_is_big_endian = entry.is_big_endian;\n orientation_offset = entry.data_offset;\n return false;\n }\n });\n\n if (orientation_offset) {\n var orientation_patch = exif_is_big_endian ?\n new Uint8Array([ 0, 1 ]) :\n new Uint8Array([ 1, 0 ]);\n\n env.blob = new Blob([\n data.slice(0, orientation_offset),\n orientation_patch,\n data.slice(orientation_offset + 2)\n ], { type: 'image/jpeg' });\n }\n } catch (_) {}\n\n return env;\n });\n}\n\n\nfunction jpeg_rotate_canvas(env) {\n if (!env.is_jpeg) return Promise.resolve(env);\n\n var orientation = env.orientation - 1;\n if (!orientation) return Promise.resolve(env);\n\n var canvas;\n\n if (orientation & 4) {\n canvas = this.pica.options.createCanvas(env.out_canvas.height, env.out_canvas.width);\n } else {\n canvas = this.pica.options.createCanvas(env.out_canvas.width, env.out_canvas.height);\n }\n\n var ctx = canvas.getContext('2d');\n\n ctx.save();\n\n if (orientation & 1) ctx.transform(-1, 0, 0, 1, canvas.width, 0);\n if (orientation & 2) ctx.transform(-1, 0, 0, -1, canvas.width, canvas.height);\n if (orientation & 4) ctx.transform(0, 1, 1, 0, 0, 0);\n\n ctx.drawImage(env.out_canvas, 0, 0);\n ctx.restore();\n\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n env.out_canvas.width = env.out_canvas.height = 0;\n\n env.out_canvas = canvas;\n\n return Promise.resolve(env);\n}\n\n\nfunction jpeg_attach_orig_segments(env) {\n if (!env.is_jpeg) return Promise.resolve(env);\n\n return Promise.all([\n this._getUint8Array(env.blob),\n this._getUint8Array(env.out_blob)\n ]).then(function (res) {\n var data = res[0];\n var data_out = res[1];\n\n if (!image_traverse.is_jpeg(data)) return Promise.resolve(env);\n\n var segments = [];\n\n image_traverse.jpeg_segments_each(data, function (segment) {\n if (segment.code === 0xDA /* SOS */) return false;\n segments.push(segment);\n });\n\n segments = segments\n .filter(function (segment) {\n // Drop ICC_PROFILE\n //\n if (segment.code === 0xE2) return false;\n\n // Keep all APPn segments excluding APP2 (ICC_PROFILE),\n // remove others because most of them depend on image data (DCT and such).\n //\n // APP0 - JFIF, APP1 - Exif, the rest are photoshop metadata and such\n //\n // See full list at https://www.w3.org/Graphics/JPEG/itu-t81.pdf (table B.1 on page 32)\n //\n if (segment.code >= 0xE0 && segment.code < 0xF0) return true;\n\n // Keep comments\n //\n if (segment.code === 0xFE) return true;\n\n return false;\n })\n .map(function (segment) {\n return data.slice(segment.offset, segment.offset + segment.length);\n });\n\n env.out_blob = new Blob(\n // intentionally omitting expected JFIF segment (offset 2 to 20)\n [ data_out.slice(0, 2) ].concat(segments).concat([ data_out.slice(20) ]),\n { type: 'image/jpeg' }\n );\n\n return env;\n });\n}\n\n\nfunction assign(reducer) {\n reducer.before('_blob_to_image', jpeg_patch_exif);\n reducer.after('_transform', jpeg_rotate_canvas);\n reducer.after('_create_blob', jpeg_attach_orig_segments);\n}\n\n\nvar jpeg_patch_exif_1 = jpeg_patch_exif;\nvar jpeg_rotate_canvas_1 = jpeg_rotate_canvas;\nvar jpeg_attach_orig_segments_1 = jpeg_attach_orig_segments;\nvar assign_1 = assign;\n\nvar jpeg_plugins = {\n\tjpeg_patch_exif: jpeg_patch_exif_1,\n\tjpeg_rotate_canvas: jpeg_rotate_canvas_1,\n\tjpeg_attach_orig_segments: jpeg_attach_orig_segments_1,\n\tassign: assign_1\n};\n\nfunction ImageBlobReduce(options) {\n if (!(this instanceof ImageBlobReduce)) return new ImageBlobReduce(options);\n\n options = options || {};\n\n this.pica = options.pica || pica({});\n this.initialized = false;\n\n this.utils = utils;\n}\n\n\nImageBlobReduce.prototype.use = function (plugin /*, params, ... */) {\n var args = [ this ].concat(Array.prototype.slice.call(arguments, 1));\n plugin.apply(plugin, args);\n return this;\n};\n\n\nImageBlobReduce.prototype.init = function () {\n this.use(jpeg_plugins.assign);\n};\n\n\nImageBlobReduce.prototype.toBlob = function (blob, options) {\n var opts = utils.assign({ max: Infinity }, options);\n var env = {\n blob: blob,\n opts: opts\n };\n\n if (!this.initialized) {\n this.init();\n this.initialized = true;\n }\n\n return Promise.resolve(env)\n .then(this._blob_to_image)\n .then(this._calculate_size)\n .then(this._transform)\n .then(this._cleanup)\n .then(this._create_blob)\n .then(function (_env) {\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n _env.out_canvas.width = _env.out_canvas.height = 0;\n\n return _env.out_blob;\n });\n};\n\n\nImageBlobReduce.prototype.toCanvas = function (blob, options) {\n var opts = utils.assign({ max: Infinity }, options);\n var env = {\n blob: blob,\n opts: opts\n };\n\n if (!this.initialized) {\n this.init();\n this.initialized = true;\n }\n\n return Promise.resolve(env)\n .then(this._blob_to_image)\n .then(this._calculate_size)\n .then(this._transform)\n .then(this._cleanup)\n .then(function (_env) { return _env.out_canvas; });\n};\n\n\nImageBlobReduce.prototype.before = function (method_name, fn) {\n if (!this[method_name]) throw new Error('Method \"' + method_name + '\" does not exist');\n if (typeof fn !== 'function') throw new Error('Invalid argument \"fn\", function expected');\n\n var old_fn = this[method_name];\n var self = this;\n\n this[method_name] = function (env) {\n return fn.call(self, env).then(function (_env) {\n return old_fn.call(self, _env);\n });\n };\n\n return this;\n};\n\n\nImageBlobReduce.prototype.after = function (method_name, fn) {\n if (!this[method_name]) throw new Error('Method \"' + method_name + '\" does not exist');\n if (typeof fn !== 'function') throw new Error('Invalid argument \"fn\", function expected');\n\n var old_fn = this[method_name];\n var self = this;\n\n this[method_name] = function (env) {\n return old_fn.call(self, env).then(function (_env) {\n return fn.call(self, _env);\n });\n };\n\n return this;\n};\n\n\nImageBlobReduce.prototype._blob_to_image = function (env) {\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n env.image = document.createElement('img');\n env.image_url = URL.createObjectURL(env.blob);\n env.image.src = env.image_url;\n\n return new Promise(function (resolve, reject) {\n env.image.onerror = function () { reject(new Error('ImageBlobReduce: failed to create Image() from blob')); };\n env.image.onload = function () { resolve(env); };\n });\n};\n\n\nImageBlobReduce.prototype._calculate_size = function (env) {\n //\n // Note, if your need not \"symmetric\" resize logic, you MUST check\n // `env.orientation` (set by plugins) and swap width/height appropriately.\n //\n var scale_factor = env.opts.max / Math.max(env.image.width, env.image.height);\n\n if (scale_factor > 1) scale_factor = 1;\n\n env.transform_width = Math.max(Math.round(env.image.width * scale_factor), 1);\n env.transform_height = Math.max(Math.round(env.image.height * scale_factor), 1);\n\n // Info for user plugins, to check if scaling applied\n env.scale_factor = scale_factor;\n\n return Promise.resolve(env);\n};\n\n\nImageBlobReduce.prototype._transform = function (env) {\n env.out_canvas = this.pica.options.createCanvas(env.transform_width, env.transform_height);\n\n // Dim env temporary vars to prohibit use and avoid confusion when orientation\n // changed. You should take real size from canvas.\n env.transform_width = null;\n env.transform_height = null;\n\n // By default use alpha for png only\n var pica_opts = { alpha: env.blob.type === 'image/png' };\n\n // Extract pica options if been passed\n this.utils.assign(pica_opts, this.utils.pick_pica_resize_options(env.opts));\n\n return this.pica\n .resize(env.image, env.out_canvas, pica_opts)\n .then(function () { return env; });\n};\n\n\nImageBlobReduce.prototype._cleanup = function (env) {\n env.image.src = '';\n env.image = null;\n\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n if (URL.revokeObjectURL) URL.revokeObjectURL(env.image_url);\n\n env.image_url = null;\n\n return Promise.resolve(env);\n};\n\n\nImageBlobReduce.prototype._create_blob = function (env) {\n return this.pica.toBlob(env.out_canvas, env.blob.type)\n .then(function (blob) {\n env.out_blob = blob;\n return env;\n });\n};\n\n\nImageBlobReduce.prototype._getUint8Array = function (blob) {\n if (blob.arrayBuffer) {\n return blob.arrayBuffer().then(function (buf) {\n return new Uint8Array(buf);\n });\n }\n\n return new Promise(function (resolve, reject) {\n var fr = new FileReader();\n\n fr.readAsArrayBuffer(blob);\n\n fr.onload = function () { resolve(new Uint8Array(fr.result)); };\n fr.onerror = function () {\n reject(new Error('ImageBlobReduce: failed to load data from input blob'));\n fr.abort();\n };\n fr.onabort = function () {\n reject(new Error('ImageBlobReduce: failed to load data from input blob (aborted)'));\n };\n });\n};\n\n\nImageBlobReduce.pica = pica;\n\nvar imageBlobReduce = ImageBlobReduce;\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (imageBlobReduce);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2ltYWdlLWJsb2ItcmVkdWNlL2Rpc3QvaW1hZ2UtYmxvYi1yZWR1Y2UuZXNtLm1qcy5qcyIsIm1hcHBpbmdzIjoiOzs7OztBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0Isc0JBQXNCO0FBQ3hDOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLGNBQWMscUJBQXFCLGFBQWEsbUJBQW1CLGtCQUFrQixnQkFBZ0IsVUFBVSxVQUFVLDBEQUEwRCx3QkFBd0Isb0JBQW9CLDhDQUE4QyxrQ0FBa0MsWUFBWSxZQUFZLG1DQUFtQyxpQkFBaUIsZUFBZSx1QkFBdUIsb0JBQW9CLGtFQUFrRSxXQUFXLFlBQVksU0FBUyxTQUFTLEtBQUs7O0FBRXJpQjs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSxtRUFBbUU7QUFDdEU7O0FBRUE7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCOztBQUV0QixpQkFBaUIsYUFBYTtBQUM5QixtQkFBbUI7O0FBRW5CLG9CQUFvQixlQUFlO0FBQ25DO0FBQ0E7QUFDQTtBQUNB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QTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUcsR0FBRztBQUNOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUcsR0FBRzs7QUFFTjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRzs7O0FBR0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTCxHQUFHO0FBQ0gsR0FBRzs7O0FBR0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7OztBQUdKO0FBQ0E7QUFDQTtBQUNBLEtBQUssR0FBRzs7QUFFUjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLDJFQUEyRTtBQUMzRTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsZ0RBQWdELFFBQVE7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztB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QUFHQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1COztBQUVuQjtBQUNBLG1CQUFtQjs7QUFFbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTs7QUFFQSxrQkFBa0IsaUJBQWlCO0FBQ25DO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxvQkFBb0IsV0FBVztBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQSxxRkFBcUY7QUFDckY7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDREQUE0RDtBQUM1RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxNQUFNO0FBQ047QUFDQSxtQ0FBbUM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUEscUJBQXFCLDREQUE0RDtBQUNqRjtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxvQkFBb0IsbUJBQW1CO0FBQ3ZDO0FBQ0EsTUFBTTtBQUNOO0FBQ0Esc0JBQXNCLFNBQVM7QUFDL0I7QUFDQSxPQUFPO0FBQ1AsTUFBTTtBQUNOLHdCQUF3Qjs7QUFFeEI7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsb0JBQW9CO0FBQ2pDO0FBQ0EsTUFBTTs7QUFFTjtBQUNBLEdBQUc7QUFDSDs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjs7QUFFQTtBQUNBLEdBQUc7QUFDSDs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEscUNBQXFDO0FBQ3JDOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQSw0QkFBNEIsZUFBZTtBQUMzQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDs7O0FBR0E7QUFDQSw0QkFBNEIsZUFBZTtBQUMzQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLHlCQUF5QjtBQUNyRDs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHNDQUFzQztBQUN0QyxxQ0FBcUM7QUFDckMsR0FBRztBQUNIOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxvQkFBb0I7O0FBRXBCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHdCQUF3QixhQUFhO0FBQ3JDOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBOztBQUVBLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7O0FBR0E7O0FBRUE7O0FBRUEsaUVBQWUsZUFBZSxFQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9pbWFnZS1ibG9iLXJlZHVjZS9kaXN0L2ltYWdlLWJsb2ItcmVkdWNlLmVzbS5tanM/OTI4NSJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qISBpbWFnZS1ibG9iLXJlZHVjZSAzLjAuMSBodHRwczovL2dpdGh1Yi5jb20vbm9kZWNhL2ltYWdlLWJsb2ItcmVkdWNlIEBsaWNlbnNlIE1JVCAqL1xudmFyIGFzc2lnbiQxID0gZnVuY3Rpb24gYXNzaWduKHRvKSB7XG4gIHZhciBmcm9tO1xuXG4gIGZvciAodmFyIHMgPSAxOyBzIDwgYXJndW1lbnRzLmxlbmd0aDsgcysrKSB7XG4gICAgZnJvbSA9IE9iamVjdChhcmd1bWVudHNbc10pO1xuXG4gICAgZm9yICh2YXIga2V5IGluIGZyb20pIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZnJvbSwga2V5KSkgdG9ba2V5XSA9IGZyb21ba2V5XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdG87XG59O1xuXG5cbmZ1bmN0aW9uIHBpY2soZnJvbSwgcHJvcHMpIHtcbiAgdmFyIHRvID0ge307XG5cbiAgcHJvcHMuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChmcm9tLCBrZXkpKSB0b1trZXldID0gZnJvbVtrZXldO1xuICB9KTtcblxuICByZXR1cm4gdG87XG59XG5cblxuZnVuY3Rpb24gcGlja19waWNhX3Jlc2l6ZV9vcHRpb25zKGZyb20pIHtcbiAgcmV0dXJuIHBpY2soZnJvbSwgW1xuICAgICdhbHBoYScsXG4gICAgJ3Vuc2hhcnBBbW91bnQnLFxuICAgICd1bnNoYXJwUmFkaXVzJyxcbiAgICAndW5zaGFycFRocmVzaG9sZCcsXG4gICAgJ2NhbmNlbFRva2VuJ1xuICBdKTtcbn1cblxuXG52YXIgcGlja18xID0gcGljaztcbnZhciBwaWNrX3BpY2FfcmVzaXplX29wdGlvbnNfMSA9IHBpY2tfcGljYV9yZXNpemVfb3B0aW9ucztcblxudmFyIHV0aWxzID0ge1xuXHRhc3NpZ246IGFzc2lnbiQxLFxuXHRwaWNrOiBwaWNrXzEsXG5cdHBpY2tfcGljYV9yZXNpemVfb3B0aW9uczogcGlja19waWNhX3Jlc2l6ZV9vcHRpb25zXzFcbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZUNvbW1vbmpzTW9kdWxlKGZuKSB7XG4gIHZhciBtb2R1bGUgPSB7IGV4cG9ydHM6IHt9IH07XG5cdHJldHVybiBmbihtb2R1bGUsIG1vZHVsZS5leHBvcnRzKSwgbW9kdWxlLmV4cG9ydHM7XG59XG5cbmZ1bmN0aW9uIGNvbW1vbmpzUmVxdWlyZSAodGFyZ2V0KSB7XG5cdHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGR5bmFtaWNhbGx5IHJlcXVpcmUgXCInICsgdGFyZ2V0ICsgJ1wiLiBQbGVhc2UgY29uZmlndXJlIHRoZSBkeW5hbWljUmVxdWlyZVRhcmdldHMgb3B0aW9uIG9mIEByb2xsdXAvcGx1Z2luLWNvbW1vbmpzIGFwcHJvcHJpYXRlbHkgZm9yIHRoaXMgcmVxdWlyZSBjYWxsIHRvIGJlaGF2ZSBwcm9wZXJseS4nKTtcbn1cblxuLyohXG5cbnBpY2Fcbmh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYVxuXG4qL1xuXG52YXIgcGljYSA9IGNyZWF0ZUNvbW1vbmpzTW9kdWxlKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMpIHtcbihmdW5jdGlvbihmKXt7bW9kdWxlLmV4cG9ydHM9ZigpO319KShmdW5jdGlvbigpe3JldHVybiAoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiBjb21tb25qc1JlcXVpcmUmJmNvbW1vbmpzUmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KTt9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgY29tbW9uanNSZXF1aXJlJiZjb21tb25qc1JlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpKHsxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxudmFyIGluaGVyaXRzID0gX2RlcmVxXygnaW5oZXJpdHMnKTtcblxudmFyIE11bHRpbWF0aCA9IF9kZXJlcV8oJ211bHRpbWF0aCcpO1xuXG52YXIgbW1fdW5zaGFycF9tYXNrID0gX2RlcmVxXygnLi9tbV91bnNoYXJwX21hc2snKTtcblxudmFyIG1tX3Jlc2l6ZSA9IF9kZXJlcV8oJy4vbW1fcmVzaXplJyk7XG5cbmZ1bmN0aW9uIE1hdGhMaWIocmVxdWVzdGVkX2ZlYXR1cmVzKSB7XG4gIHZhciBfX3JlcXVlc3RlZF9mZWF0dXJlcyA9IHJlcXVlc3RlZF9mZWF0dXJlcyB8fCBbXTtcblxuICB2YXIgZmVhdHVyZXMgPSB7XG4gICAganM6IF9fcmVxdWVzdGVkX2ZlYXR1cmVzLmluZGV4T2YoJ2pzJykgPj0gMCxcbiAgICB3YXNtOiBfX3JlcXVlc3RlZF9mZWF0dXJlcy5pbmRleE9mKCd3YXNtJykgPj0gMFxuICB9O1xuICBNdWx0aW1hdGguY2FsbCh0aGlzLCBmZWF0dXJlcyk7XG4gIHRoaXMuZmVhdHVyZXMgPSB7XG4gICAganM6IGZlYXR1cmVzLmpzLFxuICAgIHdhc206IGZlYXR1cmVzLndhc20gJiYgdGhpcy5oYXNfd2FzbSgpXG4gIH07XG4gIHRoaXMudXNlKG1tX3Vuc2hhcnBfbWFzayk7XG4gIHRoaXMudXNlKG1tX3Jlc2l6ZSk7XG59XG5cbmluaGVyaXRzKE1hdGhMaWIsIE11bHRpbWF0aCk7XG5cbk1hdGhMaWIucHJvdG90eXBlLnJlc2l6ZUFuZFVuc2hhcnAgPSBmdW5jdGlvbiByZXNpemVBbmRVbnNoYXJwKG9wdGlvbnMsIGNhY2hlKSB7XG4gIHZhciByZXN1bHQgPSB0aGlzLnJlc2l6ZShvcHRpb25zLCBjYWNoZSk7XG5cbiAgaWYgKG9wdGlvbnMudW5zaGFycEFtb3VudCkge1xuICAgIHRoaXMudW5zaGFycF9tYXNrKHJlc3VsdCwgb3B0aW9ucy50b1dpZHRoLCBvcHRpb25zLnRvSGVpZ2h0LCBvcHRpb25zLnVuc2hhcnBBbW91bnQsIG9wdGlvbnMudW5zaGFycFJhZGl1cywgb3B0aW9ucy51bnNoYXJwVGhyZXNob2xkKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGhMaWI7XG5cbn0se1wiLi9tbV9yZXNpemVcIjo0LFwiLi9tbV91bnNoYXJwX21hc2tcIjo5LFwiaW5oZXJpdHNcIjoxOSxcIm11bHRpbWF0aFwiOjIwfV0sMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vL3ZhciBGSVhFRF9GUkFDX0JJVFMgPSAxNDtcblxuZnVuY3Rpb24gY2xhbXBUbzgoaSkge1xuICByZXR1cm4gaSA8IDAgPyAwIDogaSA+IDI1NSA/IDI1NSA6IGk7XG59IC8vIENvbnZvbHZlIGltYWdlIGluIGhvcml6b250YWwgZGlyZWN0aW9ucyBhbmQgdHJhbnNwb3NlIG91dHB1dC4gSW4gdGhlb3J5LFxuLy8gdHJhbnNwb3NlIGFsbG93OlxuLy9cbi8vIC0gdXNlIHRoZSBzYW1lIGNvbnZvbHZlciBmb3IgYm90aCBwYXNzZXMgKHRoaXMgZmFpbHMgZHVlIGRpZmZlcmVudFxuLy8gICB0eXBlcyBvZiBpbnB1dCBhcnJheSBhbmQgdGVtcG9yYXJ5IGJ1ZmZlcilcbi8vIC0gbWFraW5nIHZlcnRpY2FsIHBhc3MgYnkgaG9yaXNvbmx0YWwgbGluZXMgaW5wcm92ZSBDUFUgY2FjaGUgdXNlLlxuLy9cbi8vIEJ1dCBpbiByZWFsIGxpZmUgdGhpcyBkb2Vzbid0IHdvcmsgOilcbi8vXG5cblxuZnVuY3Rpb24gY29udm9sdmVIb3Jpem9udGFsbHkoc3JjLCBkZXN0LCBzcmNXLCBzcmNILCBkZXN0VywgZmlsdGVycykge1xuICB2YXIgciwgZywgYiwgYTtcbiAgdmFyIGZpbHRlclB0ciwgZmlsdGVyU2hpZnQsIGZpbHRlclNpemU7XG4gIHZhciBzcmNQdHIsIHNyY1ksIGRlc3RYLCBmaWx0ZXJWYWw7XG4gIHZhciBzcmNPZmZzZXQgPSAwLFxuICAgICAgZGVzdE9mZnNldCA9IDA7IC8vIEZvciBlYWNoIHJvd1xuXG4gIGZvciAoc3JjWSA9IDA7IHNyY1kgPCBzcmNIOyBzcmNZKyspIHtcbiAgICBmaWx0ZXJQdHIgPSAwOyAvLyBBcHBseSBwcmVjb21wdXRlZCBmaWx0ZXJzIHRvIGVhY2ggZGVzdGluYXRpb24gcm93IHBvaW50XG5cbiAgICBmb3IgKGRlc3RYID0gMDsgZGVzdFggPCBkZXN0VzsgZGVzdFgrKykge1xuICAgICAgLy8gR2V0IHRoZSBmaWx0ZXIgdGhhdCBkZXRlcm1pbmVzIHRoZSBjdXJyZW50IG91dHB1dCBwaXhlbC5cbiAgICAgIGZpbHRlclNoaWZ0ID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBmaWx0ZXJTaXplID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBzcmNQdHIgPSBzcmNPZmZzZXQgKyBmaWx0ZXJTaGlmdCAqIDQgfCAwO1xuICAgICAgciA9IGcgPSBiID0gYSA9IDA7IC8vIEFwcGx5IHRoZSBmaWx0ZXIgdG8gdGhlIHJvdyB0byBnZXQgdGhlIGRlc3RpbmF0aW9uIHBpeGVsIHIsIGcsIGIsIGFcblxuICAgICAgZm9yICg7IGZpbHRlclNpemUgPiAwOyBmaWx0ZXJTaXplLS0pIHtcbiAgICAgICAgZmlsdGVyVmFsID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107IC8vIFVzZSByZXZlcnNlIG9yZGVyIHRvIHdvcmthcm91bmQgZGVvcHRzIGluIG9sZCB2OCAobm9kZSB2LjEwKVxuICAgICAgICAvLyBCaWcgdGhhbmtzIHRvIEBtcmFsZXBoIChWeWFjaGVzbGF2IEVnb3JvdikgZm9yIHRoZSB0aXAuXG5cbiAgICAgICAgYSA9IGEgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyICsgM10gfCAwO1xuICAgICAgICBiID0gYiArIGZpbHRlclZhbCAqIHNyY1tzcmNQdHIgKyAyXSB8IDA7XG4gICAgICAgIGcgPSBnICsgZmlsdGVyVmFsICogc3JjW3NyY1B0ciArIDFdIHwgMDtcbiAgICAgICAgciA9IHIgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyXSB8IDA7XG4gICAgICAgIHNyY1B0ciA9IHNyY1B0ciArIDQgfCAwO1xuICAgICAgfSAvLyBCcmluZyB0aGlzIHZhbHVlIGJhY2sgaW4gcmFuZ2UuIEFsbCBvZiB0aGUgZmlsdGVyIHNjYWxpbmcgZmFjdG9yc1xuICAgICAgLy8gYXJlIGluIGZpeGVkIHBvaW50IHdpdGggRklYRURfRlJBQ19CSVRTIGJpdHMgb2YgZnJhY3Rpb25hbCBwYXJ0LlxuICAgICAgLy9cbiAgICAgIC8vICghKSBBZGQgMS8yIG9mIHZhbHVlIGJlZm9yZSBjbGFtcGluZyB0byBnZXQgcHJvcGVyIHJvdW5kaW5nLiBJbiBvdGhlclxuICAgICAgLy8gY2FzZSBicmlnaHRuZXNzIGxvc3Mgd2lsbCBiZSBub3RpY2VhYmxlIGlmIHlvdSByZXNpemUgaW1hZ2Ugd2l0aCB3aGl0ZVxuICAgICAgLy8gYm9yZGVyIGFuZCBwbGFjZSBpdCBvbiB3aGl0ZSBiYWNrZ3JvdW5kLlxuICAgICAgLy9cblxuXG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAzXSA9IGNsYW1wVG84KGEgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAyXSA9IGNsYW1wVG84KGIgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAxXSA9IGNsYW1wVG84KGcgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXRdID0gY2xhbXBUbzgociArICgxIDw8IDEzKSA+PiAxNFxuICAgICAgLypGSVhFRF9GUkFDX0JJVFMqL1xuICAgICAgKTtcbiAgICAgIGRlc3RPZmZzZXQgPSBkZXN0T2Zmc2V0ICsgc3JjSCAqIDQgfCAwO1xuICAgIH1cblxuICAgIGRlc3RPZmZzZXQgPSAoc3JjWSArIDEpICogNCB8IDA7XG4gICAgc3JjT2Zmc2V0ID0gKHNyY1kgKyAxKSAqIHNyY1cgKiA0IHwgMDtcbiAgfVxufSAvLyBUZWNobmljYWxseSwgY29udm9sdmVycyBhcmUgdGhlIHNhbWUuIEJ1dCBpbnB1dCBhcnJheSBhbmQgdGVtcG9yYXJ5XG4vLyBidWZmZXIgY2FuIGJlIG9mIGRpZmZlcmVudCB0eXBlIChlc3BlY2lhbGx5LCBpbiBvbGQgYnJvd3NlcnMpLiBTbyxcbi8vIGtlZXAgY29kZSBpbiBzZXBhcmF0ZSBmdW5jdGlvbnMgdG8gYXZvaWQgZGVvcHRpbWl6YXRpb25zICYgc3BlZWQgbG9zcy5cblxuXG5mdW5jdGlvbiBjb252b2x2ZVZlcnRpY2FsbHkoc3JjLCBkZXN0LCBzcmNXLCBzcmNILCBkZXN0VywgZmlsdGVycykge1xuICB2YXIgciwgZywgYiwgYTtcbiAgdmFyIGZpbHRlclB0ciwgZmlsdGVyU2hpZnQsIGZpbHRlclNpemU7XG4gIHZhciBzcmNQdHIsIHNyY1ksIGRlc3RYLCBmaWx0ZXJWYWw7XG4gIHZhciBzcmNPZmZzZXQgPSAwLFxuICAgICAgZGVzdE9mZnNldCA9IDA7IC8vIEZvciBlYWNoIHJvd1xuXG4gIGZvciAoc3JjWSA9IDA7IHNyY1kgPCBzcmNIOyBzcmNZKyspIHtcbiAgICBmaWx0ZXJQdHIgPSAwOyAvLyBBcHBseSBwcmVjb21wdXRlZCBmaWx0ZXJzIHRvIGVhY2ggZGVzdGluYXRpb24gcm93IHBvaW50XG5cbiAgICBmb3IgKGRlc3RYID0gMDsgZGVzdFggPCBkZXN0VzsgZGVzdFgrKykge1xuICAgICAgLy8gR2V0IHRoZSBmaWx0ZXIgdGhhdCBkZXRlcm1pbmVzIHRoZSBjdXJyZW50IG91dHB1dCBwaXhlbC5cbiAgICAgIGZpbHRlclNoaWZ0ID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBmaWx0ZXJTaXplID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBzcmNQdHIgPSBzcmNPZmZzZXQgKyBmaWx0ZXJTaGlmdCAqIDQgfCAwO1xuICAgICAgciA9IGcgPSBiID0gYSA9IDA7IC8vIEFwcGx5IHRoZSBmaWx0ZXIgdG8gdGhlIHJvdyB0byBnZXQgdGhlIGRlc3RpbmF0aW9uIHBpeGVsIHIsIGcsIGIsIGFcblxuICAgICAgZm9yICg7IGZpbHRlclNpemUgPiAwOyBmaWx0ZXJTaXplLS0pIHtcbiAgICAgICAgZmlsdGVyVmFsID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107IC8vIFVzZSByZXZlcnNlIG9yZGVyIHRvIHdvcmthcm91bmQgZGVvcHRzIGluIG9sZCB2OCAobm9kZSB2LjEwKVxuICAgICAgICAvLyBCaWcgdGhhbmtzIHRvIEBtcmFsZXBoIChWeWFjaGVzbGF2IEVnb3JvdikgZm9yIHRoZSB0aXAuXG5cbiAgICAgICAgYSA9IGEgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyICsgM10gfCAwO1xuICAgICAgICBiID0gYiArIGZpbHRlclZhbCAqIHNyY1tzcmNQdHIgKyAyXSB8IDA7XG4gICAgICAgIGcgPSBnICsgZmlsdGVyVmFsICogc3JjW3NyY1B0ciArIDFdIHwgMDtcbiAgICAgICAgciA9IHIgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyXSB8IDA7XG4gICAgICAgIHNyY1B0ciA9IHNyY1B0ciArIDQgfCAwO1xuICAgICAgfSAvLyBCcmluZyB0aGlzIHZhbHVlIGJhY2sgaW4gcmFuZ2UuIEFsbCBvZiB0aGUgZmlsdGVyIHNjYWxpbmcgZmFjdG9yc1xuICAgICAgLy8gYXJlIGluIGZpeGVkIHBvaW50IHdpdGggRklYRURfRlJBQ19CSVRTIGJpdHMgb2YgZnJhY3Rpb25hbCBwYXJ0LlxuICAgICAgLy9cbiAgICAgIC8vICghKSBBZGQgMS8yIG9mIHZhbHVlIGJlZm9yZSBjbGFtcGluZyB0byBnZXQgcHJvcGVyIHJvdW5kaW5nLiBJbiBvdGhlclxuICAgICAgLy8gY2FzZSBicmlnaHRuZXNzIGxvc3Mgd2lsbCBiZSBub3RpY2VhYmxlIGlmIHlvdSByZXNpemUgaW1hZ2Ugd2l0aCB3aGl0ZVxuICAgICAgLy8gYm9yZGVyIGFuZCBwbGFjZSBpdCBvbiB3aGl0ZSBiYWNrZ3JvdW5kLlxuICAgICAgLy9cblxuXG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAzXSA9IGNsYW1wVG84KGEgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAyXSA9IGNsYW1wVG84KGIgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAxXSA9IGNsYW1wVG84KGcgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXRdID0gY2xhbXBUbzgociArICgxIDw8IDEzKSA+PiAxNFxuICAgICAgLypGSVhFRF9GUkFDX0JJVFMqL1xuICAgICAgKTtcbiAgICAgIGRlc3RPZmZzZXQgPSBkZXN0T2Zmc2V0ICsgc3JjSCAqIDQgfCAwO1xuICAgIH1cblxuICAgIGRlc3RPZmZzZXQgPSAoc3JjWSArIDEpICogNCB8IDA7XG4gICAgc3JjT2Zmc2V0ID0gKHNyY1kgKyAxKSAqIHNyY1cgKiA0IHwgMDtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY29udm9sdmVIb3Jpem9udGFsbHk6IGNvbnZvbHZlSG9yaXpvbnRhbGx5LFxuICBjb252b2x2ZVZlcnRpY2FsbHk6IGNvbnZvbHZlVmVydGljYWxseVxufTtcblxufSx7fV0sMzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cbm1vZHVsZS5leHBvcnRzID0gJ0FHRnpiUUVBQUFBQURBWmtlV3hwYm1zQUFBQUFBQUVYQTJBQUFHQUdmMzkvZjM5L0FHQUhmMzkvZjM5L2Z3QUNEd0VEWlc1MkJtMWxiVzl5ZVFJQUFBTUVBd0FCQWdZR0FYOEFRUUFMQjFjRkVWOWZkMkZ6YlY5allXeHNYMk4wYjNKekFBQUlZMjl1ZG05c2RtVUFBUXBqYjI1MmIyeDJaVWhXQUFJTVgxOWtjMjlmYUdGdVpHeGxBd0FZWDE5M1lYTnRYMkZ3Y0d4NVgyUmhkR0ZmY21Wc2IyTnpBQUFLN0FNREF3QUJDOFlEQVE5L0FrQWdBMFVOQUNBRVJRMEFBMEFnRENFTlFRQWhFMEVBSVFjRFFDQUhRUUpxSVFZQ2Z5QUhRUUYwSUFWcUlnY3VBUUlpRkVVRVFFR0F3QUFoQ0VHQXdBQWhDVUdBd0FBaENrR0F3QUFoQ3lBR0RBRUxJQklnQnk0QkFHb2hDRUVBSVFzZ0ZDRUhRUUFoRGlBR0lRbEJBQ0VQUVFBaEVBTkFJQVVnQ1VFQmRHb3VBUUFpRVNBQUlBaEJBblJxS0FJQUlncEJHSFpzSUJCcUlSQWdDa0gvQVhFZ0VXd2dDMm9oQ3lBS1FSQjJRZjhCY1NBUmJDQVBhaUVQSUFwQkNIWkIvd0Z4SUJGc0lBNXFJUTRnQ0VFQmFpRUlJQWxCQVdvaENTQUhRUUZySWdjTkFBc2dDMEdBUUdzaENDQU9RWUJBYXlFSklBOUJnRUJySVFvZ0VFR0FRR3NoQ3lBR0lCUnFDeUVISUFFZ0RVRUNkR29nQ1VFT2RTSUdRZjhCSUFaQi93RklHeUlHUVFBZ0JrRUFTaHRCQ0hSQmdQNERjU0FLUVE1MUlnWkIvd0VnQmtIL0FVZ2JJZ1pCQUNBR1FRQktHMEVRZEVHQWdQd0hjU0FMUVE1MUlnWkIvd0VnQmtIL0FVZ2JJZ1pCQUNBR1FRQktHMEVZZEhKeUlBaEJEblVpQmtIL0FTQUdRZjhCU0JzaUJrRUFJQVpCQUVvYmNqWUNBQ0FESUExcUlRMGdFMEVCYWlJVElBUkhEUUFMSUF4QkFXb2lEQ0FDYkNFU0lBTWdERWNOQUFzTEN4NEFRUUFnQWlBRElBUWdCU0FBRUFFZ0FrRUFJQVFnQlNBR0lBRVFBUXM9JztcblxufSx7fV0sNDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBuYW1lOiAncmVzaXplJyxcbiAgZm46IF9kZXJlcV8oJy4vcmVzaXplJyksXG4gIHdhc21fZm46IF9kZXJlcV8oJy4vcmVzaXplX3dhc20nKSxcbiAgd2FzbV9zcmM6IF9kZXJlcV8oJy4vY29udm9sdmVfd2FzbV9iYXNlNjQnKVxufTtcblxufSx7XCIuL2NvbnZvbHZlX3dhc21fYmFzZTY0XCI6MyxcIi4vcmVzaXplXCI6NSxcIi4vcmVzaXplX3dhc21cIjo4fV0sNTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cbnZhciBjcmVhdGVGaWx0ZXJzID0gX2RlcmVxXygnLi9yZXNpemVfZmlsdGVyX2dlbicpO1xuXG52YXIgY29udm9sdmVIb3Jpem9udGFsbHkgPSBfZGVyZXFfKCcuL2NvbnZvbHZlJykuY29udm9sdmVIb3Jpem9udGFsbHk7XG5cbnZhciBjb252b2x2ZVZlcnRpY2FsbHkgPSBfZGVyZXFfKCcuL2NvbnZvbHZlJykuY29udm9sdmVWZXJ0aWNhbGx5O1xuXG5mdW5jdGlvbiByZXNldEFscGhhKGRzdCwgd2lkdGgsIGhlaWdodCkge1xuICB2YXIgcHRyID0gMyxcbiAgICAgIGxlbiA9IHdpZHRoICogaGVpZ2h0ICogNCB8IDA7XG5cbiAgd2hpbGUgKHB0ciA8IGxlbikge1xuICAgIGRzdFtwdHJdID0gMHhGRjtcbiAgICBwdHIgPSBwdHIgKyA0IHwgMDtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlc2l6ZShvcHRpb25zKSB7XG4gIHZhciBzcmMgPSBvcHRpb25zLnNyYztcbiAgdmFyIHNyY1cgPSBvcHRpb25zLndpZHRoO1xuICB2YXIgc3JjSCA9IG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgZGVzdFcgPSBvcHRpb25zLnRvV2lkdGg7XG4gIHZhciBkZXN0SCA9IG9wdGlvbnMudG9IZWlnaHQ7XG4gIHZhciBzY2FsZVggPSBvcHRpb25zLnNjYWxlWCB8fCBvcHRpb25zLnRvV2lkdGggLyBvcHRpb25zLndpZHRoO1xuICB2YXIgc2NhbGVZID0gb3B0aW9ucy5zY2FsZVkgfHwgb3B0aW9ucy50b0hlaWdodCAvIG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgb2Zmc2V0WCA9IG9wdGlvbnMub2Zmc2V0WCB8fCAwO1xuICB2YXIgb2Zmc2V0WSA9IG9wdGlvbnMub2Zmc2V0WSB8fCAwO1xuICB2YXIgZGVzdCA9IG9wdGlvbnMuZGVzdCB8fCBuZXcgVWludDhBcnJheShkZXN0VyAqIGRlc3RIICogNCk7XG4gIHZhciBxdWFsaXR5ID0gdHlwZW9mIG9wdGlvbnMucXVhbGl0eSA9PT0gJ3VuZGVmaW5lZCcgPyAzIDogb3B0aW9ucy5xdWFsaXR5O1xuICB2YXIgYWxwaGEgPSBvcHRpb25zLmFscGhhIHx8IGZhbHNlO1xuICB2YXIgZmlsdGVyc1ggPSBjcmVhdGVGaWx0ZXJzKHF1YWxpdHksIHNyY1csIGRlc3RXLCBzY2FsZVgsIG9mZnNldFgpLFxuICAgICAgZmlsdGVyc1kgPSBjcmVhdGVGaWx0ZXJzKHF1YWxpdHksIHNyY0gsIGRlc3RILCBzY2FsZVksIG9mZnNldFkpO1xuICB2YXIgdG1wID0gbmV3IFVpbnQ4QXJyYXkoZGVzdFcgKiBzcmNIICogNCk7IC8vIFRvIHVzZSBzaW5nbGUgZnVuY3Rpb24gd2UgbmVlZCBzcmMgJiB0bXAgb2YgdGhlIHNhbWUgdHlwZS5cbiAgLy8gQnV0IHNyYyBjYW4gYmUgQ2FudmFzUGl4ZWxBcnJheSwgYW5kIHRtcCAtIFVpbnQ4QXJyYXkuIFNvLCBrZWVwXG4gIC8vIHZlcnRpY2FsIGFuZCBob3Jpem9udGFsIHBhc3NlcyBzZXBhcmF0ZWx5IHRvIGF2b2lkIGRlb3B0aW1pemF0aW9uLlxuXG4gIGNvbnZvbHZlSG9yaXpvbnRhbGx5KHNyYywgdG1wLCBzcmNXLCBzcmNILCBkZXN0VywgZmlsdGVyc1gpO1xuICBjb252b2x2ZVZlcnRpY2FsbHkodG1wLCBkZXN0LCBzcmNILCBkZXN0VywgZGVzdEgsIGZpbHRlcnNZKTsgLy8gVGhhdCdzIGZhc3RlciB0aGFuIGRvaW5nIGNoZWNrcyBpbiBjb252b2x2ZXIuXG4gIC8vICEhISBOb3RlLCBjYW52YXMgZGF0YSBpcyBub3QgcHJlbXVsdGlwbGVkLiBXZSBkb24ndCBuZWVkIG90aGVyXG4gIC8vIGFscGhhIGNvcnJlY3Rpb25zLlxuXG4gIGlmICghYWxwaGEpIHJlc2V0QWxwaGEoZGVzdCwgZGVzdFcsIGRlc3RIKTtcbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG59LHtcIi4vY29udm9sdmVcIjoyLFwiLi9yZXNpemVfZmlsdGVyX2dlblwiOjZ9XSw2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxudmFyIEZJTFRFUl9JTkZPID0gX2RlcmVxXygnLi9yZXNpemVfZmlsdGVyX2luZm8nKTsgLy8gUHJlY2lzaW9uIG9mIGZpeGVkIEZQIHZhbHVlc1xuXG5cbnZhciBGSVhFRF9GUkFDX0JJVFMgPSAxNDtcblxuZnVuY3Rpb24gdG9GaXhlZFBvaW50KG51bSkge1xuICByZXR1cm4gTWF0aC5yb3VuZChudW0gKiAoKDEgPDwgRklYRURfRlJBQ19CSVRTKSAtIDEpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiByZXNpemVGaWx0ZXJHZW4ocXVhbGl0eSwgc3JjU2l6ZSwgZGVzdFNpemUsIHNjYWxlLCBvZmZzZXQpIHtcbiAgdmFyIGZpbHRlckZ1bmN0aW9uID0gRklMVEVSX0lORk9bcXVhbGl0eV0uZmlsdGVyO1xuICB2YXIgc2NhbGVJbnZlcnRlZCA9IDEuMCAvIHNjYWxlO1xuICB2YXIgc2NhbGVDbGFtcGVkID0gTWF0aC5taW4oMS4wLCBzY2FsZSk7IC8vIEZvciB1cHNjYWxlXG4gIC8vIEZpbHRlciB3aW5kb3cgKGF2ZXJhZ2luZyBpbnRlcnZhbCksIHNjYWxlZCB0byBzcmMgaW1hZ2VcblxuICB2YXIgc3JjV2luZG93ID0gRklMVEVSX0lORk9bcXVhbGl0eV0ud2luIC8gc2NhbGVDbGFtcGVkO1xuICB2YXIgZGVzdFBpeGVsLCBzcmNQaXhlbCwgc3JjRmlyc3QsIHNyY0xhc3QsIGZpbHRlckVsZW1lbnRTaXplLCBmbG9hdEZpbHRlciwgZnhwRmlsdGVyLCB0b3RhbCwgcHhsLCBpZHgsIGZsb2F0VmFsLCBmaWx0ZXJUb3RhbCwgZmlsdGVyVmFsO1xuICB2YXIgbGVmdE5vdEVtcHR5LCByaWdodE5vdEVtcHR5LCBmaWx0ZXJTaGlmdCwgZmlsdGVyU2l6ZTtcbiAgdmFyIG1heEZpbHRlckVsZW1lbnRTaXplID0gTWF0aC5mbG9vcigoc3JjV2luZG93ICsgMSkgKiAyKTtcbiAgdmFyIHBhY2tlZEZpbHRlciA9IG5ldyBJbnQxNkFycmF5KChtYXhGaWx0ZXJFbGVtZW50U2l6ZSArIDIpICogZGVzdFNpemUpO1xuICB2YXIgcGFja2VkRmlsdGVyUHRyID0gMDtcbiAgdmFyIHNsb3dDb3B5ID0gIXBhY2tlZEZpbHRlci5zdWJhcnJheSB8fCAhcGFja2VkRmlsdGVyLnNldDsgLy8gRm9yIGVhY2ggZGVzdGluYXRpb24gcGl4ZWwgY2FsY3VsYXRlIHNvdXJjZSByYW5nZSBhbmQgYnVpbHQgZmlsdGVyIHZhbHVlc1xuXG4gIGZvciAoZGVzdFBpeGVsID0gMDsgZGVzdFBpeGVsIDwgZGVzdFNpemU7IGRlc3RQaXhlbCsrKSB7XG4gICAgLy8gU2NhbGluZyBzaG91bGQgYmUgZG9uZSByZWxhdGl2ZSB0byBjZW50cmFsIHBpeGVsIHBvaW50XG4gICAgc3JjUGl4ZWwgPSAoZGVzdFBpeGVsICsgMC41KSAqIHNjYWxlSW52ZXJ0ZWQgKyBvZmZzZXQ7XG4gICAgc3JjRmlyc3QgPSBNYXRoLm1heCgwLCBNYXRoLmZsb29yKHNyY1BpeGVsIC0gc3JjV2luZG93KSk7XG4gICAgc3JjTGFzdCA9IE1hdGgubWluKHNyY1NpemUgLSAxLCBNYXRoLmNlaWwoc3JjUGl4ZWwgKyBzcmNXaW5kb3cpKTtcbiAgICBmaWx0ZXJFbGVtZW50U2l6ZSA9IHNyY0xhc3QgLSBzcmNGaXJzdCArIDE7XG4gICAgZmxvYXRGaWx0ZXIgPSBuZXcgRmxvYXQzMkFycmF5KGZpbHRlckVsZW1lbnRTaXplKTtcbiAgICBmeHBGaWx0ZXIgPSBuZXcgSW50MTZBcnJheShmaWx0ZXJFbGVtZW50U2l6ZSk7XG4gICAgdG90YWwgPSAwLjA7IC8vIEZpbGwgZmlsdGVyIHZhbHVlcyBmb3IgY2FsY3VsYXRlZCByYW5nZVxuXG4gICAgZm9yIChweGwgPSBzcmNGaXJzdCwgaWR4ID0gMDsgcHhsIDw9IHNyY0xhc3Q7IHB4bCsrLCBpZHgrKykge1xuICAgICAgZmxvYXRWYWwgPSBmaWx0ZXJGdW5jdGlvbigocHhsICsgMC41IC0gc3JjUGl4ZWwpICogc2NhbGVDbGFtcGVkKTtcbiAgICAgIHRvdGFsICs9IGZsb2F0VmFsO1xuICAgICAgZmxvYXRGaWx0ZXJbaWR4XSA9IGZsb2F0VmFsO1xuICAgIH0gLy8gTm9ybWFsaXplIGZpbHRlciwgY29udmVydCB0byBmaXhlZCBwb2ludCBhbmQgYWNjdW11bGF0ZSBjb252ZXJzaW9uIGVycm9yXG5cblxuICAgIGZpbHRlclRvdGFsID0gMDtcblxuICAgIGZvciAoaWR4ID0gMDsgaWR4IDwgZmxvYXRGaWx0ZXIubGVuZ3RoOyBpZHgrKykge1xuICAgICAgZmlsdGVyVmFsID0gZmxvYXRGaWx0ZXJbaWR4XSAvIHRvdGFsO1xuICAgICAgZmlsdGVyVG90YWwgKz0gZmlsdGVyVmFsO1xuICAgICAgZnhwRmlsdGVyW2lkeF0gPSB0b0ZpeGVkUG9pbnQoZmlsdGVyVmFsKTtcbiAgICB9IC8vIENvbXBlbnNhdGUgbm9ybWFsaXphdGlvbiBlcnJvciwgdG8gbWluaW1pemUgYnJpZ2h0bmVzcyBkcmlmdFxuXG5cbiAgICBmeHBGaWx0ZXJbZGVzdFNpemUgPj4gMV0gKz0gdG9GaXhlZFBvaW50KDEuMCAtIGZpbHRlclRvdGFsKTsgLy9cbiAgICAvLyBOb3cgcGFjayBmaWx0ZXIgdG8gdXNlYWJsZSBmb3JtXG4gICAgLy9cbiAgICAvLyAxLiBUcmltIGhlYWRpbmcgYW5kIHRhaWxpbmcgemVybyB2YWx1ZXMsIGFuZCBjb21wZW5zYXRlIHNoaXRmL2xlbmd0aFxuICAgIC8vIDIuIFB1dCBhbGwgdG8gc2luZ2xlIGFycmF5IGluIHRoaXMgZm9ybWF0OlxuICAgIC8vXG4gICAgLy8gICAgWyBwb3Mgc2hpZnQsIGRhdGEgbGVuZ3RoLCB2YWx1ZTEsIHZhbHVlMiwgdmFsdWUzLCAuLi4gXVxuICAgIC8vXG5cbiAgICBsZWZ0Tm90RW1wdHkgPSAwO1xuXG4gICAgd2hpbGUgKGxlZnROb3RFbXB0eSA8IGZ4cEZpbHRlci5sZW5ndGggJiYgZnhwRmlsdGVyW2xlZnROb3RFbXB0eV0gPT09IDApIHtcbiAgICAgIGxlZnROb3RFbXB0eSsrO1xuICAgIH1cblxuICAgIGlmIChsZWZ0Tm90RW1wdHkgPCBmeHBGaWx0ZXIubGVuZ3RoKSB7XG4gICAgICByaWdodE5vdEVtcHR5ID0gZnhwRmlsdGVyLmxlbmd0aCAtIDE7XG5cbiAgICAgIHdoaWxlIChyaWdodE5vdEVtcHR5ID4gMCAmJiBmeHBGaWx0ZXJbcmlnaHROb3RFbXB0eV0gPT09IDApIHtcbiAgICAgICAgcmlnaHROb3RFbXB0eS0tO1xuICAgICAgfVxuXG4gICAgICBmaWx0ZXJTaGlmdCA9IHNyY0ZpcnN0ICsgbGVmdE5vdEVtcHR5O1xuICAgICAgZmlsdGVyU2l6ZSA9IHJpZ2h0Tm90RW1wdHkgLSBsZWZ0Tm90RW1wdHkgKyAxO1xuICAgICAgcGFja2VkRmlsdGVyW3BhY2tlZEZpbHRlclB0cisrXSA9IGZpbHRlclNoaWZ0OyAvLyBzaGlmdFxuXG4gICAgICBwYWNrZWRGaWx0ZXJbcGFja2VkRmlsdGVyUHRyKytdID0gZmlsdGVyU2l6ZTsgLy8gc2l6ZVxuXG4gICAgICBpZiAoIXNsb3dDb3B5KSB7XG4gICAgICAgIHBhY2tlZEZpbHRlci5zZXQoZnhwRmlsdGVyLnN1YmFycmF5KGxlZnROb3RFbXB0eSwgcmlnaHROb3RFbXB0eSArIDEpLCBwYWNrZWRGaWx0ZXJQdHIpO1xuICAgICAgICBwYWNrZWRGaWx0ZXJQdHIgKz0gZmlsdGVyU2l6ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGZhbGxiYWNrIGZvciBvbGQgSUUgPCAxMSwgd2l0aG91dCBzdWJhcnJheS9zZXQgbWV0aG9kc1xuICAgICAgICBmb3IgKGlkeCA9IGxlZnROb3RFbXB0eTsgaWR4IDw9IHJpZ2h0Tm90RW1wdHk7IGlkeCsrKSB7XG4gICAgICAgICAgcGFja2VkRmlsdGVyW3BhY2tlZEZpbHRlclB0cisrXSA9IGZ4cEZpbHRlcltpZHhdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHplcm8gZGF0YSwgd3JpdGUgaGVhZGVyIG9ubHlcbiAgICAgIHBhY2tlZEZpbHRlcltwYWNrZWRGaWx0ZXJQdHIrK10gPSAwOyAvLyBzaGlmdFxuXG4gICAgICBwYWNrZWRGaWx0ZXJbcGFja2VkRmlsdGVyUHRyKytdID0gMDsgLy8gc2l6ZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYWNrZWRGaWx0ZXI7XG59O1xuXG59LHtcIi4vcmVzaXplX2ZpbHRlcl9pbmZvXCI6N31dLDc6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXG5tb2R1bGUuZXhwb3J0cyA9IFt7XG4gIC8vIE5lYXJlc3QgbmVpYm9yIChCb3gpXG4gIHdpbjogMC41LFxuICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcih4KSB7XG4gICAgcmV0dXJuIHggPj0gLTAuNSAmJiB4IDwgMC41ID8gMS4wIDogMC4wO1xuICB9XG59LCB7XG4gIC8vIEhhbW1pbmdcbiAgd2luOiAxLjAsXG4gIGZpbHRlcjogZnVuY3Rpb24gZmlsdGVyKHgpIHtcbiAgICBpZiAoeCA8PSAtMS4wIHx8IHggPj0gMS4wKSB7XG4gICAgICByZXR1cm4gMC4wO1xuICAgIH1cblxuICAgIGlmICh4ID4gLTEuMTkyMDkyOTBFLTA3ICYmIHggPCAxLjE5MjA5MjkwRS0wNykge1xuICAgICAgcmV0dXJuIDEuMDtcbiAgICB9XG5cbiAgICB2YXIgeHBpID0geCAqIE1hdGguUEk7XG4gICAgcmV0dXJuIE1hdGguc2luKHhwaSkgLyB4cGkgKiAoMC41NCArIDAuNDYgKiBNYXRoLmNvcyh4cGkgLyAxLjApKTtcbiAgfVxufSwge1xuICAvLyBMYW5jem9zLCB3aW4gPSAyXG4gIHdpbjogMi4wLFxuICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcih4KSB7XG4gICAgaWYgKHggPD0gLTIuMCB8fCB4ID49IDIuMCkge1xuICAgICAgcmV0dXJuIDAuMDtcbiAgICB9XG5cbiAgICBpZiAoeCA+IC0xLjE5MjA5MjkwRS0wNyAmJiB4IDwgMS4xOTIwOTI5MEUtMDcpIHtcbiAgICAgIHJldHVybiAxLjA7XG4gICAgfVxuXG4gICAgdmFyIHhwaSA9IHggKiBNYXRoLlBJO1xuICAgIHJldHVybiBNYXRoLnNpbih4cGkpIC8geHBpICogTWF0aC5zaW4oeHBpIC8gMi4wKSAvICh4cGkgLyAyLjApO1xuICB9XG59LCB7XG4gIC8vIExhbmN6b3MsIHdpbiA9IDNcbiAgd2luOiAzLjAsXG4gIGZpbHRlcjogZnVuY3Rpb24gZmlsdGVyKHgpIHtcbiAgICBpZiAoeCA8PSAtMy4wIHx8IHggPj0gMy4wKSB7XG4gICAgICByZXR1cm4gMC4wO1xuICAgIH1cblxuICAgIGlmICh4ID4gLTEuMTkyMDkyOTBFLTA3ICYmIHggPCAxLjE5MjA5MjkwRS0wNykge1xuICAgICAgcmV0dXJuIDEuMDtcbiAgICB9XG5cbiAgICB2YXIgeHBpID0geCAqIE1hdGguUEk7XG4gICAgcmV0dXJuIE1hdGguc2luKHhwaSkgLyB4cGkgKiBNYXRoLnNpbih4cGkgLyAzLjApIC8gKHhwaSAvIDMuMCk7XG4gIH1cbn1dO1xuXG59LHt9XSw4OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxudmFyIGNyZWF0ZUZpbHRlcnMgPSBfZGVyZXFfKCcuL3Jlc2l6ZV9maWx0ZXJfZ2VuJyk7XG5cbmZ1bmN0aW9uIHJlc2V0QWxwaGEoZHN0LCB3aWR0aCwgaGVpZ2h0KSB7XG4gIHZhciBwdHIgPSAzLFxuICAgICAgbGVuID0gd2lkdGggKiBoZWlnaHQgKiA0IHwgMDtcblxuICB3aGlsZSAocHRyIDwgbGVuKSB7XG4gICAgZHN0W3B0cl0gPSAweEZGO1xuICAgIHB0ciA9IHB0ciArIDQgfCAwO1xuICB9XG59XG5cbmZ1bmN0aW9uIGFzVWludDhBcnJheShzcmMpIHtcbiAgcmV0dXJuIG5ldyBVaW50OEFycmF5KHNyYy5idWZmZXIsIDAsIHNyYy5ieXRlTGVuZ3RoKTtcbn1cblxudmFyIElTX0xFID0gdHJ1ZTsgLy8gc2hvdWxkIG5vdCBjcmFzaCBldmVyeXRoaW5nIG9uIG1vZHVsZSBsb2FkIGluIG9sZCBicm93c2Vyc1xuXG50cnkge1xuICBJU19MRSA9IG5ldyBVaW50MzJBcnJheShuZXcgVWludDhBcnJheShbMSwgMCwgMCwgMF0pLmJ1ZmZlcilbMF0gPT09IDE7XG59IGNhdGNoIChfXykge31cblxuZnVuY3Rpb24gY29weUludDE2YXNMRShzcmMsIHRhcmdldCwgdGFyZ2V0X29mZnNldCkge1xuICBpZiAoSVNfTEUpIHtcbiAgICB0YXJnZXQuc2V0KGFzVWludDhBcnJheShzcmMpLCB0YXJnZXRfb2Zmc2V0KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBmb3IgKHZhciBwdHIgPSB0YXJnZXRfb2Zmc2V0LCBpID0gMDsgaSA8IHNyYy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBkYXRhID0gc3JjW2ldO1xuICAgIHRhcmdldFtwdHIrK10gPSBkYXRhICYgMHhGRjtcbiAgICB0YXJnZXRbcHRyKytdID0gZGF0YSA+PiA4ICYgMHhGRjtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlc2l6ZV93YXNtKG9wdGlvbnMpIHtcbiAgdmFyIHNyYyA9IG9wdGlvbnMuc3JjO1xuICB2YXIgc3JjVyA9IG9wdGlvbnMud2lkdGg7XG4gIHZhciBzcmNIID0gb3B0aW9ucy5oZWlnaHQ7XG4gIHZhciBkZXN0VyA9IG9wdGlvbnMudG9XaWR0aDtcbiAgdmFyIGRlc3RIID0gb3B0aW9ucy50b0hlaWdodDtcbiAgdmFyIHNjYWxlWCA9IG9wdGlvbnMuc2NhbGVYIHx8IG9wdGlvbnMudG9XaWR0aCAvIG9wdGlvbnMud2lkdGg7XG4gIHZhciBzY2FsZVkgPSBvcHRpb25zLnNjYWxlWSB8fCBvcHRpb25zLnRvSGVpZ2h0IC8gb3B0aW9ucy5oZWlnaHQ7XG4gIHZhciBvZmZzZXRYID0gb3B0aW9ucy5vZmZzZXRYIHx8IDAuMDtcbiAgdmFyIG9mZnNldFkgPSBvcHRpb25zLm9mZnNldFkgfHwgMC4wO1xuICB2YXIgZGVzdCA9IG9wdGlvbnMuZGVzdCB8fCBuZXcgVWludDhBcnJheShkZXN0VyAqIGRlc3RIICogNCk7XG4gIHZhciBxdWFsaXR5ID0gdHlwZW9mIG9wdGlvbnMucXVhbGl0eSA9PT0gJ3VuZGVmaW5lZCcgPyAzIDogb3B0aW9ucy5xdWFsaXR5O1xuICB2YXIgYWxwaGEgPSBvcHRpb25zLmFscGhhIHx8IGZhbHNlO1xuICB2YXIgZmlsdGVyc1ggPSBjcmVhdGVGaWx0ZXJzKHF1YWxpdHksIHNyY1csIGRlc3RXLCBzY2FsZVgsIG9mZnNldFgpLFxuICAgICAgZmlsdGVyc1kgPSBjcmVhdGVGaWx0ZXJzKHF1YWxpdHksIHNyY0gsIGRlc3RILCBzY2FsZVksIG9mZnNldFkpOyAvLyBkZXN0aW5hdGlvbiBpcyAwIHRvby5cblxuICB2YXIgc3JjX29mZnNldCA9IDA7IC8vIGJ1ZmZlciBiZXR3ZWVuIGNvbnZvbHZlIHBhc3Nlc1xuXG4gIHZhciB0bXBfb2Zmc2V0ID0gdGhpcy5fX2FsaWduKHNyY19vZmZzZXQgKyBNYXRoLm1heChzcmMuYnl0ZUxlbmd0aCwgZGVzdC5ieXRlTGVuZ3RoKSk7XG5cbiAgdmFyIGZpbHRlcnNYX29mZnNldCA9IHRoaXMuX19hbGlnbih0bXBfb2Zmc2V0ICsgc3JjSCAqIGRlc3RXICogNCk7XG5cbiAgdmFyIGZpbHRlcnNZX29mZnNldCA9IHRoaXMuX19hbGlnbihmaWx0ZXJzWF9vZmZzZXQgKyBmaWx0ZXJzWC5ieXRlTGVuZ3RoKTtcblxuICB2YXIgYWxsb2NfYnl0ZXMgPSBmaWx0ZXJzWV9vZmZzZXQgKyBmaWx0ZXJzWS5ieXRlTGVuZ3RoO1xuXG4gIHZhciBpbnN0YW5jZSA9IHRoaXMuX19pbnN0YW5jZSgncmVzaXplJywgYWxsb2NfYnl0ZXMpOyAvL1xuICAvLyBGaWxsIG1lbW9yeSBibG9jayB3aXRoIGRhdGEgdG8gcHJvY2Vzc1xuICAvL1xuXG5cbiAgdmFyIG1lbSA9IG5ldyBVaW50OEFycmF5KHRoaXMuX19tZW1vcnkuYnVmZmVyKTtcbiAgdmFyIG1lbTMyID0gbmV3IFVpbnQzMkFycmF5KHRoaXMuX19tZW1vcnkuYnVmZmVyKTsgLy8gMzItYml0IGNvcHkgaXMgbXVjaCBmYXN0ZXIgaW4gY2hyb21lXG5cbiAgdmFyIHNyYzMyID0gbmV3IFVpbnQzMkFycmF5KHNyYy5idWZmZXIpO1xuICBtZW0zMi5zZXQoc3JjMzIpOyAvLyBXZSBzaG91bGQgZ3VhcmFudGVlIExFIGJ5dGVzIG9yZGVyLiBGaWx0ZXJzIGFyZSBub3QgYmlnLCBzb1xuICAvLyBzcGVlZCBkaWZmZXJlbmNlIGlzIG5vdCBzaWduaWZpY2FudCB2cyBkaXJlY3QgLnNldCgpXG5cbiAgY29weUludDE2YXNMRShmaWx0ZXJzWCwgbWVtLCBmaWx0ZXJzWF9vZmZzZXQpO1xuICBjb3B5SW50MTZhc0xFKGZpbHRlcnNZLCBtZW0sIGZpbHRlcnNZX29mZnNldCk7IC8vXG4gIC8vIE5vdyBjYWxsIHdlYmFzc2VtYmx5IG1ldGhvZFxuICAvLyBlbXNkayBkb2VzIG1ldGhvZCBuYW1lcyB3aXRoICdfJ1xuXG4gIHZhciBmbiA9IGluc3RhbmNlLmV4cG9ydHMuY29udm9sdmVIViB8fCBpbnN0YW5jZS5leHBvcnRzLl9jb252b2x2ZUhWO1xuICBmbihmaWx0ZXJzWF9vZmZzZXQsIGZpbHRlcnNZX29mZnNldCwgdG1wX29mZnNldCwgc3JjVywgc3JjSCwgZGVzdFcsIGRlc3RIKTsgLy9cbiAgLy8gQ29weSBkYXRhIGJhY2sgdG8gdHlwZWQgYXJyYXlcbiAgLy9cbiAgLy8gMzItYml0IGNvcHkgaXMgbXVjaCBmYXN0ZXIgaW4gY2hyb21lXG5cbiAgdmFyIGRlc3QzMiA9IG5ldyBVaW50MzJBcnJheShkZXN0LmJ1ZmZlcik7XG4gIGRlc3QzMi5zZXQobmV3IFVpbnQzMkFycmF5KHRoaXMuX19tZW1vcnkuYnVmZmVyLCAwLCBkZXN0SCAqIGRlc3RXKSk7IC8vIFRoYXQncyBmYXN0ZXIgdGhhbiBkb2luZyBjaGVja3MgaW4gY29udm9sdmVyLlxuICAvLyAhISEgTm90ZSwgY2FudmFzIGRhdGEgaXMgbm90IHByZW11bHRpcGxlZC4gV2UgZG9uJ3QgbmVlZCBvdGhlclxuICAvLyBhbHBoYSBjb3JyZWN0aW9ucy5cblxuICBpZiAoIWFscGhhKSByZXNldEFscGhhKGRlc3QsIGRlc3RXLCBkZXN0SCk7XG4gIHJldHVybiBkZXN0O1xufTtcblxufSx7XCIuL3Jlc2l6ZV9maWx0ZXJfZ2VuXCI6Nn1dLDk6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgbmFtZTogJ3Vuc2hhcnBfbWFzaycsXG4gIGZuOiBfZGVyZXFfKCcuL3Vuc2hhcnBfbWFzaycpLFxuICB3YXNtX2ZuOiBfZGVyZXFfKCcuL3Vuc2hhcnBfbWFza193YXNtJyksXG4gIHdhc21fc3JjOiBfZGVyZXFfKCcuL3Vuc2hhcnBfbWFza193YXNtX2Jhc2U2NCcpXG59O1xuXG59LHtcIi4vdW5zaGFycF9tYXNrXCI6MTAsXCIuL3Vuc2hhcnBfbWFza193YXNtXCI6MTEsXCIuL3Vuc2hhcnBfbWFza193YXNtX2Jhc2U2NFwiOjEyfV0sMTA6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXG52YXIgZ2x1cl9tb25vMTYgPSBfZGVyZXFfKCdnbHVyL21vbm8xNicpO1xuXG5mdW5jdGlvbiBoc3ZfdjE2KGltZywgd2lkdGgsIGhlaWdodCkge1xuICB2YXIgc2l6ZSA9IHdpZHRoICogaGVpZ2h0O1xuICB2YXIgb3V0ID0gbmV3IFVpbnQxNkFycmF5KHNpemUpO1xuICB2YXIgciwgZywgYiwgbWF4O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgciA9IGltZ1s0ICogaV07XG4gICAgZyA9IGltZ1s0ICogaSArIDFdO1xuICAgIGIgPSBpbWdbNCAqIGkgKyAyXTtcbiAgICBtYXggPSByID49IGcgJiYgciA+PSBiID8gciA6IGcgPj0gYiAmJiBnID49IHIgPyBnIDogYjtcbiAgICBvdXRbaV0gPSBtYXggPDwgODtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gdW5zaGFycChpbWcsIHdpZHRoLCBoZWlnaHQsIGFtb3VudCwgcmFkaXVzLCB0aHJlc2hvbGQpIHtcbiAgdmFyIHYxLCB2Miwgdm11bDtcbiAgdmFyIGRpZmYsIGlUaW1lczQ7XG5cbiAgaWYgKGFtb3VudCA9PT0gMCB8fCByYWRpdXMgPCAwLjUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAocmFkaXVzID4gMi4wKSB7XG4gICAgcmFkaXVzID0gMi4wO1xuICB9XG5cbiAgdmFyIGJyaWdodG5lc3MgPSBoc3ZfdjE2KGltZywgd2lkdGgsIGhlaWdodCk7XG4gIHZhciBibHVyZWQgPSBuZXcgVWludDE2QXJyYXkoYnJpZ2h0bmVzcyk7IC8vIGNvcHksIGJlY2F1c2UgYmx1ciBtb2RpZnkgc3JjXG5cbiAgZ2x1cl9tb25vMTYoYmx1cmVkLCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpO1xuICB2YXIgYW1vdW50RnAgPSBhbW91bnQgLyAxMDAgKiAweDEwMDAgKyAwLjUgfCAwO1xuICB2YXIgdGhyZXNob2xkRnAgPSB0aHJlc2hvbGQgPDwgODtcbiAgdmFyIHNpemUgPSB3aWR0aCAqIGhlaWdodDtcbiAgLyogZXNsaW50LWRpc2FibGUgaW5kZW50ICovXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICB2MSA9IGJyaWdodG5lc3NbaV07XG4gICAgZGlmZiA9IHYxIC0gYmx1cmVkW2ldO1xuXG4gICAgaWYgKE1hdGguYWJzKGRpZmYpID49IHRocmVzaG9sZEZwKSB7XG4gICAgICAvLyBhZGQgdW5zaGFycCBtYXNrIHRvIHRoZSBicmlnaHRuZXNzIGNoYW5uZWxcbiAgICAgIHYyID0gdjEgKyAoYW1vdW50RnAgKiBkaWZmICsgMHg4MDAgPj4gMTIpOyAvLyBCb3RoIHYxIGFuZCB2MiBhcmUgd2l0aGluIFswLjAgLi4gMjU1LjBdICgwMDAwLUZGMDApIHJhbmdlLCBuZXZlciBnb2luZyBpbnRvXG4gICAgICAvLyBbMjU1LjAwMyAuLiAyNTUuOTk2XSAoRkYwMS1GRkZGKS4gVGhpcyBhbGxvd3MgdG8gcm91bmQgdGhpcyB2YWx1ZSBhcyAoeCsuNSl8MFxuICAgICAgLy8gbGF0ZXIgd2l0aG91dCBvdmVyZmxvd2luZy5cblxuICAgICAgdjIgPSB2MiA+IDB4ZmYwMCA/IDB4ZmYwMCA6IHYyO1xuICAgICAgdjIgPSB2MiA8IDB4MDAwMCA/IDB4MDAwMCA6IHYyOyAvLyBBdm9pZCBkaXZpc2lvbiBieSAwLiBWPTAgbWVhbnMgcmdiKDAsMCwwKSwgdW5zaGFycCB3aXRoIHVuc2hhcnBBbW91bnQ+MCBjYW5ub3RcbiAgICAgIC8vIGNoYW5nZSB0aGlzIHZhbHVlIChiZWNhdXNlIGRpZmYgYmV0d2VlbiBjb2xvcnMgZ2V0cyBpbmZsYXRlZCksIHNvIG5vIG5lZWQgdG8gdmVyaWZ5IGNvcnJlY3RuZXNzLlxuXG4gICAgICB2MSA9IHYxICE9PSAwID8gdjEgOiAxOyAvLyBNdWx0aXBseWluZyBWIGluIEhTViBtb2RlbCBieSBhIGNvbnN0YW50IGlzIGVxdWl2YWxlbnQgdG8gbXVsdGlwbHlpbmcgZWFjaCBjb21wb25lbnRcbiAgICAgIC8vIGluIFJHQiBieSB0aGUgc2FtZSBjb25zdGFudCAoc2FtZSBmb3IgSFNMKSwgc2VlIGFsc286XG4gICAgICAvLyBodHRwczovL2JlZXNidXp6LmJpei9jb2RlLzE2LWhzdi1jb2xvci10cmFuc2Zvcm1zXG5cbiAgICAgIHZtdWwgPSAodjIgPDwgMTIpIC8gdjEgfCAwOyAvLyBSZXN1bHQgd2lsbCBiZSBpbiBbMC4uMjU1XSByYW5nZSBiZWNhdXNlOlxuICAgICAgLy8gIC0gYWxsIG51bWJlcnMgYXJlIHBvc2l0aXZlXG4gICAgICAvLyAgLSByLGcsYiA8PSAodjEvMjU2KVxuICAgICAgLy8gIC0gcixnLGIsKHYxLzI1NiksKHYyLzI1NikgPD0gMjU1XG4gICAgICAvLyBTbyBoaWdoZXN0IHRoaXMgbnVtYmVyIGNhbiBnZXQgaXMgWCoyNTUvWCswLjU9MjU1LjUgd2hpY2ggaXMgPCAyNTYgYW5kIHJvdW5kcyBkb3duLlxuXG4gICAgICBpVGltZXM0ID0gaSAqIDQ7XG4gICAgICBpbWdbaVRpbWVzNF0gPSBpbWdbaVRpbWVzNF0gKiB2bXVsICsgMHg4MDAgPj4gMTI7IC8vIFJcblxuICAgICAgaW1nW2lUaW1lczQgKyAxXSA9IGltZ1tpVGltZXM0ICsgMV0gKiB2bXVsICsgMHg4MDAgPj4gMTI7IC8vIEdcblxuICAgICAgaW1nW2lUaW1lczQgKyAyXSA9IGltZ1tpVGltZXM0ICsgMl0gKiB2bXVsICsgMHg4MDAgPj4gMTI7IC8vIEJcbiAgICB9XG4gIH1cbn07XG5cbn0se1wiZ2x1ci9tb25vMTZcIjoxOH1dLDExOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB1bnNoYXJwKGltZywgd2lkdGgsIGhlaWdodCwgYW1vdW50LCByYWRpdXMsIHRocmVzaG9sZCkge1xuICBpZiAoYW1vdW50ID09PSAwIHx8IHJhZGl1cyA8IDAuNSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChyYWRpdXMgPiAyLjApIHtcbiAgICByYWRpdXMgPSAyLjA7XG4gIH1cblxuICB2YXIgcGl4ZWxzID0gd2lkdGggKiBoZWlnaHQ7XG4gIHZhciBpbWdfYnl0ZXNfY250ID0gcGl4ZWxzICogNDtcbiAgdmFyIGhzdl9ieXRlc19jbnQgPSBwaXhlbHMgKiAyO1xuICB2YXIgYmx1cl9ieXRlc19jbnQgPSBwaXhlbHMgKiAyO1xuICB2YXIgYmx1cl9saW5lX2J5dGVfY250ID0gTWF0aC5tYXgod2lkdGgsIGhlaWdodCkgKiA0OyAvLyBmbG9hdDMyIGFycmF5XG5cbiAgdmFyIGJsdXJfY29lZmZzX2J5dGVfY250ID0gOCAqIDQ7IC8vIGZsb2F0MzIgYXJyYXlcblxuICB2YXIgaW1nX29mZnNldCA9IDA7XG4gIHZhciBoc3Zfb2Zmc2V0ID0gaW1nX2J5dGVzX2NudDtcbiAgdmFyIGJsdXJfb2Zmc2V0ID0gaHN2X29mZnNldCArIGhzdl9ieXRlc19jbnQ7XG4gIHZhciBibHVyX3RtcF9vZmZzZXQgPSBibHVyX29mZnNldCArIGJsdXJfYnl0ZXNfY250O1xuICB2YXIgYmx1cl9saW5lX29mZnNldCA9IGJsdXJfdG1wX29mZnNldCArIGJsdXJfYnl0ZXNfY250O1xuICB2YXIgYmx1cl9jb2VmZnNfb2Zmc2V0ID0gYmx1cl9saW5lX29mZnNldCArIGJsdXJfbGluZV9ieXRlX2NudDtcblxuICB2YXIgaW5zdGFuY2UgPSB0aGlzLl9faW5zdGFuY2UoJ3Vuc2hhcnBfbWFzaycsIGltZ19ieXRlc19jbnQgKyBoc3ZfYnl0ZXNfY250ICsgYmx1cl9ieXRlc19jbnQgKiAyICsgYmx1cl9saW5lX2J5dGVfY250ICsgYmx1cl9jb2VmZnNfYnl0ZV9jbnQsIHtcbiAgICBleHA6IE1hdGguZXhwXG4gIH0pOyAvLyAzMi1iaXQgY29weSBpcyBtdWNoIGZhc3RlciBpbiBjaHJvbWVcblxuXG4gIHZhciBpbWczMiA9IG5ldyBVaW50MzJBcnJheShpbWcuYnVmZmVyKTtcbiAgdmFyIG1lbTMyID0gbmV3IFVpbnQzMkFycmF5KHRoaXMuX19tZW1vcnkuYnVmZmVyKTtcbiAgbWVtMzIuc2V0KGltZzMyKTsgLy8gSFNMXG5cbiAgdmFyIGZuID0gaW5zdGFuY2UuZXhwb3J0cy5oc3ZfdjE2IHx8IGluc3RhbmNlLmV4cG9ydHMuX2hzdl92MTY7XG4gIGZuKGltZ19vZmZzZXQsIGhzdl9vZmZzZXQsIHdpZHRoLCBoZWlnaHQpOyAvLyBCTFVSXG5cbiAgZm4gPSBpbnN0YW5jZS5leHBvcnRzLmJsdXJNb25vMTYgfHwgaW5zdGFuY2UuZXhwb3J0cy5fYmx1ck1vbm8xNjtcbiAgZm4oaHN2X29mZnNldCwgYmx1cl9vZmZzZXQsIGJsdXJfdG1wX29mZnNldCwgYmx1cl9saW5lX29mZnNldCwgYmx1cl9jb2VmZnNfb2Zmc2V0LCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpOyAvLyBVTlNIQVJQXG5cbiAgZm4gPSBpbnN0YW5jZS5leHBvcnRzLnVuc2hhcnAgfHwgaW5zdGFuY2UuZXhwb3J0cy5fdW5zaGFycDtcbiAgZm4oaW1nX29mZnNldCwgaW1nX29mZnNldCwgaHN2X29mZnNldCwgYmx1cl9vZmZzZXQsIHdpZHRoLCBoZWlnaHQsIGFtb3VudCwgdGhyZXNob2xkKTsgLy8gMzItYml0IGNvcHkgaXMgbXVjaCBmYXN0ZXIgaW4gY2hyb21lXG5cbiAgaW1nMzIuc2V0KG5ldyBVaW50MzJBcnJheSh0aGlzLl9fbWVtb3J5LmJ1ZmZlciwgMCwgcGl4ZWxzKSk7XG59O1xuXG59LHt9XSwxMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cbm1vZHVsZS5leHBvcnRzID0gJ0FHRnpiUUVBQUFBQURBWmtlV3hwYm1zQUFBQUFBQUUwQjJBQUFHQUVmMzkvZndCZ0JuOS9mMzkvZndCZ0NIOS9mMzkvZjM5L0FHQUlmMzkvZjM5L2YzMEFZQUo5ZndCZ0FYd0JmQUlaQWdObGJuWURaWGh3QUFZRFpXNTJCbTFsYlc5eWVRSUFBQU1IQmdBRkFnUUJBd1lHQVg4QVFRQUxCNG9CQ0JGZlgzZGhjMjFmWTJGc2JGOWpkRzl5Y3dBQkZsOWZZblZwYkdSZloyRjFjM05wWVc1ZlkyOWxabk1BQWc1ZlgyZGhkWE56TVRaZmJHbHVaUUFEQ21Kc2RYSk5iMjV2TVRZQUJBZG9jM1pmZGpFMkFBVUhkVzV6YUdGeWNBQUdERjlmWkhOdlgyaGhibVJzWlFNQUdGOWZkMkZ6YlY5aGNIQnNlVjlrWVhSaFgzSmxiRzlqY3dBQkNzVU1CZ01BQVF2V0FRRUhmQ0FCUk51R3VrT0NHdnMvSUFDN295SUNSQUFBQUFBQUFBREFvaEFBSWdXMmpEZ0NGQ0FCSUFLYUVBQWlBeUFEb0NJR3RqZ0NFQ0FCUkFBQUFBQUFBUEEvSUFPaElnUWdCS0lnQXlBQ0lBS2dva1FBQUFBQUFBRHdQNkFnQmFHaklnUzJPQUlBSUFFZ0JTQUVtcUlpQjdZNEFnd2dBU0FESUFKRUFBQUFBQUFBOEQrZ0lBU2lvaUlJdGpnQ0NDQUJJQU1nQWtRQUFBQUFBQUR3djZBZ0JLS2lJZ0syT0FJRUlBRWdCeUFJb0NBRlJBQUFBQUFBQVBBL0lBYWhvQ0lEbzdZNEFod2dBU0FFSUFLZ0lBT2p0amdDR0F1R0JRTUdmd2w4QW4wZ0F5b0NEQ0VWSUFNcUFnZ2hGaUFES2dJVXV5RVJJQU1xQWhDN0lSQUNRQ0FFUVFGcklnaEJBRWdpQ1FSQUlBSWhCeUFBSVFZTUFRc2dBaUFBTHdFQXVDSVBJQU1xQWhpN29pSU1JQkdpSWcwZ0RDQVFvaUFQSUFNcUFnUzdJaE9pSWhRZ0F5b0NBTHNpRWlBUG9xQ2dvQ0lPdGpnQ0FDQUNRUVJxSVFjZ0FFRUNhaUVHSUFoRkRRQWdDRUVCSUFoQkFVZ2JJZ3BCZjNNaEN3Si9JQVFnQ210QkFYRkZCRUFnRGlFTklBZ01BUXNnQWlBTklBNGdFS0lnRkNBU0lBQXZBUUs0SWcraW9LQ2dJZzIyT0FJRUlBSkJDR29oQnlBQVFRUnFJUVlnRGlFTUlBUkJBbXNMSVFJZ0MwRUFJQVJyUmcwQUEwQWdCeUFNSUJHaUlBMGdFS0lnRHlBVG9pQVNJQVl2QVFDNElnNmlvS0NnSWd5Mk9BSUFJQWNnRFNBUm9pQU1JQkNpSUE0Z0U2SWdFaUFHTHdFQ3VDSVBvcUNnb0NJTnRqZ0NCQ0FIUVFocUlRY2dCa0VFYWlFR0lBSkJBa29oQUNBQ1FRSnJJUUlnQUEwQUN3c0NRQ0FKRFFBZ0FTQUZJQWhzUVFGMGFpSUFBbjhnQmtFQ2F5OEJBQ0lDdUNJTklCVzdJaEtpSUEwZ0Zyc2lFNktnSUEwZ0F5b0NITHVpSWd3Z0VLS2dJQXdnRWFLZ0lnOGdCMEVFYXlJSEtnSUF1NkFpRGtRQUFBQUFBQUR3UVdNZ0RrUUFBQUFBQUFBQUFHWnhCRUFnRHFzTUFRdEJBQXM3QVFBZ0NFVU5BQ0FHUVFScklRWkJBQ0FGYTBFQmRDRUJBMEFDZnlBTklCS2lJQUpCLy84RGNiZ2lEU0FUb3FBZ0R5SU9JQkNpb0NBTUlCR2lvQ0lQSUFkQkJHc2lCeW9DQUx1Z0lneEVBQUFBQUFBQThFRmpJQXhFQUFBQUFBQUFBQUJtY1FSQUlBeXJEQUVMUVFBTElRTWdCaThCQUNFQ0lBQWdBV29pQUNBRE93RUFJQVpCQW1zaEJpQUlRUUZLSVFNZ0RpRU1JQWhCQVdzaENDQUREUUFMQ3d2UkFnSUJmd2Q4QWtBZ0IwTUFBQUFBV3cwQUlBUkUyNGE2UTRJYSt6OGdCME1BQUFBL2w3dWpJZ2xFQUFBQUFBQUFBTUNpRUFBaURMYU1PQUlVSUFRZ0Nab1FBQ0lLSUFxZ0lnMjJPQUlRSUFSRUFBQUFBQUFBOEQ4Z0NxRWlDeUFMb2lBS0lBa2dDYUNpUkFBQUFBQUFBUEEvb0NBTW9hTWlDN1k0QWdBZ0JDQU1JQXVhb2lJT3RqZ0NEQ0FFSUFvZ0NVUUFBQUFBQUFEd1A2QWdDNktpSWcrMk9BSUlJQVFnQ2lBSlJBQUFBQUFBQVBDL29DQUxvcUlpQ2JZNEFnUWdCQ0FPSUErZ0lBeEVBQUFBQUFBQThEOGdEYUdnSWdxanRqZ0NIQ0FFSUFzZ0NhQWdDcU8yT0FJWUlBWUVRQU5BSUFBZ0JTQUliRUVCZEdvZ0FpQUlRUUYwYWlBRElBUWdCU0FHRUFNZ0NFRUJhaUlJSUFaSERRQUxDeUFGUlEwQVFRQWhDQU5BSUFJZ0JpQUliRUVCZEdvZ0FTQUlRUUYwYWlBRElBUWdCaUFGRUFNZ0NFRUJhaUlJSUFWSERRQUxDd3R4QVFOL0lBSWdBMndpQlFSQUEwQWdBU0FBS0FJQUlnUkJFSFpCL3dGeElnSWdBaUFFUVFoMlFmOEJjU0lESUFNZ0JFSC9BWEVpQkVrYklBSWdBMHNiSWdZZ0JpQUVJQUlnQkVzYklBTWdCRXNiUVFoME93RUFJQUZCQW1vaEFTQUFRUVJxSVFBZ0JVRUJheUlGRFFBTEN3dVpBZ0lEZndGOElBUWdCV3doQkFKL0lBYXpRd0FBZ0VXVVF3QUF5RUtWdTBRQUFBQUFBQURnUDZBaUM1bEVBQUFBQUFBQTRFRmpCRUFnQzZvTUFRdEJnSUNBZ0hnTElRVWdCQVJBSUFkQkNIUWhDVUVBSVFZRFFDQUpJQUlnQmtFQmRDSUhhaThCQUNJQklBTWdCMm92QVFCcklnY2dCMEVmZFNJSWFpQUljMDBFUUNBQUlBWkJBblFpQ0dvaUNpQUZJQWRzUVlBUWFrRU1kU0FCYWlJSFFZRCtBeUFIUVlEK0EwZ2JJZ2RCQUNBSFFRQktHMEVNZENBQlFRRWdBUnR1SWdFZ0NpMEFBR3hCZ0JCcVFReDJPZ0FBSUFBZ0NFRUJjbW9pQnlBQklBY3RBQUJzUVlBUWFrRU1kam9BQUNBQUlBaEJBbkpxSWdjZ0FTQUhMUUFBYkVHQUVHcEJESFk2QUFBTElBWkJBV29pQmlBRVJ3MEFDd3NMJztcblxufSx7fV0sMTM6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXG52YXIgR0NfSU5URVJWQUwgPSAxMDA7XG5cbmZ1bmN0aW9uIFBvb2woY3JlYXRlLCBpZGxlKSB7XG4gIHRoaXMuY3JlYXRlID0gY3JlYXRlO1xuICB0aGlzLmF2YWlsYWJsZSA9IFtdO1xuICB0aGlzLmFjcXVpcmVkID0ge307XG4gIHRoaXMubGFzdElkID0gMTtcbiAgdGhpcy50aW1lb3V0SWQgPSAwO1xuICB0aGlzLmlkbGUgPSBpZGxlIHx8IDIwMDA7XG59XG5cblBvb2wucHJvdG90eXBlLmFjcXVpcmUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgdmFyIHJlc291cmNlO1xuXG4gIGlmICh0aGlzLmF2YWlsYWJsZS5sZW5ndGggIT09IDApIHtcbiAgICByZXNvdXJjZSA9IHRoaXMuYXZhaWxhYmxlLnBvcCgpO1xuICB9IGVsc2Uge1xuICAgIHJlc291cmNlID0gdGhpcy5jcmVhdGUoKTtcbiAgICByZXNvdXJjZS5pZCA9IHRoaXMubGFzdElkKys7XG5cbiAgICByZXNvdXJjZS5yZWxlYXNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIF90aGlzLnJlbGVhc2UocmVzb3VyY2UpO1xuICAgIH07XG4gIH1cblxuICB0aGlzLmFjcXVpcmVkW3Jlc291cmNlLmlkXSA9IHJlc291cmNlO1xuICByZXR1cm4gcmVzb3VyY2U7XG59O1xuXG5Qb29sLnByb3RvdHlwZS5yZWxlYXNlID0gZnVuY3Rpb24gKHJlc291cmNlKSB7XG4gIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gIGRlbGV0ZSB0aGlzLmFjcXVpcmVkW3Jlc291cmNlLmlkXTtcbiAgcmVzb3VyY2UubGFzdFVzZWQgPSBEYXRlLm5vdygpO1xuICB0aGlzLmF2YWlsYWJsZS5wdXNoKHJlc291cmNlKTtcblxuICBpZiAodGhpcy50aW1lb3V0SWQgPT09IDApIHtcbiAgICB0aGlzLnRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIF90aGlzMi5nYygpO1xuICAgIH0sIEdDX0lOVEVSVkFMKTtcbiAgfVxufTtcblxuUG9vbC5wcm90b3R5cGUuZ2MgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gIHZhciBub3cgPSBEYXRlLm5vdygpO1xuICB0aGlzLmF2YWlsYWJsZSA9IHRoaXMuYXZhaWxhYmxlLmZpbHRlcihmdW5jdGlvbiAocmVzb3VyY2UpIHtcbiAgICBpZiAobm93IC0gcmVzb3VyY2UubGFzdFVzZWQgPiBfdGhpczMuaWRsZSkge1xuICAgICAgcmVzb3VyY2UuZGVzdHJveSgpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9KTtcblxuICBpZiAodGhpcy5hdmFpbGFibGUubGVuZ3RoICE9PSAwKSB7XG4gICAgdGhpcy50aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBfdGhpczMuZ2MoKTtcbiAgICB9LCBHQ19JTlRFUlZBTCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy50aW1lb3V0SWQgPSAwO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBvb2w7XG5cbn0se31dLDE0OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIG1pbiBzaXplID0gMSBjYW4gY29uc3VtZSBsYXJnZSBhbW91bnQgb2YgbWVtb3J5XG5cbnZhciBNSU5fSU5ORVJfVElMRV9TSVpFID0gMjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjcmVhdGVTdGFnZXMoZnJvbVdpZHRoLCBmcm9tSGVpZ2h0LCB0b1dpZHRoLCB0b0hlaWdodCwgc3JjVGlsZVNpemUsIGRlc3RUaWxlQm9yZGVyKSB7XG4gIHZhciBzY2FsZVggPSB0b1dpZHRoIC8gZnJvbVdpZHRoO1xuICB2YXIgc2NhbGVZID0gdG9IZWlnaHQgLyBmcm9tSGVpZ2h0OyAvLyBkZXJpdmVkIGZyb20gY3JlYXRlUmVnaW9ucyBlcXVhdGlvbjpcbiAgLy8gaW5uZXJUaWxlV2lkdGggPSBwaXhlbEZsb29yKHNyY1RpbGVTaXplICogc2NhbGVYKSAtIDIgKiBkZXN0VGlsZUJvcmRlcjtcblxuICB2YXIgbWluU2NhbGUgPSAoMiAqIGRlc3RUaWxlQm9yZGVyICsgTUlOX0lOTkVSX1RJTEVfU0laRSArIDEpIC8gc3JjVGlsZVNpemU7IC8vIHJlZnVzZSB0byBzY2FsZSBpbWFnZSBtdWx0aXBsZSB0aW1lcyBieSBsZXNzIHRoYW4gdHdpY2UgZWFjaCB0aW1lLFxuICAvLyBpdCBjb3VsZCBvbmx5IGhhcHBlbiBiZWNhdXNlIG9mIGludmFsaWQgb3B0aW9uc1xuXG4gIGlmIChtaW5TY2FsZSA+IDAuNSkgcmV0dXJuIFtbdG9XaWR0aCwgdG9IZWlnaHRdXTtcbiAgdmFyIHN0YWdlQ291bnQgPSBNYXRoLmNlaWwoTWF0aC5sb2coTWF0aC5taW4oc2NhbGVYLCBzY2FsZVkpKSAvIE1hdGgubG9nKG1pblNjYWxlKSk7IC8vIG5vIGFkZGl0aW9uYWwgcmVzaXplcyBhcmUgbmVjZXNzYXJ5LFxuICAvLyBzdGFnZUNvdW50IGNhbiBiZSB6ZXJvIG9yIGJlIG5lZ2F0aXZlIHdoZW4gZW5sYXJnaW5nIHRoZSBpbWFnZVxuXG4gIGlmIChzdGFnZUNvdW50IDw9IDEpIHJldHVybiBbW3RvV2lkdGgsIHRvSGVpZ2h0XV07XG4gIHZhciByZXN1bHQgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YWdlQ291bnQ7IGkrKykge1xuICAgIHZhciB3aWR0aCA9IE1hdGgucm91bmQoTWF0aC5wb3coTWF0aC5wb3coZnJvbVdpZHRoLCBzdGFnZUNvdW50IC0gaSAtIDEpICogTWF0aC5wb3codG9XaWR0aCwgaSArIDEpLCAxIC8gc3RhZ2VDb3VudCkpO1xuICAgIHZhciBoZWlnaHQgPSBNYXRoLnJvdW5kKE1hdGgucG93KE1hdGgucG93KGZyb21IZWlnaHQsIHN0YWdlQ291bnQgLSBpIC0gMSkgKiBNYXRoLnBvdyh0b0hlaWdodCwgaSArIDEpLCAxIC8gc3RhZ2VDb3VudCkpO1xuICAgIHJlc3VsdC5wdXNoKFt3aWR0aCwgaGVpZ2h0XSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxufSx7fV0sMTU6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLypcbiAqIHBpeGVsRmxvb3IgYW5kIHBpeGVsQ2VpbCBhcmUgbW9kaWZpZWQgdmVyc2lvbnMgb2YgTWF0aC5mbG9vciBhbmQgTWF0aC5jZWlsXG4gKiBmdW5jdGlvbnMgd2hpY2ggdGFrZSBpbnRvIGFjY291bnQgZmxvYXRpbmcgcG9pbnQgYXJpdGhtZXRpYyBlcnJvcnMuXG4gKiBUaG9zZSBlcnJvcnMgY2FuIGNhdXNlIHVuZGVzaXJlZCBpbmNyZW1lbnRzL2RlY3JlbWVudHMgb2Ygc2l6ZXMgYW5kIG9mZnNldHM6XG4gKiBNYXRoLmNlaWwoMzYgLyAoMzYgLyA1MDApKSA9IDUwMVxuICogcGl4ZWxDZWlsKDM2IC8gKDM2IC8gNTAwKSkgPSA1MDBcbiAqL1xuXG52YXIgUElYRUxfRVBTSUxPTiA9IDFlLTU7XG5cbmZ1bmN0aW9uIHBpeGVsRmxvb3IoeCkge1xuICB2YXIgbmVhcmVzdCA9IE1hdGgucm91bmQoeCk7XG5cbiAgaWYgKE1hdGguYWJzKHggLSBuZWFyZXN0KSA8IFBJWEVMX0VQU0lMT04pIHtcbiAgICByZXR1cm4gbmVhcmVzdDtcbiAgfVxuXG4gIHJldHVybiBNYXRoLmZsb29yKHgpO1xufVxuXG5mdW5jdGlvbiBwaXhlbENlaWwoeCkge1xuICB2YXIgbmVhcmVzdCA9IE1hdGgucm91bmQoeCk7XG5cbiAgaWYgKE1hdGguYWJzKHggLSBuZWFyZXN0KSA8IFBJWEVMX0VQU0lMT04pIHtcbiAgICByZXR1cm4gbmVhcmVzdDtcbiAgfVxuXG4gIHJldHVybiBNYXRoLmNlaWwoeCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlUmVnaW9ucyhvcHRpb25zKSB7XG4gIHZhciBzY2FsZVggPSBvcHRpb25zLnRvV2lkdGggLyBvcHRpb25zLndpZHRoO1xuICB2YXIgc2NhbGVZID0gb3B0aW9ucy50b0hlaWdodCAvIG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgaW5uZXJUaWxlV2lkdGggPSBwaXhlbEZsb29yKG9wdGlvbnMuc3JjVGlsZVNpemUgKiBzY2FsZVgpIC0gMiAqIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7XG4gIHZhciBpbm5lclRpbGVIZWlnaHQgPSBwaXhlbEZsb29yKG9wdGlvbnMuc3JjVGlsZVNpemUgKiBzY2FsZVkpIC0gMiAqIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7IC8vIHByZXZlbnQgaW5maW5pdGUgbG9vcCwgdGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuXG5cbiAgaWYgKGlubmVyVGlsZVdpZHRoIDwgMSB8fCBpbm5lclRpbGVIZWlnaHQgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnRlcm5hbCBlcnJvciBpbiBwaWNhOiB0YXJnZXQgdGlsZSB3aWR0aC9oZWlnaHQgaXMgdG9vIHNtYWxsLicpO1xuICB9XG5cbiAgdmFyIHgsIHk7XG4gIHZhciBpbm5lclgsIGlubmVyWSwgdG9UaWxlV2lkdGgsIHRvVGlsZUhlaWdodDtcbiAgdmFyIHRpbGVzID0gW107XG4gIHZhciB0aWxlOyAvLyB3ZSBnbyB0b3AtdG8tZG93biBpbnN0ZWFkIG9mIGxlZnQtdG8tcmlnaHQgdG8gbWFrZSBpbWFnZSBkaXNwbGF5ZWQgZnJvbSB0b3AgdG9cbiAgLy8gZG9lc24gaW4gdGhlIGJyb3dzZXJcblxuICBmb3IgKGlubmVyWSA9IDA7IGlubmVyWSA8IG9wdGlvbnMudG9IZWlnaHQ7IGlubmVyWSArPSBpbm5lclRpbGVIZWlnaHQpIHtcbiAgICBmb3IgKGlubmVyWCA9IDA7IGlubmVyWCA8IG9wdGlvbnMudG9XaWR0aDsgaW5uZXJYICs9IGlubmVyVGlsZVdpZHRoKSB7XG4gICAgICB4ID0gaW5uZXJYIC0gb3B0aW9ucy5kZXN0VGlsZUJvcmRlcjtcblxuICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgIHggPSAwO1xuICAgICAgfVxuXG4gICAgICB0b1RpbGVXaWR0aCA9IGlubmVyWCArIGlubmVyVGlsZVdpZHRoICsgb3B0aW9ucy5kZXN0VGlsZUJvcmRlciAtIHg7XG5cbiAgICAgIGlmICh4ICsgdG9UaWxlV2lkdGggPj0gb3B0aW9ucy50b1dpZHRoKSB7XG4gICAgICAgIHRvVGlsZVdpZHRoID0gb3B0aW9ucy50b1dpZHRoIC0geDtcbiAgICAgIH1cblxuICAgICAgeSA9IGlubmVyWSAtIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7XG5cbiAgICAgIGlmICh5IDwgMCkge1xuICAgICAgICB5ID0gMDtcbiAgICAgIH1cblxuICAgICAgdG9UaWxlSGVpZ2h0ID0gaW5uZXJZICsgaW5uZXJUaWxlSGVpZ2h0ICsgb3B0aW9ucy5kZXN0VGlsZUJvcmRlciAtIHk7XG5cbiAgICAgIGlmICh5ICsgdG9UaWxlSGVpZ2h0ID49IG9wdGlvbnMudG9IZWlnaHQpIHtcbiAgICAgICAgdG9UaWxlSGVpZ2h0ID0gb3B0aW9ucy50b0hlaWdodCAtIHk7XG4gICAgICB9XG5cbiAgICAgIHRpbGUgPSB7XG4gICAgICAgIHRvWDogeCxcbiAgICAgICAgdG9ZOiB5LFxuICAgICAgICB0b1dpZHRoOiB0b1RpbGVXaWR0aCxcbiAgICAgICAgdG9IZWlnaHQ6IHRvVGlsZUhlaWdodCxcbiAgICAgICAgdG9Jbm5lclg6IGlubmVyWCxcbiAgICAgICAgdG9Jbm5lclk6IGlubmVyWSxcbiAgICAgICAgdG9Jbm5lcldpZHRoOiBpbm5lclRpbGVXaWR0aCxcbiAgICAgICAgdG9Jbm5lckhlaWdodDogaW5uZXJUaWxlSGVpZ2h0LFxuICAgICAgICBvZmZzZXRYOiB4IC8gc2NhbGVYIC0gcGl4ZWxGbG9vcih4IC8gc2NhbGVYKSxcbiAgICAgICAgb2Zmc2V0WTogeSAvIHNjYWxlWSAtIHBpeGVsRmxvb3IoeSAvIHNjYWxlWSksXG4gICAgICAgIHNjYWxlWDogc2NhbGVYLFxuICAgICAgICBzY2FsZVk6IHNjYWxlWSxcbiAgICAgICAgeDogcGl4ZWxGbG9vcih4IC8gc2NhbGVYKSxcbiAgICAgICAgeTogcGl4ZWxGbG9vcih5IC8gc2NhbGVZKSxcbiAgICAgICAgd2lkdGg6IHBpeGVsQ2VpbCh0b1RpbGVXaWR0aCAvIHNjYWxlWCksXG4gICAgICAgIGhlaWdodDogcGl4ZWxDZWlsKHRvVGlsZUhlaWdodCAvIHNjYWxlWSlcbiAgICAgIH07XG4gICAgICB0aWxlcy5wdXNoKHRpbGUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aWxlcztcbn07XG5cbn0se31dLDE2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxuZnVuY3Rpb24gb2JqQ2xhc3Mob2JqKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKTtcbn1cblxubW9kdWxlLmV4cG9ydHMuaXNDYW52YXMgPSBmdW5jdGlvbiBpc0NhbnZhcyhlbGVtZW50KSB7XG4gIHZhciBjbmFtZSA9IG9iakNsYXNzKGVsZW1lbnQpO1xuICByZXR1cm4gY25hbWUgPT09ICdbb2JqZWN0IEhUTUxDYW52YXNFbGVtZW50XSdcbiAgLyogYnJvd3NlciAqL1xuICB8fCBjbmFtZSA9PT0gJ1tvYmplY3QgT2Zmc2NyZWVuQ2FudmFzXScgfHwgY25hbWUgPT09ICdbb2JqZWN0IENhbnZhc10nXG4gIC8qIG5vZGUtY2FudmFzICovXG4gIDtcbn07XG5cbm1vZHVsZS5leHBvcnRzLmlzSW1hZ2UgPSBmdW5jdGlvbiBpc0ltYWdlKGVsZW1lbnQpIHtcbiAgcmV0dXJuIG9iakNsYXNzKGVsZW1lbnQpID09PSAnW29iamVjdCBIVE1MSW1hZ2VFbGVtZW50XSc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5pc0ltYWdlQml0bWFwID0gZnVuY3Rpb24gaXNJbWFnZUJpdG1hcChlbGVtZW50KSB7XG4gIHJldHVybiBvYmpDbGFzcyhlbGVtZW50KSA9PT0gJ1tvYmplY3QgSW1hZ2VCaXRtYXBdJztcbn07XG5cbm1vZHVsZS5leHBvcnRzLmxpbWl0ZXIgPSBmdW5jdGlvbiBsaW1pdGVyKGNvbmN1cnJlbmN5KSB7XG4gIHZhciBhY3RpdmUgPSAwLFxuICAgICAgcXVldWUgPSBbXTtcblxuICBmdW5jdGlvbiByb2xsKCkge1xuICAgIGlmIChhY3RpdmUgPCBjb25jdXJyZW5jeSAmJiBxdWV1ZS5sZW5ndGgpIHtcbiAgICAgIGFjdGl2ZSsrO1xuICAgICAgcXVldWUuc2hpZnQoKSgpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiBsaW1pdChmbikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBxdWV1ZS5wdXNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZm4oKS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgYWN0aXZlLS07XG4gICAgICAgICAgcm9sbCgpO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgYWN0aXZlLS07XG4gICAgICAgICAgcm9sbCgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgcm9sbCgpO1xuICAgIH0pO1xuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMuY2liX3F1YWxpdHlfbmFtZSA9IGZ1bmN0aW9uIGNpYl9xdWFsaXR5X25hbWUobnVtKSB7XG4gIHN3aXRjaCAobnVtKSB7XG4gICAgY2FzZSAwOlxuICAgICAgcmV0dXJuICdwaXhlbGF0ZWQnO1xuXG4gICAgY2FzZSAxOlxuICAgICAgcmV0dXJuICdsb3cnO1xuXG4gICAgY2FzZSAyOlxuICAgICAgcmV0dXJuICdtZWRpdW0nO1xuICB9XG5cbiAgcmV0dXJuICdoaWdoJztcbn07XG5cbm1vZHVsZS5leHBvcnRzLmNpYl9zdXBwb3J0ID0gZnVuY3Rpb24gY2liX3N1cHBvcnQoY3JlYXRlQ2FudmFzKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodHlwZW9mIGNyZWF0ZUltYWdlQml0bWFwID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBjID0gY3JlYXRlQ2FudmFzKDEwMCwgMTAwKTtcbiAgICByZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAoYywgMCwgMCwgMTAwLCAxMDAsIHtcbiAgICAgIHJlc2l6ZVdpZHRoOiAxMCxcbiAgICAgIHJlc2l6ZUhlaWdodDogMTAsXG4gICAgICByZXNpemVRdWFsaXR5OiAnaGlnaCdcbiAgICB9KS50aGVuKGZ1bmN0aW9uIChiaXRtYXApIHtcbiAgICAgIHZhciBzdGF0dXMgPSBiaXRtYXAud2lkdGggPT09IDEwOyAvLyBCcmFuY2ggYmVsb3cgaXMgZmlsdGVyZWQgb24gdXBwZXIgbGV2ZWwuIFdlIGRvIG5vdCBjYWxsIHJlc2l6ZVxuICAgICAgLy8gZGV0ZWN0aW9uIGZvciBiYXNpYyBJbWFnZUJpdG1hcC5cbiAgICAgIC8vXG4gICAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSW1hZ2VCaXRtYXBcbiAgICAgIC8vIG9sZCBDcm9tZSA1MSBoYXMgSW1hZ2VCaXRtYXAgd2l0aG91dCAuY2xvc2UoKS4gVGhlbiB0aGlzIGNvZGVcbiAgICAgIC8vIHdpbGwgdGhyb3cgYW5kIHJldHVybiAnZmFsc2UnIGFzIGV4cGVjdGVkLlxuICAgICAgLy9cblxuICAgICAgYml0bWFwLmNsb3NlKCk7XG4gICAgICBjID0gbnVsbDtcbiAgICAgIHJldHVybiBzdGF0dXM7XG4gICAgfSk7XG4gIH0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy53b3JrZXJfb2Zmc2NyZWVuX2NhbnZhc19zdXBwb3J0ID0gZnVuY3Rpb24gd29ya2VyX29mZnNjcmVlbl9jYW52YXNfc3VwcG9ydCgpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBpZiAodHlwZW9mIE9mZnNjcmVlbkNhbnZhcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIC8vIGlmIE9mZnNjcmVlbkNhbnZhcyBpcyBwcmVzZW50LCB3ZSBhc3N1bWUgYnJvd3NlciBzdXBwb3J0cyBXb3JrZXIgYW5kIGJ1aWx0LWluIFByb21pc2UgYXMgd2VsbFxuICAgICAgcmVzb2x2ZShmYWxzZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gd29ya2VyUGF5bG9hZChzZWxmKSB7XG4gICAgICBpZiAodHlwZW9mIGNyZWF0ZUltYWdlQml0bWFwID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBzZWxmLnBvc3RNZXNzYWdlKGZhbHNlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNhbnZhcyA9IG5ldyBPZmZzY3JlZW5DYW52YXMoMTAsIDEwKTsgLy8gdGVzdCB0aGF0IDJkIGNvbnRleHQgY2FuIGJlIHVzZWQgaW4gd29ya2VyXG5cbiAgICAgICAgdmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgICBjdHgucmVjdCgwLCAwLCAxLCAxKTsgLy8gdGVzdCB0aGF0IGNpYiBjYW4gYmUgdXNlZCB0byByZXR1cm4gaW1hZ2UgYml0bWFwIGZyb20gd29ya2VyXG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKGNhbnZhcywgMCwgMCwgMSwgMSk7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYucG9zdE1lc3NhZ2UodHJ1ZSk7XG4gICAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBzZWxmLnBvc3RNZXNzYWdlKGZhbHNlKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHZhciBjb2RlID0gYnRvYShcIihcIi5jb25jYXQod29ya2VyUGF5bG9hZC50b1N0cmluZygpLCBcIikoc2VsZik7XCIpKTtcbiAgICB2YXIgdyA9IG5ldyBXb3JrZXIoXCJkYXRhOnRleHQvamF2YXNjcmlwdDtiYXNlNjQsXCIuY29uY2F0KGNvZGUpKTtcblxuICAgIHcub25tZXNzYWdlID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZShldi5kYXRhKTtcbiAgICB9O1xuXG4gICAgdy5vbmVycm9yID0gcmVqZWN0O1xuICB9KS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9KTtcbn07IC8vIENoZWNrIGlmIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpLmdldEltYWdlRGF0YSBjYW4gYmUgdXNlZCxcbi8vIEZpcmVGb3ggcmFuZG9taXplcyB0aGUgb3V0cHV0IG9mIHRoYXQgZnVuY3Rpb24gaW4gYHByaXZhY3kucmVzaXN0RmluZ2VycHJpbnRpbmdgIG1vZGVcblxuXG5tb2R1bGUuZXhwb3J0cy5jYW5fdXNlX2NhbnZhcyA9IGZ1bmN0aW9uIGNhbl91c2VfY2FudmFzKGNyZWF0ZUNhbnZhcykge1xuICB2YXIgdXNhYmxlID0gZmFsc2U7XG5cbiAgdHJ5IHtcbiAgICB2YXIgY2FudmFzID0gY3JlYXRlQ2FudmFzKDIsIDEpO1xuICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICB2YXIgZCA9IGN0eC5jcmVhdGVJbWFnZURhdGEoMiwgMSk7XG4gICAgZC5kYXRhWzBdID0gMTI7XG4gICAgZC5kYXRhWzFdID0gMjM7XG4gICAgZC5kYXRhWzJdID0gMzQ7XG4gICAgZC5kYXRhWzNdID0gMjU1O1xuICAgIGQuZGF0YVs0XSA9IDQ1O1xuICAgIGQuZGF0YVs1XSA9IDU2O1xuICAgIGQuZGF0YVs2XSA9IDY3O1xuICAgIGQuZGF0YVs3XSA9IDI1NTtcbiAgICBjdHgucHV0SW1hZ2VEYXRhKGQsIDAsIDApO1xuICAgIGQgPSBudWxsO1xuICAgIGQgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIDIsIDEpO1xuXG4gICAgaWYgKGQuZGF0YVswXSA9PT0gMTIgJiYgZC5kYXRhWzFdID09PSAyMyAmJiBkLmRhdGFbMl0gPT09IDM0ICYmIGQuZGF0YVszXSA9PT0gMjU1ICYmIGQuZGF0YVs0XSA9PT0gNDUgJiYgZC5kYXRhWzVdID09PSA1NiAmJiBkLmRhdGFbNl0gPT09IDY3ICYmIGQuZGF0YVs3XSA9PT0gMjU1KSB7XG4gICAgICB1c2FibGUgPSB0cnVlO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7fVxuXG4gIHJldHVybiB1c2FibGU7XG59OyAvLyBDaGVjayBpZiBjcmVhdGVJbWFnZUJpdG1hcChpbWcsIHN4LCBzeSwgc3csIHNoKSBzaWduYXR1cmUgd29ya3MgY29ycmVjdGx5XG4vLyB3aXRoIEpQRUcgaW1hZ2VzIG9yaWVudGVkIHdpdGggRXhpZjtcbi8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTEyMjA2NzFcbi8vIFRPRE86IHJlbW92ZSBhZnRlciBpdCdzIGZpeGVkIGluIGNocm9tZSBmb3IgYXQgbGVhc3QgMiByZWxlYXNlc1xuXG5cbm1vZHVsZS5leHBvcnRzLmNpYl9jYW5fdXNlX3JlZ2lvbiA9IGZ1bmN0aW9uIGNpYl9jYW5fdXNlX3JlZ2lvbigpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgaWYgKHR5cGVvZiBjcmVhdGVJbWFnZUJpdG1hcCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBpbWFnZSA9IG5ldyBJbWFnZSgpO1xuICAgIGltYWdlLnNyYyA9ICdkYXRhOmltYWdlL2pwZWc7YmFzZTY0LCcgKyAnLzlqLzRRQmlSWGhwWmdBQVRVMEFLZ0FBQUFnQUJRRVNBQU1BQUFBQkFBWUFBQUVhQUFVQUFBQUJBQUFBU2dFYkFBVUFBJyArICdBQUJBQUFBVWdFb0FBTUFBQUFCQUFJQUFBSVRBQU1BQUFBQkFBRUFBQUFBQUFBQUFBQklBQUFBQVFBQUFFZ0FBQUFCLzknICsgJ3NBUXdBRUF3TUVBd01FQkFNRUJRUUVCUVlLQndZR0JnWU5DUW9JQ2c4TkVCQVBEUThPRVJNWUZCRVNGeElPRHhVY0ZSYycgKyAnWkdSc2JHeEFVSFI4ZEdoOFlHaHNhLzlzQVF3RUVCUVVHQlFZTUJ3Y01HaEVQRVJvYUdob2FHaG9hR2hvYUdob2FHaG9hJyArICdHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYS84SUFFUWdBQVFBQ0F3RVJBQUlSQVFNUkEnICsgJ2YvRUFCUUFBUUFBQUFBQUFBQUFBQUFBQUFBQUFBZi94QUFVQVFFQUFBQUFBQUFBQUFBQUFBQUFBQUFBLzlvQURBTUJBQScgKyAnSVFBeEFBQUFGL1AvL0VBQlFRQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUQvMmdBSUFRRUFBUVVDZi8vRUFCUVJBUUFBQUFBJyArICdBQUFBQUFBQUFBQUFBQUFELzJnQUlBUU1CQVQ4QmYvL0VBQlFSQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUQvMmdBSUFRSUInICsgJ0FUOEJmLy9FQUJRUUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFELzJnQUlBUUVBQmo4Q2YvL0VBQlFRQVFBQUFBQUFBQUFBQScgKyAnQUFBQUFBQUFBRC8yZ0FJQVFFQUFUOGhmLy9hQUF3REFRQUNBQU1BQUFBUUgvL0VBQlFSQVFBQUFBQUFBQUFBQUFBQUFBJyArICdBQUFBRC8yZ0FJQVFNQkFUOFFmLy9FQUJRUkFRQUFBQUFBQUFBQUFBQUFBQUFBQUFELzJnQUlBUUlCQVQ4UWYvL0VBQlEnICsgJ1FBUUFBQUFBQUFBQUFBQUFBQUFBQUFBRC8yZ0FJQVFFQUFUOFFmLy9aJztcblxuICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGNyZWF0ZUltYWdlQml0bWFwKGltYWdlLCAwLCAwLCBpbWFnZS53aWR0aCwgaW1hZ2UuaGVpZ2h0KS50aGVuKGZ1bmN0aW9uIChiaXRtYXApIHtcbiAgICAgICAgaWYgKGJpdG1hcC53aWR0aCA9PT0gaW1hZ2Uud2lkdGggJiYgYml0bWFwLmhlaWdodCA9PT0gaW1hZ2UuaGVpZ2h0KSB7XG4gICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShmYWxzZSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgaW1hZ2Uub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiByZXNvbHZlKGZhbHNlKTtcbiAgICB9O1xuICB9KTtcbn07XG5cbn0se31dLDE3OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBNYXRoTGliID0gX2RlcmVxXygnLi9tYXRobGliJyk7XG5cbiAgdmFyIG1hdGhMaWI7XG4gIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG5cbiAgb25tZXNzYWdlID0gZnVuY3Rpb24gb25tZXNzYWdlKGV2KSB7XG4gICAgdmFyIHRpbGVPcHRzID0gZXYuZGF0YS5vcHRzO1xuICAgIHZhciByZXR1cm5CaXRtYXAgPSBmYWxzZTtcblxuICAgIGlmICghdGlsZU9wdHMuc3JjICYmIHRpbGVPcHRzLnNyY0JpdG1hcCkge1xuICAgICAgdmFyIGNhbnZhcyA9IG5ldyBPZmZzY3JlZW5DYW52YXModGlsZU9wdHMud2lkdGgsIHRpbGVPcHRzLmhlaWdodCk7XG4gICAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJywge1xuICAgICAgICBhbHBoYTogQm9vbGVhbih0aWxlT3B0cy5hbHBoYSlcbiAgICAgIH0pO1xuICAgICAgY3R4LmRyYXdJbWFnZSh0aWxlT3B0cy5zcmNCaXRtYXAsIDAsIDApO1xuICAgICAgdGlsZU9wdHMuc3JjID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCB0aWxlT3B0cy53aWR0aCwgdGlsZU9wdHMuaGVpZ2h0KS5kYXRhO1xuICAgICAgY2FudmFzLndpZHRoID0gY2FudmFzLmhlaWdodCA9IDA7XG4gICAgICBjYW52YXMgPSBudWxsO1xuICAgICAgdGlsZU9wdHMuc3JjQml0bWFwLmNsb3NlKCk7XG4gICAgICB0aWxlT3B0cy5zcmNCaXRtYXAgPSBudWxsO1xuICAgICAgcmV0dXJuQml0bWFwID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoIW1hdGhMaWIpIG1hdGhMaWIgPSBuZXcgTWF0aExpYihldi5kYXRhLmZlYXR1cmVzKTsgLy8gVXNlIG11bHRpbWF0aCdzIHN5bmMgYXV0by1pbml0LiBBdm9pZCBQcm9taXNlIHVzZSBpbiBvbGQgYnJvd3NlcnMsXG4gICAgLy8gYmVjYXVzZSBwb2x5ZmlsbHMgYXJlIG5vdCBwcm9wYWdhdGVkIHRvIHdlYndvcmtlci5cblxuICAgIHZhciBkYXRhID0gbWF0aExpYi5yZXNpemVBbmRVbnNoYXJwKHRpbGVPcHRzKTtcblxuICAgIGlmIChyZXR1cm5CaXRtYXApIHtcbiAgICAgIHZhciB0b0ltYWdlRGF0YSA9IG5ldyBJbWFnZURhdGEobmV3IFVpbnQ4Q2xhbXBlZEFycmF5KGRhdGEpLCB0aWxlT3B0cy50b1dpZHRoLCB0aWxlT3B0cy50b0hlaWdodCk7XG5cbiAgICAgIHZhciBfY2FudmFzID0gbmV3IE9mZnNjcmVlbkNhbnZhcyh0aWxlT3B0cy50b1dpZHRoLCB0aWxlT3B0cy50b0hlaWdodCk7XG5cbiAgICAgIHZhciBfY3R4ID0gX2NhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICAgICAgYWxwaGE6IEJvb2xlYW4odGlsZU9wdHMuYWxwaGEpXG4gICAgICB9KTtcblxuICAgICAgX2N0eC5wdXRJbWFnZURhdGEodG9JbWFnZURhdGEsIDAsIDApO1xuXG4gICAgICBjcmVhdGVJbWFnZUJpdG1hcChfY2FudmFzKS50aGVuKGZ1bmN0aW9uIChiaXRtYXApIHtcbiAgICAgICAgcG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgIGJpdG1hcDogYml0bWFwXG4gICAgICAgIH0sIFtiaXRtYXBdKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBwb3N0TWVzc2FnZSh7XG4gICAgICAgIGRhdGE6IGRhdGFcbiAgICAgIH0sIFtkYXRhLmJ1ZmZlcl0pO1xuICAgIH1cbiAgfTtcbn07XG5cbn0se1wiLi9tYXRobGliXCI6MX1dLDE4OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIENhbGN1bGF0ZSBHYXVzc2lhbiBibHVyIG9mIGFuIGltYWdlIHVzaW5nIElJUiBmaWx0ZXJcbi8vIFRoZSBtZXRob2QgaXMgdGFrZW4gZnJvbSBJbnRlbCdzIHdoaXRlIHBhcGVyIGFuZCBjb2RlIGV4YW1wbGUgYXR0YWNoZWQgdG8gaXQ6XG4vLyBodHRwczovL3NvZnR3YXJlLmludGVsLmNvbS9lbi11cy9hcnRpY2xlcy9paXItZ2F1c3NpYW4tYmx1ci1maWx0ZXJcbi8vIC1pbXBsZW1lbnRhdGlvbi11c2luZy1pbnRlbC1hZHZhbmNlZC12ZWN0b3ItZXh0ZW5zaW9uc1xuXG52YXIgYTAsIGExLCBhMiwgYTMsIGIxLCBiMiwgbGVmdF9jb3JuZXIsIHJpZ2h0X2Nvcm5lcjtcblxuZnVuY3Rpb24gZ2F1c3NDb2VmKHNpZ21hKSB7XG4gIGlmIChzaWdtYSA8IDAuNSkge1xuICAgIHNpZ21hID0gMC41O1xuICB9XG5cbiAgdmFyIGEgPSBNYXRoLmV4cCgwLjcyNiAqIDAuNzI2KSAvIHNpZ21hLFxuICAgICAgZzEgPSBNYXRoLmV4cCgtYSksXG4gICAgICBnMiA9IE1hdGguZXhwKC0yICogYSksXG4gICAgICBrID0gKDEgLSBnMSkgKiAoMSAtIGcxKSAvICgxICsgMiAqIGEgKiBnMSAtIGcyKTtcblxuICBhMCA9IGs7XG4gIGExID0gayAqIChhIC0gMSkgKiBnMTtcbiAgYTIgPSBrICogKGEgKyAxKSAqIGcxO1xuICBhMyA9IC1rICogZzI7XG4gIGIxID0gMiAqIGcxO1xuICBiMiA9IC1nMjtcbiAgbGVmdF9jb3JuZXIgPSAoYTAgKyBhMSkgLyAoMSAtIGIxIC0gYjIpO1xuICByaWdodF9jb3JuZXIgPSAoYTIgKyBhMykgLyAoMSAtIGIxIC0gYjIpO1xuXG4gIC8vIEF0dGVtcHQgdG8gZm9yY2UgdHlwZSB0byBGUDMyLlxuICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShbIGEwLCBhMSwgYTIsIGEzLCBiMSwgYjIsIGxlZnRfY29ybmVyLCByaWdodF9jb3JuZXIgXSk7XG59XG5cbmZ1bmN0aW9uIGNvbnZvbHZlTW9ubzE2KHNyYywgb3V0LCBsaW5lLCBjb2VmZiwgd2lkdGgsIGhlaWdodCkge1xuICAvLyB0YWtlcyBzcmMgaW1hZ2UgYW5kIHdyaXRlcyB0aGUgYmx1cnJlZCBhbmQgdHJhbnNwb3NlZCByZXN1bHQgaW50byBvdXRcblxuICB2YXIgcHJldl9zcmMsIGN1cnJfc3JjLCBjdXJyX291dCwgcHJldl9vdXQsIHByZXZfcHJldl9vdXQ7XG4gIHZhciBzcmNfaW5kZXgsIG91dF9pbmRleCwgbGluZV9pbmRleDtcbiAgdmFyIGksIGo7XG4gIHZhciBjb2VmZl9hMCwgY29lZmZfYTEsIGNvZWZmX2IxLCBjb2VmZl9iMjtcblxuICBmb3IgKGkgPSAwOyBpIDwgaGVpZ2h0OyBpKyspIHtcbiAgICBzcmNfaW5kZXggPSBpICogd2lkdGg7XG4gICAgb3V0X2luZGV4ID0gaTtcbiAgICBsaW5lX2luZGV4ID0gMDtcblxuICAgIC8vIGxlZnQgdG8gcmlnaHRcbiAgICBwcmV2X3NyYyA9IHNyY1tzcmNfaW5kZXhdO1xuICAgIHByZXZfcHJldl9vdXQgPSBwcmV2X3NyYyAqIGNvZWZmWzZdO1xuICAgIHByZXZfb3V0ID0gcHJldl9wcmV2X291dDtcblxuICAgIGNvZWZmX2EwID0gY29lZmZbMF07XG4gICAgY29lZmZfYTEgPSBjb2VmZlsxXTtcbiAgICBjb2VmZl9iMSA9IGNvZWZmWzRdO1xuICAgIGNvZWZmX2IyID0gY29lZmZbNV07XG5cbiAgICBmb3IgKGogPSAwOyBqIDwgd2lkdGg7IGorKykge1xuICAgICAgY3Vycl9zcmMgPSBzcmNbc3JjX2luZGV4XTtcblxuICAgICAgY3Vycl9vdXQgPSBjdXJyX3NyYyAqIGNvZWZmX2EwICtcbiAgICAgICAgICAgICAgICAgcHJldl9zcmMgKiBjb2VmZl9hMSArXG4gICAgICAgICAgICAgICAgIHByZXZfb3V0ICogY29lZmZfYjEgK1xuICAgICAgICAgICAgICAgICBwcmV2X3ByZXZfb3V0ICogY29lZmZfYjI7XG5cbiAgICAgIHByZXZfcHJldl9vdXQgPSBwcmV2X291dDtcbiAgICAgIHByZXZfb3V0ID0gY3Vycl9vdXQ7XG4gICAgICBwcmV2X3NyYyA9IGN1cnJfc3JjO1xuXG4gICAgICBsaW5lW2xpbmVfaW5kZXhdID0gcHJldl9vdXQ7XG4gICAgICBsaW5lX2luZGV4Kys7XG4gICAgICBzcmNfaW5kZXgrKztcbiAgICB9XG5cbiAgICBzcmNfaW5kZXgtLTtcbiAgICBsaW5lX2luZGV4LS07XG4gICAgb3V0X2luZGV4ICs9IGhlaWdodCAqICh3aWR0aCAtIDEpO1xuXG4gICAgLy8gcmlnaHQgdG8gbGVmdFxuICAgIHByZXZfc3JjID0gc3JjW3NyY19pbmRleF07XG4gICAgcHJldl9wcmV2X291dCA9IHByZXZfc3JjICogY29lZmZbN107XG4gICAgcHJldl9vdXQgPSBwcmV2X3ByZXZfb3V0O1xuICAgIGN1cnJfc3JjID0gcHJldl9zcmM7XG5cbiAgICBjb2VmZl9hMCA9IGNvZWZmWzJdO1xuICAgIGNvZWZmX2ExID0gY29lZmZbM107XG5cbiAgICBmb3IgKGogPSB3aWR0aCAtIDE7IGogPj0gMDsgai0tKSB7XG4gICAgICBjdXJyX291dCA9IGN1cnJfc3JjICogY29lZmZfYTAgK1xuICAgICAgICAgICAgICAgICBwcmV2X3NyYyAqIGNvZWZmX2ExICtcbiAgICAgICAgICAgICAgICAgcHJldl9vdXQgKiBjb2VmZl9iMSArXG4gICAgICAgICAgICAgICAgIHByZXZfcHJldl9vdXQgKiBjb2VmZl9iMjtcblxuICAgICAgcHJldl9wcmV2X291dCA9IHByZXZfb3V0O1xuICAgICAgcHJldl9vdXQgPSBjdXJyX291dDtcblxuICAgICAgcHJldl9zcmMgPSBjdXJyX3NyYztcbiAgICAgIGN1cnJfc3JjID0gc3JjW3NyY19pbmRleF07XG5cbiAgICAgIG91dFtvdXRfaW5kZXhdID0gbGluZVtsaW5lX2luZGV4XSArIHByZXZfb3V0O1xuXG4gICAgICBzcmNfaW5kZXgtLTtcbiAgICAgIGxpbmVfaW5kZXgtLTtcbiAgICAgIG91dF9pbmRleCAtPSBoZWlnaHQ7XG4gICAgfVxuICB9XG59XG5cblxuZnVuY3Rpb24gYmx1ck1vbm8xNihzcmMsIHdpZHRoLCBoZWlnaHQsIHJhZGl1cykge1xuICAvLyBRdWljayBleGl0IG9uIHplcm8gcmFkaXVzXG4gIGlmICghcmFkaXVzKSB7IHJldHVybjsgfVxuXG4gIHZhciBvdXQgICAgICA9IG5ldyBVaW50MTZBcnJheShzcmMubGVuZ3RoKSxcbiAgICAgIHRtcF9saW5lID0gbmV3IEZsb2F0MzJBcnJheShNYXRoLm1heCh3aWR0aCwgaGVpZ2h0KSk7XG5cbiAgdmFyIGNvZWZmID0gZ2F1c3NDb2VmKHJhZGl1cyk7XG5cbiAgY29udm9sdmVNb25vMTYoc3JjLCBvdXQsIHRtcF9saW5lLCBjb2VmZiwgd2lkdGgsIGhlaWdodCk7XG4gIGNvbnZvbHZlTW9ubzE2KG91dCwgc3JjLCB0bXBfbGluZSwgY29lZmYsIGhlaWdodCwgd2lkdGgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJsdXJNb25vMTY7XG5cbn0se31dLDE5OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbmlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yO1xuICAgICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcbiAgICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvcjtcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZTtcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKCk7XG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3I7XG4gICAgfVxuICB9O1xufVxuXG59LHt9XSwyMDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cblxudmFyIGFzc2lnbiAgICAgICAgID0gX2RlcmVxXygnb2JqZWN0LWFzc2lnbicpO1xudmFyIGJhc2U2NGRlY29kZSAgID0gX2RlcmVxXygnLi9saWIvYmFzZTY0ZGVjb2RlJyk7XG52YXIgaGFzV2ViQXNzZW1ibHkgPSBfZGVyZXFfKCcuL2xpYi93YV9kZXRlY3QnKTtcblxuXG52YXIgREVGQVVMVF9PUFRJT05TID0ge1xuICBqczogdHJ1ZSxcbiAgd2FzbTogdHJ1ZVxufTtcblxuXG5mdW5jdGlvbiBNdWx0aU1hdGgob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTXVsdGlNYXRoKSkgcmV0dXJuIG5ldyBNdWx0aU1hdGgob3B0aW9ucyk7XG5cbiAgdmFyIG9wdHMgPSBhc3NpZ24oe30sIERFRkFVTFRfT1BUSU9OUywgb3B0aW9ucyB8fCB7fSk7XG5cbiAgdGhpcy5vcHRpb25zICAgICAgICAgPSBvcHRzO1xuXG4gIHRoaXMuX19jYWNoZSAgICAgICAgID0ge307XG5cbiAgdGhpcy5fX2luaXRfcHJvbWlzZSAgPSBudWxsO1xuICB0aGlzLl9fbW9kdWxlcyAgICAgICA9IG9wdHMubW9kdWxlcyB8fCB7fTtcbiAgdGhpcy5fX21lbW9yeSAgICAgICAgPSBudWxsO1xuICB0aGlzLl9fd2FzbSAgICAgICAgICA9IHt9O1xuXG4gIHRoaXMuX19pc0xFID0gKChuZXcgVWludDMyQXJyYXkoKG5ldyBVaW50OEFycmF5KFsgMSwgMCwgMCwgMCBdKSkuYnVmZmVyKSlbMF0gPT09IDEpO1xuXG4gIGlmICghdGhpcy5vcHRpb25zLmpzICYmICF0aGlzLm9wdGlvbnMud2FzbSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbWF0aGxpYjogYXQgbGVhc3QgXCJqc1wiIG9yIFwid2FzbVwiIHNob3VsZCBiZSBlbmFibGVkJyk7XG4gIH1cbn1cblxuXG5NdWx0aU1hdGgucHJvdG90eXBlLmhhc193YXNtID0gaGFzV2ViQXNzZW1ibHk7XG5cblxuTXVsdGlNYXRoLnByb3RvdHlwZS51c2UgPSBmdW5jdGlvbiAobW9kdWxlKSB7XG4gIHRoaXMuX19tb2R1bGVzW21vZHVsZS5uYW1lXSA9IG1vZHVsZTtcblxuICAvLyBQaW4gdGhlIGJlc3QgcG9zc2libGUgaW1wbGVtZW50YXRpb25cbiAgaWYgKHRoaXMub3B0aW9ucy53YXNtICYmIHRoaXMuaGFzX3dhc20oKSAmJiBtb2R1bGUud2FzbV9mbikge1xuICAgIHRoaXNbbW9kdWxlLm5hbWVdID0gbW9kdWxlLndhc21fZm47XG4gIH0gZWxzZSB7XG4gICAgdGhpc1ttb2R1bGUubmFtZV0gPSBtb2R1bGUuZm47XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cblxuTXVsdGlNYXRoLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5fX2luaXRfcHJvbWlzZSkgcmV0dXJuIHRoaXMuX19pbml0X3Byb21pc2U7XG5cbiAgaWYgKCF0aGlzLm9wdGlvbnMuanMgJiYgdGhpcy5vcHRpb25zLndhc20gJiYgIXRoaXMuaGFzX3dhc20oKSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ21hdGhsaWI6IG9ubHkgXCJ3YXNtXCIgd2FzIGVuYWJsZWQsIGJ1dCBpdFxcJ3Mgbm90IHN1cHBvcnRlZCcpKTtcbiAgfVxuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLl9faW5pdF9wcm9taXNlID0gUHJvbWlzZS5hbGwoT2JqZWN0LmtleXMoc2VsZi5fX21vZHVsZXMpLm1hcChmdW5jdGlvbiAobmFtZSkge1xuICAgIHZhciBtb2R1bGUgPSBzZWxmLl9fbW9kdWxlc1tuYW1lXTtcblxuICAgIGlmICghc2VsZi5vcHRpb25zLndhc20gfHwgIXNlbGYuaGFzX3dhc20oKSB8fCAhbW9kdWxlLndhc21fZm4pIHJldHVybiBudWxsO1xuXG4gICAgLy8gSWYgYWxyZWFkeSBjb21waWxlZCAtIGV4aXRcbiAgICBpZiAoc2VsZi5fX3dhc21bbmFtZV0pIHJldHVybiBudWxsO1xuXG4gICAgLy8gQ29tcGlsZSB3YXNtIHNvdXJjZVxuICAgIHJldHVybiBXZWJBc3NlbWJseS5jb21waWxlKHNlbGYuX19iYXNlNjRkZWNvZGUobW9kdWxlLndhc21fc3JjKSlcbiAgICAgIC50aGVuKGZ1bmN0aW9uIChtKSB7IHNlbGYuX193YXNtW25hbWVdID0gbTsgfSk7XG4gIH0pKVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlbGY7IH0pO1xuXG4gIHJldHVybiB0aGlzLl9faW5pdF9wcm9taXNlO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gTWV0aG9kcyBiZWxvdyBhcmUgZm9yIGludGVybmFsIHVzZSBmcm9tIHBsdWdpbnNcblxuXG4vLyBTaW1wbGUgZGVjb2RlIGJhc2U2NCB0byB0eXBlZCBhcnJheS4gVXNlZnVsIHRvIGxvYWQgZW1iZWRkZWQgd2ViYXNzZW1ibHlcbi8vIGNvZGUuIFlvdSBwcm9iYWJseSBkb24ndCBuZWVkIHRvIGNhbGwgdGhpcyBtZXRob2QgZGlyZWN0bHkuXG4vL1xuTXVsdGlNYXRoLnByb3RvdHlwZS5fX2Jhc2U2NGRlY29kZSA9IGJhc2U2NGRlY29kZTtcblxuXG4vLyBJbmNyZWFzZSBjdXJyZW50IG1lbW9yeSB0byBpbmNsdWRlIHNwZWNpZmllZCBudW1iZXIgb2YgYnl0ZXMuIERvIG5vdGhpbmcgaWZcbi8vIHNpemUgaXMgYWxyZWFkeSBvay4gWW91IHByb2JhYmx5IGRvbid0IG5lZWQgdG8gY2FsbCB0aGlzIG1ldGhvZCBkaXJlY3RseSxcbi8vIGJlY2F1c2UgaXQgd2lsbCBiZSBpbnZva2VkIGZyb20gYC5fX2luc3RhbmNlKClgLlxuLy9cbk11bHRpTWF0aC5wcm90b3R5cGUuX19yZWFsbG9jYXRlID0gZnVuY3Rpb24gbWVtX2dyb3dfdG8oYnl0ZXMpIHtcbiAgaWYgKCF0aGlzLl9fbWVtb3J5KSB7XG4gICAgdGhpcy5fX21lbW9yeSA9IG5ldyBXZWJBc3NlbWJseS5NZW1vcnkoe1xuICAgICAgaW5pdGlhbDogTWF0aC5jZWlsKGJ5dGVzIC8gKDY0ICogMTAyNCkpXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMuX19tZW1vcnk7XG4gIH1cblxuICB2YXIgbWVtX3NpemUgPSB0aGlzLl9fbWVtb3J5LmJ1ZmZlci5ieXRlTGVuZ3RoO1xuXG4gIGlmIChtZW1fc2l6ZSA8IGJ5dGVzKSB7XG4gICAgdGhpcy5fX21lbW9yeS5ncm93KE1hdGguY2VpbCgoYnl0ZXMgLSBtZW1fc2l6ZSkgLyAoNjQgKiAxMDI0KSkpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX19tZW1vcnk7XG59O1xuXG5cbi8vIFJldHVybnMgaW5zdGFudGluYXRlZCB3ZWJhc3NlbWJseSBpdGVtIGJ5IG5hbWUsIHdpdGggc3BlY2lmaWVkIG1lbW9yeSBzaXplXG4vLyBhbmQgZW52aXJvbm1lbnQuXG4vLyAtIHVzZSBjYWNoZSBpZiBhdmFpbGFibGVcbi8vIC0gZG8gc3luYyBtb2R1bGUgaW5pdCwgaWYgYXN5bmMgaW5pdCB3YXMgbm90IGNhbGxlZCBlYXJsaWVyXG4vLyAtIGFsbG9jYXRlIG1lbW9yeSBpZiBub3QgZW5vdWd0aFxuLy8gLSBjYW4gZXhwb3J0IGZ1bmN0aW9ucyB0byB3ZWJhc3NlbWJseSB2aWEgXCJlbnZfZXh0cmFcIixcbi8vICAgZm9yIGV4YW1wbGUsIHsgZXhwOiBNYXRoLmV4cCB9XG4vL1xuTXVsdGlNYXRoLnByb3RvdHlwZS5fX2luc3RhbmNlID0gZnVuY3Rpb24gaW5zdGFuY2UobmFtZSwgbWVtc2l6ZSwgZW52X2V4dHJhKSB7XG4gIGlmIChtZW1zaXplKSB0aGlzLl9fcmVhbGxvY2F0ZShtZW1zaXplKTtcblxuICAvLyBJZiAuaW5pdCgpIHdhcyBub3QgY2FsbGVkLCBkbyBzeW5jIGNvbXBpbGVcbiAgaWYgKCF0aGlzLl9fd2FzbVtuYW1lXSkge1xuICAgIHZhciBtb2R1bGUgPSB0aGlzLl9fbW9kdWxlc1tuYW1lXTtcbiAgICB0aGlzLl9fd2FzbVtuYW1lXSA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUodGhpcy5fX2Jhc2U2NGRlY29kZShtb2R1bGUud2FzbV9zcmMpKTtcbiAgfVxuXG4gIGlmICghdGhpcy5fX2NhY2hlW25hbWVdKSB7XG4gICAgdmFyIGVudl9iYXNlID0ge1xuICAgICAgbWVtb3J5QmFzZTogMCxcbiAgICAgIG1lbW9yeTogdGhpcy5fX21lbW9yeSxcbiAgICAgIHRhYmxlQmFzZTogMCxcbiAgICAgIHRhYmxlOiBuZXcgV2ViQXNzZW1ibHkuVGFibGUoeyBpbml0aWFsOiAwLCBlbGVtZW50OiAnYW55ZnVuYycgfSlcbiAgICB9O1xuXG4gICAgdGhpcy5fX2NhY2hlW25hbWVdID0gbmV3IFdlYkFzc2VtYmx5Lkluc3RhbmNlKHRoaXMuX193YXNtW25hbWVdLCB7XG4gICAgICBlbnY6IGFzc2lnbihlbnZfYmFzZSwgZW52X2V4dHJhIHx8IHt9KVxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX19jYWNoZVtuYW1lXTtcbn07XG5cblxuLy8gSGVscGVyIHRvIGNhbGN1bGF0ZSBtZW1vcnkgYWxpZ2ggZm9yIHBvaW50ZXJzLiBXZWJhc3NlbWJseSBkb2VzIG5vdCByZXF1aXJlXG4vLyB0aGlzLCBidXQgeW91IG1heSB3aXNoIHRvIGV4cGVyaW1lbnQuIERlZmF1bHQgYmFzZSA9IDg7XG4vL1xuTXVsdGlNYXRoLnByb3RvdHlwZS5fX2FsaWduID0gZnVuY3Rpb24gYWxpZ24obnVtYmVyLCBiYXNlKSB7XG4gIGJhc2UgPSBiYXNlIHx8IDg7XG4gIHZhciByZW1pbmRlciA9IG51bWJlciAlIGJhc2U7XG4gIHJldHVybiBudW1iZXIgKyAocmVtaW5kZXIgPyBiYXNlIC0gcmVtaW5kZXIgOiAwKTtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBNdWx0aU1hdGg7XG5cbn0se1wiLi9saWIvYmFzZTY0ZGVjb2RlXCI6MjEsXCIuL2xpYi93YV9kZXRlY3RcIjoyMixcIm9iamVjdC1hc3NpZ25cIjoyM31dLDIxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxuXG52YXIgQkFTRTY0X01BUCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJztcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGJhc2U2NGRlY29kZShzdHIpIHtcbiAgdmFyIGlucHV0ID0gc3RyLnJlcGxhY2UoL1tcXHJcXG49XS9nLCAnJyksIC8vIHJlbW92ZSBDUi9MRiAmIHBhZGRpbmcgdG8gc2ltcGxpZnkgc2NhblxuICAgICAgbWF4ICAgPSBpbnB1dC5sZW5ndGg7XG5cbiAgdmFyIG91dCA9IG5ldyBVaW50OEFycmF5KChtYXggKiAzKSA+PiAyKTtcblxuICAvLyBDb2xsZWN0IGJ5IDYqNCBiaXRzICgzIGJ5dGVzKVxuXG4gIHZhciBiaXRzID0gMDtcbiAgdmFyIHB0ciAgPSAwO1xuXG4gIGZvciAodmFyIGlkeCA9IDA7IGlkeCA8IG1heDsgaWR4KyspIHtcbiAgICBpZiAoKGlkeCAlIDQgPT09IDApICYmIGlkeCkge1xuICAgICAgb3V0W3B0cisrXSA9IChiaXRzID4+IDE2KSAmIDB4RkY7XG4gICAgICBvdXRbcHRyKytdID0gKGJpdHMgPj4gOCkgJiAweEZGO1xuICAgICAgb3V0W3B0cisrXSA9IGJpdHMgJiAweEZGO1xuICAgIH1cblxuICAgIGJpdHMgPSAoYml0cyA8PCA2KSB8IEJBU0U2NF9NQVAuaW5kZXhPZihpbnB1dC5jaGFyQXQoaWR4KSk7XG4gIH1cblxuICAvLyBEdW1wIHRhaWxcblxuICB2YXIgdGFpbGJpdHMgPSAobWF4ICUgNCkgKiA2O1xuXG4gIGlmICh0YWlsYml0cyA9PT0gMCkge1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAxNikgJiAweEZGO1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiA4KSAmIDB4RkY7XG4gICAgb3V0W3B0cisrXSA9IGJpdHMgJiAweEZGO1xuICB9IGVsc2UgaWYgKHRhaWxiaXRzID09PSAxOCkge1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAxMCkgJiAweEZGO1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAyKSAmIDB4RkY7XG4gIH0gZWxzZSBpZiAodGFpbGJpdHMgPT09IDEyKSB7XG4gICAgb3V0W3B0cisrXSA9IChiaXRzID4+IDQpICYgMHhGRjtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59O1xuXG59LHt9XSwyMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cblxudmFyIHdhO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaGFzV2ViQXNzZW1ibHkoKSB7XG4gIC8vIHVzZSBjYWNoZSBpZiBjYWxsZWQgYmVmb3JlO1xuICBpZiAodHlwZW9mIHdhICE9PSAndW5kZWZpbmVkJykgcmV0dXJuIHdhO1xuXG4gIHdhID0gZmFsc2U7XG5cbiAgaWYgKHR5cGVvZiBXZWJBc3NlbWJseSA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiB3YTtcblxuICAvLyBJZiBXZWJBc3NlbmJseSBpcyBkaXNhYmxlZCwgY29kZSBjYW4gdGhyb3cgb24gY29tcGlsZVxuICB0cnkge1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9icmlvbi9taW4td2FzbS1mYWlsL2Jsb2IvbWFzdGVyL21pbi13YXNtLWZhaWwuaW4uanNcbiAgICAvLyBBZGRpdGlvbmFsIGNoZWNrIHRoYXQgV0EgaW50ZXJuYWxzIGFyZSBjb3JyZWN0XG5cbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBjb21tYS1zcGFjaW5nLCBtYXgtbGVuICovXG4gICAgdmFyIGJpbiAgICAgID0gbmV3IFVpbnQ4QXJyYXkoWyAwLDk3LDExNSwxMDksMSwwLDAsMCwxLDYsMSw5NiwxLDEyNywxLDEyNywzLDIsMSwwLDUsMywxLDAsMSw3LDgsMSw0LDExNiwxMDEsMTE1LDExNiwwLDAsMTAsMTYsMSwxNCwwLDMyLDAsNjUsMSw1NCwyLDAsMzIsMCw0MCwyLDAsMTEgXSk7XG4gICAgdmFyIG1vZHVsZSAgID0gbmV3IFdlYkFzc2VtYmx5Lk1vZHVsZShiaW4pO1xuICAgIHZhciBpbnN0YW5jZSA9IG5ldyBXZWJBc3NlbWJseS5JbnN0YW5jZShtb2R1bGUsIHt9KTtcblxuICAgIC8vIHRlc3Qgc3RvcmluZyB0byBhbmQgbG9hZGluZyBmcm9tIGEgbm9uLXplcm8gbG9jYXRpb24gdmlhIGEgcGFyYW1ldGVyLlxuICAgIC8vIFNhZmFyaSBvbiBpT1MgMTEuMi41IHJldHVybnMgMCB1bmV4cGVjdGVkbHkgYXQgbm9uLXplcm8gbG9jYXRpb25zXG4gICAgaWYgKGluc3RhbmNlLmV4cG9ydHMudGVzdCg0KSAhPT0gMCkgd2EgPSB0cnVlO1xuXG4gICAgcmV0dXJuIHdhO1xuICB9IGNhdGNoIChfXykge31cblxuICByZXR1cm4gd2E7XG59O1xuXG59LHt9XSwyMzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xudmFyIGdldE93blByb3BlcnR5U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIHByb3BJc0VudW1lcmFibGUgPSBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG5mdW5jdGlvbiB0b09iamVjdCh2YWwpIHtcblx0aWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IHVuZGVmaW5lZCkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ09iamVjdC5hc3NpZ24gY2Fubm90IGJlIGNhbGxlZCB3aXRoIG51bGwgb3IgdW5kZWZpbmVkJyk7XG5cdH1cblxuXHRyZXR1cm4gT2JqZWN0KHZhbCk7XG59XG5cbmZ1bmN0aW9uIHNob3VsZFVzZU5hdGl2ZSgpIHtcblx0dHJ5IHtcblx0XHRpZiAoIU9iamVjdC5hc3NpZ24pIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBEZXRlY3QgYnVnZ3kgcHJvcGVydHkgZW51bWVyYXRpb24gb3JkZXIgaW4gb2xkZXIgVjggdmVyc2lvbnMuXG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD00MTE4XG5cdFx0dmFyIHRlc3QxID0gbmV3IFN0cmluZygnYWJjJyk7ICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ldy13cmFwcGVyc1xuXHRcdHRlc3QxWzVdID0gJ2RlJztcblx0XHRpZiAoT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGVzdDEpWzBdID09PSAnNScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMDU2XG5cdFx0dmFyIHRlc3QyID0ge307XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCAxMDsgaSsrKSB7XG5cdFx0XHR0ZXN0MlsnXycgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGkpXSA9IGk7XG5cdFx0fVxuXHRcdHZhciBvcmRlcjIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0ZXN0MikubWFwKGZ1bmN0aW9uIChuKSB7XG5cdFx0XHRyZXR1cm4gdGVzdDJbbl07XG5cdFx0fSk7XG5cdFx0aWYgKG9yZGVyMi5qb2luKCcnKSAhPT0gJzAxMjM0NTY3ODknKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzA1NlxuXHRcdHZhciB0ZXN0MyA9IHt9O1xuXHRcdCdhYmNkZWZnaGlqa2xtbm9wcXJzdCcuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24gKGxldHRlcikge1xuXHRcdFx0dGVzdDNbbGV0dGVyXSA9IGxldHRlcjtcblx0XHR9KTtcblx0XHRpZiAoT2JqZWN0LmtleXMoT2JqZWN0LmFzc2lnbih7fSwgdGVzdDMpKS5qb2luKCcnKSAhPT1cblx0XHRcdFx0J2FiY2RlZmdoaWprbG1ub3BxcnN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlcnIpIHtcblx0XHQvLyBXZSBkb24ndCBleHBlY3QgYW55IG9mIHRoZSBhYm92ZSB0byB0aHJvdywgYnV0IGJldHRlciB0byBiZSBzYWZlLlxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNob3VsZFVzZU5hdGl2ZSgpID8gT2JqZWN0LmFzc2lnbiA6IGZ1bmN0aW9uICh0YXJnZXQsIHNvdXJjZSkge1xuXHR2YXIgZnJvbTtcblx0dmFyIHRvID0gdG9PYmplY3QodGFyZ2V0KTtcblx0dmFyIHN5bWJvbHM7XG5cblx0Zm9yICh2YXIgcyA9IDE7IHMgPCBhcmd1bWVudHMubGVuZ3RoOyBzKyspIHtcblx0XHRmcm9tID0gT2JqZWN0KGFyZ3VtZW50c1tzXSk7XG5cblx0XHRmb3IgKHZhciBrZXkgaW4gZnJvbSkge1xuXHRcdFx0aWYgKGhhc093blByb3BlcnR5LmNhbGwoZnJvbSwga2V5KSkge1xuXHRcdFx0XHR0b1trZXldID0gZnJvbVtrZXldO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChnZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcblx0XHRcdHN5bWJvbHMgPSBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMoZnJvbSk7XG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHN5bWJvbHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0aWYgKHByb3BJc0VudW1lcmFibGUuY2FsbChmcm9tLCBzeW1ib2xzW2ldKSkge1xuXHRcdFx0XHRcdHRvW3N5bWJvbHNbaV1dID0gZnJvbVtzeW1ib2xzW2ldXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0bztcbn07XG5cbn0se31dLDI0OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbnZhciBidW5kbGVGbiA9IGFyZ3VtZW50c1szXTtcbnZhciBzb3VyY2VzID0gYXJndW1lbnRzWzRdO1xudmFyIGNhY2hlID0gYXJndW1lbnRzWzVdO1xuXG52YXIgc3RyaW5naWZ5ID0gSlNPTi5zdHJpbmdpZnk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGZuLCBvcHRpb25zKSB7XG4gICAgdmFyIHdrZXk7XG4gICAgdmFyIGNhY2hlS2V5cyA9IE9iamVjdC5rZXlzKGNhY2hlKTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBsID0gY2FjaGVLZXlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICB2YXIga2V5ID0gY2FjaGVLZXlzW2ldO1xuICAgICAgICB2YXIgZXhwID0gY2FjaGVba2V5XS5leHBvcnRzO1xuICAgICAgICAvLyBVc2luZyBiYWJlbCBhcyBhIHRyYW5zcGlsZXIgdG8gdXNlIGVzbW9kdWxlLCB0aGUgZXhwb3J0IHdpbGwgYWx3YXlzXG4gICAgICAgIC8vIGJlIGFuIG9iamVjdCB3aXRoIHRoZSBkZWZhdWx0IGV4cG9ydCBhcyBhIHByb3BlcnR5IG9mIGl0LiBUbyBlbnN1cmVcbiAgICAgICAgLy8gdGhlIGV4aXN0aW5nIGFwaSBhbmQgYmFiZWwgZXNtb2R1bGUgZXhwb3J0cyBhcmUgYm90aCBzdXBwb3J0ZWQgd2VcbiAgICAgICAgLy8gY2hlY2sgZm9yIGJvdGhcbiAgICAgICAgaWYgKGV4cCA9PT0gZm4gfHwgZXhwICYmIGV4cC5kZWZhdWx0ID09PSBmbikge1xuICAgICAgICAgICAgd2tleSA9IGtleTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF3a2V5KSB7XG4gICAgICAgIHdrZXkgPSBNYXRoLmZsb29yKE1hdGgucG93KDE2LCA4KSAqIE1hdGgucmFuZG9tKCkpLnRvU3RyaW5nKDE2KTtcbiAgICAgICAgdmFyIHdjYWNoZSA9IHt9O1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGNhY2hlS2V5cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBjYWNoZUtleXNbaV07XG4gICAgICAgICAgICB3Y2FjaGVba2V5XSA9IGtleTtcbiAgICAgICAgfVxuICAgICAgICBzb3VyY2VzW3drZXldID0gW1xuICAgICAgICAgICAgJ2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeycgKyBmbiArICcoc2VsZik7IH0nLFxuICAgICAgICAgICAgd2NhY2hlXG4gICAgICAgIF07XG4gICAgfVxuICAgIHZhciBza2V5ID0gTWF0aC5mbG9vcihNYXRoLnBvdygxNiwgOCkgKiBNYXRoLnJhbmRvbSgpKS50b1N0cmluZygxNik7XG5cbiAgICB2YXIgc2NhY2hlID0ge307IHNjYWNoZVt3a2V5XSA9IHdrZXk7XG4gICAgc291cmNlc1tza2V5XSA9IFtcbiAgICAgICAgJ2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeycgK1xuICAgICAgICAgICAgLy8gdHJ5IHRvIGNhbGwgZGVmYXVsdCBpZiBkZWZpbmVkIHRvIGFsc28gc3VwcG9ydCBiYWJlbCBlc21vZHVsZSBleHBvcnRzXG4gICAgICAgICAgICAndmFyIGYgPSByZXF1aXJlKCcgKyBzdHJpbmdpZnkod2tleSkgKyAnKTsnICtcbiAgICAgICAgICAgICcoZi5kZWZhdWx0ID8gZi5kZWZhdWx0IDogZikoc2VsZik7JyArXG4gICAgICAgICd9JyxcbiAgICAgICAgc2NhY2hlXG4gICAgXTtcblxuICAgIHZhciB3b3JrZXJTb3VyY2VzID0ge307XG4gICAgcmVzb2x2ZVNvdXJjZXMoc2tleSk7XG5cbiAgICBmdW5jdGlvbiByZXNvbHZlU291cmNlcyhrZXkpIHtcbiAgICAgICAgd29ya2VyU291cmNlc1trZXldID0gdHJ1ZTtcblxuICAgICAgICBmb3IgKHZhciBkZXBQYXRoIGluIHNvdXJjZXNba2V5XVsxXSkge1xuICAgICAgICAgICAgdmFyIGRlcEtleSA9IHNvdXJjZXNba2V5XVsxXVtkZXBQYXRoXTtcbiAgICAgICAgICAgIGlmICghd29ya2VyU291cmNlc1tkZXBLZXldKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZVNvdXJjZXMoZGVwS2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBzcmMgPSAnKCcgKyBidW5kbGVGbiArICcpKHsnXG4gICAgICAgICsgT2JqZWN0LmtleXMod29ya2VyU291cmNlcykubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBzdHJpbmdpZnkoa2V5KSArICc6WydcbiAgICAgICAgICAgICAgICArIHNvdXJjZXNba2V5XVswXVxuICAgICAgICAgICAgICAgICsgJywnICsgc3RyaW5naWZ5KHNvdXJjZXNba2V5XVsxXSkgKyAnXSdcbiAgICAgICAgICAgIDtcbiAgICAgICAgfSkuam9pbignLCcpXG4gICAgICAgICsgJ30se30sWycgKyBzdHJpbmdpZnkoc2tleSkgKyAnXSknXG4gICAgO1xuXG4gICAgdmFyIFVSTCA9IHdpbmRvdy5VUkwgfHwgd2luZG93LndlYmtpdFVSTCB8fCB3aW5kb3cubW96VVJMIHx8IHdpbmRvdy5tc1VSTDtcblxuICAgIHZhciBibG9iID0gbmV3IEJsb2IoW3NyY10sIHsgdHlwZTogJ3RleHQvamF2YXNjcmlwdCcgfSk7XG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5iYXJlKSB7IHJldHVybiBibG9iOyB9XG4gICAgdmFyIHdvcmtlclVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgdmFyIHdvcmtlciA9IG5ldyBXb3JrZXIod29ya2VyVXJsKTtcbiAgICB3b3JrZXIub2JqZWN0VVJMID0gd29ya2VyVXJsO1xuICAgIHJldHVybiB3b3JrZXI7XG59O1xuXG59LHt9XSxcIi9pbmRleC5qc1wiOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxuZnVuY3Rpb24gX3NsaWNlZFRvQXJyYXkoYXJyLCBpKSB7IHJldHVybiBfYXJyYXlXaXRoSG9sZXMoYXJyKSB8fCBfaXRlcmFibGVUb0FycmF5TGltaXQoYXJyLCBpKSB8fCBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkoYXJyLCBpKSB8fCBfbm9uSXRlcmFibGVSZXN0KCk7IH1cblxuZnVuY3Rpb24gX25vbkl0ZXJhYmxlUmVzdCgpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBkZXN0cnVjdHVyZSBub24taXRlcmFibGUgaW5zdGFuY2UuXFxuSW4gb3JkZXIgdG8gYmUgaXRlcmFibGUsIG5vbi1hcnJheSBvYmplY3RzIG11c3QgaGF2ZSBhIFtTeW1ib2wuaXRlcmF0b3JdKCkgbWV0aG9kLlwiKTsgfVxuXG5mdW5jdGlvbiBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkobywgbWluTGVuKSB7IGlmICghbykgcmV0dXJuOyBpZiAodHlwZW9mIG8gPT09IFwic3RyaW5nXCIpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pOyB2YXIgbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKS5zbGljZSg4LCAtMSk7IGlmIChuID09PSBcIk9iamVjdFwiICYmIG8uY29uc3RydWN0b3IpIG4gPSBvLmNvbnN0cnVjdG9yLm5hbWU7IGlmIChuID09PSBcIk1hcFwiIHx8IG4gPT09IFwiU2V0XCIpIHJldHVybiBBcnJheS5mcm9tKG8pOyBpZiAobiA9PT0gXCJBcmd1bWVudHNcIiB8fCAvXig/OlVpfEkpbnQoPzo4fDE2fDMyKSg/OkNsYW1wZWQpP0FycmF5JC8udGVzdChuKSkgcmV0dXJuIF9hcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7IH1cblxuZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkoYXJyLCBsZW4pIHsgaWYgKGxlbiA9PSBudWxsIHx8IGxlbiA+IGFyci5sZW5ndGgpIGxlbiA9IGFyci5sZW5ndGg7IGZvciAodmFyIGkgPSAwLCBhcnIyID0gbmV3IEFycmF5KGxlbik7IGkgPCBsZW47IGkrKykgeyBhcnIyW2ldID0gYXJyW2ldOyB9IHJldHVybiBhcnIyOyB9XG5cbmZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHsgdmFyIF9pID0gYXJyID09IG51bGwgPyBudWxsIDogdHlwZW9mIFN5bWJvbCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBhcnJbU3ltYm9sLml0ZXJhdG9yXSB8fCBhcnJbXCJAQGl0ZXJhdG9yXCJdOyBpZiAoX2kgPT0gbnVsbCkgcmV0dXJuOyB2YXIgX2FyciA9IFtdOyB2YXIgX24gPSB0cnVlOyB2YXIgX2QgPSBmYWxzZTsgdmFyIF9zLCBfZTsgdHJ5IHsgZm9yIChfaSA9IF9pLmNhbGwoYXJyKTsgIShfbiA9IChfcyA9IF9pLm5leHQoKSkuZG9uZSk7IF9uID0gdHJ1ZSkgeyBfYXJyLnB1c2goX3MudmFsdWUpOyBpZiAoaSAmJiBfYXJyLmxlbmd0aCA9PT0gaSkgYnJlYWs7IH0gfSBjYXRjaCAoZXJyKSB7IF9kID0gdHJ1ZTsgX2UgPSBlcnI7IH0gZmluYWxseSB7IHRyeSB7IGlmICghX24gJiYgX2lbXCJyZXR1cm5cIl0gIT0gbnVsbCkgX2lbXCJyZXR1cm5cIl0oKTsgfSBmaW5hbGx5IHsgaWYgKF9kKSB0aHJvdyBfZTsgfSB9IHJldHVybiBfYXJyOyB9XG5cbmZ1bmN0aW9uIF9hcnJheVdpdGhIb2xlcyhhcnIpIHsgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgcmV0dXJuIGFycjsgfVxuXG52YXIgYXNzaWduID0gX2RlcmVxXygnb2JqZWN0LWFzc2lnbicpO1xuXG52YXIgd2Vid29ya2lmeSA9IF9kZXJlcV8oJ3dlYndvcmtpZnknKTtcblxudmFyIE1hdGhMaWIgPSBfZGVyZXFfKCcuL2xpYi9tYXRobGliJyk7XG5cbnZhciBQb29sID0gX2RlcmVxXygnLi9saWIvcG9vbCcpO1xuXG52YXIgdXRpbHMgPSBfZGVyZXFfKCcuL2xpYi91dGlscycpO1xuXG52YXIgd29ya2VyID0gX2RlcmVxXygnLi9saWIvd29ya2VyJyk7XG5cbnZhciBjcmVhdGVTdGFnZXMgPSBfZGVyZXFfKCcuL2xpYi9zdGVwcGVyJyk7XG5cbnZhciBjcmVhdGVSZWdpb25zID0gX2RlcmVxXygnLi9saWIvdGlsZXInKTsgLy8gRGVkdXBsaWNhdGUgcG9vbHMgJiBsaW1pdGVycyB3aXRoIHRoZSBzYW1lIGNvbmZpZ3Ncbi8vIHdoZW4gdXNlciBjcmVhdGVzIG11bHRpcGxlIHBpY2EgaW5zdGFuY2VzLlxuXG5cbnZhciBzaW5nbGV0b25lcyA9IHt9O1xudmFyIE5FRURfU0FGQVJJX0ZJWCA9IGZhbHNlO1xuXG50cnkge1xuICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCkge1xuICAgIE5FRURfU0FGQVJJX0ZJWCA9IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignU2FmYXJpJykgPj0gMDtcbiAgfVxufSBjYXRjaCAoZSkge31cblxudmFyIGNvbmN1cnJlbmN5ID0gMTtcblxuaWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnKSB7XG4gIGNvbmN1cnJlbmN5ID0gTWF0aC5taW4obmF2aWdhdG9yLmhhcmR3YXJlQ29uY3VycmVuY3kgfHwgMSwgNCk7XG59XG5cbnZhciBERUZBVUxUX1BJQ0FfT1BUUyA9IHtcbiAgdGlsZTogMTAyNCxcbiAgY29uY3VycmVuY3k6IGNvbmN1cnJlbmN5LFxuICBmZWF0dXJlczogWydqcycsICd3YXNtJywgJ3d3J10sXG4gIGlkbGU6IDIwMDAsXG4gIGNyZWF0ZUNhbnZhczogZnVuY3Rpb24gY3JlYXRlQ2FudmFzKHdpZHRoLCBoZWlnaHQpIHtcbiAgICB2YXIgdG1wQ2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgdG1wQ2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgdG1wQ2FudmFzLmhlaWdodCA9IGhlaWdodDtcbiAgICByZXR1cm4gdG1wQ2FudmFzO1xuICB9XG59O1xudmFyIERFRkFVTFRfUkVTSVpFX09QVFMgPSB7XG4gIHF1YWxpdHk6IDMsXG4gIGFscGhhOiBmYWxzZSxcbiAgdW5zaGFycEFtb3VudDogMCxcbiAgdW5zaGFycFJhZGl1czogMC4wLFxuICB1bnNoYXJwVGhyZXNob2xkOiAwXG59O1xudmFyIENBTl9ORVdfSU1BR0VfREFUQSA9IGZhbHNlO1xudmFyIENBTl9DUkVBVEVfSU1BR0VfQklUTUFQID0gZmFsc2U7XG52YXIgQ0FOX1VTRV9DQU5WQVNfR0VUX0lNQUdFX0RBVEEgPSBmYWxzZTtcbnZhciBDQU5fVVNFX09GRlNDUkVFTl9DQU5WQVMgPSBmYWxzZTtcbnZhciBDQU5fVVNFX0NJQl9SRUdJT05fRk9SX0lNQUdFID0gZmFsc2U7XG5cbmZ1bmN0aW9uIHdvcmtlckZhYnJpYygpIHtcbiAgcmV0dXJuIHtcbiAgICB2YWx1ZTogd2Vid29ya2lmeSh3b3JrZXIpLFxuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICB0aGlzLnZhbHVlLnRlcm1pbmF0ZSgpO1xuXG4gICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdmFyIHVybCA9IHdpbmRvdy5VUkwgfHwgd2luZG93LndlYmtpdFVSTCB8fCB3aW5kb3cubW96VVJMIHx8IHdpbmRvdy5tc1VSTDtcblxuICAgICAgICBpZiAodXJsICYmIHVybC5yZXZva2VPYmplY3RVUkwgJiYgdGhpcy52YWx1ZS5vYmplY3RVUkwpIHtcbiAgICAgICAgICB1cmwucmV2b2tlT2JqZWN0VVJMKHRoaXMudmFsdWUub2JqZWN0VVJMKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcbn0gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIEFQSSBtZXRob2RzXG5cblxuZnVuY3Rpb24gUGljYShvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBQaWNhKSkgcmV0dXJuIG5ldyBQaWNhKG9wdGlvbnMpO1xuICB0aGlzLm9wdGlvbnMgPSBhc3NpZ24oe30sIERFRkFVTFRfUElDQV9PUFRTLCBvcHRpb25zIHx8IHt9KTtcbiAgdmFyIGxpbWl0ZXJfa2V5ID0gXCJsa19cIi5jb25jYXQodGhpcy5vcHRpb25zLmNvbmN1cnJlbmN5KTsgLy8gU2hhcmUgbGltaXRlcnMgdG8gYXZvaWQgbXVsdGlwbGUgcGFyYWxsZWwgd29ya2VycyB3aGVuIHVzZXIgY3JlYXRlc1xuICAvLyBtdWx0aXBsZSBwaWNhIGluc3RhbmNlcy5cblxuICB0aGlzLl9fbGltaXQgPSBzaW5nbGV0b25lc1tsaW1pdGVyX2tleV0gfHwgdXRpbHMubGltaXRlcih0aGlzLm9wdGlvbnMuY29uY3VycmVuY3kpO1xuICBpZiAoIXNpbmdsZXRvbmVzW2xpbWl0ZXJfa2V5XSkgc2luZ2xldG9uZXNbbGltaXRlcl9rZXldID0gdGhpcy5fX2xpbWl0OyAvLyBMaXN0IG9mIHN1cHBvcnRlZCBmZWF0dXJlcywgYWNjb3JkaW5nIHRvIG9wdGlvbnMgJiBicm93c2VyL25vZGUuanNcblxuICB0aGlzLmZlYXR1cmVzID0ge1xuICAgIGpzOiBmYWxzZSxcbiAgICAvLyBwdXJlIEpTIGltcGxlbWVudGF0aW9uLCBjYW4gYmUgZGlzYWJsZWQgZm9yIHRlc3RpbmdcbiAgICB3YXNtOiBmYWxzZSxcbiAgICAvLyB3ZWJhc3NlbWJseSBpbXBsZW1lbnRhdGlvbiBmb3IgaGVhdnkgZnVuY3Rpb25zXG4gICAgY2liOiBmYWxzZSxcbiAgICAvLyByZXNpemUgdmlhIGNyZWF0ZUltYWdlQml0bWFwIChvbmx5IEZGIGF0IHRoaXMgbW9tZW50KVxuICAgIHd3OiBmYWxzZSAvLyB3ZWJ3b3JrZXJzXG5cbiAgfTtcbiAgdGhpcy5fX3dvcmtlcnNQb29sID0gbnVsbDsgLy8gU3RvcmUgcmVxdWVzdGVkIGZlYXR1cmVzIGZvciB3ZWJ3b3JrZXJzXG5cbiAgdGhpcy5fX3JlcXVlc3RlZF9mZWF0dXJlcyA9IFtdO1xuICB0aGlzLl9fbWF0aGxpYiA9IG51bGw7XG59XG5cblBpY2EucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgaWYgKHRoaXMuX19pbml0UHJvbWlzZSkgcmV0dXJuIHRoaXMuX19pbml0UHJvbWlzZTsgLy8gVGVzdCBpZiB3ZSBjYW4gY3JlYXRlIEltYWdlRGF0YSB3aXRob3V0IGNhbnZhcyBhbmQgbWVtb3J5IGNvcHlcblxuICBpZiAodHlwZW9mIEltYWdlRGF0YSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIFVpbnQ4Q2xhbXBlZEFycmF5ICE9PSAndW5kZWZpbmVkJykge1xuICAgIHRyeSB7XG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1uZXcgKi9cbiAgICAgIG5ldyBJbWFnZURhdGEobmV3IFVpbnQ4Q2xhbXBlZEFycmF5KDQwMCksIDEwLCAxMCk7XG4gICAgICBDQU5fTkVXX0lNQUdFX0RBVEEgPSB0cnVlO1xuICAgIH0gY2F0Y2ggKF9fKSB7fVxuICB9IC8vIEltYWdlQml0bWFwIGNhbiBiZSBlZmZlY3RpdmUgaW4gMiBwbGFjZXM6XG4gIC8vXG4gIC8vIDEuIFRocmVhZGVkIGpwZWcgdW5wYWNrIChiYXNpYylcbiAgLy8gMi4gQnVpbHQtaW4gcmVzaXplIChibG9ja2VkIGR1ZSBwcm9ibGVtIGluIGNocm9tZSwgc2VlIGlzc3VlICM4OSlcbiAgLy9cbiAgLy8gRm9yIGJhc2ljIHVzZSB3ZSBhbHNvIG5lZWQgSW1hZ2VCaXRtYXAgd28gc3VwcG9ydCAuY2xvc2UoKSBtZXRob2QsXG4gIC8vIHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9ydS9kb2NzL1dlYi9BUEkvSW1hZ2VCaXRtYXBcblxuXG4gIGlmICh0eXBlb2YgSW1hZ2VCaXRtYXAgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKEltYWdlQml0bWFwLnByb3RvdHlwZSAmJiBJbWFnZUJpdG1hcC5wcm90b3R5cGUuY2xvc2UpIHtcbiAgICAgIENBTl9DUkVBVEVfSU1BR0VfQklUTUFQID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kZWJ1ZygnSW1hZ2VCaXRtYXAgZG9lcyBub3Qgc3VwcG9ydCAuY2xvc2UoKSwgZGlzYWJsZWQnKTtcbiAgICB9XG4gIH1cblxuICB2YXIgZmVhdHVyZXMgPSB0aGlzLm9wdGlvbnMuZmVhdHVyZXMuc2xpY2UoKTtcblxuICBpZiAoZmVhdHVyZXMuaW5kZXhPZignYWxsJykgPj0gMCkge1xuICAgIGZlYXR1cmVzID0gWydjaWInLCAnd2FzbScsICdqcycsICd3dyddO1xuICB9XG5cbiAgdGhpcy5fX3JlcXVlc3RlZF9mZWF0dXJlcyA9IGZlYXR1cmVzO1xuICB0aGlzLl9fbWF0aGxpYiA9IG5ldyBNYXRoTGliKGZlYXR1cmVzKTsgLy8gQ2hlY2sgV2ViV29ya2VyIHN1cHBvcnQgaWYgcmVxdWVzdGVkXG5cbiAgaWYgKGZlYXR1cmVzLmluZGV4T2YoJ3d3JykgPj0gMCkge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiAnV29ya2VyJyBpbiB3aW5kb3cpIHtcbiAgICAgIC8vIElFIDw9IDExIGRvbid0IGFsbG93IHRvIGNyZWF0ZSB3ZWJ3b3JrZXJzIGZyb20gc3RyaW5nLiBXZSBzaG91bGQgY2hlY2sgaXQuXG4gICAgICAvLyBodHRwczovL2Nvbm5lY3QubWljcm9zb2Z0LmNvbS9JRS9mZWVkYmFjay9kZXRhaWxzLzgwMTgxMC93ZWItd29ya2Vycy1mcm9tLWJsb2ItdXJscy1pbi1pZS0xMC1hbmQtMTFcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciB3a3IgPSBfZGVyZXFfKCd3ZWJ3b3JraWZ5JykoZnVuY3Rpb24gKCkge30pO1xuXG4gICAgICAgIHdrci50ZXJtaW5hdGUoKTtcbiAgICAgICAgdGhpcy5mZWF0dXJlcy53dyA9IHRydWU7IC8vIHBvb2wgdW5pcXVlbmVzcyBkZXBlbmRzIG9uIHBvb2wgY29uZmlnICsgd2Vid29ya2VyIGNvbmZpZ1xuXG4gICAgICAgIHZhciB3cG9vbF9rZXkgPSBcIndwX1wiLmNvbmNhdChKU09OLnN0cmluZ2lmeSh0aGlzLm9wdGlvbnMpKTtcblxuICAgICAgICBpZiAoc2luZ2xldG9uZXNbd3Bvb2xfa2V5XSkge1xuICAgICAgICAgIHRoaXMuX193b3JrZXJzUG9vbCA9IHNpbmdsZXRvbmVzW3dwb29sX2tleV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5fX3dvcmtlcnNQb29sID0gbmV3IFBvb2wod29ya2VyRmFicmljLCB0aGlzLm9wdGlvbnMuaWRsZSk7XG4gICAgICAgICAgc2luZ2xldG9uZXNbd3Bvb2xfa2V5XSA9IHRoaXMuX193b3JrZXJzUG9vbDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoX18pIHt9XG4gICAgfVxuICB9XG5cbiAgdmFyIGluaXRNYXRoID0gdGhpcy5fX21hdGhsaWIuaW5pdCgpLnRoZW4oZnVuY3Rpb24gKG1hdGhsaWIpIHtcbiAgICAvLyBDb3B5IGRldGVjdGVkIGZlYXR1cmVzXG4gICAgYXNzaWduKF90aGlzLmZlYXR1cmVzLCBtYXRobGliLmZlYXR1cmVzKTtcbiAgfSk7XG5cbiAgdmFyIGNoZWNrQ2liUmVzaXplO1xuXG4gIGlmICghQ0FOX0NSRUFURV9JTUFHRV9CSVRNQVApIHtcbiAgICBjaGVja0NpYlJlc2l6ZSA9IFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gIH0gZWxzZSB7XG4gICAgY2hlY2tDaWJSZXNpemUgPSB1dGlscy5jaWJfc3VwcG9ydCh0aGlzLm9wdGlvbnMuY3JlYXRlQ2FudmFzKS50aGVuKGZ1bmN0aW9uIChzdGF0dXMpIHtcbiAgICAgIGlmIChfdGhpcy5mZWF0dXJlcy5jaWIgJiYgZmVhdHVyZXMuaW5kZXhPZignY2liJykgPCAwKSB7XG4gICAgICAgIF90aGlzLmRlYnVnKCdjcmVhdGVJbWFnZUJpdG1hcCgpIHJlc2l6ZSBzdXBwb3J0ZWQsIGJ1dCBkaXNhYmxlZCBieSBjb25maWcnKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChmZWF0dXJlcy5pbmRleE9mKCdjaWInKSA+PSAwKSBfdGhpcy5mZWF0dXJlcy5jaWIgPSBzdGF0dXM7XG4gICAgfSk7XG4gIH1cblxuICBDQU5fVVNFX0NBTlZBU19HRVRfSU1BR0VfREFUQSA9IHV0aWxzLmNhbl91c2VfY2FudmFzKHRoaXMub3B0aW9ucy5jcmVhdGVDYW52YXMpO1xuICB2YXIgY2hlY2tPZmZzY3JlZW5DYW52YXM7XG5cbiAgaWYgKENBTl9DUkVBVEVfSU1BR0VfQklUTUFQICYmIENBTl9ORVdfSU1BR0VfREFUQSAmJiBmZWF0dXJlcy5pbmRleE9mKCd3dycpICE9PSAtMSkge1xuICAgIGNoZWNrT2Zmc2NyZWVuQ2FudmFzID0gdXRpbHMud29ya2VyX29mZnNjcmVlbl9jYW52YXNfc3VwcG9ydCgpO1xuICB9IGVsc2Uge1xuICAgIGNoZWNrT2Zmc2NyZWVuQ2FudmFzID0gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgfVxuXG4gIGNoZWNrT2Zmc2NyZWVuQ2FudmFzID0gY2hlY2tPZmZzY3JlZW5DYW52YXMudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgQ0FOX1VTRV9PRkZTQ1JFRU5fQ0FOVkFTID0gcmVzdWx0O1xuICB9KTsgLy8gd2UgdXNlIGNyZWF0ZUltYWdlQml0bWFwIHRvIGNyb3AgaW1hZ2UgZGF0YSBhbmQgcGFzcyBpdCB0byB3b3JrZXJzLFxuICAvLyBzbyBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgZnVuY3Rpb24gd29ya3MgY29ycmVjdGx5O1xuICAvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0xMjIwNjcxXG5cbiAgdmFyIGNoZWNrQ2liUmVnaW9uID0gdXRpbHMuY2liX2Nhbl91c2VfcmVnaW9uKCkudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgQ0FOX1VTRV9DSUJfUkVHSU9OX0ZPUl9JTUFHRSA9IHJlc3VsdDtcbiAgfSk7IC8vIEluaXQgbWF0aCBsaWIuIFRoYXQncyBhc3luYyBiZWNhdXNlIGNhbiBsb2FkIHNvbWVcblxuICB0aGlzLl9faW5pdFByb21pc2UgPSBQcm9taXNlLmFsbChbaW5pdE1hdGgsIGNoZWNrQ2liUmVzaXplLCBjaGVja09mZnNjcmVlbkNhbnZhcywgY2hlY2tDaWJSZWdpb25dKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH0pO1xuICByZXR1cm4gdGhpcy5fX2luaXRQcm9taXNlO1xufTsgLy8gQ2FsbCByZXNpemVyIGluIHdlYndvcmtlciBvciBsb2NhbGx5LCBkZXBlbmRpbmcgb24gY29uZmlnXG5cblxuUGljYS5wcm90b3R5cGUuX19pbnZva2VSZXNpemUgPSBmdW5jdGlvbiAodGlsZU9wdHMsIG9wdHMpIHtcbiAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgLy8gU2hhcmUgY2FjaGUgYmV0d2VlbiBjYWxsczpcbiAgLy9cbiAgLy8gLSB3YXNtIGluc3RhbmNlXG4gIC8vIC0gd2FzbSBtZW1vcnkgb2JqZWN0XG4gIC8vXG4gIG9wdHMuX19tYXRoQ2FjaGUgPSBvcHRzLl9fbWF0aENhY2hlIHx8IHt9O1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFfdGhpczIuZmVhdHVyZXMud3cpIHtcbiAgICAgIC8vIG5vdCBwb3NzaWJsZSB0byBoYXZlIEltYWdlQml0bWFwIGhlcmUgaWYgdXNlciBkaXNhYmxlZCBXV1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGF0YTogX3RoaXMyLl9fbWF0aGxpYi5yZXNpemVBbmRVbnNoYXJwKHRpbGVPcHRzLCBvcHRzLl9fbWF0aENhY2hlKVxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgdmFyIHcgPSBfdGhpczIuX193b3JrZXJzUG9vbC5hY3F1aXJlKCk7XG5cbiAgICAgIGlmIChvcHRzLmNhbmNlbFRva2VuKSBvcHRzLmNhbmNlbFRva2VuW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKGVycikge1xuICAgICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICB9KTtcblxuICAgICAgdy52YWx1ZS5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgdy5yZWxlYXNlKCk7XG4gICAgICAgIGlmIChldi5kYXRhLmVycikgcmVqZWN0KGV2LmRhdGEuZXJyKTtlbHNlIHJlc29sdmUoZXYuZGF0YSk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgdHJhbnNmZXIgPSBbXTtcbiAgICAgIGlmICh0aWxlT3B0cy5zcmMpIHRyYW5zZmVyLnB1c2godGlsZU9wdHMuc3JjLmJ1ZmZlcik7XG4gICAgICBpZiAodGlsZU9wdHMuc3JjQml0bWFwKSB0cmFuc2Zlci5wdXNoKHRpbGVPcHRzLnNyY0JpdG1hcCk7XG4gICAgICB3LnZhbHVlLnBvc3RNZXNzYWdlKHtcbiAgICAgICAgb3B0czogdGlsZU9wdHMsXG4gICAgICAgIGZlYXR1cmVzOiBfdGhpczIuX19yZXF1ZXN0ZWRfZmVhdHVyZXMsXG4gICAgICAgIHByZWxvYWQ6IHtcbiAgICAgICAgICB3YXNtX25vZHVsZTogX3RoaXMyLl9fbWF0aGxpYi5fX1xuICAgICAgICB9XG4gICAgICB9LCB0cmFuc2Zlcik7XG4gICAgfSk7XG4gIH0pO1xufTsgLy8gdGhpcyBmdW5jdGlvbiBjYW4gcmV0dXJuIHByb21pc2UgaWYgY3JlYXRlSW1hZ2VCaXRtYXAgaXMgdXNlZFxuXG5cblBpY2EucHJvdG90eXBlLl9fZXh0cmFjdFRpbGVEYXRhID0gZnVuY3Rpb24gKHRpbGUsIGZyb20sIG9wdHMsIHN0YWdlRW52LCBleHRyYWN0VG8pIHtcbiAgaWYgKHRoaXMuZmVhdHVyZXMud3cgJiYgQ0FOX1VTRV9PRkZTQ1JFRU5fQ0FOVkFTICYmICggLy8gY3JlYXRlSW1hZ2VCaXRtYXAgZG9lc24ndCB3b3JrIGZvciBpbWFnZXMgKEltYWdlLCBJbWFnZUJpdG1hcCkgd2l0aCBFeGlmIG9yaWVudGF0aW9uIGluIENocm9tZSxcbiAgLy8gY2FuIHVzZSBjYW52YXMgYmVjYXVzZSBjYW52YXMgZG9lc24ndCBoYXZlIG9yaWVudGF0aW9uO1xuICAvLyBzZWUgaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9MTIyMDY3MVxuICB1dGlscy5pc0NhbnZhcyhmcm9tKSB8fCBDQU5fVVNFX0NJQl9SRUdJT05fRk9SX0lNQUdFKSkge1xuICAgIHRoaXMuZGVidWcoJ0NyZWF0ZSB0aWxlIGZvciBPZmZzY3JlZW5DYW52YXMnKTtcbiAgICByZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAoc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXAgfHwgZnJvbSwgdGlsZS54LCB0aWxlLnksIHRpbGUud2lkdGgsIHRpbGUuaGVpZ2h0KS50aGVuKGZ1bmN0aW9uIChiaXRtYXApIHtcbiAgICAgIGV4dHJhY3RUby5zcmNCaXRtYXAgPSBiaXRtYXA7XG4gICAgICByZXR1cm4gZXh0cmFjdFRvO1xuICAgIH0pO1xuICB9IC8vIEV4dHJhY3QgdGlsZSBSR0JBIGJ1ZmZlciwgZGVwZW5kaW5nIG9uIGlucHV0IHR5cGVcblxuXG4gIGlmICh1dGlscy5pc0NhbnZhcyhmcm9tKSkge1xuICAgIGlmICghc3RhZ2VFbnYuc3JjQ3R4KSBzdGFnZUVudi5zcmNDdHggPSBmcm9tLmdldENvbnRleHQoJzJkJywge1xuICAgICAgYWxwaGE6IEJvb2xlYW4ob3B0cy5hbHBoYSlcbiAgICB9KTsgLy8gSWYgaW5wdXQgaXMgQ2FudmFzIC0gZXh0cmFjdCByZWdpb24gZGF0YSBkaXJlY3RseVxuXG4gICAgdGhpcy5kZWJ1ZygnR2V0IHRpbGUgcGl4ZWwgZGF0YScpO1xuICAgIGV4dHJhY3RUby5zcmMgPSBzdGFnZUVudi5zcmNDdHguZ2V0SW1hZ2VEYXRhKHRpbGUueCwgdGlsZS55LCB0aWxlLndpZHRoLCB0aWxlLmhlaWdodCkuZGF0YTtcbiAgICByZXR1cm4gZXh0cmFjdFRvO1xuICB9IC8vIElmIGlucHV0IGlzIEltYWdlIG9yIGRlY29kZWQgdG8gSW1hZ2VCaXRtYXAsXG4gIC8vIGRyYXcgcmVnaW9uIHRvIHRlbXBvcmFyeSBjYW52YXMgYW5kIGV4dHJhY3QgZGF0YSBmcm9tIGl0XG4gIC8vXG4gIC8vIE5vdGUhIEF0dGVtcHQgdG8gcmV1c2UgdGhpcyBjYW52YXMgY2F1c2VzIHNpZ25pZmljYW50IHNsb3dkb3duIGluIGNocm9tZVxuICAvL1xuXG5cbiAgdGhpcy5kZWJ1ZygnRHJhdyB0aWxlIGltYWdlQml0bWFwL2ltYWdlIHRvIHRlbXBvcmFyeSBjYW52YXMnKTtcbiAgdmFyIHRtcENhbnZhcyA9IHRoaXMub3B0aW9ucy5jcmVhdGVDYW52YXModGlsZS53aWR0aCwgdGlsZS5oZWlnaHQpO1xuICB2YXIgdG1wQ3R4ID0gdG1wQ2FudmFzLmdldENvbnRleHQoJzJkJywge1xuICAgIGFscGhhOiBCb29sZWFuKG9wdHMuYWxwaGEpXG4gIH0pO1xuICB0bXBDdHguZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gJ2NvcHknO1xuICB0bXBDdHguZHJhd0ltYWdlKHN0YWdlRW52LnNyY0ltYWdlQml0bWFwIHx8IGZyb20sIHRpbGUueCwgdGlsZS55LCB0aWxlLndpZHRoLCB0aWxlLmhlaWdodCwgMCwgMCwgdGlsZS53aWR0aCwgdGlsZS5oZWlnaHQpO1xuICB0aGlzLmRlYnVnKCdHZXQgdGlsZSBwaXhlbCBkYXRhJyk7XG4gIGV4dHJhY3RUby5zcmMgPSB0bXBDdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIHRpbGUud2lkdGgsIHRpbGUuaGVpZ2h0KS5kYXRhOyAvLyBTYWZhcmkgMTIgd29ya2Fyb3VuZFxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vbm9kZWNhL3BpY2EvaXNzdWVzLzE5OVxuXG4gIHRtcENhbnZhcy53aWR0aCA9IHRtcENhbnZhcy5oZWlnaHQgPSAwO1xuICByZXR1cm4gZXh0cmFjdFRvO1xufTtcblxuUGljYS5wcm90b3R5cGUuX19sYW5kVGlsZURhdGEgPSBmdW5jdGlvbiAodGlsZSwgcmVzdWx0LCBzdGFnZUVudikge1xuICB2YXIgdG9JbWFnZURhdGE7XG4gIHRoaXMuZGVidWcoJ0NvbnZlcnQgcmF3IHJnYmEgdGlsZSByZXN1bHQgdG8gSW1hZ2VEYXRhJyk7XG5cbiAgaWYgKHJlc3VsdC5iaXRtYXApIHtcbiAgICBzdGFnZUVudi50b0N0eC5kcmF3SW1hZ2UocmVzdWx0LmJpdG1hcCwgdGlsZS50b1gsIHRpbGUudG9ZKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChDQU5fTkVXX0lNQUdFX0RBVEEpIHtcbiAgICAvLyB0aGlzIGJyYW5jaCBpcyBmb3IgbW9kZXJuIGJyb3dzZXJzXG4gICAgLy8gSWYgYG5ldyBJbWFnZURhdGEoKWAgJiBVaW50OENsYW1wZWRBcnJheSBzdXBvcnRlZFxuICAgIHRvSW1hZ2VEYXRhID0gbmV3IEltYWdlRGF0YShuZXcgVWludDhDbGFtcGVkQXJyYXkocmVzdWx0LmRhdGEpLCB0aWxlLnRvV2lkdGgsIHRpbGUudG9IZWlnaHQpO1xuICB9IGVsc2Uge1xuICAgIC8vIGZhbGxiYWNrIGZvciBgbm9kZS1jYW52YXNgIGFuZCBvbGQgYnJvd3NlcnNcbiAgICAvLyAoSUUxMSBoYXMgSW1hZ2VEYXRhIGJ1dCBkb2VzIG5vdCBzdXBwb3J0IGBuZXcgSW1hZ2VEYXRhKClgKVxuICAgIHRvSW1hZ2VEYXRhID0gc3RhZ2VFbnYudG9DdHguY3JlYXRlSW1hZ2VEYXRhKHRpbGUudG9XaWR0aCwgdGlsZS50b0hlaWdodCk7XG5cbiAgICBpZiAodG9JbWFnZURhdGEuZGF0YS5zZXQpIHtcbiAgICAgIHRvSW1hZ2VEYXRhLmRhdGEuc2V0KHJlc3VsdC5kYXRhKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSUU5IGRvbid0IGhhdmUgYC5zZXQoKWBcbiAgICAgIGZvciAodmFyIGkgPSB0b0ltYWdlRGF0YS5kYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIHRvSW1hZ2VEYXRhLmRhdGFbaV0gPSByZXN1bHQuZGF0YVtpXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aGlzLmRlYnVnKCdEcmF3IHRpbGUnKTtcblxuICBpZiAoTkVFRF9TQUZBUklfRklYKSB7XG4gICAgLy8gU2FmYXJpIGRyYXdzIHRoaW4gd2hpdGUgc3RyaXBlcyBiZXR3ZWVuIHRpbGVzIHdpdGhvdXQgdGhpcyBmaXhcbiAgICBzdGFnZUVudi50b0N0eC5wdXRJbWFnZURhdGEodG9JbWFnZURhdGEsIHRpbGUudG9YLCB0aWxlLnRvWSwgdGlsZS50b0lubmVyWCAtIHRpbGUudG9YLCB0aWxlLnRvSW5uZXJZIC0gdGlsZS50b1ksIHRpbGUudG9Jbm5lcldpZHRoICsgMWUtNSwgdGlsZS50b0lubmVySGVpZ2h0ICsgMWUtNSk7XG4gIH0gZWxzZSB7XG4gICAgc3RhZ2VFbnYudG9DdHgucHV0SW1hZ2VEYXRhKHRvSW1hZ2VEYXRhLCB0aWxlLnRvWCwgdGlsZS50b1ksIHRpbGUudG9Jbm5lclggLSB0aWxlLnRvWCwgdGlsZS50b0lubmVyWSAtIHRpbGUudG9ZLCB0aWxlLnRvSW5uZXJXaWR0aCwgdGlsZS50b0lubmVySGVpZ2h0KTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufTtcblxuUGljYS5wcm90b3R5cGUuX190aWxlQW5kUmVzaXplID0gZnVuY3Rpb24gKGZyb20sIHRvLCBvcHRzKSB7XG4gIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gIHZhciBzdGFnZUVudiA9IHtcbiAgICBzcmNDdHg6IG51bGwsXG4gICAgc3JjSW1hZ2VCaXRtYXA6IG51bGwsXG4gICAgaXNJbWFnZUJpdG1hcFJldXNlZDogZmFsc2UsXG4gICAgdG9DdHg6IG51bGxcbiAgfTtcblxuICB2YXIgcHJvY2Vzc1RpbGUgPSBmdW5jdGlvbiBwcm9jZXNzVGlsZSh0aWxlKSB7XG4gICAgcmV0dXJuIF90aGlzMy5fX2xpbWl0KGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChvcHRzLmNhbmNlbGVkKSByZXR1cm4gb3B0cy5jYW5jZWxUb2tlbjtcbiAgICAgIHZhciB0aWxlT3B0cyA9IHtcbiAgICAgICAgd2lkdGg6IHRpbGUud2lkdGgsXG4gICAgICAgIGhlaWdodDogdGlsZS5oZWlnaHQsXG4gICAgICAgIHRvV2lkdGg6IHRpbGUudG9XaWR0aCxcbiAgICAgICAgdG9IZWlnaHQ6IHRpbGUudG9IZWlnaHQsXG4gICAgICAgIHNjYWxlWDogdGlsZS5zY2FsZVgsXG4gICAgICAgIHNjYWxlWTogdGlsZS5zY2FsZVksXG4gICAgICAgIG9mZnNldFg6IHRpbGUub2Zmc2V0WCxcbiAgICAgICAgb2Zmc2V0WTogdGlsZS5vZmZzZXRZLFxuICAgICAgICBxdWFsaXR5OiBvcHRzLnF1YWxpdHksXG4gICAgICAgIGFscGhhOiBvcHRzLmFscGhhLFxuICAgICAgICB1bnNoYXJwQW1vdW50OiBvcHRzLnVuc2hhcnBBbW91bnQsXG4gICAgICAgIHVuc2hhcnBSYWRpdXM6IG9wdHMudW5zaGFycFJhZGl1cyxcbiAgICAgICAgdW5zaGFycFRocmVzaG9sZDogb3B0cy51bnNoYXJwVGhyZXNob2xkXG4gICAgICB9O1xuXG4gICAgICBfdGhpczMuZGVidWcoJ0ludm9rZSByZXNpemUgbWF0aCcpO1xuXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRpbGVPcHRzKS50aGVuKGZ1bmN0aW9uICh0aWxlT3B0cykge1xuICAgICAgICByZXR1cm4gX3RoaXMzLl9fZXh0cmFjdFRpbGVEYXRhKHRpbGUsIGZyb20sIG9wdHMsIHN0YWdlRW52LCB0aWxlT3B0cyk7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uICh0aWxlT3B0cykge1xuICAgICAgICBfdGhpczMuZGVidWcoJ0ludm9rZSByZXNpemUgbWF0aCcpO1xuXG4gICAgICAgIHJldHVybiBfdGhpczMuX19pbnZva2VSZXNpemUodGlsZU9wdHMsIG9wdHMpO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgIGlmIChvcHRzLmNhbmNlbGVkKSByZXR1cm4gb3B0cy5jYW5jZWxUb2tlbjtcbiAgICAgICAgc3RhZ2VFbnYuc3JjSW1hZ2VEYXRhID0gbnVsbDtcbiAgICAgICAgcmV0dXJuIF90aGlzMy5fX2xhbmRUaWxlRGF0YSh0aWxlLCByZXN1bHQsIHN0YWdlRW52KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9OyAvLyBOZWVkIHRvIG5vcm1hbGl6ZSBkYXRhIHNvdXJjZSBmaXJzdC4gSXQgY2FuIGJlIGNhbnZhcyBvciBpbWFnZS5cbiAgLy8gSWYgaW1hZ2UgLSB0cnkgdG8gZGVjb2RlIGluIGJhY2tncm91bmQgaWYgcG9zc2libGVcblxuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBzdGFnZUVudi50b0N0eCA9IHRvLmdldENvbnRleHQoJzJkJywge1xuICAgICAgYWxwaGE6IEJvb2xlYW4ob3B0cy5hbHBoYSlcbiAgICB9KTtcbiAgICBpZiAodXRpbHMuaXNDYW52YXMoZnJvbSkpIHJldHVybiBudWxsO1xuXG4gICAgaWYgKHV0aWxzLmlzSW1hZ2VCaXRtYXAoZnJvbSkpIHtcbiAgICAgIHN0YWdlRW52LnNyY0ltYWdlQml0bWFwID0gZnJvbTtcbiAgICAgIHN0YWdlRW52LmlzSW1hZ2VCaXRtYXBSZXVzZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHV0aWxzLmlzSW1hZ2UoZnJvbSkpIHtcbiAgICAgIC8vIHRyeSBkbyBkZWNvZGUgaW1hZ2UgaW4gYmFja2dyb3VuZCBmb3IgZmFzdGVyIG5leHQgb3BlcmF0aW9ucztcbiAgICAgIC8vIGlmIHdlJ3JlIHVzaW5nIG9mZnNjcmVlbiBjYW52YXMsIGNpYiBpcyBjYWxsZWQgcGVyIHRpbGUsIHNvIG5vdCBuZWVkZWQgaGVyZVxuICAgICAgaWYgKCFDQU5fQ1JFQVRFX0lNQUdFX0JJVE1BUCkgcmV0dXJuIG51bGw7XG5cbiAgICAgIF90aGlzMy5kZWJ1ZygnRGVjb2RlIGltYWdlIHZpYSBjcmVhdGVJbWFnZUJpdG1hcCcpO1xuXG4gICAgICByZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAoZnJvbSkudGhlbihmdW5jdGlvbiAoaW1hZ2VCaXRtYXApIHtcbiAgICAgICAgc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXAgPSBpbWFnZUJpdG1hcDtcbiAgICAgIH0pIC8vIFN1cHByZXNzIGVycm9yIHRvIHVzZSBmYWxsYmFjaywgaWYgbWV0aG9kIGZhaWxzXG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbm9kZWNhL3BpY2EvaXNzdWVzLzE5MFxuXG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xuICAgICAgW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BpY2E6IFwiLmZyb21cIiBzaG91bGQgYmUgSW1hZ2UsIENhbnZhcyBvciBJbWFnZUJpdG1hcCcpO1xuICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAob3B0cy5jYW5jZWxlZCkgcmV0dXJuIG9wdHMuY2FuY2VsVG9rZW47XG5cbiAgICBfdGhpczMuZGVidWcoJ0NhbGN1bGF0ZSB0aWxlcycpOyAvL1xuICAgIC8vIEhlcmUgd2UgYXJlIHdpdGggXCJub3JtYWxpemVkXCIgc291cmNlLFxuICAgIC8vIGZvbGxvdyB0byB0aWxpbmdcbiAgICAvL1xuXG5cbiAgICB2YXIgcmVnaW9ucyA9IGNyZWF0ZVJlZ2lvbnMoe1xuICAgICAgd2lkdGg6IG9wdHMud2lkdGgsXG4gICAgICBoZWlnaHQ6IG9wdHMuaGVpZ2h0LFxuICAgICAgc3JjVGlsZVNpemU6IF90aGlzMy5vcHRpb25zLnRpbGUsXG4gICAgICB0b1dpZHRoOiBvcHRzLnRvV2lkdGgsXG4gICAgICB0b0hlaWdodDogb3B0cy50b0hlaWdodCxcbiAgICAgIGRlc3RUaWxlQm9yZGVyOiBvcHRzLl9fZGVzdFRpbGVCb3JkZXJcbiAgICB9KTtcbiAgICB2YXIgam9icyA9IHJlZ2lvbnMubWFwKGZ1bmN0aW9uICh0aWxlKSB7XG4gICAgICByZXR1cm4gcHJvY2Vzc1RpbGUodGlsZSk7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBjbGVhbnVwKHN0YWdlRW52KSB7XG4gICAgICBpZiAoc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXApIHtcbiAgICAgICAgaWYgKCFzdGFnZUVudi5pc0ltYWdlQml0bWFwUmV1c2VkKSBzdGFnZUVudi5zcmNJbWFnZUJpdG1hcC5jbG9zZSgpO1xuICAgICAgICBzdGFnZUVudi5zcmNJbWFnZUJpdG1hcCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX3RoaXMzLmRlYnVnKCdQcm9jZXNzIHRpbGVzJyk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoam9icykudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICBfdGhpczMuZGVidWcoJ0ZpbmlzaGVkIScpO1xuXG4gICAgICBjbGVhbnVwKHN0YWdlRW52KTtcbiAgICAgIHJldHVybiB0bztcbiAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBjbGVhbnVwKHN0YWdlRW52KTtcbiAgICAgIHRocm93IGVycjtcbiAgICB9KTtcbiAgfSk7XG59O1xuXG5QaWNhLnByb3RvdHlwZS5fX3Byb2Nlc3NTdGFnZXMgPSBmdW5jdGlvbiAoc3RhZ2VzLCBmcm9tLCB0bywgb3B0cykge1xuICB2YXIgX3RoaXM0ID0gdGhpcztcblxuICBpZiAob3B0cy5jYW5jZWxlZCkgcmV0dXJuIG9wdHMuY2FuY2VsVG9rZW47XG5cbiAgdmFyIF9zdGFnZXMkc2hpZnQgPSBzdGFnZXMuc2hpZnQoKSxcbiAgICAgIF9zdGFnZXMkc2hpZnQyID0gX3NsaWNlZFRvQXJyYXkoX3N0YWdlcyRzaGlmdCwgMiksXG4gICAgICB0b1dpZHRoID0gX3N0YWdlcyRzaGlmdDJbMF0sXG4gICAgICB0b0hlaWdodCA9IF9zdGFnZXMkc2hpZnQyWzFdO1xuXG4gIHZhciBpc0xhc3RTdGFnZSA9IHN0YWdlcy5sZW5ndGggPT09IDA7XG4gIG9wdHMgPSBhc3NpZ24oe30sIG9wdHMsIHtcbiAgICB0b1dpZHRoOiB0b1dpZHRoLFxuICAgIHRvSGVpZ2h0OiB0b0hlaWdodCxcbiAgICAvLyBvbmx5IHVzZSB1c2VyLWRlZmluZWQgcXVhbGl0eSBmb3IgdGhlIGxhc3Qgc3RhZ2UsXG4gICAgLy8gdXNlIHNpbXBsZXIgKEhhbW1pbmcpIGZpbHRlciBmb3IgdGhlIGZpcnN0IHN0YWdlcyB3aGVyZVxuICAgIC8vIHNjYWxlIGZhY3RvciBpcyBsYXJnZSBlbm91Z2ggKG1vcmUgdGhhbiAyLTMpXG4gICAgcXVhbGl0eTogaXNMYXN0U3RhZ2UgPyBvcHRzLnF1YWxpdHkgOiBNYXRoLm1pbigxLCBvcHRzLnF1YWxpdHkpXG4gIH0pO1xuICB2YXIgdG1wQ2FudmFzO1xuXG4gIGlmICghaXNMYXN0U3RhZ2UpIHtcbiAgICAvLyBjcmVhdGUgdGVtcG9yYXJ5IGNhbnZhc1xuICAgIHRtcENhbnZhcyA9IHRoaXMub3B0aW9ucy5jcmVhdGVDYW52YXModG9XaWR0aCwgdG9IZWlnaHQpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX190aWxlQW5kUmVzaXplKGZyb20sIGlzTGFzdFN0YWdlID8gdG8gOiB0bXBDYW52YXMsIG9wdHMpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIGlmIChpc0xhc3RTdGFnZSkgcmV0dXJuIHRvO1xuICAgIG9wdHMud2lkdGggPSB0b1dpZHRoO1xuICAgIG9wdHMuaGVpZ2h0ID0gdG9IZWlnaHQ7XG4gICAgcmV0dXJuIF90aGlzNC5fX3Byb2Nlc3NTdGFnZXMoc3RhZ2VzLCB0bXBDYW52YXMsIHRvLCBvcHRzKTtcbiAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgaWYgKHRtcENhbnZhcykge1xuICAgICAgLy8gU2FmYXJpIDEyIHdvcmthcm91bmRcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYS9pc3N1ZXMvMTk5XG4gICAgICB0bXBDYW52YXMud2lkdGggPSB0bXBDYW52YXMuaGVpZ2h0ID0gMDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9KTtcbn07XG5cblBpY2EucHJvdG90eXBlLl9fcmVzaXplVmlhQ3JlYXRlSW1hZ2VCaXRtYXAgPSBmdW5jdGlvbiAoZnJvbSwgdG8sIG9wdHMpIHtcbiAgdmFyIF90aGlzNSA9IHRoaXM7XG5cbiAgdmFyIHRvQ3R4ID0gdG8uZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgYWxwaGE6IEJvb2xlYW4ob3B0cy5hbHBoYSlcbiAgfSk7XG4gIHRoaXMuZGVidWcoJ1Jlc2l6ZSB2aWEgY3JlYXRlSW1hZ2VCaXRtYXAoKScpO1xuICByZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAoZnJvbSwge1xuICAgIHJlc2l6ZVdpZHRoOiBvcHRzLnRvV2lkdGgsXG4gICAgcmVzaXplSGVpZ2h0OiBvcHRzLnRvSGVpZ2h0LFxuICAgIHJlc2l6ZVF1YWxpdHk6IHV0aWxzLmNpYl9xdWFsaXR5X25hbWUob3B0cy5xdWFsaXR5KVxuICB9KS50aGVuKGZ1bmN0aW9uIChpbWFnZUJpdG1hcCkge1xuICAgIGlmIChvcHRzLmNhbmNlbGVkKSByZXR1cm4gb3B0cy5jYW5jZWxUb2tlbjsgLy8gaWYgbm8gdW5zaGFycCAtIGRyYXcgZGlyZWN0bHkgdG8gb3V0cHV0IGNhbnZhc1xuXG4gICAgaWYgKCFvcHRzLnVuc2hhcnBBbW91bnQpIHtcbiAgICAgIHRvQ3R4LmRyYXdJbWFnZShpbWFnZUJpdG1hcCwgMCwgMCk7XG4gICAgICBpbWFnZUJpdG1hcC5jbG9zZSgpO1xuICAgICAgdG9DdHggPSBudWxsO1xuXG4gICAgICBfdGhpczUuZGVidWcoJ0ZpbmlzaGVkIScpO1xuXG4gICAgICByZXR1cm4gdG87XG4gICAgfVxuXG4gICAgX3RoaXM1LmRlYnVnKCdVbnNoYXJwIHJlc3VsdCcpO1xuXG4gICAgdmFyIHRtcENhbnZhcyA9IF90aGlzNS5vcHRpb25zLmNyZWF0ZUNhbnZhcyhvcHRzLnRvV2lkdGgsIG9wdHMudG9IZWlnaHQpO1xuXG4gICAgdmFyIHRtcEN0eCA9IHRtcENhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICAgIGFscGhhOiBCb29sZWFuKG9wdHMuYWxwaGEpXG4gICAgfSk7XG4gICAgdG1wQ3R4LmRyYXdJbWFnZShpbWFnZUJpdG1hcCwgMCwgMCk7XG4gICAgaW1hZ2VCaXRtYXAuY2xvc2UoKTtcbiAgICB2YXIgaURhdGEgPSB0bXBDdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIG9wdHMudG9XaWR0aCwgb3B0cy50b0hlaWdodCk7XG5cbiAgICBfdGhpczUuX19tYXRobGliLnVuc2hhcnBfbWFzayhpRGF0YS5kYXRhLCBvcHRzLnRvV2lkdGgsIG9wdHMudG9IZWlnaHQsIG9wdHMudW5zaGFycEFtb3VudCwgb3B0cy51bnNoYXJwUmFkaXVzLCBvcHRzLnVuc2hhcnBUaHJlc2hvbGQpO1xuXG4gICAgdG9DdHgucHV0SW1hZ2VEYXRhKGlEYXRhLCAwLCAwKTsgLy8gU2FmYXJpIDEyIHdvcmthcm91bmRcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbm9kZWNhL3BpY2EvaXNzdWVzLzE5OVxuXG4gICAgdG1wQ2FudmFzLndpZHRoID0gdG1wQ2FudmFzLmhlaWdodCA9IDA7XG4gICAgaURhdGEgPSB0bXBDdHggPSB0bXBDYW52YXMgPSB0b0N0eCA9IG51bGw7XG5cbiAgICBfdGhpczUuZGVidWcoJ0ZpbmlzaGVkIScpO1xuXG4gICAgcmV0dXJuIHRvO1xuICB9KTtcbn07XG5cblBpY2EucHJvdG90eXBlLnJlc2l6ZSA9IGZ1bmN0aW9uIChmcm9tLCB0bywgb3B0aW9ucykge1xuICB2YXIgX3RoaXM2ID0gdGhpcztcblxuICB0aGlzLmRlYnVnKCdTdGFydCByZXNpemUuLi4nKTtcbiAgdmFyIG9wdHMgPSBhc3NpZ24oe30sIERFRkFVTFRfUkVTSVpFX09QVFMpO1xuXG4gIGlmICghaXNOYU4ob3B0aW9ucykpIHtcbiAgICBvcHRzID0gYXNzaWduKG9wdHMsIHtcbiAgICAgIHF1YWxpdHk6IG9wdGlvbnNcbiAgICB9KTtcbiAgfSBlbHNlIGlmIChvcHRpb25zKSB7XG4gICAgb3B0cyA9IGFzc2lnbihvcHRzLCBvcHRpb25zKTtcbiAgfVxuXG4gIG9wdHMudG9XaWR0aCA9IHRvLndpZHRoO1xuICBvcHRzLnRvSGVpZ2h0ID0gdG8uaGVpZ2h0O1xuICBvcHRzLndpZHRoID0gZnJvbS5uYXR1cmFsV2lkdGggfHwgZnJvbS53aWR0aDtcbiAgb3B0cy5oZWlnaHQgPSBmcm9tLm5hdHVyYWxIZWlnaHQgfHwgZnJvbS5oZWlnaHQ7IC8vIFByZXZlbnQgc3RlcHBlciBmcm9tIGluZmluaXRlIGxvb3BcblxuICBpZiAodG8ud2lkdGggPT09IDAgfHwgdG8uaGVpZ2h0ID09PSAwKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkludmFsaWQgb3V0cHV0IHNpemU6IFwiLmNvbmNhdCh0by53aWR0aCwgXCJ4XCIpLmNvbmNhdCh0by5oZWlnaHQpKSk7XG4gIH1cblxuICBpZiAob3B0cy51bnNoYXJwUmFkaXVzID4gMikgb3B0cy51bnNoYXJwUmFkaXVzID0gMjtcbiAgb3B0cy5jYW5jZWxlZCA9IGZhbHNlO1xuXG4gIGlmIChvcHRzLmNhbmNlbFRva2VuKSB7XG4gICAgLy8gV3JhcCBjYW5jZWxUb2tlbiB0byBhdm9pZCBzdWNjZXNzaXZlIHJlc29sdmUgJiBzZXQgZmxhZ1xuICAgIG9wdHMuY2FuY2VsVG9rZW4gPSBvcHRzLmNhbmNlbFRva2VuLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgIG9wdHMuY2FuY2VsZWQgPSB0cnVlO1xuICAgICAgdGhyb3cgZGF0YTtcbiAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBvcHRzLmNhbmNlbGVkID0gdHJ1ZTtcbiAgICAgIHRocm93IGVycjtcbiAgICB9KTtcbiAgfVxuXG4gIHZhciBERVNUX1RJTEVfQk9SREVSID0gMzsgLy8gTWF4IHBvc3NpYmxlIGZpbHRlciB3aW5kb3cgc2l6ZVxuXG4gIG9wdHMuX19kZXN0VGlsZUJvcmRlciA9IE1hdGguY2VpbChNYXRoLm1heChERVNUX1RJTEVfQk9SREVSLCAyLjUgKiBvcHRzLnVuc2hhcnBSYWRpdXMgfCAwKSk7XG4gIHJldHVybiB0aGlzLmluaXQoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAob3B0cy5jYW5jZWxlZCkgcmV0dXJuIG9wdHMuY2FuY2VsVG9rZW47IC8vIGlmIGNyZWF0ZUltYWdlQml0bWFwIHN1cHBvcnRzIHJlc2l6ZSwganVzdCBkbyBpdCBhbmQgcmV0dXJuXG5cbiAgICBpZiAoX3RoaXM2LmZlYXR1cmVzLmNpYikge1xuICAgICAgcmV0dXJuIF90aGlzNi5fX3Jlc2l6ZVZpYUNyZWF0ZUltYWdlQml0bWFwKGZyb20sIHRvLCBvcHRzKTtcbiAgICB9XG5cbiAgICBpZiAoIUNBTl9VU0VfQ0FOVkFTX0dFVF9JTUFHRV9EQVRBKSB7XG4gICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdQaWNhOiBjYW5ub3QgdXNlIGdldEltYWdlRGF0YSBvbiBjYW52YXMsICcgKyBcIm1ha2Ugc3VyZSBmaW5nZXJwcmludGluZyBwcm90ZWN0aW9uIGlzbid0IGVuYWJsZWRcIik7XG4gICAgICBlcnIuY29kZSA9ICdFUlJfR0VUX0lNQUdFX0RBVEEnO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH0gLy9cbiAgICAvLyBObyBlYXN5IHdheSwgbGV0J3MgcmVzaXplIG1hbnVhbGx5IHZpYSBhcnJheXNcbiAgICAvL1xuXG5cbiAgICB2YXIgc3RhZ2VzID0gY3JlYXRlU3RhZ2VzKG9wdHMud2lkdGgsIG9wdHMuaGVpZ2h0LCBvcHRzLnRvV2lkdGgsIG9wdHMudG9IZWlnaHQsIF90aGlzNi5vcHRpb25zLnRpbGUsIG9wdHMuX19kZXN0VGlsZUJvcmRlcik7XG4gICAgcmV0dXJuIF90aGlzNi5fX3Byb2Nlc3NTdGFnZXMoc3RhZ2VzLCBmcm9tLCB0bywgb3B0cyk7XG4gIH0pO1xufTsgLy8gUkdCQSBidWZmZXIgcmVzaXplXG4vL1xuXG5cblBpY2EucHJvdG90eXBlLnJlc2l6ZUJ1ZmZlciA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIHZhciBfdGhpczcgPSB0aGlzO1xuXG4gIHZhciBvcHRzID0gYXNzaWduKHt9LCBERUZBVUxUX1JFU0laRV9PUFRTLCBvcHRpb25zKTtcbiAgcmV0dXJuIHRoaXMuaW5pdCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdGhpczcuX19tYXRobGliLnJlc2l6ZUFuZFVuc2hhcnAob3B0cyk7XG4gIH0pO1xufTtcblxuUGljYS5wcm90b3R5cGUudG9CbG9iID0gZnVuY3Rpb24gKGNhbnZhcywgbWltZVR5cGUsIHF1YWxpdHkpIHtcbiAgbWltZVR5cGUgPSBtaW1lVHlwZSB8fCAnaW1hZ2UvcG5nJztcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgaWYgKGNhbnZhcy50b0Jsb2IpIHtcbiAgICAgIGNhbnZhcy50b0Jsb2IoZnVuY3Rpb24gKGJsb2IpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoYmxvYik7XG4gICAgICB9LCBtaW1lVHlwZSwgcXVhbGl0eSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGNhbnZhcy5jb252ZXJ0VG9CbG9iKSB7XG4gICAgICByZXNvbHZlKGNhbnZhcy5jb252ZXJ0VG9CbG9iKHtcbiAgICAgICAgdHlwZTogbWltZVR5cGUsXG4gICAgICAgIHF1YWxpdHk6IHF1YWxpdHlcbiAgICAgIH0pKTtcbiAgICAgIHJldHVybjtcbiAgICB9IC8vIEZhbGxiYWNrIGZvciBvbGQgYnJvd3NlcnNcblxuXG4gICAgdmFyIGFzU3RyaW5nID0gYXRvYihjYW52YXMudG9EYXRhVVJMKG1pbWVUeXBlLCBxdWFsaXR5KS5zcGxpdCgnLCcpWzFdKTtcbiAgICB2YXIgbGVuID0gYXNTdHJpbmcubGVuZ3RoO1xuICAgIHZhciBhc0J1ZmZlciA9IG5ldyBVaW50OEFycmF5KGxlbik7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBhc0J1ZmZlcltpXSA9IGFzU3RyaW5nLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuXG4gICAgcmVzb2x2ZShuZXcgQmxvYihbYXNCdWZmZXJdLCB7XG4gICAgICB0eXBlOiBtaW1lVHlwZVxuICAgIH0pKTtcbiAgfSk7XG59O1xuXG5QaWNhLnByb3RvdHlwZS5kZWJ1ZyA9IGZ1bmN0aW9uICgpIHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBpY2E7XG5cbn0se1wiLi9saWIvbWF0aGxpYlwiOjEsXCIuL2xpYi9wb29sXCI6MTMsXCIuL2xpYi9zdGVwcGVyXCI6MTQsXCIuL2xpYi90aWxlclwiOjE1LFwiLi9saWIvdXRpbHNcIjoxNixcIi4vbGliL3dvcmtlclwiOjE3LFwib2JqZWN0LWFzc2lnblwiOjIzLFwid2Vid29ya2lmeVwiOjI0fV19LHt9LFtdKShcIi9pbmRleC5qc1wiKVxufSk7XG59KTtcblxudmFyIGltYWdlX3RyYXZlcnNlID0gY3JlYXRlQ29tbW9uanNNb2R1bGUoZnVuY3Rpb24gKG1vZHVsZSkge1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gSGVscGVyc1xuLy9cbmZ1bmN0aW9uIGVycm9yKG1lc3NhZ2UsIGNvZGUpIHtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgZXJyLmNvZGUgPSBjb2RlO1xuICByZXR1cm4gZXJyO1xufVxuXG5cbi8vIENvbnZlcnQgbnVtYmVyIHRvIDB4SEggc3RyaW5nXG4vL1xuZnVuY3Rpb24gdG9faGV4KG51bWJlcikge1xuICB2YXIgbiA9IG51bWJlci50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTtcbiAgZm9yICh2YXIgaSA9IDIgLSBuLmxlbmd0aDsgaSA+IDA7IGktLSkgbiA9ICcwJyArIG47XG4gIHJldHVybiAnMHgnICsgbjtcbn1cblxuXG5mdW5jdGlvbiB1dGY4X2VuY29kZShzdHIpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KHN0cikpO1xuICB9IGNhdGNoIChfKSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHV0ZjhfZGVjb2RlKHN0cikge1xuICB0cnkge1xuICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKHN0cikpO1xuICB9IGNhdGNoIChfKSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufVxuXG5cbi8vIENoZWNrIGlmIGlucHV0IGlzIGEgVWludDhBcnJheVxuLy9cbmZ1bmN0aW9uIGlzX3VpbnQ4YXJyYXkoYmluKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYmluKSA9PT0gJ1tvYmplY3QgVWludDhBcnJheV0nO1xufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBFeGlmIHBhcnNlclxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46ICAgVWludDhBcnJheSAtIGpwZWcgZmlsZVxuLy8gIC0gZXhpZl9zdGFydDogTnVtYmVyICAgICAtIHN0YXJ0IG9mIFRJRkYgaGVhZGVyIChhZnRlciBFeGlmXFwwXFwwKVxuLy8gIC0gZXhpZl9lbmQ6ICAgTnVtYmVyICAgICAtIGVuZCBvZiBFeGlmIHNlZ21lbnRcbi8vICAtIG9uX2VudHJ5OiAgIE51bWJlciAgICAgLSBjYWxsYmFja1xuLy9cbmZ1bmN0aW9uIEV4aWZQYXJzZXIoanBlZ19iaW4sIGV4aWZfc3RhcnQsIGV4aWZfZW5kKSB7XG4gIC8vIFVpbnQ4QXJyYXksIGV4aWYgd2l0aG91dCBzaWduYXR1cmUgKHdoaWNoIGlzbid0IGluY2x1ZGVkIGluIG9mZnNldHMpXG4gIHRoaXMuaW5wdXQgICAgICA9IGpwZWdfYmluLnN1YmFycmF5KGV4aWZfc3RhcnQsIGV4aWZfZW5kKTtcblxuICAvLyBvZmZzZXQgY29ycmVjdGlvbiBmb3IgYG9uX2VudHJ5YCBjYWxsYmFja1xuICB0aGlzLnN0YXJ0ICAgICAgPSBleGlmX3N0YXJ0O1xuXG4gIC8vIENoZWNrIFRJRkYgaGVhZGVyIChpbmNsdWRlcyBieXRlIGFsaWdubWVudCBhbmQgZmlyc3QgSUZEIG9mZnNldClcbiAgdmFyIHNpZyA9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgdGhpcy5pbnB1dC5zdWJhcnJheSgwLCA0KSk7XG5cbiAgaWYgKHNpZyAhPT0gJ0lJXFx4MkFcXDAnICYmIHNpZyAhPT0gJ01NXFwwXFx4MkEnKSB7XG4gICAgdGhyb3cgZXJyb3IoJ2ludmFsaWQgVElGRiBzaWduYXR1cmUnLCAnRUJBRERBVEEnKTtcbiAgfVxuXG4gIC8vIHRydWUgaWYgbW90b3JvbGEgKGJpZyBlbmRpYW4pIGJ5dGUgYWxpZ25tZW50LCBmYWxzZSBpZiBpbnRlbFxuICB0aGlzLmJpZ19lbmRpYW4gPSBzaWdbMF0gPT09ICdNJztcbn1cblxuXG5FeGlmUGFyc2VyLnByb3RvdHlwZS5lYWNoID0gZnVuY3Rpb24gKG9uX2VudHJ5KSB7XG4gIC8vIGFsbG93IHByZW1hdHVyZSBleGl0XG4gIHRoaXMuYWJvcnRlZCA9IGZhbHNlO1xuXG4gIHZhciBvZmZzZXQgPSB0aGlzLnJlYWRfdWludDMyKDQpO1xuXG4gIHRoaXMuaWZkc190b19yZWFkID0gWyB7XG4gICAgaWQ6ICAgICAwLFxuICAgIG9mZnNldDogb2Zmc2V0XG4gIH0gXTtcblxuICB3aGlsZSAodGhpcy5pZmRzX3RvX3JlYWQubGVuZ3RoID4gMCAmJiAhdGhpcy5hYm9ydGVkKSB7XG4gICAgdmFyIGkgPSB0aGlzLmlmZHNfdG9fcmVhZC5zaGlmdCgpO1xuICAgIGlmICghaS5vZmZzZXQpIGNvbnRpbnVlO1xuICAgIHRoaXMuc2Nhbl9pZmQoaS5pZCwgaS5vZmZzZXQsIG9uX2VudHJ5KTtcbiAgfVxufTtcblxuXG5FeGlmUGFyc2VyLnByb3RvdHlwZS5maWx0ZXIgPSBmdW5jdGlvbiAob25fZW50cnkpIHtcbiAgdmFyIGlmZHMgPSB7fTtcblxuICAvLyBtYWtlIHN1cmUgSUZEMCBhbHdheXMgZXhpc3RzXG4gIGlmZHMuaWZkMCA9IHsgaWQ6IDAsIGVudHJpZXM6IFtdIH07XG5cbiAgdGhpcy5lYWNoKGZ1bmN0aW9uIChlbnRyeSkge1xuICAgIGlmIChvbl9lbnRyeShlbnRyeSkgPT09IGZhbHNlICYmICFlbnRyeS5pc19zdWJpZmRfbGluaykgcmV0dXJuO1xuICAgIGlmIChlbnRyeS5pc19zdWJpZmRfbGluayAmJiBlbnRyeS5jb3VudCAhPT0gMSAmJiBlbnRyeS5mb3JtYXQgIT09IDQpIHJldHVybjsgLy8gZmlsdGVyIG91dCBib2d1cyBsaW5rc1xuXG4gICAgaWYgKCFpZmRzWydpZmQnICsgZW50cnkuaWZkXSkge1xuICAgICAgaWZkc1snaWZkJyArIGVudHJ5LmlmZF0gPSB7IGlkOiBlbnRyeS5pZmQsIGVudHJpZXM6IFtdIH07XG4gICAgfVxuXG4gICAgaWZkc1snaWZkJyArIGVudHJ5LmlmZF0uZW50cmllcy5wdXNoKGVudHJ5KTtcbiAgfSk7XG5cbiAgLy8gdGh1bWJuYWlscyBhcmUgbm90IHN1cHBvcnRlZCBqdXN0IHlldCwgc28gZGVsZXRlIGFsbCBpbmZvcm1hdGlvbiByZWxhdGVkIHRvIGl0XG4gIGRlbGV0ZSBpZmRzLmlmZDE7XG5cbiAgLy8gQ2FsY3VsYXRlIG91dHB1dCBzaXplXG4gIHZhciBsZW5ndGggPSA4O1xuICBPYmplY3Qua2V5cyhpZmRzKS5mb3JFYWNoKGZ1bmN0aW9uIChpZmRfbm8pIHtcbiAgICBsZW5ndGggKz0gMjtcblxuICAgIGlmZHNbaWZkX25vXS5lbnRyaWVzLmZvckVhY2goZnVuY3Rpb24gKGVudHJ5KSB7XG4gICAgICBsZW5ndGggKz0gMTIgKyAoZW50cnkuZGF0YV9sZW5ndGggPiA0ID8gTWF0aC5jZWlsKGVudHJ5LmRhdGFfbGVuZ3RoIC8gMikgKiAyIDogMCk7XG4gICAgfSk7XG5cbiAgICBsZW5ndGggKz0gNDtcbiAgfSk7XG5cbiAgdGhpcy5vdXRwdXQgPSBuZXcgVWludDhBcnJheShsZW5ndGgpO1xuICB0aGlzLm91dHB1dFswXSA9IHRoaXMub3V0cHV0WzFdID0gKHRoaXMuYmlnX2VuZGlhbiA/ICdNJyA6ICdJJykuY2hhckNvZGVBdCgwKTtcbiAgdGhpcy53cml0ZV91aW50MTYoMiwgMHgyQSk7XG5cbiAgdmFyIG9mZnNldCA9IDg7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy53cml0ZV91aW50MzIoNCwgb2Zmc2V0KTtcblxuICBPYmplY3Qua2V5cyhpZmRzKS5mb3JFYWNoKGZ1bmN0aW9uIChpZmRfbm8pIHtcbiAgICBpZmRzW2lmZF9ub10ud3JpdHRlbl9vZmZzZXQgPSBvZmZzZXQ7XG5cbiAgICB2YXIgaWZkX3N0YXJ0ID0gb2Zmc2V0O1xuICAgIHZhciBpZmRfZW5kICAgPSBpZmRfc3RhcnQgKyAyICsgaWZkc1tpZmRfbm9dLmVudHJpZXMubGVuZ3RoICogMTIgKyA0O1xuICAgIG9mZnNldCA9IGlmZF9lbmQ7XG5cbiAgICBzZWxmLndyaXRlX3VpbnQxNihpZmRfc3RhcnQsIGlmZHNbaWZkX25vXS5lbnRyaWVzLmxlbmd0aCk7XG5cbiAgICBpZmRzW2lmZF9ub10uZW50cmllcy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAvLyBJRkQgZW50cmllcyBtdXN0IGJlIGluIG9yZGVyIG9mIGluY3JlYXNpbmcgdGFnIElEc1xuICAgICAgcmV0dXJuIGEudGFnIC0gYi50YWc7XG4gICAgfSkuZm9yRWFjaChmdW5jdGlvbiAoZW50cnksIGlkeCkge1xuICAgICAgdmFyIGVudHJ5X29mZnNldCA9IGlmZF9zdGFydCArIDIgKyBpZHggKiAxMjtcblxuICAgICAgc2VsZi53cml0ZV91aW50MTYoZW50cnlfb2Zmc2V0LCBlbnRyeS50YWcpO1xuICAgICAgc2VsZi53cml0ZV91aW50MTYoZW50cnlfb2Zmc2V0ICsgMiwgZW50cnkuZm9ybWF0KTtcbiAgICAgIHNlbGYud3JpdGVfdWludDMyKGVudHJ5X29mZnNldCArIDQsIGVudHJ5LmNvdW50KTtcblxuICAgICAgaWYgKGVudHJ5LmlzX3N1YmlmZF9saW5rKSB7XG4gICAgICAgIC8vIGZpbGxlZCBpbiBsYXRlclxuICAgICAgICBpZiAoaWZkc1snaWZkJyArIGVudHJ5LnRhZ10pIGlmZHNbJ2lmZCcgKyBlbnRyeS50YWddLmxpbmtfb2Zmc2V0ID0gZW50cnlfb2Zmc2V0ICsgODtcbiAgICAgIH0gZWxzZSBpZiAoZW50cnkuZGF0YV9sZW5ndGggPD0gNCkge1xuICAgICAgICBzZWxmLm91dHB1dC5zZXQoXG4gICAgICAgICAgc2VsZi5pbnB1dC5zdWJhcnJheShlbnRyeS5kYXRhX29mZnNldCAtIHNlbGYuc3RhcnQsIGVudHJ5LmRhdGFfb2Zmc2V0IC0gc2VsZi5zdGFydCArIDQpLFxuICAgICAgICAgIGVudHJ5X29mZnNldCArIDhcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlbGYud3JpdGVfdWludDMyKGVudHJ5X29mZnNldCArIDgsIG9mZnNldCk7XG4gICAgICAgIHNlbGYub3V0cHV0LnNldChcbiAgICAgICAgICBzZWxmLmlucHV0LnN1YmFycmF5KGVudHJ5LmRhdGFfb2Zmc2V0IC0gc2VsZi5zdGFydCwgZW50cnkuZGF0YV9vZmZzZXQgLSBzZWxmLnN0YXJ0ICsgZW50cnkuZGF0YV9sZW5ndGgpLFxuICAgICAgICAgIG9mZnNldFxuICAgICAgICApO1xuICAgICAgICBvZmZzZXQgKz0gTWF0aC5jZWlsKGVudHJ5LmRhdGFfbGVuZ3RoIC8gMikgKiAyO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdmFyIG5leHRfaWZkID0gaWZkc1snaWZkJyArIChpZmRzW2lmZF9ub10uaWQgKyAxKV07XG4gICAgaWYgKG5leHRfaWZkKSBuZXh0X2lmZC5saW5rX29mZnNldCA9IGlmZF9lbmQgLSA0O1xuICB9KTtcblxuICBPYmplY3Qua2V5cyhpZmRzKS5mb3JFYWNoKGZ1bmN0aW9uIChpZmRfbm8pIHtcbiAgICBpZiAoaWZkc1tpZmRfbm9dLndyaXR0ZW5fb2Zmc2V0ICYmIGlmZHNbaWZkX25vXS5saW5rX29mZnNldCkge1xuICAgICAgc2VsZi53cml0ZV91aW50MzIoaWZkc1tpZmRfbm9dLmxpbmtfb2Zmc2V0LCBpZmRzW2lmZF9ub10ud3JpdHRlbl9vZmZzZXQpO1xuICAgIH1cbiAgfSk7XG5cbiAgaWYgKHRoaXMub3V0cHV0Lmxlbmd0aCAhPT0gb2Zmc2V0KSB0aHJvdyBlcnJvcignaW50ZXJuYWwgZXJyb3I6IGluY29ycmVjdCBidWZmZXIgc2l6ZSBhbGxvY2F0ZWQnKTtcblxuICByZXR1cm4gdGhpcy5vdXRwdXQ7XG59O1xuXG5cbkV4aWZQYXJzZXIucHJvdG90eXBlLnJlYWRfdWludDE2ID0gZnVuY3Rpb24gKG9mZnNldCkge1xuICB2YXIgZCA9IHRoaXMuaW5wdXQ7XG4gIGlmIChvZmZzZXQgKyAyID4gZC5sZW5ndGgpIHRocm93IGVycm9yKCd1bmV4cGVjdGVkIEVPRicsICdFQkFEREFUQScpO1xuXG4gIHJldHVybiB0aGlzLmJpZ19lbmRpYW4gP1xuICAgIGRbb2Zmc2V0XSAqIDB4MTAwICsgZFtvZmZzZXQgKyAxXSA6XG4gICAgZFtvZmZzZXRdICsgZFtvZmZzZXQgKyAxXSAqIDB4MTAwO1xufTtcblxuXG5FeGlmUGFyc2VyLnByb3RvdHlwZS5yZWFkX3VpbnQzMiA9IGZ1bmN0aW9uIChvZmZzZXQpIHtcbiAgdmFyIGQgPSB0aGlzLmlucHV0O1xuICBpZiAob2Zmc2V0ICsgNCA+IGQubGVuZ3RoKSB0aHJvdyBlcnJvcigndW5leHBlY3RlZCBFT0YnLCAnRUJBRERBVEEnKTtcblxuICByZXR1cm4gdGhpcy5iaWdfZW5kaWFuID9cbiAgICBkW29mZnNldF0gKiAweDEwMDAwMDAgKyBkW29mZnNldCArIDFdICogMHgxMDAwMCArIGRbb2Zmc2V0ICsgMl0gKiAweDEwMCArIGRbb2Zmc2V0ICsgM10gOlxuICAgIGRbb2Zmc2V0XSArIGRbb2Zmc2V0ICsgMV0gKiAweDEwMCArIGRbb2Zmc2V0ICsgMl0gKiAweDEwMDAwICsgZFtvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMDtcbn07XG5cblxuRXhpZlBhcnNlci5wcm90b3R5cGUud3JpdGVfdWludDE2ID0gZnVuY3Rpb24gKG9mZnNldCwgdmFsdWUpIHtcbiAgdmFyIGQgPSB0aGlzLm91dHB1dDtcblxuICBpZiAodGhpcy5iaWdfZW5kaWFuKSB7XG4gICAgZFtvZmZzZXRdICAgICA9ICh2YWx1ZSA+Pj4gOCkgJiAweEZGO1xuICAgIGRbb2Zmc2V0ICsgMV0gPSB2YWx1ZSAmIDB4RkY7XG4gIH0gZWxzZSB7XG4gICAgZFtvZmZzZXRdICAgICA9IHZhbHVlICYgMHhGRjtcbiAgICBkW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KSAmIDB4RkY7XG4gIH1cbn07XG5cblxuRXhpZlBhcnNlci5wcm90b3R5cGUud3JpdGVfdWludDMyID0gZnVuY3Rpb24gKG9mZnNldCwgdmFsdWUpIHtcbiAgdmFyIGQgPSB0aGlzLm91dHB1dDtcblxuICBpZiAodGhpcy5iaWdfZW5kaWFuKSB7XG4gICAgZFtvZmZzZXRdICAgICA9ICh2YWx1ZSA+Pj4gMjQpICYgMHhGRjtcbiAgICBkW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNikgJiAweEZGO1xuICAgIGRbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpICYgMHhGRjtcbiAgICBkW29mZnNldCArIDNdID0gdmFsdWUgJiAweEZGO1xuICB9IGVsc2Uge1xuICAgIGRbb2Zmc2V0XSAgICAgPSB2YWx1ZSAmIDB4RkY7XG4gICAgZFtvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOCkgJiAweEZGO1xuICAgIGRbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KSAmIDB4RkY7XG4gICAgZFtvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpICYgMHhGRjtcbiAgfVxufTtcblxuXG5FeGlmUGFyc2VyLnByb3RvdHlwZS5pc19zdWJpZmRfbGluayA9IGZ1bmN0aW9uIChpZmQsIHRhZykge1xuICByZXR1cm4gKGlmZCA9PT0gMCAmJiB0YWcgPT09IDB4ODc2OSkgfHwgLy8gU3ViSUZEXG4gICAgICAgICAoaWZkID09PSAwICYmIHRhZyA9PT0gMHg4ODI1KSB8fCAvLyBHUFMgSW5mb1xuICAgICAgICAgKGlmZCA9PT0gMHg4NzY5ICYmIHRhZyA9PT0gMHhBMDA1KTsgLy8gSW50ZXJvcCBJRkRcbn07XG5cblxuLy8gUmV0dXJucyBieXRlIGxlbmd0aCBvZiBhIHNpbmdsZSBjb21wb25lbnQgb2YgYSBnaXZlbiBmb3JtYXRcbi8vXG5FeGlmUGFyc2VyLnByb3RvdHlwZS5leGlmX2Zvcm1hdF9sZW5ndGggPSBmdW5jdGlvbiAoZm9ybWF0KSB7XG4gIHN3aXRjaCAoZm9ybWF0KSB7XG4gICAgY2FzZSAxOiAvLyBieXRlXG4gICAgY2FzZSAyOiAvLyBhc2NpaVxuICAgIGNhc2UgNjogLy8gc2J5dGVcbiAgICBjYXNlIDc6IC8vIHVuZGVmaW5lZFxuICAgICAgcmV0dXJuIDE7XG5cbiAgICBjYXNlIDM6IC8vIHNob3J0XG4gICAgY2FzZSA4OiAvLyBzc2hvcnRcbiAgICAgIHJldHVybiAyO1xuXG4gICAgY2FzZSA0OiAgLy8gbG9uZ1xuICAgIGNhc2UgOTogIC8vIHNsb25nXG4gICAgY2FzZSAxMTogLy8gZmxvYXRcbiAgICAgIHJldHVybiA0O1xuXG4gICAgY2FzZSA1OiAgLy8gcmF0aW9uYWxcbiAgICBjYXNlIDEwOiAvLyBzcmF0aW9uYWxcbiAgICBjYXNlIDEyOiAvLyBkb3VibGVcbiAgICAgIHJldHVybiA4O1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIHVua25vd24gdHlwZVxuICAgICAgcmV0dXJuIDA7XG4gIH1cbn07XG5cblxuLy8gUmVhZHMgRXhpZiBkYXRhXG4vL1xuRXhpZlBhcnNlci5wcm90b3R5cGUuZXhpZl9mb3JtYXRfcmVhZCA9IGZ1bmN0aW9uIChmb3JtYXQsIG9mZnNldCkge1xuICB2YXIgdjtcblxuICBzd2l0Y2ggKGZvcm1hdCkge1xuICAgIGNhc2UgMTogLy8gYnl0ZVxuICAgIGNhc2UgMjogLy8gYXNjaWlcbiAgICAgIHYgPSB0aGlzLmlucHV0W29mZnNldF07XG4gICAgICByZXR1cm4gdjtcblxuICAgIGNhc2UgNjogLy8gc2J5dGVcbiAgICAgIHYgPSB0aGlzLmlucHV0W29mZnNldF07XG4gICAgICByZXR1cm4gdiB8ICh2ICYgMHg4MCkgKiAweDFmZmZmZmU7XG5cbiAgICBjYXNlIDM6IC8vIHNob3J0XG4gICAgICB2ID0gdGhpcy5yZWFkX3VpbnQxNihvZmZzZXQpO1xuICAgICAgcmV0dXJuIHY7XG5cbiAgICBjYXNlIDg6IC8vIHNzaG9ydFxuICAgICAgdiA9IHRoaXMucmVhZF91aW50MTYob2Zmc2V0KTtcbiAgICAgIHJldHVybiB2IHwgKHYgJiAweDgwMDApICogMHgxZmZmZTtcblxuICAgIGNhc2UgNDogLy8gbG9uZ1xuICAgICAgdiA9IHRoaXMucmVhZF91aW50MzIob2Zmc2V0KTtcbiAgICAgIHJldHVybiB2O1xuXG4gICAgY2FzZSA5OiAvLyBzbG9uZ1xuICAgICAgdiA9IHRoaXMucmVhZF91aW50MzIob2Zmc2V0KTtcbiAgICAgIHJldHVybiB2IHwgMDtcblxuICAgIGNhc2UgNTogIC8vIHJhdGlvbmFsXG4gICAgY2FzZSAxMDogLy8gc3JhdGlvbmFsXG4gICAgY2FzZSAxMTogLy8gZmxvYXRcbiAgICBjYXNlIDEyOiAvLyBkb3VibGVcbiAgICAgIHJldHVybiBudWxsOyAvLyBub3QgaW1wbGVtZW50ZWRcblxuICAgIGNhc2UgNzogLy8gdW5kZWZpbmVkXG4gICAgICByZXR1cm4gbnVsbDsgLy8gYmxvYlxuXG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIHVua25vd24gdHlwZVxuICAgICAgcmV0dXJuIG51bGw7XG4gIH1cbn07XG5cblxuRXhpZlBhcnNlci5wcm90b3R5cGUuc2Nhbl9pZmQgPSBmdW5jdGlvbiAoaWZkX25vLCBvZmZzZXQsIG9uX2VudHJ5KSB7XG4gIHZhciBlbnRyeV9jb3VudCA9IHRoaXMucmVhZF91aW50MTYob2Zmc2V0KTtcblxuICBvZmZzZXQgKz0gMjtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGVudHJ5X2NvdW50OyBpKyspIHtcbiAgICB2YXIgdGFnICAgID0gdGhpcy5yZWFkX3VpbnQxNihvZmZzZXQpO1xuICAgIHZhciBmb3JtYXQgPSB0aGlzLnJlYWRfdWludDE2KG9mZnNldCArIDIpO1xuICAgIHZhciBjb3VudCAgPSB0aGlzLnJlYWRfdWludDMyKG9mZnNldCArIDQpO1xuXG4gICAgdmFyIGNvbXBfbGVuZ3RoICAgID0gdGhpcy5leGlmX2Zvcm1hdF9sZW5ndGgoZm9ybWF0KTtcbiAgICB2YXIgZGF0YV9sZW5ndGggICAgPSBjb3VudCAqIGNvbXBfbGVuZ3RoO1xuICAgIHZhciBkYXRhX29mZnNldCAgICA9IGRhdGFfbGVuZ3RoIDw9IDQgPyBvZmZzZXQgKyA4IDogdGhpcy5yZWFkX3VpbnQzMihvZmZzZXQgKyA4KTtcbiAgICB2YXIgaXNfc3ViaWZkX2xpbmsgPSBmYWxzZTtcblxuICAgIGlmIChkYXRhX29mZnNldCArIGRhdGFfbGVuZ3RoID4gdGhpcy5pbnB1dC5sZW5ndGgpIHtcbiAgICAgIHRocm93IGVycm9yKCd1bmV4cGVjdGVkIEVPRicsICdFQkFEREFUQScpO1xuICAgIH1cblxuICAgIHZhciB2YWx1ZSA9IFtdO1xuICAgIHZhciBjb21wX29mZnNldCA9IGRhdGFfb2Zmc2V0O1xuXG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBjb3VudDsgaisrLCBjb21wX29mZnNldCArPSBjb21wX2xlbmd0aCkge1xuICAgICAgdmFyIGl0ZW0gPSB0aGlzLmV4aWZfZm9ybWF0X3JlYWQoZm9ybWF0LCBjb21wX29mZnNldCk7XG4gICAgICBpZiAoaXRlbSA9PT0gbnVsbCkge1xuICAgICAgICB2YWx1ZSA9IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgdmFsdWUucHVzaChpdGVtKTtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgZm9ybWF0ID09PSAyKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YWx1ZSA9IHV0ZjhfZGVjb2RlKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgdmFsdWUpKTtcbiAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgdmFsdWUgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBpZiAodmFsdWUgJiYgdmFsdWVbdmFsdWUubGVuZ3RoIC0gMV0gPT09ICdcXDAnKSB2YWx1ZSA9IHZhbHVlLnNsaWNlKDAsIC0xKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc19zdWJpZmRfbGluayhpZmRfbm8sIHRhZykpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSAmJiBOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlWzBdKSAmJiB2YWx1ZVswXSA+IDApIHtcbiAgICAgICAgdGhpcy5pZmRzX3RvX3JlYWQucHVzaCh7XG4gICAgICAgICAgaWQ6ICAgICB0YWcsXG4gICAgICAgICAgb2Zmc2V0OiB2YWx1ZVswXVxuICAgICAgICB9KTtcbiAgICAgICAgaXNfc3ViaWZkX2xpbmsgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBlbnRyeSA9IHtcbiAgICAgIGlzX2JpZ19lbmRpYW46ICB0aGlzLmJpZ19lbmRpYW4sXG4gICAgICBpZmQ6ICAgICAgICAgICAgaWZkX25vLFxuICAgICAgdGFnOiAgICAgICAgICAgIHRhZyxcbiAgICAgIGZvcm1hdDogICAgICAgICBmb3JtYXQsXG4gICAgICBjb3VudDogICAgICAgICAgY291bnQsXG4gICAgICBlbnRyeV9vZmZzZXQ6ICAgb2Zmc2V0ICsgdGhpcy5zdGFydCxcbiAgICAgIGRhdGFfbGVuZ3RoOiAgICBkYXRhX2xlbmd0aCxcbiAgICAgIGRhdGFfb2Zmc2V0OiAgICBkYXRhX29mZnNldCArIHRoaXMuc3RhcnQsXG4gICAgICB2YWx1ZTogICAgICAgICAgdmFsdWUsXG4gICAgICBpc19zdWJpZmRfbGluazogaXNfc3ViaWZkX2xpbmtcbiAgICB9O1xuXG4gICAgaWYgKG9uX2VudHJ5KGVudHJ5KSA9PT0gZmFsc2UpIHtcbiAgICAgIHRoaXMuYWJvcnRlZCA9IHRydWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgb2Zmc2V0ICs9IDEyO1xuICB9XG5cbiAgaWYgKGlmZF9ubyA9PT0gMCkge1xuICAgIHRoaXMuaWZkc190b19yZWFkLnB1c2goe1xuICAgICAgaWQ6ICAgICAxLFxuICAgICAgb2Zmc2V0OiB0aGlzLnJlYWRfdWludDMyKG9mZnNldClcbiAgICB9KTtcbiAgfVxufTtcblxuXG4vLyBDaGVjayB3aGV0aGVyIGlucHV0IGlzIGEgSlBFRyBpbWFnZVxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46IFVpbnQ4QXJyYXkgLSBqcGVnIGZpbGVcbi8vXG4vLyBSZXR1cm5zIHRydWUgaWYgaXQgaXMgYW5kIGZhbHNlIG90aGVyd2lzZVxuLy9cbm1vZHVsZS5leHBvcnRzLmlzX2pwZWcgPSBmdW5jdGlvbiAoanBlZ19iaW4pIHtcbiAgcmV0dXJuIGpwZWdfYmluLmxlbmd0aCA+PSA0ICYmIGpwZWdfYmluWzBdID09PSAweEZGICYmIGpwZWdfYmluWzFdID09PSAweEQ4ICYmIGpwZWdfYmluWzJdID09PSAweEZGO1xufTtcblxuXG4vLyBDYWxsIGFuIGl0ZXJhdG9yIG9uIGVhY2ggc2VnbWVudCBpbiB0aGUgZ2l2ZW4gSlBFRyBpbWFnZVxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46ICAgVWludDhBcnJheSAtIGpwZWcgZmlsZVxuLy8gIC0gb25fc2VnbWVudDogRnVuY3Rpb24gLSBjYWxsYmFjayBleGVjdXRlZCBvbiBlYWNoIEpQRUcgbWFya2VyIHNlZ21lbnRcbi8vICAgIC0gc2VnbWVudDogIE9iamVjdFxuLy8gICAgICAtIGNvZGU6ICAgTnVtYmVyIC0gbWFya2VyIHR5cGUgKDJuZCBieXRlLCBlLmcuIDB4RTAgZm9yIEFQUDApXG4vLyAgICAgIC0gb2Zmc2V0OiBOdW1iZXIgLSBvZmZzZXQgb2YgdGhlIGZpcnN0IGJ5dGUgKDB4RkYpIHJlbGF0aXZlIHRvIGBqcGVnX2JpbmAgc3RhcnRcbi8vICAgICAgLSBsZW5ndGg6IE51bWJlciAtIGxlbmd0aCBvZiB0aGUgZW50aXJlIG1hcmtlciBzZWdtZW50IGluY2x1ZGluZyBmaXJzdCB0d28gYnl0ZXMgYW5kIGxlbmd0aFxuLy8gICAgICAgIC0gMiBmb3Igc3RhbmRhbG9uZSBtYXJrZXJzXG4vLyAgICAgICAgLSA0K2xlbmd0aCBmb3IgbWFya2VycyB3aXRoIGRhdGFcbi8vXG4vLyBJdGVyYXRpb24gc3RvcHMgd2hlbiBgRU9JYCAoMHhGRkQ5KSBtYXJrZXIgaXMgcmVhY2hlZCBvciBpZiBgb25fc2VnbWVudGBcbi8vIGZ1bmN0aW9uIHJldHVybnMgYGZhbHNlYC5cbi8vXG5tb2R1bGUuZXhwb3J0cy5qcGVnX3NlZ21lbnRzX2VhY2ggPSBmdW5jdGlvbiAoanBlZ19iaW4sIG9uX3NlZ21lbnQpIHtcbiAgaWYgKCFpc191aW50OGFycmF5KGpwZWdfYmluKSkge1xuICAgIHRocm93IGVycm9yKCdJbnZhbGlkIGFyZ3VtZW50IChqcGVnX2JpbiksIFVpbnQ4QXJyYXkgZXhwZWN0ZWQnLCAnRUlOVkFMJyk7XG4gIH1cblxuICBpZiAodHlwZW9mIG9uX3NlZ21lbnQgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBlcnJvcignSW52YWxpZCBhcmd1bWVudCAob25fc2VnbWVudCksIEZ1bmN0aW9uIGV4cGVjdGVkJywgJ0VJTlZBTCcpO1xuICB9XG5cbiAgaWYgKCFtb2R1bGUuZXhwb3J0cy5pc19qcGVnKGpwZWdfYmluKSkge1xuICAgIHRocm93IGVycm9yKCdVbmtub3duIGZpbGUgZm9ybWF0JywgJ0VOT1RKUEVHJyk7XG4gIH1cblxuICB2YXIgb2Zmc2V0ID0gMCwgbGVuZ3RoID0ganBlZ19iaW4ubGVuZ3RoLCBpbnNpZGVfc2NhbiA9IGZhbHNlO1xuXG4gIGZvciAoOzspIHtcbiAgICB2YXIgc2VnbWVudF9jb2RlLCBzZWdtZW50X2xlbmd0aDtcblxuICAgIGlmIChvZmZzZXQgKyAxID49IGxlbmd0aCkgdGhyb3cgZXJyb3IoJ1VuZXhwZWN0ZWQgRU9GJywgJ0VCQUREQVRBJyk7XG4gICAgdmFyIGJ5dGUxID0ganBlZ19iaW5bb2Zmc2V0XTtcbiAgICB2YXIgYnl0ZTIgPSBqcGVnX2JpbltvZmZzZXQgKyAxXTtcblxuICAgIGlmIChieXRlMSA9PT0gMHhGRiAmJiBieXRlMiA9PT0gMHhGRikge1xuICAgICAgLy8gcGFkZGluZ1xuICAgICAgc2VnbWVudF9jb2RlID0gMHhGRjtcbiAgICAgIHNlZ21lbnRfbGVuZ3RoID0gMTtcblxuICAgIH0gZWxzZSBpZiAoYnl0ZTEgPT09IDB4RkYgJiYgYnl0ZTIgIT09IDApIHtcbiAgICAgIC8vIG1hcmtlclxuICAgICAgc2VnbWVudF9jb2RlID0gYnl0ZTI7XG4gICAgICBzZWdtZW50X2xlbmd0aCA9IDI7XG5cbiAgICAgIGlmICgoMHhEMCA8PSBzZWdtZW50X2NvZGUgJiYgc2VnbWVudF9jb2RlIDw9IDB4RDkpIHx8IHNlZ21lbnRfY29kZSA9PT0gMHgwMSkgOyBlbHNlIHtcbiAgICAgICAgaWYgKG9mZnNldCArIDMgPj0gbGVuZ3RoKSB0aHJvdyBlcnJvcignVW5leHBlY3RlZCBFT0YnLCAnRUJBRERBVEEnKTtcbiAgICAgICAgc2VnbWVudF9sZW5ndGggKz0ganBlZ19iaW5bb2Zmc2V0ICsgMl0gKiAweDEwMCArIGpwZWdfYmluW29mZnNldCArIDNdO1xuICAgICAgICBpZiAoc2VnbWVudF9sZW5ndGggPCAyKSB0aHJvdyBlcnJvcignSW52YWxpZCBzZWdtZW50IGxlbmd0aCcsICdFQkFEREFUQScpO1xuICAgICAgICBpZiAob2Zmc2V0ICsgc2VnbWVudF9sZW5ndGggLSAxID49IGxlbmd0aCkgdGhyb3cgZXJyb3IoJ1VuZXhwZWN0ZWQgRU9GJywgJ0VCQUREQVRBJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbnNpZGVfc2Nhbikge1xuICAgICAgICBpZiAoc2VnbWVudF9jb2RlID49IDB4RDAgJiYgc2VnbWVudF9jb2RlIDw9IDB4RDcpIDsgZWxzZSB7XG4gICAgICAgICAgaW5zaWRlX3NjYW4gPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoc2VnbWVudF9jb2RlID09PSAweERBIC8qIFNPUyAqLykgaW5zaWRlX3NjYW4gPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoaW5zaWRlX3NjYW4pIHtcbiAgICAgIC8vIGVudHJvcHktZW5jb2RlZCBzZWdtZW50XG4gICAgICBmb3IgKHZhciBwb3MgPSBvZmZzZXQgKyAxOyA7IHBvcysrKSB7XG4gICAgICAgIC8vIHNjYW4gdW50aWwgd2UgZmluZCBGRlxuICAgICAgICBpZiAocG9zID49IGxlbmd0aCkgdGhyb3cgZXJyb3IoJ1VuZXhwZWN0ZWQgRU9GJywgJ0VCQUREQVRBJyk7XG4gICAgICAgIGlmIChqcGVnX2Jpbltwb3NdID09PSAweEZGKSB7XG4gICAgICAgICAgaWYgKHBvcyArIDEgPj0gbGVuZ3RoKSB0aHJvdyBlcnJvcignVW5leHBlY3RlZCBFT0YnLCAnRUJBRERBVEEnKTtcbiAgICAgICAgICBpZiAoanBlZ19iaW5bcG9zICsgMV0gIT09IDApIHtcbiAgICAgICAgICAgIHNlZ21lbnRfY29kZSA9IDA7XG4gICAgICAgICAgICBzZWdtZW50X2xlbmd0aCA9IHBvcyAtIG9mZnNldDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBlcnJvcignVW5leHBlY3RlZCBieXRlIGF0IHNlZ21lbnQgc3RhcnQ6ICcgKyB0b19oZXgoYnl0ZTEpICtcbiAgICAgICAgJyAob2Zmc2V0ICcgKyB0b19oZXgob2Zmc2V0KSArICcpJywgJ0VCQUREQVRBJyk7XG4gICAgfVxuXG4gICAgaWYgKG9uX3NlZ21lbnQoeyBjb2RlOiBzZWdtZW50X2NvZGUsIG9mZnNldDogb2Zmc2V0LCBsZW5ndGg6IHNlZ21lbnRfbGVuZ3RoIH0pID09PSBmYWxzZSkgYnJlYWs7XG4gICAgaWYgKHNlZ21lbnRfY29kZSA9PT0gMHhEOSAvKiBFT0kgKi8pIGJyZWFrO1xuICAgIG9mZnNldCArPSBzZWdtZW50X2xlbmd0aDtcbiAgfVxufTtcblxuXG4vLyBSZXBsYWNlIG9yIHJlbW92ZSBzZWdtZW50cyBpbiB0aGUgZ2l2ZW4gSlBFRyBpbWFnZVxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46ICAgVWludDhBcnJheSAtIGpwZWcgZmlsZVxuLy8gIC0gb25fc2VnbWVudDogRnVuY3Rpb24gLSBjYWxsYmFjayBleGVjdXRlZCBvbiBlYWNoIEpQRUcgbWFya2VyIHNlZ21lbnRcbi8vICAgIC0gc2VnbWVudDogIE9iamVjdFxuLy8gICAgICAtIGNvZGU6ICAgTnVtYmVyIC0gbWFya2VyIHR5cGUgKDJuZCBieXRlLCBlLmcuIDB4RTAgZm9yIEFQUDApXG4vLyAgICAgIC0gb2Zmc2V0OiBOdW1iZXIgLSBvZmZzZXQgb2YgdGhlIGZpcnN0IGJ5dGUgKDB4RkYpIHJlbGF0aXZlIHRvIGBqcGVnX2JpbmAgc3RhcnRcbi8vICAgICAgLSBsZW5ndGg6IE51bWJlciAtIGxlbmd0aCBvZiB0aGUgZW50aXJlIG1hcmtlciBzZWdtZW50IGluY2x1ZGluZyBmaXJzdCB0d28gYnl0ZXMgYW5kIGxlbmd0aFxuLy8gICAgICAgIC0gMiBmb3Igc3RhbmRhbG9uZSBtYXJrZXJzXG4vLyAgICAgICAgLSA0K2xlbmd0aCBmb3IgbWFya2VycyB3aXRoIGRhdGFcbi8vXG4vLyBgb25fc2VnbWVudGAgZnVuY3Rpb24gc2hvdWxkIHJldHVybiBvbmUgb2YgdGhlIGZvbGxvd2luZzpcbi8vICAtIGBmYWxzZWAgICAgICAgIC0gc2VnbWVudCBpcyByZW1vdmVkIGZyb20gdGhlIG91dHB1dFxuLy8gIC0gVWludDhBcnJheSAgICAgLSBzZWdtZW50IGlzIHJlcGxhY2VkIHdpdGggdGhlIG5ldyBkYXRhXG4vLyAgLSBbIFVpbnQ4QXJyYXkgXSAtIHNlZ21lbnQgaXMgcmVwbGFjZWQgd2l0aCB0aGUgbmV3IGRhdGFcbi8vICAtIGFueXRoaW5nIGVsc2UgIC0gc2VnbWVudCBpcyBjb3BpZWQgdG8gdGhlIG91dHB1dCBhcyBpc1xuLy9cbi8vIEFueSBkYXRhIGFmdGVyIGBFT0lgICgweEZGRDkpIG1hcmtlciBpcyByZW1vdmVkLlxuLy9cbm1vZHVsZS5leHBvcnRzLmpwZWdfc2VnbWVudHNfZmlsdGVyID0gZnVuY3Rpb24gKGpwZWdfYmluLCBvbl9zZWdtZW50KSB7XG4gIGlmICghaXNfdWludDhhcnJheShqcGVnX2JpbikpIHtcbiAgICB0aHJvdyBlcnJvcignSW52YWxpZCBhcmd1bWVudCAoanBlZ19iaW4pLCBVaW50OEFycmF5IGV4cGVjdGVkJywgJ0VJTlZBTCcpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvbl9zZWdtZW50ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgZXJyb3IoJ0ludmFsaWQgYXJndW1lbnQgKG9uX3NlZ21lbnQpLCBGdW5jdGlvbiBleHBlY3RlZCcsICdFSU5WQUwnKTtcbiAgfVxuXG4gIHZhciByYW5nZXMgPSBbXTtcbiAgdmFyIG91dF9sZW5ndGggPSAwO1xuXG4gIG1vZHVsZS5leHBvcnRzLmpwZWdfc2VnbWVudHNfZWFjaChqcGVnX2JpbiwgZnVuY3Rpb24gKHNlZ21lbnQpIHtcbiAgICB2YXIgbmV3X3NlZ21lbnQgPSBvbl9zZWdtZW50KHNlZ21lbnQpO1xuXG4gICAgaWYgKGlzX3VpbnQ4YXJyYXkobmV3X3NlZ21lbnQpKSB7XG4gICAgICByYW5nZXMucHVzaCh7IGRhdGE6IG5ld19zZWdtZW50IH0pO1xuICAgICAgb3V0X2xlbmd0aCArPSBuZXdfc2VnbWVudC5sZW5ndGg7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KG5ld19zZWdtZW50KSkge1xuICAgICAgbmV3X3NlZ21lbnQuZmlsdGVyKGlzX3VpbnQ4YXJyYXkpLmZvckVhY2goZnVuY3Rpb24gKHMpIHtcbiAgICAgICAgcmFuZ2VzLnB1c2goeyBkYXRhOiBzIH0pO1xuICAgICAgICBvdXRfbGVuZ3RoICs9IHMubGVuZ3RoO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChuZXdfc2VnbWVudCAhPT0gZmFsc2UpIHtcbiAgICAgIHZhciBuZXdfcmFuZ2UgPSB7IHN0YXJ0OiBzZWdtZW50Lm9mZnNldCwgZW5kOiBzZWdtZW50Lm9mZnNldCArIHNlZ21lbnQubGVuZ3RoIH07XG5cbiAgICAgIGlmIChyYW5nZXMubGVuZ3RoID4gMCAmJiByYW5nZXNbcmFuZ2VzLmxlbmd0aCAtIDFdLmVuZCA9PT0gbmV3X3JhbmdlLnN0YXJ0KSB7XG4gICAgICAgIHJhbmdlc1tyYW5nZXMubGVuZ3RoIC0gMV0uZW5kID0gbmV3X3JhbmdlLmVuZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJhbmdlcy5wdXNoKG5ld19yYW5nZSk7XG4gICAgICB9XG5cbiAgICAgIG91dF9sZW5ndGggKz0gc2VnbWVudC5sZW5ndGg7XG4gICAgfVxuICB9KTtcblxuICB2YXIgcmVzdWx0ID0gbmV3IFVpbnQ4QXJyYXkob3V0X2xlbmd0aCk7XG4gIHZhciBvZmZzZXQgPSAwO1xuXG4gIHJhbmdlcy5mb3JFYWNoKGZ1bmN0aW9uIChyYW5nZSkge1xuICAgIHZhciBkYXRhID0gcmFuZ2UuZGF0YSB8fCBqcGVnX2Jpbi5zdWJhcnJheShyYW5nZS5zdGFydCwgcmFuZ2UuZW5kKTtcbiAgICByZXN1bHQuc2V0KGRhdGEsIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IGRhdGEubGVuZ3RoO1xuICB9KTtcblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuXG4vLyBDYWxsIGFuIGl0ZXJhdG9yIG9uIGVhY2ggRXhpZiBlbnRyeSBpbiB0aGUgZ2l2ZW4gSlBFRyBpbWFnZVxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46IFVpbnQ4QXJyYXkgLSBqcGVnIGZpbGVcbi8vICAtIG9uX2VudHJ5OiBGdW5jdGlvbiAtIGNhbGxiYWNrIGV4ZWN1dGVkIG9uIGVhY2ggRXhpZiBlbnRyeVxuLy8gICAgLSBlbnRyeTogIE9iamVjdFxuLy8gICAgICAtIGlzX2JpZ19lbmRpYW46ICBCb29sZWFuIC0gd2hldGhlciBFeGlmIHVzZXMgYmlnIG9yIGxpdHRsZSBlbmRpYW4gYnl0ZSBhbGlnbm1lbnRcbi8vICAgICAgLSBpZmQ6ICAgICAgICAgICAgTnVtYmVyICAtIElGRCBpZGVudGlmaWVyICgwIGZvciBJRkQwLCAxIGZvciBJRkQxLCAweDg3NjkgZm9yIFN1YklGRCxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4ODI1IGZvciBHUFMgSW5mbywgMHhBMDA1IGZvciBJbnRlcm9wIElGRClcbi8vICAgICAgLSB0YWc6ICAgICAgICAgICAgTnVtYmVyICAtIGV4aWYgZW50cnkgdGFnICgweDAxMTAgLSBjYW1lcmEgbmFtZSwgMHgwMTEyIC0gb3JpZW50YXRpb24sIGV0Yy4gLSBzZWUgRXhpZiBzcGVjKVxuLy8gICAgICAtIGZvcm1hdDogICAgICAgICBOdW1iZXIgIC0gZXhpZiBlbnRyeSBmb3JtYXQgKDEgLSBieXRlLCAyIC0gYXNjaWksIDMgLSBzaG9ydCwgZXRjLiAtIHNlZSBFeGlmIHNwZWMpXG4vLyAgICAgIC0gY291bnQ6ICAgICAgICAgIE51bWJlciAgLSBudW1iZXIgb2YgY29tcG9uZW50cyBvZiB0aGUgZ2l2ZW4gZm9ybWF0IGluc2lkZSBkYXRhXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1c3VhbGx5IDEsIG9yIHN0cmluZyBsZW5ndGggZm9yIGFzY2lpIGZvcm1hdClcbi8vICAgICAgLSBlbnRyeV9vZmZzZXQ6ICAgTnVtYmVyICAtIHN0YXJ0IG9mIEV4aWYgZW50cnkgKGVudHJ5IGxlbmd0aCBpcyBhbHdheXMgMTIsIHNvIG5vdCBpbmNsdWRlZClcbi8vICAgICAgLSBkYXRhX29mZnNldDogICAgTnVtYmVyICAtIHN0YXJ0IG9mIGRhdGEgYXR0YWNoZWQgdG8gRXhpZiBlbnRyeSAod2lsbCBvdmVybGFwIHdpdGggZW50cnkgaWYgbGVuZ3RoIDw9IDQpXG4vLyAgICAgIC0gZGF0YV9sZW5ndGg6ICAgIE51bWJlciAgLSBsZW5ndGggb2YgZGF0YSBhdHRhY2hlZCB0byBFeGlmIGVudHJ5XG4vLyAgICAgIC0gdmFsdWU6ICAgICAgICAgIEFycmF5fFN0cmluZ3xOdWxsIC0gb3VyIGJlc3QgYXR0ZW1wdCBhdCBwYXJzaW5nIGRhdGEgKG5vdCBhbGwgZm9ybWF0cyBzdXBwb3J0ZWQgcmlnaHQgbm93KVxuLy8gICAgICAtIGlzX3N1YmlmZF9saW5rOiBCb29sZWFuIC0gd2hldGhlciB0aGlzIGVudHJ5IGlzIHJlY29nbml6ZWQgdG8gYmUgYSBsaW5rIHRvIHN1YmlmZCAoY2FuJ3QgZmlsdGVyIHRoZXNlIG91dClcbi8vXG4vLyBJdGVyYXRpb24gc3RvcHMgZWFybHkgaWYgaXRlcmF0b3IgcmV0dXJucyBgZmFsc2VgLlxuLy9cbi8vIElmIEV4aWYgd2Fzbid0IGZvdW5kIGFueXdoZXJlIChiZWZvcmUgc3RhcnQgb2YgdGhlIGltYWdlIGRhdGEsIFNPUyksXG4vLyBpdGVyYXRvciBpcyBuZXZlciBleGVjdXRlZC5cbi8vXG5tb2R1bGUuZXhwb3J0cy5qcGVnX2V4aWZfdGFnc19lYWNoID0gZnVuY3Rpb24gKGpwZWdfYmluLCBvbl9leGlmX2VudHJ5KSB7XG4gIGlmICghaXNfdWludDhhcnJheShqcGVnX2JpbikpIHtcbiAgICB0aHJvdyBlcnJvcignSW52YWxpZCBhcmd1bWVudCAoanBlZ19iaW4pLCBVaW50OEFycmF5IGV4cGVjdGVkJywgJ0VJTlZBTCcpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvbl9leGlmX2VudHJ5ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgZXJyb3IoJ0ludmFsaWQgYXJndW1lbnQgKG9uX2V4aWZfZW50cnkpLCBGdW5jdGlvbiBleHBlY3RlZCcsICdFSU5WQUwnKTtcbiAgfVxuXG4gIC8qIGVzbGludC1kaXNhYmxlIGNvbnNpc3RlbnQtcmV0dXJuICovXG4gIG1vZHVsZS5leHBvcnRzLmpwZWdfc2VnbWVudHNfZWFjaChqcGVnX2JpbiwgZnVuY3Rpb24gKHNlZ21lbnQpIHtcbiAgICBpZiAoc2VnbWVudC5jb2RlID09PSAweERBIC8qIFNPUyAqLykgcmV0dXJuIGZhbHNlO1xuXG4gICAgLy8gbG9vayBmb3IgQVBQMSBzZWdtZW50IGFuZCBjb21wYXJlIGhlYWRlciB3aXRoICdFeGlmXFwwXFwwJ1xuICAgIGlmIChzZWdtZW50LmNvZGUgPT09IDB4RTEgJiYgc2VnbWVudC5sZW5ndGggPj0gMTAgJiZcbiAgICAgICAganBlZ19iaW5bc2VnbWVudC5vZmZzZXQgKyA0XSA9PT0gMHg0NSAmJiBqcGVnX2JpbltzZWdtZW50Lm9mZnNldCArIDVdID09PSAweDc4ICYmXG4gICAgICAgIGpwZWdfYmluW3NlZ21lbnQub2Zmc2V0ICsgNl0gPT09IDB4NjkgJiYganBlZ19iaW5bc2VnbWVudC5vZmZzZXQgKyA3XSA9PT0gMHg2NiAmJlxuICAgICAgICBqcGVnX2JpbltzZWdtZW50Lm9mZnNldCArIDhdID09PSAweDAwICYmIGpwZWdfYmluW3NlZ21lbnQub2Zmc2V0ICsgOV0gPT09IDB4MDApIHtcblxuICAgICAgbmV3IEV4aWZQYXJzZXIoanBlZ19iaW4sIHNlZ21lbnQub2Zmc2V0ICsgMTAsIHNlZ21lbnQub2Zmc2V0ICsgc2VnbWVudC5sZW5ndGgpLmVhY2gob25fZXhpZl9lbnRyeSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcbn07XG5cblxuLy8gUmVtb3ZlIEV4aWYgZW50cmllcyBpbiB0aGUgZ2l2ZW4gSlBFRyBpbWFnZVxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46IFVpbnQ4QXJyYXkgLSBqcGVnIGZpbGVcbi8vICAtIG9uX2VudHJ5OiBGdW5jdGlvbiAtIGNhbGxiYWNrIGV4ZWN1dGVkIG9uIGVhY2ggRXhpZiBlbnRyeVxuLy8gICAgLSBlbnRyeTogIE9iamVjdFxuLy8gICAgICAtIGlzX2JpZ19lbmRpYW46ICBCb29sZWFuIC0gd2hldGhlciBFeGlmIHVzZXMgYmlnIG9yIGxpdHRsZSBlbmRpYW4gYnl0ZSBhbGlnbm1lbnRcbi8vICAgICAgLSBpZmQ6ICAgICAgICAgICAgTnVtYmVyICAtIElGRCBpZGVudGlmaWVyICgwIGZvciBJRkQwLCAxIGZvciBJRkQxLCAweDg3NjkgZm9yIFN1YklGRCxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODgyNSBmb3IgR1BTIEluZm8sIDB4QTAwNSBmb3IgSW50ZXJvcCBJRkQpXG4vLyAgICAgIC0gdGFnOiAgICAgICAgICAgIE51bWJlciAgLSBleGlmIGVudHJ5IHRhZyAoMHgwMTEwIC0gY2FtZXJhIG5hbWUsIDB4MDExMiAtIG9yaWVudGF0aW9uLCBldGMuIC0gc2VlIEV4aWYgc3BlYylcbi8vICAgICAgLSBmb3JtYXQ6ICAgICAgICAgTnVtYmVyICAtIGV4aWYgZW50cnkgZm9ybWF0ICgxIC0gYnl0ZSwgMiAtIGFzY2lpLCAzIC0gc2hvcnQsIGV0Yy4gLSBzZWUgRXhpZiBzcGVjKVxuLy8gICAgICAtIGNvdW50OiAgICAgICAgICBOdW1iZXIgIC0gbnVtYmVyIG9mIGNvbXBvbmVudHMgb2YgdGhlIGdpdmVuIGZvcm1hdCBpbnNpZGUgZGF0YVxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVzdWFsbHkgMSwgb3Igc3RyaW5nIGxlbmd0aCBmb3IgYXNjaWkgZm9ybWF0KVxuLy8gICAgICAtIGVudHJ5X29mZnNldDogICBOdW1iZXIgIC0gc3RhcnQgb2YgRXhpZiBlbnRyeSAoZW50cnkgbGVuZ3RoIGlzIGFsd2F5cyAxMiwgc28gbm90IGluY2x1ZGVkKVxuLy8gICAgICAtIGRhdGFfb2Zmc2V0OiAgICBOdW1iZXIgIC0gc3RhcnQgb2YgZGF0YSBhdHRhY2hlZCB0byBFeGlmIGVudHJ5ICh3aWxsIG92ZXJsYXAgd2l0aCBlbnRyeSBpZiBsZW5ndGggPD0gNClcbi8vICAgICAgLSBkYXRhX2xlbmd0aDogICAgTnVtYmVyICAtIGxlbmd0aCBvZiBkYXRhIGF0dGFjaGVkIHRvIEV4aWYgZW50cnlcbi8vICAgICAgLSB2YWx1ZTogICAgICAgICAgQXJyYXl8U3RyaW5nfE51bGwgLSBvdXIgYmVzdCBhdHRlbXB0IGF0IHBhcnNpbmcgZGF0YSAobm90IGFsbCBmb3JtYXRzIHN1cHBvcnRlZCByaWdodCBub3cpXG4vLyAgICAgIC0gaXNfc3ViaWZkX2xpbms6IEJvb2xlYW4gLSB3aGV0aGVyIHRoaXMgZW50cnkgaXMgcmVjb2duaXplZCB0byBiZSBhIGxpbmsgdG8gc3ViaWZkIChjYW4ndCBmaWx0ZXIgdGhlc2Ugb3V0KVxuLy9cbi8vIFRoaXMgZnVuY3Rpb24gcmVtb3ZlcyBmb2xsb3dpbmcgZnJvbSBFeGlmOlxuLy8gIC0gYWxsIGVudHJpZXMgd2hlcmUgaXRlcmF0b3IgcmV0dXJuZWQgZmFsc2UgKGV4Y2VwdCBzdWJpZmQgbGlua3Mgd2hpY2ggYXJlIG1hbmRhdG9yeSlcbi8vICAtIElGRDEgYW5kIHRodW1ibmFpbCBpbWFnZSAodGhlIHB1cnBvc2Ugb2YgdGhpcyBmdW5jdGlvbiBpcyB0byByZWR1Y2UgZmlsZSBzaXplLFxuLy8gICAgc28gdGh1bWJuYWlsIGlzIHVzdWFsbHkgdGhlIGZpcnN0IHRoaW5nIHRvIGdvKVxuLy8gIC0gYWxsIG90aGVyIGRhdGEgdGhhdCBpc24ndCBpbiBJRkQwLCBTdWJJRkQsIEdQU0lGRCwgSW50ZXJvcElGRFxuLy8gICAgKHRoZW9yZXRpY2FsbHkgcG9zc2libGUgcHJvcHJpZXRhcnkgZXh0ZW5zaW9ucywgSSBoYXZlbid0IHNlZW4gYW55IG9mIHRoZXNlIHlldClcbi8vXG4vLyBDaGFuZ2luZyBkYXRhIGluc2lkZSBFeGlmIGVudHJpZXMgaXMgTk9UIHN1cHBvcnRlZCB5ZXQgKG1vZGlmeWluZyBgZW50cnlgIG9iamVjdCBpbnNpZGUgY2FsbGJhY2sgbWF5IGJyZWFrIHN0dWZmKS5cbi8vXG4vLyBJZiBFeGlmIHdhc24ndCBmb3VuZCBhbnl3aGVyZSAoYmVmb3JlIHN0YXJ0IG9mIHRoZSBpbWFnZSBkYXRhLCBTT1MpLFxuLy8gaXRlcmF0b3IgaXMgbmV2ZXIgZXhlY3V0ZWQsIGFuZCBvcmlnaW5hbCBKUEVHIGlzIHJldHVybmVkIGFzIGlzLlxuLy9cbm1vZHVsZS5leHBvcnRzLmpwZWdfZXhpZl90YWdzX2ZpbHRlciA9IGZ1bmN0aW9uIChqcGVnX2Jpbiwgb25fZXhpZl9lbnRyeSkge1xuICBpZiAoIWlzX3VpbnQ4YXJyYXkoanBlZ19iaW4pKSB7XG4gICAgdGhyb3cgZXJyb3IoJ0ludmFsaWQgYXJndW1lbnQgKGpwZWdfYmluKSwgVWludDhBcnJheSBleHBlY3RlZCcsICdFSU5WQUwnKTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb25fZXhpZl9lbnRyeSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IGVycm9yKCdJbnZhbGlkIGFyZ3VtZW50IChvbl9leGlmX2VudHJ5KSwgRnVuY3Rpb24gZXhwZWN0ZWQnLCAnRUlOVkFMJyk7XG4gIH1cblxuICB2YXIgc3RvcF9zZWFyY2ggPSBmYWxzZTtcblxuICByZXR1cm4gbW9kdWxlLmV4cG9ydHMuanBlZ19zZWdtZW50c19maWx0ZXIoanBlZ19iaW4sIGZ1bmN0aW9uIChzZWdtZW50KSB7XG4gICAgaWYgKHN0b3Bfc2VhcmNoKSByZXR1cm47XG4gICAgaWYgKHNlZ21lbnQuY29kZSA9PT0gMHhEQSAvKiBTT1MgKi8pIHN0b3Bfc2VhcmNoID0gdHJ1ZTtcblxuICAgIC8vIGxvb2sgZm9yIEFQUDEgc2VnbWVudCBhbmQgY29tcGFyZSBoZWFkZXIgd2l0aCAnRXhpZlxcMFxcMCdcbiAgICBpZiAoc2VnbWVudC5jb2RlID09PSAweEUxICYmIHNlZ21lbnQubGVuZ3RoID49IDEwICYmXG4gICAgICAgIGpwZWdfYmluW3NlZ21lbnQub2Zmc2V0ICsgNF0gPT09IDB4NDUgJiYganBlZ19iaW5bc2VnbWVudC5vZmZzZXQgKyA1XSA9PT0gMHg3OCAmJlxuICAgICAgICBqcGVnX2JpbltzZWdtZW50Lm9mZnNldCArIDZdID09PSAweDY5ICYmIGpwZWdfYmluW3NlZ21lbnQub2Zmc2V0ICsgN10gPT09IDB4NjYgJiZcbiAgICAgICAganBlZ19iaW5bc2VnbWVudC5vZmZzZXQgKyA4XSA9PT0gMHgwMCAmJiBqcGVnX2JpbltzZWdtZW50Lm9mZnNldCArIDldID09PSAweDAwKSB7XG5cbiAgICAgIHZhciBuZXdfZXhpZiA9IG5ldyBFeGlmUGFyc2VyKGpwZWdfYmluLCBzZWdtZW50Lm9mZnNldCArIDEwLCBzZWdtZW50Lm9mZnNldCArIHNlZ21lbnQubGVuZ3RoKVxuICAgICAgICAuZmlsdGVyKG9uX2V4aWZfZW50cnkpO1xuICAgICAgaWYgKCFuZXdfZXhpZikgcmV0dXJuIGZhbHNlO1xuXG4gICAgICB2YXIgaGVhZGVyID0gbmV3IFVpbnQ4QXJyYXkoMTApO1xuXG4gICAgICBoZWFkZXIuc2V0KGpwZWdfYmluLnNsaWNlKHNlZ21lbnQub2Zmc2V0LCBzZWdtZW50Lm9mZnNldCArIDEwKSk7XG4gICAgICBoZWFkZXJbMl0gPSAoKG5ld19leGlmLmxlbmd0aCArIDgpID4+PiA4KSAmIDB4RkY7XG4gICAgICBoZWFkZXJbM10gPSAobmV3X2V4aWYubGVuZ3RoICsgOCkgJiAweEZGO1xuXG4gICAgICBzdG9wX3NlYXJjaCA9IHRydWU7XG4gICAgICByZXR1cm4gWyBoZWFkZXIsIG5ld19leGlmIF07XG4gICAgfVxuICB9KTtcbn07XG5cblxuLy8gSW5zZXJ0cyBhIGN1c3RvbSBjb21tZW50IG1hcmtlciBzZWdtZW50IGludG8gSlBFRyBmaWxlLlxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46IFVpbnQ4QXJyYXkgLSBqcGVnIGZpbGVcbi8vICAtIGNvbW1lbnQ6ICBTdHJpbmdcbi8vXG4vLyBDb21tZW50IGlzIGluc2VydGVkIGFmdGVyIGZpcnN0IHR3byBieXRlcyAoRkZEOCwgU09JKS5cbi8vXG4vLyBJZiBKRklGIChBUFAwKSBtYXJrZXIgZXhpc3RzIGltbWVkaWF0ZWx5IGFmdGVyIFNPSSAoYXMgbWFuZGF0ZWQgYnkgdGhlIEpGSUZcbi8vIHNwZWMpLCB3ZSBpbnNlcnQgY29tbWVudCBhZnRlciBpdCBpbnN0ZWFkLlxuLy9cbm1vZHVsZS5leHBvcnRzLmpwZWdfYWRkX2NvbW1lbnQgPSBmdW5jdGlvbiAoanBlZ19iaW4sIGNvbW1lbnQpIHtcbiAgdmFyIGNvbW1lbnRfaW5zZXJ0ZWQgPSBmYWxzZSwgc2VnbWVudF9jb3VudCA9IDA7XG5cbiAgcmV0dXJuIG1vZHVsZS5leHBvcnRzLmpwZWdfc2VnbWVudHNfZmlsdGVyKGpwZWdfYmluLCBmdW5jdGlvbiAoc2VnbWVudCkge1xuICAgIHNlZ21lbnRfY291bnQrKztcbiAgICBpZiAoc2VnbWVudF9jb3VudCA9PT0gMSAmJiBzZWdtZW50LmNvZGUgPT09IDB4RDggLyogU09JICAqLykgcmV0dXJuO1xuICAgIGlmIChzZWdtZW50X2NvdW50ID09PSAyICYmIHNlZ21lbnQuY29kZSA9PT0gMHhFMCAvKiBBUFAwICovKSByZXR1cm47XG5cbiAgICBpZiAoY29tbWVudF9pbnNlcnRlZCkgcmV0dXJuO1xuICAgIGNvbW1lbnQgPSB1dGY4X2VuY29kZShjb21tZW50KTtcblxuICAgIC8vIGNvbW1lbnQgc2VnbWVudFxuICAgIHZhciBjc2VnbWVudCA9IG5ldyBVaW50OEFycmF5KDUgKyBjb21tZW50Lmxlbmd0aCk7XG4gICAgdmFyIG9mZnNldCA9IDA7XG5cbiAgICBjc2VnbWVudFtvZmZzZXQrK10gPSAweEZGO1xuICAgIGNzZWdtZW50W29mZnNldCsrXSA9IDB4RkU7XG4gICAgY3NlZ21lbnRbb2Zmc2V0KytdID0gKChjb21tZW50Lmxlbmd0aCArIDMpID4+PiA4KSAmIDB4RkY7XG4gICAgY3NlZ21lbnRbb2Zmc2V0KytdID0gKGNvbW1lbnQubGVuZ3RoICsgMykgJiAweEZGO1xuXG4gICAgY29tbWVudC5zcGxpdCgnJykuZm9yRWFjaChmdW5jdGlvbiAoYykge1xuICAgICAgY3NlZ21lbnRbb2Zmc2V0KytdID0gYy5jaGFyQ29kZUF0KDApICYgMHhGRjtcbiAgICB9KTtcblxuICAgIGNzZWdtZW50W29mZnNldCsrXSA9IDA7XG4gICAgY29tbWVudF9pbnNlcnRlZCA9IHRydWU7XG5cbiAgICByZXR1cm4gWyBjc2VnbWVudCwganBlZ19iaW4uc3ViYXJyYXkoc2VnbWVudC5vZmZzZXQsIHNlZ21lbnQub2Zmc2V0ICsgc2VnbWVudC5sZW5ndGgpIF07XG4gIH0pO1xufTtcbn0pO1xuXG5mdW5jdGlvbiBqcGVnX3BhdGNoX2V4aWYoZW52KSB7XG4gIHJldHVybiB0aGlzLl9nZXRVaW50OEFycmF5KGVudi5ibG9iKS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgZW52LmlzX2pwZWcgPSBpbWFnZV90cmF2ZXJzZS5pc19qcGVnKGRhdGEpO1xuXG4gICAgaWYgKCFlbnYuaXNfanBlZykgcmV0dXJuIFByb21pc2UucmVzb2x2ZShlbnYpO1xuXG4gICAgZW52Lm9yaWdfYmxvYiA9IGVudi5ibG9iO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciBleGlmX2lzX2JpZ19lbmRpYW4sIG9yaWVudGF0aW9uX29mZnNldDtcblxuICAgICAgLyogZXNsaW50LWRpc2FibGUgY29uc2lzdGVudC1yZXR1cm4gKi9cbiAgICAgIGltYWdlX3RyYXZlcnNlLmpwZWdfZXhpZl90YWdzX2VhY2goZGF0YSwgZnVuY3Rpb24gKGVudHJ5KSB7XG4gICAgICAgIGlmIChlbnRyeS5pZmQgPT09IDAgJiYgZW50cnkudGFnID09PSAweDExMiAmJiBBcnJheS5pc0FycmF5KGVudHJ5LnZhbHVlKSkge1xuICAgICAgICAgIGVudi5vcmllbnRhdGlvbiAgICA9IGVudHJ5LnZhbHVlWzBdIHx8IDE7XG4gICAgICAgICAgZXhpZl9pc19iaWdfZW5kaWFuID0gZW50cnkuaXNfYmlnX2VuZGlhbjtcbiAgICAgICAgICBvcmllbnRhdGlvbl9vZmZzZXQgPSBlbnRyeS5kYXRhX29mZnNldDtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAob3JpZW50YXRpb25fb2Zmc2V0KSB7XG4gICAgICAgIHZhciBvcmllbnRhdGlvbl9wYXRjaCA9IGV4aWZfaXNfYmlnX2VuZGlhbiA/XG4gICAgICAgICAgbmV3IFVpbnQ4QXJyYXkoWyAwLCAxIF0pIDpcbiAgICAgICAgICBuZXcgVWludDhBcnJheShbIDEsIDAgXSk7XG5cbiAgICAgICAgZW52LmJsb2IgPSBuZXcgQmxvYihbXG4gICAgICAgICAgZGF0YS5zbGljZSgwLCBvcmllbnRhdGlvbl9vZmZzZXQpLFxuICAgICAgICAgIG9yaWVudGF0aW9uX3BhdGNoLFxuICAgICAgICAgIGRhdGEuc2xpY2Uob3JpZW50YXRpb25fb2Zmc2V0ICsgMilcbiAgICAgICAgXSwgeyB0eXBlOiAnaW1hZ2UvanBlZycgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoXykge31cblxuICAgIHJldHVybiBlbnY7XG4gIH0pO1xufVxuXG5cbmZ1bmN0aW9uIGpwZWdfcm90YXRlX2NhbnZhcyhlbnYpIHtcbiAgaWYgKCFlbnYuaXNfanBlZykgcmV0dXJuIFByb21pc2UucmVzb2x2ZShlbnYpO1xuXG4gIHZhciBvcmllbnRhdGlvbiA9IGVudi5vcmllbnRhdGlvbiAtIDE7XG4gIGlmICghb3JpZW50YXRpb24pIHJldHVybiBQcm9taXNlLnJlc29sdmUoZW52KTtcblxuICB2YXIgY2FudmFzO1xuXG4gIGlmIChvcmllbnRhdGlvbiAmIDQpIHtcbiAgICBjYW52YXMgPSB0aGlzLnBpY2Eub3B0aW9ucy5jcmVhdGVDYW52YXMoZW52Lm91dF9jYW52YXMuaGVpZ2h0LCBlbnYub3V0X2NhbnZhcy53aWR0aCk7XG4gIH0gZWxzZSB7XG4gICAgY2FudmFzID0gdGhpcy5waWNhLm9wdGlvbnMuY3JlYXRlQ2FudmFzKGVudi5vdXRfY2FudmFzLndpZHRoLCBlbnYub3V0X2NhbnZhcy5oZWlnaHQpO1xuICB9XG5cbiAgdmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuXG4gIGN0eC5zYXZlKCk7XG5cbiAgaWYgKG9yaWVudGF0aW9uICYgMSkgY3R4LnRyYW5zZm9ybSgtMSwgMCwgMCwgMSwgY2FudmFzLndpZHRoLCAwKTtcbiAgaWYgKG9yaWVudGF0aW9uICYgMikgY3R4LnRyYW5zZm9ybSgtMSwgMCwgMCwgLTEsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XG4gIGlmIChvcmllbnRhdGlvbiAmIDQpIGN0eC50cmFuc2Zvcm0oMCwgMSwgMSwgMCwgMCwgMCk7XG5cbiAgY3R4LmRyYXdJbWFnZShlbnYub3V0X2NhbnZhcywgMCwgMCk7XG4gIGN0eC5yZXN0b3JlKCk7XG5cbiAgLy8gU2FmYXJpIDEyIHdvcmthcm91bmRcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhL2lzc3Vlcy8xOTlcbiAgZW52Lm91dF9jYW52YXMud2lkdGggPSBlbnYub3V0X2NhbnZhcy5oZWlnaHQgPSAwO1xuXG4gIGVudi5vdXRfY2FudmFzID0gY2FudmFzO1xuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoZW52KTtcbn1cblxuXG5mdW5jdGlvbiBqcGVnX2F0dGFjaF9vcmlnX3NlZ21lbnRzKGVudikge1xuICBpZiAoIWVudi5pc19qcGVnKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGVudik7XG5cbiAgcmV0dXJuIFByb21pc2UuYWxsKFtcbiAgICB0aGlzLl9nZXRVaW50OEFycmF5KGVudi5ibG9iKSxcbiAgICB0aGlzLl9nZXRVaW50OEFycmF5KGVudi5vdXRfYmxvYilcbiAgXSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgdmFyIGRhdGEgPSByZXNbMF07XG4gICAgdmFyIGRhdGFfb3V0ID0gcmVzWzFdO1xuXG4gICAgaWYgKCFpbWFnZV90cmF2ZXJzZS5pc19qcGVnKGRhdGEpKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGVudik7XG5cbiAgICB2YXIgc2VnbWVudHMgPSBbXTtcblxuICAgIGltYWdlX3RyYXZlcnNlLmpwZWdfc2VnbWVudHNfZWFjaChkYXRhLCBmdW5jdGlvbiAoc2VnbWVudCkge1xuICAgICAgaWYgKHNlZ21lbnQuY29kZSA9PT0gMHhEQSAvKiBTT1MgKi8pIHJldHVybiBmYWxzZTtcbiAgICAgIHNlZ21lbnRzLnB1c2goc2VnbWVudCk7XG4gICAgfSk7XG5cbiAgICBzZWdtZW50cyA9IHNlZ21lbnRzXG4gICAgICAuZmlsdGVyKGZ1bmN0aW9uIChzZWdtZW50KSB7XG4gICAgICAgIC8vIERyb3AgSUNDX1BST0ZJTEVcbiAgICAgICAgLy9cbiAgICAgICAgaWYgKHNlZ21lbnQuY29kZSA9PT0gMHhFMikgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIEtlZXAgYWxsIEFQUG4gc2VnbWVudHMgZXhjbHVkaW5nIEFQUDIgKElDQ19QUk9GSUxFKSxcbiAgICAgICAgLy8gcmVtb3ZlIG90aGVycyBiZWNhdXNlIG1vc3Qgb2YgdGhlbSBkZXBlbmQgb24gaW1hZ2UgZGF0YSAoRENUIGFuZCBzdWNoKS5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gQVBQMCAtIEpGSUYsIEFQUDEgLSBFeGlmLCB0aGUgcmVzdCBhcmUgcGhvdG9zaG9wIG1ldGFkYXRhIGFuZCBzdWNoXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFNlZSBmdWxsIGxpc3QgYXQgaHR0cHM6Ly93d3cudzMub3JnL0dyYXBoaWNzL0pQRUcvaXR1LXQ4MS5wZGYgKHRhYmxlIEIuMSBvbiBwYWdlIDMyKVxuICAgICAgICAvL1xuICAgICAgICBpZiAoc2VnbWVudC5jb2RlID49IDB4RTAgJiYgc2VnbWVudC5jb2RlIDwgMHhGMCkgcmV0dXJuIHRydWU7XG5cbiAgICAgICAgLy8gS2VlcCBjb21tZW50c1xuICAgICAgICAvL1xuICAgICAgICBpZiAoc2VnbWVudC5jb2RlID09PSAweEZFKSByZXR1cm4gdHJ1ZTtcblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9KVxuICAgICAgLm1hcChmdW5jdGlvbiAoc2VnbWVudCkge1xuICAgICAgICByZXR1cm4gZGF0YS5zbGljZShzZWdtZW50Lm9mZnNldCwgc2VnbWVudC5vZmZzZXQgKyBzZWdtZW50Lmxlbmd0aCk7XG4gICAgICB9KTtcblxuICAgIGVudi5vdXRfYmxvYiA9IG5ldyBCbG9iKFxuICAgICAgLy8gaW50ZW50aW9uYWxseSBvbWl0dGluZyBleHBlY3RlZCBKRklGIHNlZ21lbnQgKG9mZnNldCAyIHRvIDIwKVxuICAgICAgWyBkYXRhX291dC5zbGljZSgwLCAyKSBdLmNvbmNhdChzZWdtZW50cykuY29uY2F0KFsgZGF0YV9vdXQuc2xpY2UoMjApIF0pLFxuICAgICAgeyB0eXBlOiAnaW1hZ2UvanBlZycgfVxuICAgICk7XG5cbiAgICByZXR1cm4gZW52O1xuICB9KTtcbn1cblxuXG5mdW5jdGlvbiBhc3NpZ24ocmVkdWNlcikge1xuICByZWR1Y2VyLmJlZm9yZSgnX2Jsb2JfdG9faW1hZ2UnLCBqcGVnX3BhdGNoX2V4aWYpO1xuICByZWR1Y2VyLmFmdGVyKCdfdHJhbnNmb3JtJywgICAgICBqcGVnX3JvdGF0ZV9jYW52YXMpO1xuICByZWR1Y2VyLmFmdGVyKCdfY3JlYXRlX2Jsb2InLCAgICBqcGVnX2F0dGFjaF9vcmlnX3NlZ21lbnRzKTtcbn1cblxuXG52YXIganBlZ19wYXRjaF9leGlmXzEgPSBqcGVnX3BhdGNoX2V4aWY7XG52YXIganBlZ19yb3RhdGVfY2FudmFzXzEgPSBqcGVnX3JvdGF0ZV9jYW52YXM7XG52YXIganBlZ19hdHRhY2hfb3JpZ19zZWdtZW50c18xID0ganBlZ19hdHRhY2hfb3JpZ19zZWdtZW50cztcbnZhciBhc3NpZ25fMSA9IGFzc2lnbjtcblxudmFyIGpwZWdfcGx1Z2lucyA9IHtcblx0anBlZ19wYXRjaF9leGlmOiBqcGVnX3BhdGNoX2V4aWZfMSxcblx0anBlZ19yb3RhdGVfY2FudmFzOiBqcGVnX3JvdGF0ZV9jYW52YXNfMSxcblx0anBlZ19hdHRhY2hfb3JpZ19zZWdtZW50czoganBlZ19hdHRhY2hfb3JpZ19zZWdtZW50c18xLFxuXHRhc3NpZ246IGFzc2lnbl8xXG59O1xuXG5mdW5jdGlvbiBJbWFnZUJsb2JSZWR1Y2Uob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgSW1hZ2VCbG9iUmVkdWNlKSkgcmV0dXJuIG5ldyBJbWFnZUJsb2JSZWR1Y2Uob3B0aW9ucyk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgdGhpcy5waWNhID0gb3B0aW9ucy5waWNhIHx8IHBpY2Eoe30pO1xuICB0aGlzLmluaXRpYWxpemVkID0gZmFsc2U7XG5cbiAgdGhpcy51dGlscyA9IHV0aWxzO1xufVxuXG5cbkltYWdlQmxvYlJlZHVjZS5wcm90b3R5cGUudXNlID0gZnVuY3Rpb24gKHBsdWdpbiAvKiwgcGFyYW1zLCAuLi4gKi8pIHtcbiAgdmFyIGFyZ3MgPSBbIHRoaXMgXS5jb25jYXQoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSk7XG4gIHBsdWdpbi5hcHBseShwbHVnaW4sIGFyZ3MpO1xuICByZXR1cm4gdGhpcztcbn07XG5cblxuSW1hZ2VCbG9iUmVkdWNlLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnVzZShqcGVnX3BsdWdpbnMuYXNzaWduKTtcbn07XG5cblxuSW1hZ2VCbG9iUmVkdWNlLnByb3RvdHlwZS50b0Jsb2IgPSBmdW5jdGlvbiAoYmxvYiwgb3B0aW9ucykge1xuICB2YXIgb3B0cyA9IHV0aWxzLmFzc2lnbih7IG1heDogSW5maW5pdHkgfSwgb3B0aW9ucyk7XG4gIHZhciBlbnYgPSB7XG4gICAgYmxvYjogYmxvYixcbiAgICBvcHRzOiBvcHRzXG4gIH07XG5cbiAgaWYgKCF0aGlzLmluaXRpYWxpemVkKSB7XG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5pbml0aWFsaXplZCA9IHRydWU7XG4gIH1cblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGVudilcbiAgICAudGhlbih0aGlzLl9ibG9iX3RvX2ltYWdlKVxuICAgIC50aGVuKHRoaXMuX2NhbGN1bGF0ZV9zaXplKVxuICAgIC50aGVuKHRoaXMuX3RyYW5zZm9ybSlcbiAgICAudGhlbih0aGlzLl9jbGVhbnVwKVxuICAgIC50aGVuKHRoaXMuX2NyZWF0ZV9ibG9iKVxuICAgIC50aGVuKGZ1bmN0aW9uIChfZW52KSB7XG4gICAgICAvLyBTYWZhcmkgMTIgd29ya2Fyb3VuZFxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhL2lzc3Vlcy8xOTlcbiAgICAgIF9lbnYub3V0X2NhbnZhcy53aWR0aCA9IF9lbnYub3V0X2NhbnZhcy5oZWlnaHQgPSAwO1xuXG4gICAgICByZXR1cm4gX2Vudi5vdXRfYmxvYjtcbiAgICB9KTtcbn07XG5cblxuSW1hZ2VCbG9iUmVkdWNlLnByb3RvdHlwZS50b0NhbnZhcyA9IGZ1bmN0aW9uIChibG9iLCBvcHRpb25zKSB7XG4gIHZhciBvcHRzID0gdXRpbHMuYXNzaWduKHsgbWF4OiBJbmZpbml0eSB9LCBvcHRpb25zKTtcbiAgdmFyIGVudiA9IHtcbiAgICBibG9iOiBibG9iLFxuICAgIG9wdHM6IG9wdHNcbiAgfTtcblxuICBpZiAoIXRoaXMuaW5pdGlhbGl6ZWQpIHtcbiAgICB0aGlzLmluaXQoKTtcbiAgICB0aGlzLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoZW52KVxuICAgIC50aGVuKHRoaXMuX2Jsb2JfdG9faW1hZ2UpXG4gICAgLnRoZW4odGhpcy5fY2FsY3VsYXRlX3NpemUpXG4gICAgLnRoZW4odGhpcy5fdHJhbnNmb3JtKVxuICAgIC50aGVuKHRoaXMuX2NsZWFudXApXG4gICAgLnRoZW4oZnVuY3Rpb24gKF9lbnYpIHsgcmV0dXJuIF9lbnYub3V0X2NhbnZhczsgfSk7XG59O1xuXG5cbkltYWdlQmxvYlJlZHVjZS5wcm90b3R5cGUuYmVmb3JlID0gZnVuY3Rpb24gKG1ldGhvZF9uYW1lLCBmbikge1xuICBpZiAoIXRoaXNbbWV0aG9kX25hbWVdKSB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBcIicgKyBtZXRob2RfbmFtZSArICdcIiBkb2VzIG5vdCBleGlzdCcpO1xuICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYXJndW1lbnQgXCJmblwiLCBmdW5jdGlvbiBleHBlY3RlZCcpO1xuXG4gIHZhciBvbGRfZm4gPSB0aGlzW21ldGhvZF9uYW1lXTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXNbbWV0aG9kX25hbWVdID0gZnVuY3Rpb24gKGVudikge1xuICAgIHJldHVybiBmbi5jYWxsKHNlbGYsIGVudikudGhlbihmdW5jdGlvbiAoX2Vudikge1xuICAgICAgcmV0dXJuIG9sZF9mbi5jYWxsKHNlbGYsIF9lbnYpO1xuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuXG5JbWFnZUJsb2JSZWR1Y2UucHJvdG90eXBlLmFmdGVyID0gZnVuY3Rpb24gKG1ldGhvZF9uYW1lLCBmbikge1xuICBpZiAoIXRoaXNbbWV0aG9kX25hbWVdKSB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBcIicgKyBtZXRob2RfbmFtZSArICdcIiBkb2VzIG5vdCBleGlzdCcpO1xuICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYXJndW1lbnQgXCJmblwiLCBmdW5jdGlvbiBleHBlY3RlZCcpO1xuXG4gIHZhciBvbGRfZm4gPSB0aGlzW21ldGhvZF9uYW1lXTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXNbbWV0aG9kX25hbWVdID0gZnVuY3Rpb24gKGVudikge1xuICAgIHJldHVybiBvbGRfZm4uY2FsbChzZWxmLCBlbnYpLnRoZW4oZnVuY3Rpb24gKF9lbnYpIHtcbiAgICAgIHJldHVybiBmbi5jYWxsKHNlbGYsIF9lbnYpO1xuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuXG5JbWFnZUJsb2JSZWR1Y2UucHJvdG90eXBlLl9ibG9iX3RvX2ltYWdlID0gZnVuY3Rpb24gKGVudikge1xuICB2YXIgVVJMID0gd2luZG93LlVSTCB8fCB3aW5kb3cud2Via2l0VVJMIHx8IHdpbmRvdy5tb3pVUkwgfHwgd2luZG93Lm1zVVJMO1xuXG4gIGVudi5pbWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICBlbnYuaW1hZ2VfdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChlbnYuYmxvYik7XG4gIGVudi5pbWFnZS5zcmMgPSBlbnYuaW1hZ2VfdXJsO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgZW52LmltYWdlLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7IHJlamVjdChuZXcgRXJyb3IoJ0ltYWdlQmxvYlJlZHVjZTogZmFpbGVkIHRvIGNyZWF0ZSBJbWFnZSgpIGZyb20gYmxvYicpKTsgfTtcbiAgICBlbnYuaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkgeyByZXNvbHZlKGVudik7IH07XG4gIH0pO1xufTtcblxuXG5JbWFnZUJsb2JSZWR1Y2UucHJvdG90eXBlLl9jYWxjdWxhdGVfc2l6ZSA9IGZ1bmN0aW9uIChlbnYpIHtcbiAgLy9cbiAgLy8gTm90ZSwgaWYgeW91ciBuZWVkIG5vdCBcInN5bW1ldHJpY1wiIHJlc2l6ZSBsb2dpYywgeW91IE1VU1QgY2hlY2tcbiAgLy8gYGVudi5vcmllbnRhdGlvbmAgKHNldCBieSBwbHVnaW5zKSBhbmQgc3dhcCB3aWR0aC9oZWlnaHQgYXBwcm9wcmlhdGVseS5cbiAgLy9cbiAgdmFyIHNjYWxlX2ZhY3RvciA9IGVudi5vcHRzLm1heCAvIE1hdGgubWF4KGVudi5pbWFnZS53aWR0aCwgZW52LmltYWdlLmhlaWdodCk7XG5cbiAgaWYgKHNjYWxlX2ZhY3RvciA+IDEpIHNjYWxlX2ZhY3RvciA9IDE7XG5cbiAgZW52LnRyYW5zZm9ybV93aWR0aCA9IE1hdGgubWF4KE1hdGgucm91bmQoZW52LmltYWdlLndpZHRoICogc2NhbGVfZmFjdG9yKSwgMSk7XG4gIGVudi50cmFuc2Zvcm1faGVpZ2h0ID0gTWF0aC5tYXgoTWF0aC5yb3VuZChlbnYuaW1hZ2UuaGVpZ2h0ICogc2NhbGVfZmFjdG9yKSwgMSk7XG5cbiAgLy8gSW5mbyBmb3IgdXNlciBwbHVnaW5zLCB0byBjaGVjayBpZiBzY2FsaW5nIGFwcGxpZWRcbiAgZW52LnNjYWxlX2ZhY3RvciA9IHNjYWxlX2ZhY3RvcjtcblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGVudik7XG59O1xuXG5cbkltYWdlQmxvYlJlZHVjZS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChlbnYpIHtcbiAgZW52Lm91dF9jYW52YXMgPSB0aGlzLnBpY2Eub3B0aW9ucy5jcmVhdGVDYW52YXMoZW52LnRyYW5zZm9ybV93aWR0aCwgZW52LnRyYW5zZm9ybV9oZWlnaHQpO1xuXG4gIC8vIERpbSBlbnYgdGVtcG9yYXJ5IHZhcnMgdG8gcHJvaGliaXQgdXNlIGFuZCBhdm9pZCBjb25mdXNpb24gd2hlbiBvcmllbnRhdGlvblxuICAvLyBjaGFuZ2VkLiBZb3Ugc2hvdWxkIHRha2UgcmVhbCBzaXplIGZyb20gY2FudmFzLlxuICBlbnYudHJhbnNmb3JtX3dpZHRoID0gbnVsbDtcbiAgZW52LnRyYW5zZm9ybV9oZWlnaHQgPSBudWxsO1xuXG4gIC8vIEJ5IGRlZmF1bHQgdXNlIGFscGhhIGZvciBwbmcgb25seVxuICB2YXIgcGljYV9vcHRzID0geyBhbHBoYTogZW52LmJsb2IudHlwZSA9PT0gJ2ltYWdlL3BuZycgfTtcblxuICAvLyBFeHRyYWN0IHBpY2Egb3B0aW9ucyBpZiBiZWVuIHBhc3NlZFxuICB0aGlzLnV0aWxzLmFzc2lnbihwaWNhX29wdHMsIHRoaXMudXRpbHMucGlja19waWNhX3Jlc2l6ZV9vcHRpb25zKGVudi5vcHRzKSk7XG5cbiAgcmV0dXJuIHRoaXMucGljYVxuICAgIC5yZXNpemUoZW52LmltYWdlLCBlbnYub3V0X2NhbnZhcywgcGljYV9vcHRzKVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGVudjsgfSk7XG59O1xuXG5cbkltYWdlQmxvYlJlZHVjZS5wcm90b3R5cGUuX2NsZWFudXAgPSBmdW5jdGlvbiAoZW52KSB7XG4gIGVudi5pbWFnZS5zcmMgPSAnJztcbiAgZW52LmltYWdlID0gbnVsbDtcblxuICB2YXIgVVJMID0gd2luZG93LlVSTCB8fCB3aW5kb3cud2Via2l0VVJMIHx8IHdpbmRvdy5tb3pVUkwgfHwgd2luZG93Lm1zVVJMO1xuICBpZiAoVVJMLnJldm9rZU9iamVjdFVSTCkgVVJMLnJldm9rZU9iamVjdFVSTChlbnYuaW1hZ2VfdXJsKTtcblxuICBlbnYuaW1hZ2VfdXJsID0gbnVsbDtcblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGVudik7XG59O1xuXG5cbkltYWdlQmxvYlJlZHVjZS5wcm90b3R5cGUuX2NyZWF0ZV9ibG9iID0gZnVuY3Rpb24gKGVudikge1xuICByZXR1cm4gdGhpcy5waWNhLnRvQmxvYihlbnYub3V0X2NhbnZhcywgZW52LmJsb2IudHlwZSlcbiAgICAudGhlbihmdW5jdGlvbiAoYmxvYikge1xuICAgICAgZW52Lm91dF9ibG9iID0gYmxvYjtcbiAgICAgIHJldHVybiBlbnY7XG4gICAgfSk7XG59O1xuXG5cbkltYWdlQmxvYlJlZHVjZS5wcm90b3R5cGUuX2dldFVpbnQ4QXJyYXkgPSBmdW5jdGlvbiAoYmxvYikge1xuICBpZiAoYmxvYi5hcnJheUJ1ZmZlcikge1xuICAgIHJldHVybiBibG9iLmFycmF5QnVmZmVyKCkudGhlbihmdW5jdGlvbiAoYnVmKSB7XG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYnVmKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgdmFyIGZyID0gbmV3IEZpbGVSZWFkZXIoKTtcblxuICAgIGZyLnJlYWRBc0FycmF5QnVmZmVyKGJsb2IpO1xuXG4gICAgZnIub25sb2FkID0gZnVuY3Rpb24gKCkgeyByZXNvbHZlKG5ldyBVaW50OEFycmF5KGZyLnJlc3VsdCkpOyB9O1xuICAgIGZyLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZWplY3QobmV3IEVycm9yKCdJbWFnZUJsb2JSZWR1Y2U6IGZhaWxlZCB0byBsb2FkIGRhdGEgZnJvbSBpbnB1dCBibG9iJykpO1xuICAgICAgZnIuYWJvcnQoKTtcbiAgICB9O1xuICAgIGZyLm9uYWJvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZWplY3QobmV3IEVycm9yKCdJbWFnZUJsb2JSZWR1Y2U6IGZhaWxlZCB0byBsb2FkIGRhdGEgZnJvbSBpbnB1dCBibG9iIChhYm9ydGVkKScpKTtcbiAgICB9O1xuICB9KTtcbn07XG5cblxuSW1hZ2VCbG9iUmVkdWNlLnBpY2EgPSBwaWNhO1xuXG52YXIgaW1hZ2VCbG9iUmVkdWNlID0gSW1hZ2VCbG9iUmVkdWNlO1xuXG5leHBvcnQgZGVmYXVsdCBpbWFnZUJsb2JSZWR1Y2U7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///../../../node_modules/image-blob-reduce/dist/image-blob-reduce.esm.mjs\n");
28
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n\n/*! image-blob-reduce 3.0.1 https://github.com/nodeca/image-blob-reduce @license MIT */\nvar assign$1 = function assign(to) {\n var from;\n\n for (var s = 1; s < arguments.length; s++) {\n from = Object(arguments[s]);\n\n for (var key in from) {\n if (Object.prototype.hasOwnProperty.call(from, key)) to[key] = from[key];\n }\n }\n\n return to;\n};\n\n\nfunction pick(from, props) {\n var to = {};\n\n props.forEach(function (key) {\n if (Object.prototype.hasOwnProperty.call(from, key)) to[key] = from[key];\n });\n\n return to;\n}\n\n\nfunction pick_pica_resize_options(from) {\n return pick(from, [\n 'alpha',\n 'unsharpAmount',\n 'unsharpRadius',\n 'unsharpThreshold',\n 'cancelToken'\n ]);\n}\n\n\nvar pick_1 = pick;\nvar pick_pica_resize_options_1 = pick_pica_resize_options;\n\nvar utils = {\n\tassign: assign$1,\n\tpick: pick_1,\n\tpick_pica_resize_options: pick_pica_resize_options_1\n};\n\nfunction createCommonjsModule(fn) {\n var module = { exports: {} };\n\treturn fn(module, module.exports), module.exports;\n}\n\nfunction commonjsRequire (target) {\n\tthrow new Error('Could not dynamically require \"' + target + '\". Please configure the dynamicRequireTargets option of @rollup/plugin-commonjs appropriately for this require call to behave properly.');\n}\n\n/*!\n\npica\nhttps://github.com/nodeca/pica\n\n*/\n\nvar pica = createCommonjsModule(function (module, exports) {\n(function(f){{module.exports=f();}})(function(){return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof commonjsRequire&&commonjsRequire;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t);}return n[i].exports}for(var u=\"function\"==typeof commonjsRequire&&commonjsRequire,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){\n\nvar inherits = _dereq_('inherits');\n\nvar Multimath = _dereq_('multimath');\n\nvar mm_unsharp_mask = _dereq_('./mm_unsharp_mask');\n\nvar mm_resize = _dereq_('./mm_resize');\n\nfunction MathLib(requested_features) {\n var __requested_features = requested_features || [];\n\n var features = {\n js: __requested_features.indexOf('js') >= 0,\n wasm: __requested_features.indexOf('wasm') >= 0\n };\n Multimath.call(this, features);\n this.features = {\n js: features.js,\n wasm: features.wasm && this.has_wasm()\n };\n this.use(mm_unsharp_mask);\n this.use(mm_resize);\n}\n\ninherits(MathLib, Multimath);\n\nMathLib.prototype.resizeAndUnsharp = function resizeAndUnsharp(options, cache) {\n var result = this.resize(options, cache);\n\n if (options.unsharpAmount) {\n this.unsharp_mask(result, options.toWidth, options.toHeight, options.unsharpAmount, options.unsharpRadius, options.unsharpThreshold);\n }\n\n return result;\n};\n\nmodule.exports = MathLib;\n\n},{\"./mm_resize\":4,\"./mm_unsharp_mask\":9,\"inherits\":19,\"multimath\":20}],2:[function(_dereq_,module,exports){\n//var FIXED_FRAC_BITS = 14;\n\nfunction clampTo8(i) {\n return i < 0 ? 0 : i > 255 ? 255 : i;\n} // Convolve image in horizontal directions and transpose output. In theory,\n// transpose allow:\n//\n// - use the same convolver for both passes (this fails due different\n// types of input array and temporary buffer)\n// - making vertical pass by horisonltal lines inprove CPU cache use.\n//\n// But in real life this doesn't work :)\n//\n\n\nfunction convolveHorizontally(src, dest, srcW, srcH, destW, filters) {\n var r, g, b, a;\n var filterPtr, filterShift, filterSize;\n var srcPtr, srcY, destX, filterVal;\n var srcOffset = 0,\n destOffset = 0; // For each row\n\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0; // Apply precomputed filters to each destination row point\n\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++];\n filterSize = filters[filterPtr++];\n srcPtr = srcOffset + filterShift * 4 | 0;\n r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a\n\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n\n a = a + filterVal * src[srcPtr + 3] | 0;\n b = b + filterVal * src[srcPtr + 2] | 0;\n g = g + filterVal * src[srcPtr + 1] | 0;\n r = r + filterVal * src[srcPtr] | 0;\n srcPtr = srcPtr + 4 | 0;\n } // Bring this value back in range. All of the filter scaling factors\n // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n //\n // (!) Add 1/2 of value before clamping to get proper rounding. In other\n // case brightness loss will be noticeable if you resize image with white\n // border and place it on white background.\n //\n\n\n dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset] = clampTo8(r + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n destOffset = destOffset + srcH * 4 | 0;\n }\n\n destOffset = (srcY + 1) * 4 | 0;\n srcOffset = (srcY + 1) * srcW * 4 | 0;\n }\n} // Technically, convolvers are the same. But input array and temporary\n// buffer can be of different type (especially, in old browsers). So,\n// keep code in separate functions to avoid deoptimizations & speed loss.\n\n\nfunction convolveVertically(src, dest, srcW, srcH, destW, filters) {\n var r, g, b, a;\n var filterPtr, filterShift, filterSize;\n var srcPtr, srcY, destX, filterVal;\n var srcOffset = 0,\n destOffset = 0; // For each row\n\n for (srcY = 0; srcY < srcH; srcY++) {\n filterPtr = 0; // Apply precomputed filters to each destination row point\n\n for (destX = 0; destX < destW; destX++) {\n // Get the filter that determines the current output pixel.\n filterShift = filters[filterPtr++];\n filterSize = filters[filterPtr++];\n srcPtr = srcOffset + filterShift * 4 | 0;\n r = g = b = a = 0; // Apply the filter to the row to get the destination pixel r, g, b, a\n\n for (; filterSize > 0; filterSize--) {\n filterVal = filters[filterPtr++]; // Use reverse order to workaround deopts in old v8 (node v.10)\n // Big thanks to @mraleph (Vyacheslav Egorov) for the tip.\n\n a = a + filterVal * src[srcPtr + 3] | 0;\n b = b + filterVal * src[srcPtr + 2] | 0;\n g = g + filterVal * src[srcPtr + 1] | 0;\n r = r + filterVal * src[srcPtr] | 0;\n srcPtr = srcPtr + 4 | 0;\n } // Bring this value back in range. All of the filter scaling factors\n // are in fixed point with FIXED_FRAC_BITS bits of fractional part.\n //\n // (!) Add 1/2 of value before clamping to get proper rounding. In other\n // case brightness loss will be noticeable if you resize image with white\n // border and place it on white background.\n //\n\n\n dest[destOffset + 3] = clampTo8(a + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 2] = clampTo8(b + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset + 1] = clampTo8(g + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n dest[destOffset] = clampTo8(r + (1 << 13) >> 14\n /*FIXED_FRAC_BITS*/\n );\n destOffset = destOffset + srcH * 4 | 0;\n }\n\n destOffset = (srcY + 1) * 4 | 0;\n srcOffset = (srcY + 1) * srcW * 4 | 0;\n }\n}\n\nmodule.exports = {\n convolveHorizontally: convolveHorizontally,\n convolveVertically: convolveVertically\n};\n\n},{}],3:[function(_dereq_,module,exports){\n/* eslint-disable max-len */\n\nmodule.exports = 'AGFzbQEAAAAADAZkeWxpbmsAAAAAAAEXA2AAAGAGf39/f39/AGAHf39/f39/fwACDwEDZW52Bm1lbW9yeQIAAAMEAwABAgYGAX8AQQALB1cFEV9fd2FzbV9jYWxsX2N0b3JzAAAIY29udm9sdmUAAQpjb252b2x2ZUhWAAIMX19kc29faGFuZGxlAwAYX193YXNtX2FwcGx5X2RhdGFfcmVsb2NzAAAK7AMDAwABC8YDAQ9/AkAgA0UNACAERQ0AA0AgDCENQQAhE0EAIQcDQCAHQQJqIQYCfyAHQQF0IAVqIgcuAQIiFEUEQEGAwAAhCEGAwAAhCUGAwAAhCkGAwAAhCyAGDAELIBIgBy4BAGohCEEAIQsgFCEHQQAhDiAGIQlBACEPQQAhEANAIAUgCUEBdGouAQAiESAAIAhBAnRqKAIAIgpBGHZsIBBqIRAgCkH/AXEgEWwgC2ohCyAKQRB2Qf8BcSARbCAPaiEPIApBCHZB/wFxIBFsIA5qIQ4gCEEBaiEIIAlBAWohCSAHQQFrIgcNAAsgC0GAQGshCCAOQYBAayEJIA9BgEBrIQogEEGAQGshCyAGIBRqCyEHIAEgDUECdGogCUEOdSIGQf8BIAZB/wFIGyIGQQAgBkEAShtBCHRBgP4DcSAKQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EQdEGAgPwHcSALQQ51IgZB/wEgBkH/AUgbIgZBACAGQQBKG0EYdHJyIAhBDnUiBkH/ASAGQf8BSBsiBkEAIAZBAEobcjYCACADIA1qIQ0gE0EBaiITIARHDQALIAxBAWoiDCACbCESIAMgDEcNAAsLCx4AQQAgAiADIAQgBSAAEAEgAkEAIAQgBSAGIAEQAQs=';\n\n},{}],4:[function(_dereq_,module,exports){\n\nmodule.exports = {\n name: 'resize',\n fn: _dereq_('./resize'),\n wasm_fn: _dereq_('./resize_wasm'),\n wasm_src: _dereq_('./convolve_wasm_base64')\n};\n\n},{\"./convolve_wasm_base64\":3,\"./resize\":5,\"./resize_wasm\":8}],5:[function(_dereq_,module,exports){\n\nvar createFilters = _dereq_('./resize_filter_gen');\n\nvar convolveHorizontally = _dereq_('./convolve').convolveHorizontally;\n\nvar convolveVertically = _dereq_('./convolve').convolveVertically;\n\nfunction resetAlpha(dst, width, height) {\n var ptr = 3,\n len = width * height * 4 | 0;\n\n while (ptr < len) {\n dst[ptr] = 0xFF;\n ptr = ptr + 4 | 0;\n }\n}\n\nmodule.exports = function resize(options) {\n var src = options.src;\n var srcW = options.width;\n var srcH = options.height;\n var destW = options.toWidth;\n var destH = options.toHeight;\n var scaleX = options.scaleX || options.toWidth / options.width;\n var scaleY = options.scaleY || options.toHeight / options.height;\n var offsetX = options.offsetX || 0;\n var offsetY = options.offsetY || 0;\n var dest = options.dest || new Uint8Array(destW * destH * 4);\n var quality = typeof options.quality === 'undefined' ? 3 : options.quality;\n var alpha = options.alpha || false;\n var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(quality, srcH, destH, scaleY, offsetY);\n var tmp = new Uint8Array(destW * srcH * 4); // To use single function we need src & tmp of the same type.\n // But src can be CanvasPixelArray, and tmp - Uint8Array. So, keep\n // vertical and horizontal passes separately to avoid deoptimization.\n\n convolveHorizontally(src, tmp, srcW, srcH, destW, filtersX);\n convolveVertically(tmp, dest, srcH, destW, destH, filtersY); // That's faster than doing checks in convolver.\n // !!! Note, canvas data is not premultipled. We don't need other\n // alpha corrections.\n\n if (!alpha) resetAlpha(dest, destW, destH);\n return dest;\n};\n\n},{\"./convolve\":2,\"./resize_filter_gen\":6}],6:[function(_dereq_,module,exports){\n\nvar FILTER_INFO = _dereq_('./resize_filter_info'); // Precision of fixed FP values\n\n\nvar FIXED_FRAC_BITS = 14;\n\nfunction toFixedPoint(num) {\n return Math.round(num * ((1 << FIXED_FRAC_BITS) - 1));\n}\n\nmodule.exports = function resizeFilterGen(quality, srcSize, destSize, scale, offset) {\n var filterFunction = FILTER_INFO[quality].filter;\n var scaleInverted = 1.0 / scale;\n var scaleClamped = Math.min(1.0, scale); // For upscale\n // Filter window (averaging interval), scaled to src image\n\n var srcWindow = FILTER_INFO[quality].win / scaleClamped;\n var destPixel, srcPixel, srcFirst, srcLast, filterElementSize, floatFilter, fxpFilter, total, pxl, idx, floatVal, filterTotal, filterVal;\n var leftNotEmpty, rightNotEmpty, filterShift, filterSize;\n var maxFilterElementSize = Math.floor((srcWindow + 1) * 2);\n var packedFilter = new Int16Array((maxFilterElementSize + 2) * destSize);\n var packedFilterPtr = 0;\n var slowCopy = !packedFilter.subarray || !packedFilter.set; // For each destination pixel calculate source range and built filter values\n\n for (destPixel = 0; destPixel < destSize; destPixel++) {\n // Scaling should be done relative to central pixel point\n srcPixel = (destPixel + 0.5) * scaleInverted + offset;\n srcFirst = Math.max(0, Math.floor(srcPixel - srcWindow));\n srcLast = Math.min(srcSize - 1, Math.ceil(srcPixel + srcWindow));\n filterElementSize = srcLast - srcFirst + 1;\n floatFilter = new Float32Array(filterElementSize);\n fxpFilter = new Int16Array(filterElementSize);\n total = 0.0; // Fill filter values for calculated range\n\n for (pxl = srcFirst, idx = 0; pxl <= srcLast; pxl++, idx++) {\n floatVal = filterFunction((pxl + 0.5 - srcPixel) * scaleClamped);\n total += floatVal;\n floatFilter[idx] = floatVal;\n } // Normalize filter, convert to fixed point and accumulate conversion error\n\n\n filterTotal = 0;\n\n for (idx = 0; idx < floatFilter.length; idx++) {\n filterVal = floatFilter[idx] / total;\n filterTotal += filterVal;\n fxpFilter[idx] = toFixedPoint(filterVal);\n } // Compensate normalization error, to minimize brightness drift\n\n\n fxpFilter[destSize >> 1] += toFixedPoint(1.0 - filterTotal); //\n // Now pack filter to useable form\n //\n // 1. Trim heading and tailing zero values, and compensate shitf/length\n // 2. Put all to single array in this format:\n //\n // [ pos shift, data length, value1, value2, value3, ... ]\n //\n\n leftNotEmpty = 0;\n\n while (leftNotEmpty < fxpFilter.length && fxpFilter[leftNotEmpty] === 0) {\n leftNotEmpty++;\n }\n\n if (leftNotEmpty < fxpFilter.length) {\n rightNotEmpty = fxpFilter.length - 1;\n\n while (rightNotEmpty > 0 && fxpFilter[rightNotEmpty] === 0) {\n rightNotEmpty--;\n }\n\n filterShift = srcFirst + leftNotEmpty;\n filterSize = rightNotEmpty - leftNotEmpty + 1;\n packedFilter[packedFilterPtr++] = filterShift; // shift\n\n packedFilter[packedFilterPtr++] = filterSize; // size\n\n if (!slowCopy) {\n packedFilter.set(fxpFilter.subarray(leftNotEmpty, rightNotEmpty + 1), packedFilterPtr);\n packedFilterPtr += filterSize;\n } else {\n // fallback for old IE < 11, without subarray/set methods\n for (idx = leftNotEmpty; idx <= rightNotEmpty; idx++) {\n packedFilter[packedFilterPtr++] = fxpFilter[idx];\n }\n }\n } else {\n // zero data, write header only\n packedFilter[packedFilterPtr++] = 0; // shift\n\n packedFilter[packedFilterPtr++] = 0; // size\n }\n }\n\n return packedFilter;\n};\n\n},{\"./resize_filter_info\":7}],7:[function(_dereq_,module,exports){\n\nmodule.exports = [{\n // Nearest neibor (Box)\n win: 0.5,\n filter: function filter(x) {\n return x >= -0.5 && x < 0.5 ? 1.0 : 0.0;\n }\n}, {\n // Hamming\n win: 1.0,\n filter: function filter(x) {\n if (x <= -1.0 || x >= 1.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * (0.54 + 0.46 * Math.cos(xpi / 1.0));\n }\n}, {\n // Lanczos, win = 2\n win: 2.0,\n filter: function filter(x) {\n if (x <= -2.0 || x >= 2.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * Math.sin(xpi / 2.0) / (xpi / 2.0);\n }\n}, {\n // Lanczos, win = 3\n win: 3.0,\n filter: function filter(x) {\n if (x <= -3.0 || x >= 3.0) {\n return 0.0;\n }\n\n if (x > -1.19209290E-07 && x < 1.19209290E-07) {\n return 1.0;\n }\n\n var xpi = x * Math.PI;\n return Math.sin(xpi) / xpi * Math.sin(xpi / 3.0) / (xpi / 3.0);\n }\n}];\n\n},{}],8:[function(_dereq_,module,exports){\n\nvar createFilters = _dereq_('./resize_filter_gen');\n\nfunction resetAlpha(dst, width, height) {\n var ptr = 3,\n len = width * height * 4 | 0;\n\n while (ptr < len) {\n dst[ptr] = 0xFF;\n ptr = ptr + 4 | 0;\n }\n}\n\nfunction asUint8Array(src) {\n return new Uint8Array(src.buffer, 0, src.byteLength);\n}\n\nvar IS_LE = true; // should not crash everything on module load in old browsers\n\ntry {\n IS_LE = new Uint32Array(new Uint8Array([1, 0, 0, 0]).buffer)[0] === 1;\n} catch (__) {}\n\nfunction copyInt16asLE(src, target, target_offset) {\n if (IS_LE) {\n target.set(asUint8Array(src), target_offset);\n return;\n }\n\n for (var ptr = target_offset, i = 0; i < src.length; i++) {\n var data = src[i];\n target[ptr++] = data & 0xFF;\n target[ptr++] = data >> 8 & 0xFF;\n }\n}\n\nmodule.exports = function resize_wasm(options) {\n var src = options.src;\n var srcW = options.width;\n var srcH = options.height;\n var destW = options.toWidth;\n var destH = options.toHeight;\n var scaleX = options.scaleX || options.toWidth / options.width;\n var scaleY = options.scaleY || options.toHeight / options.height;\n var offsetX = options.offsetX || 0.0;\n var offsetY = options.offsetY || 0.0;\n var dest = options.dest || new Uint8Array(destW * destH * 4);\n var quality = typeof options.quality === 'undefined' ? 3 : options.quality;\n var alpha = options.alpha || false;\n var filtersX = createFilters(quality, srcW, destW, scaleX, offsetX),\n filtersY = createFilters(quality, srcH, destH, scaleY, offsetY); // destination is 0 too.\n\n var src_offset = 0; // buffer between convolve passes\n\n var tmp_offset = this.__align(src_offset + Math.max(src.byteLength, dest.byteLength));\n\n var filtersX_offset = this.__align(tmp_offset + srcH * destW * 4);\n\n var filtersY_offset = this.__align(filtersX_offset + filtersX.byteLength);\n\n var alloc_bytes = filtersY_offset + filtersY.byteLength;\n\n var instance = this.__instance('resize', alloc_bytes); //\n // Fill memory block with data to process\n //\n\n\n var mem = new Uint8Array(this.__memory.buffer);\n var mem32 = new Uint32Array(this.__memory.buffer); // 32-bit copy is much faster in chrome\n\n var src32 = new Uint32Array(src.buffer);\n mem32.set(src32); // We should guarantee LE bytes order. Filters are not big, so\n // speed difference is not significant vs direct .set()\n\n copyInt16asLE(filtersX, mem, filtersX_offset);\n copyInt16asLE(filtersY, mem, filtersY_offset); //\n // Now call webassembly method\n // emsdk does method names with '_'\n\n var fn = instance.exports.convolveHV || instance.exports._convolveHV;\n fn(filtersX_offset, filtersY_offset, tmp_offset, srcW, srcH, destW, destH); //\n // Copy data back to typed array\n //\n // 32-bit copy is much faster in chrome\n\n var dest32 = new Uint32Array(dest.buffer);\n dest32.set(new Uint32Array(this.__memory.buffer, 0, destH * destW)); // That's faster than doing checks in convolver.\n // !!! Note, canvas data is not premultipled. We don't need other\n // alpha corrections.\n\n if (!alpha) resetAlpha(dest, destW, destH);\n return dest;\n};\n\n},{\"./resize_filter_gen\":6}],9:[function(_dereq_,module,exports){\n\nmodule.exports = {\n name: 'unsharp_mask',\n fn: _dereq_('./unsharp_mask'),\n wasm_fn: _dereq_('./unsharp_mask_wasm'),\n wasm_src: _dereq_('./unsharp_mask_wasm_base64')\n};\n\n},{\"./unsharp_mask\":10,\"./unsharp_mask_wasm\":11,\"./unsharp_mask_wasm_base64\":12}],10:[function(_dereq_,module,exports){\n\nvar glur_mono16 = _dereq_('glur/mono16');\n\nfunction hsv_v16(img, width, height) {\n var size = width * height;\n var out = new Uint16Array(size);\n var r, g, b, max;\n\n for (var i = 0; i < size; i++) {\n r = img[4 * i];\n g = img[4 * i + 1];\n b = img[4 * i + 2];\n max = r >= g && r >= b ? r : g >= b && g >= r ? g : b;\n out[i] = max << 8;\n }\n\n return out;\n}\n\nmodule.exports = function unsharp(img, width, height, amount, radius, threshold) {\n var v1, v2, vmul;\n var diff, iTimes4;\n\n if (amount === 0 || radius < 0.5) {\n return;\n }\n\n if (radius > 2.0) {\n radius = 2.0;\n }\n\n var brightness = hsv_v16(img, width, height);\n var blured = new Uint16Array(brightness); // copy, because blur modify src\n\n glur_mono16(blured, width, height, radius);\n var amountFp = amount / 100 * 0x1000 + 0.5 | 0;\n var thresholdFp = threshold << 8;\n var size = width * height;\n /* eslint-disable indent */\n\n for (var i = 0; i < size; i++) {\n v1 = brightness[i];\n diff = v1 - blured[i];\n\n if (Math.abs(diff) >= thresholdFp) {\n // add unsharp mask to the brightness channel\n v2 = v1 + (amountFp * diff + 0x800 >> 12); // Both v1 and v2 are within [0.0 .. 255.0] (0000-FF00) range, never going into\n // [255.003 .. 255.996] (FF01-FFFF). This allows to round this value as (x+.5)|0\n // later without overflowing.\n\n v2 = v2 > 0xff00 ? 0xff00 : v2;\n v2 = v2 < 0x0000 ? 0x0000 : v2; // Avoid division by 0. V=0 means rgb(0,0,0), unsharp with unsharpAmount>0 cannot\n // change this value (because diff between colors gets inflated), so no need to verify correctness.\n\n v1 = v1 !== 0 ? v1 : 1; // Multiplying V in HSV model by a constant is equivalent to multiplying each component\n // in RGB by the same constant (same for HSL), see also:\n // https://beesbuzz.biz/code/16-hsv-color-transforms\n\n vmul = (v2 << 12) / v1 | 0; // Result will be in [0..255] range because:\n // - all numbers are positive\n // - r,g,b <= (v1/256)\n // - r,g,b,(v1/256),(v2/256) <= 255\n // So highest this number can get is X*255/X+0.5=255.5 which is < 256 and rounds down.\n\n iTimes4 = i * 4;\n img[iTimes4] = img[iTimes4] * vmul + 0x800 >> 12; // R\n\n img[iTimes4 + 1] = img[iTimes4 + 1] * vmul + 0x800 >> 12; // G\n\n img[iTimes4 + 2] = img[iTimes4 + 2] * vmul + 0x800 >> 12; // B\n }\n }\n};\n\n},{\"glur/mono16\":18}],11:[function(_dereq_,module,exports){\n\nmodule.exports = function unsharp(img, width, height, amount, radius, threshold) {\n if (amount === 0 || radius < 0.5) {\n return;\n }\n\n if (radius > 2.0) {\n radius = 2.0;\n }\n\n var pixels = width * height;\n var img_bytes_cnt = pixels * 4;\n var hsv_bytes_cnt = pixels * 2;\n var blur_bytes_cnt = pixels * 2;\n var blur_line_byte_cnt = Math.max(width, height) * 4; // float32 array\n\n var blur_coeffs_byte_cnt = 8 * 4; // float32 array\n\n var img_offset = 0;\n var hsv_offset = img_bytes_cnt;\n var blur_offset = hsv_offset + hsv_bytes_cnt;\n var blur_tmp_offset = blur_offset + blur_bytes_cnt;\n var blur_line_offset = blur_tmp_offset + blur_bytes_cnt;\n var blur_coeffs_offset = blur_line_offset + blur_line_byte_cnt;\n\n var instance = this.__instance('unsharp_mask', img_bytes_cnt + hsv_bytes_cnt + blur_bytes_cnt * 2 + blur_line_byte_cnt + blur_coeffs_byte_cnt, {\n exp: Math.exp\n }); // 32-bit copy is much faster in chrome\n\n\n var img32 = new Uint32Array(img.buffer);\n var mem32 = new Uint32Array(this.__memory.buffer);\n mem32.set(img32); // HSL\n\n var fn = instance.exports.hsv_v16 || instance.exports._hsv_v16;\n fn(img_offset, hsv_offset, width, height); // BLUR\n\n fn = instance.exports.blurMono16 || instance.exports._blurMono16;\n fn(hsv_offset, blur_offset, blur_tmp_offset, blur_line_offset, blur_coeffs_offset, width, height, radius); // UNSHARP\n\n fn = instance.exports.unsharp || instance.exports._unsharp;\n fn(img_offset, img_offset, hsv_offset, blur_offset, width, height, amount, threshold); // 32-bit copy is much faster in chrome\n\n img32.set(new Uint32Array(this.__memory.buffer, 0, pixels));\n};\n\n},{}],12:[function(_dereq_,module,exports){\n/* eslint-disable max-len */\n\nmodule.exports = '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';\n\n},{}],13:[function(_dereq_,module,exports){\n\nvar GC_INTERVAL = 100;\n\nfunction Pool(create, idle) {\n this.create = create;\n this.available = [];\n this.acquired = {};\n this.lastId = 1;\n this.timeoutId = 0;\n this.idle = idle || 2000;\n}\n\nPool.prototype.acquire = function () {\n var _this = this;\n\n var resource;\n\n if (this.available.length !== 0) {\n resource = this.available.pop();\n } else {\n resource = this.create();\n resource.id = this.lastId++;\n\n resource.release = function () {\n return _this.release(resource);\n };\n }\n\n this.acquired[resource.id] = resource;\n return resource;\n};\n\nPool.prototype.release = function (resource) {\n var _this2 = this;\n\n delete this.acquired[resource.id];\n resource.lastUsed = Date.now();\n this.available.push(resource);\n\n if (this.timeoutId === 0) {\n this.timeoutId = setTimeout(function () {\n return _this2.gc();\n }, GC_INTERVAL);\n }\n};\n\nPool.prototype.gc = function () {\n var _this3 = this;\n\n var now = Date.now();\n this.available = this.available.filter(function (resource) {\n if (now - resource.lastUsed > _this3.idle) {\n resource.destroy();\n return false;\n }\n\n return true;\n });\n\n if (this.available.length !== 0) {\n this.timeoutId = setTimeout(function () {\n return _this3.gc();\n }, GC_INTERVAL);\n } else {\n this.timeoutId = 0;\n }\n};\n\nmodule.exports = Pool;\n\n},{}],14:[function(_dereq_,module,exports){\n// min size = 1 can consume large amount of memory\n\nvar MIN_INNER_TILE_SIZE = 2;\n\nmodule.exports = function createStages(fromWidth, fromHeight, toWidth, toHeight, srcTileSize, destTileBorder) {\n var scaleX = toWidth / fromWidth;\n var scaleY = toHeight / fromHeight; // derived from createRegions equation:\n // innerTileWidth = pixelFloor(srcTileSize * scaleX) - 2 * destTileBorder;\n\n var minScale = (2 * destTileBorder + MIN_INNER_TILE_SIZE + 1) / srcTileSize; // refuse to scale image multiple times by less than twice each time,\n // it could only happen because of invalid options\n\n if (minScale > 0.5) return [[toWidth, toHeight]];\n var stageCount = Math.ceil(Math.log(Math.min(scaleX, scaleY)) / Math.log(minScale)); // no additional resizes are necessary,\n // stageCount can be zero or be negative when enlarging the image\n\n if (stageCount <= 1) return [[toWidth, toHeight]];\n var result = [];\n\n for (var i = 0; i < stageCount; i++) {\n var width = Math.round(Math.pow(Math.pow(fromWidth, stageCount - i - 1) * Math.pow(toWidth, i + 1), 1 / stageCount));\n var height = Math.round(Math.pow(Math.pow(fromHeight, stageCount - i - 1) * Math.pow(toHeight, i + 1), 1 / stageCount));\n result.push([width, height]);\n }\n\n return result;\n};\n\n},{}],15:[function(_dereq_,module,exports){\n/*\n * pixelFloor and pixelCeil are modified versions of Math.floor and Math.ceil\n * functions which take into account floating point arithmetic errors.\n * Those errors can cause undesired increments/decrements of sizes and offsets:\n * Math.ceil(36 / (36 / 500)) = 501\n * pixelCeil(36 / (36 / 500)) = 500\n */\n\nvar PIXEL_EPSILON = 1e-5;\n\nfunction pixelFloor(x) {\n var nearest = Math.round(x);\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) {\n return nearest;\n }\n\n return Math.floor(x);\n}\n\nfunction pixelCeil(x) {\n var nearest = Math.round(x);\n\n if (Math.abs(x - nearest) < PIXEL_EPSILON) {\n return nearest;\n }\n\n return Math.ceil(x);\n}\n\nmodule.exports = function createRegions(options) {\n var scaleX = options.toWidth / options.width;\n var scaleY = options.toHeight / options.height;\n var innerTileWidth = pixelFloor(options.srcTileSize * scaleX) - 2 * options.destTileBorder;\n var innerTileHeight = pixelFloor(options.srcTileSize * scaleY) - 2 * options.destTileBorder; // prevent infinite loop, this should never happen\n\n if (innerTileWidth < 1 || innerTileHeight < 1) {\n throw new Error('Internal error in pica: target tile width/height is too small.');\n }\n\n var x, y;\n var innerX, innerY, toTileWidth, toTileHeight;\n var tiles = [];\n var tile; // we go top-to-down instead of left-to-right to make image displayed from top to\n // doesn in the browser\n\n for (innerY = 0; innerY < options.toHeight; innerY += innerTileHeight) {\n for (innerX = 0; innerX < options.toWidth; innerX += innerTileWidth) {\n x = innerX - options.destTileBorder;\n\n if (x < 0) {\n x = 0;\n }\n\n toTileWidth = innerX + innerTileWidth + options.destTileBorder - x;\n\n if (x + toTileWidth >= options.toWidth) {\n toTileWidth = options.toWidth - x;\n }\n\n y = innerY - options.destTileBorder;\n\n if (y < 0) {\n y = 0;\n }\n\n toTileHeight = innerY + innerTileHeight + options.destTileBorder - y;\n\n if (y + toTileHeight >= options.toHeight) {\n toTileHeight = options.toHeight - y;\n }\n\n tile = {\n toX: x,\n toY: y,\n toWidth: toTileWidth,\n toHeight: toTileHeight,\n toInnerX: innerX,\n toInnerY: innerY,\n toInnerWidth: innerTileWidth,\n toInnerHeight: innerTileHeight,\n offsetX: x / scaleX - pixelFloor(x / scaleX),\n offsetY: y / scaleY - pixelFloor(y / scaleY),\n scaleX: scaleX,\n scaleY: scaleY,\n x: pixelFloor(x / scaleX),\n y: pixelFloor(y / scaleY),\n width: pixelCeil(toTileWidth / scaleX),\n height: pixelCeil(toTileHeight / scaleY)\n };\n tiles.push(tile);\n }\n }\n\n return tiles;\n};\n\n},{}],16:[function(_dereq_,module,exports){\n\nfunction objClass(obj) {\n return Object.prototype.toString.call(obj);\n}\n\nmodule.exports.isCanvas = function isCanvas(element) {\n var cname = objClass(element);\n return cname === '[object HTMLCanvasElement]'\n /* browser */\n || cname === '[object OffscreenCanvas]' || cname === '[object Canvas]'\n /* node-canvas */\n ;\n};\n\nmodule.exports.isImage = function isImage(element) {\n return objClass(element) === '[object HTMLImageElement]';\n};\n\nmodule.exports.isImageBitmap = function isImageBitmap(element) {\n return objClass(element) === '[object ImageBitmap]';\n};\n\nmodule.exports.limiter = function limiter(concurrency) {\n var active = 0,\n queue = [];\n\n function roll() {\n if (active < concurrency && queue.length) {\n active++;\n queue.shift()();\n }\n }\n\n return function limit(fn) {\n return new Promise(function (resolve, reject) {\n queue.push(function () {\n fn().then(function (result) {\n resolve(result);\n active--;\n roll();\n }, function (err) {\n reject(err);\n active--;\n roll();\n });\n });\n roll();\n });\n };\n};\n\nmodule.exports.cib_quality_name = function cib_quality_name(num) {\n switch (num) {\n case 0:\n return 'pixelated';\n\n case 1:\n return 'low';\n\n case 2:\n return 'medium';\n }\n\n return 'high';\n};\n\nmodule.exports.cib_support = function cib_support(createCanvas) {\n return Promise.resolve().then(function () {\n if (typeof createImageBitmap === 'undefined') {\n return false;\n }\n\n var c = createCanvas(100, 100);\n return createImageBitmap(c, 0, 0, 100, 100, {\n resizeWidth: 10,\n resizeHeight: 10,\n resizeQuality: 'high'\n }).then(function (bitmap) {\n var status = bitmap.width === 10; // Branch below is filtered on upper level. We do not call resize\n // detection for basic ImageBitmap.\n //\n // https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap\n // old Crome 51 has ImageBitmap without .close(). Then this code\n // will throw and return 'false' as expected.\n //\n\n bitmap.close();\n c = null;\n return status;\n });\n })[\"catch\"](function () {\n return false;\n });\n};\n\nmodule.exports.worker_offscreen_canvas_support = function worker_offscreen_canvas_support() {\n return new Promise(function (resolve, reject) {\n if (typeof OffscreenCanvas === 'undefined') {\n // if OffscreenCanvas is present, we assume browser supports Worker and built-in Promise as well\n resolve(false);\n return;\n }\n\n function workerPayload(self) {\n if (typeof createImageBitmap === 'undefined') {\n self.postMessage(false);\n return;\n }\n\n Promise.resolve().then(function () {\n var canvas = new OffscreenCanvas(10, 10); // test that 2d context can be used in worker\n\n var ctx = canvas.getContext('2d');\n ctx.rect(0, 0, 1, 1); // test that cib can be used to return image bitmap from worker\n\n return createImageBitmap(canvas, 0, 0, 1, 1);\n }).then(function () {\n return self.postMessage(true);\n }, function () {\n return self.postMessage(false);\n });\n }\n\n var code = btoa(\"(\".concat(workerPayload.toString(), \")(self);\"));\n var w = new Worker(\"data:text/javascript;base64,\".concat(code));\n\n w.onmessage = function (ev) {\n return resolve(ev.data);\n };\n\n w.onerror = reject;\n }).then(function (result) {\n return result;\n }, function () {\n return false;\n });\n}; // Check if canvas.getContext('2d').getImageData can be used,\n// FireFox randomizes the output of that function in `privacy.resistFingerprinting` mode\n\n\nmodule.exports.can_use_canvas = function can_use_canvas(createCanvas) {\n var usable = false;\n\n try {\n var canvas = createCanvas(2, 1);\n var ctx = canvas.getContext('2d');\n var d = ctx.createImageData(2, 1);\n d.data[0] = 12;\n d.data[1] = 23;\n d.data[2] = 34;\n d.data[3] = 255;\n d.data[4] = 45;\n d.data[5] = 56;\n d.data[6] = 67;\n d.data[7] = 255;\n ctx.putImageData(d, 0, 0);\n d = null;\n d = ctx.getImageData(0, 0, 2, 1);\n\n if (d.data[0] === 12 && d.data[1] === 23 && d.data[2] === 34 && d.data[3] === 255 && d.data[4] === 45 && d.data[5] === 56 && d.data[6] === 67 && d.data[7] === 255) {\n usable = true;\n }\n } catch (err) {}\n\n return usable;\n}; // Check if createImageBitmap(img, sx, sy, sw, sh) signature works correctly\n// with JPEG images oriented with Exif;\n// https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n// TODO: remove after it's fixed in chrome for at least 2 releases\n\n\nmodule.exports.cib_can_use_region = function cib_can_use_region() {\n return new Promise(function (resolve) {\n if (typeof createImageBitmap === 'undefined') {\n resolve(false);\n return;\n }\n\n var image = new Image();\n image.src = 'data:image/jpeg;base64,' + '/9j/4QBiRXhpZgAATU0AKgAAAAgABQESAAMAAAABAAYAAAEaAAUAAAABAAAASgEbAAUAA' + 'AABAAAAUgEoAAMAAAABAAIAAAITAAMAAAABAAEAAAAAAAAAAABIAAAAAQAAAEgAAAAB/9' + 'sAQwAEAwMEAwMEBAMEBQQEBQYKBwYGBgYNCQoICg8NEBAPDQ8OERMYFBESFxIODxUcFRc' + 'ZGRsbGxAUHR8dGh8YGhsa/9sAQwEEBQUGBQYMBwcMGhEPERoaGhoaGhoaGhoaGhoaGhoa' + 'GhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoa/8IAEQgAAQACAwERAAIRAQMRA' + 'f/EABQAAQAAAAAAAAAAAAAAAAAAAAf/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAA' + 'IQAxAAAAF/P//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAQUCf//EABQRAQAAAAA' + 'AAAAAAAAAAAAAAAD/2gAIAQMBAT8Bf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIB' + 'AT8Bf//EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEABj8Cf//EABQQAQAAAAAAAAAAA' + 'AAAAAAAAAD/2gAIAQEAAT8hf//aAAwDAQACAAMAAAAQH//EABQRAQAAAAAAAAAAAAAAAA' + 'AAAAD/2gAIAQMBAT8Qf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQIBAT8Qf//EABQ' + 'QAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAT8Qf//Z';\n\n image.onload = function () {\n createImageBitmap(image, 0, 0, image.width, image.height).then(function (bitmap) {\n if (bitmap.width === image.width && bitmap.height === image.height) {\n resolve(true);\n } else {\n resolve(false);\n }\n }, function () {\n return resolve(false);\n });\n };\n\n image.onerror = function () {\n return resolve(false);\n };\n });\n};\n\n},{}],17:[function(_dereq_,module,exports){\n\nmodule.exports = function () {\n var MathLib = _dereq_('./mathlib');\n\n var mathLib;\n /* eslint-disable no-undef */\n\n onmessage = function onmessage(ev) {\n var tileOpts = ev.data.opts;\n var returnBitmap = false;\n\n if (!tileOpts.src && tileOpts.srcBitmap) {\n var canvas = new OffscreenCanvas(tileOpts.width, tileOpts.height);\n var ctx = canvas.getContext('2d', {\n alpha: Boolean(tileOpts.alpha)\n });\n ctx.drawImage(tileOpts.srcBitmap, 0, 0);\n tileOpts.src = ctx.getImageData(0, 0, tileOpts.width, tileOpts.height).data;\n canvas.width = canvas.height = 0;\n canvas = null;\n tileOpts.srcBitmap.close();\n tileOpts.srcBitmap = null;\n returnBitmap = true;\n }\n\n if (!mathLib) mathLib = new MathLib(ev.data.features); // Use multimath's sync auto-init. Avoid Promise use in old browsers,\n // because polyfills are not propagated to webworker.\n\n var data = mathLib.resizeAndUnsharp(tileOpts);\n\n if (returnBitmap) {\n var toImageData = new ImageData(new Uint8ClampedArray(data), tileOpts.toWidth, tileOpts.toHeight);\n\n var _canvas = new OffscreenCanvas(tileOpts.toWidth, tileOpts.toHeight);\n\n var _ctx = _canvas.getContext('2d', {\n alpha: Boolean(tileOpts.alpha)\n });\n\n _ctx.putImageData(toImageData, 0, 0);\n\n createImageBitmap(_canvas).then(function (bitmap) {\n postMessage({\n bitmap: bitmap\n }, [bitmap]);\n });\n } else {\n postMessage({\n data: data\n }, [data.buffer]);\n }\n };\n};\n\n},{\"./mathlib\":1}],18:[function(_dereq_,module,exports){\n// Calculate Gaussian blur of an image using IIR filter\n// The method is taken from Intel's white paper and code example attached to it:\n// https://software.intel.com/en-us/articles/iir-gaussian-blur-filter\n// -implementation-using-intel-advanced-vector-extensions\n\nvar a0, a1, a2, a3, b1, b2, left_corner, right_corner;\n\nfunction gaussCoef(sigma) {\n if (sigma < 0.5) {\n sigma = 0.5;\n }\n\n var a = Math.exp(0.726 * 0.726) / sigma,\n g1 = Math.exp(-a),\n g2 = Math.exp(-2 * a),\n k = (1 - g1) * (1 - g1) / (1 + 2 * a * g1 - g2);\n\n a0 = k;\n a1 = k * (a - 1) * g1;\n a2 = k * (a + 1) * g1;\n a3 = -k * g2;\n b1 = 2 * g1;\n b2 = -g2;\n left_corner = (a0 + a1) / (1 - b1 - b2);\n right_corner = (a2 + a3) / (1 - b1 - b2);\n\n // Attempt to force type to FP32.\n return new Float32Array([ a0, a1, a2, a3, b1, b2, left_corner, right_corner ]);\n}\n\nfunction convolveMono16(src, out, line, coeff, width, height) {\n // takes src image and writes the blurred and transposed result into out\n\n var prev_src, curr_src, curr_out, prev_out, prev_prev_out;\n var src_index, out_index, line_index;\n var i, j;\n var coeff_a0, coeff_a1, coeff_b1, coeff_b2;\n\n for (i = 0; i < height; i++) {\n src_index = i * width;\n out_index = i;\n line_index = 0;\n\n // left to right\n prev_src = src[src_index];\n prev_prev_out = prev_src * coeff[6];\n prev_out = prev_prev_out;\n\n coeff_a0 = coeff[0];\n coeff_a1 = coeff[1];\n coeff_b1 = coeff[4];\n coeff_b2 = coeff[5];\n\n for (j = 0; j < width; j++) {\n curr_src = src[src_index];\n\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2;\n\n prev_prev_out = prev_out;\n prev_out = curr_out;\n prev_src = curr_src;\n\n line[line_index] = prev_out;\n line_index++;\n src_index++;\n }\n\n src_index--;\n line_index--;\n out_index += height * (width - 1);\n\n // right to left\n prev_src = src[src_index];\n prev_prev_out = prev_src * coeff[7];\n prev_out = prev_prev_out;\n curr_src = prev_src;\n\n coeff_a0 = coeff[2];\n coeff_a1 = coeff[3];\n\n for (j = width - 1; j >= 0; j--) {\n curr_out = curr_src * coeff_a0 +\n prev_src * coeff_a1 +\n prev_out * coeff_b1 +\n prev_prev_out * coeff_b2;\n\n prev_prev_out = prev_out;\n prev_out = curr_out;\n\n prev_src = curr_src;\n curr_src = src[src_index];\n\n out[out_index] = line[line_index] + prev_out;\n\n src_index--;\n line_index--;\n out_index -= height;\n }\n }\n}\n\n\nfunction blurMono16(src, width, height, radius) {\n // Quick exit on zero radius\n if (!radius) { return; }\n\n var out = new Uint16Array(src.length),\n tmp_line = new Float32Array(Math.max(width, height));\n\n var coeff = gaussCoef(radius);\n\n convolveMono16(src, out, tmp_line, coeff, width, height);\n convolveMono16(out, src, tmp_line, coeff, height, width);\n}\n\nmodule.exports = blurMono16;\n\n},{}],19:[function(_dereq_,module,exports){\nif (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor;\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n }\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n if (superCtor) {\n ctor.super_ = superCtor;\n var TempCtor = function () {};\n TempCtor.prototype = superCtor.prototype;\n ctor.prototype = new TempCtor();\n ctor.prototype.constructor = ctor;\n }\n };\n}\n\n},{}],20:[function(_dereq_,module,exports){\n\n\nvar assign = _dereq_('object-assign');\nvar base64decode = _dereq_('./lib/base64decode');\nvar hasWebAssembly = _dereq_('./lib/wa_detect');\n\n\nvar DEFAULT_OPTIONS = {\n js: true,\n wasm: true\n};\n\n\nfunction MultiMath(options) {\n if (!(this instanceof MultiMath)) return new MultiMath(options);\n\n var opts = assign({}, DEFAULT_OPTIONS, options || {});\n\n this.options = opts;\n\n this.__cache = {};\n\n this.__init_promise = null;\n this.__modules = opts.modules || {};\n this.__memory = null;\n this.__wasm = {};\n\n this.__isLE = ((new Uint32Array((new Uint8Array([ 1, 0, 0, 0 ])).buffer))[0] === 1);\n\n if (!this.options.js && !this.options.wasm) {\n throw new Error('mathlib: at least \"js\" or \"wasm\" should be enabled');\n }\n}\n\n\nMultiMath.prototype.has_wasm = hasWebAssembly;\n\n\nMultiMath.prototype.use = function (module) {\n this.__modules[module.name] = module;\n\n // Pin the best possible implementation\n if (this.options.wasm && this.has_wasm() && module.wasm_fn) {\n this[module.name] = module.wasm_fn;\n } else {\n this[module.name] = module.fn;\n }\n\n return this;\n};\n\n\nMultiMath.prototype.init = function () {\n if (this.__init_promise) return this.__init_promise;\n\n if (!this.options.js && this.options.wasm && !this.has_wasm()) {\n return Promise.reject(new Error('mathlib: only \"wasm\" was enabled, but it\\'s not supported'));\n }\n\n var self = this;\n\n this.__init_promise = Promise.all(Object.keys(self.__modules).map(function (name) {\n var module = self.__modules[name];\n\n if (!self.options.wasm || !self.has_wasm() || !module.wasm_fn) return null;\n\n // If already compiled - exit\n if (self.__wasm[name]) return null;\n\n // Compile wasm source\n return WebAssembly.compile(self.__base64decode(module.wasm_src))\n .then(function (m) { self.__wasm[name] = m; });\n }))\n .then(function () { return self; });\n\n return this.__init_promise;\n};\n\n\n////////////////////////////////////////////////////////////////////////////////\n// Methods below are for internal use from plugins\n\n\n// Simple decode base64 to typed array. Useful to load embedded webassembly\n// code. You probably don't need to call this method directly.\n//\nMultiMath.prototype.__base64decode = base64decode;\n\n\n// Increase current memory to include specified number of bytes. Do nothing if\n// size is already ok. You probably don't need to call this method directly,\n// because it will be invoked from `.__instance()`.\n//\nMultiMath.prototype.__reallocate = function mem_grow_to(bytes) {\n if (!this.__memory) {\n this.__memory = new WebAssembly.Memory({\n initial: Math.ceil(bytes / (64 * 1024))\n });\n return this.__memory;\n }\n\n var mem_size = this.__memory.buffer.byteLength;\n\n if (mem_size < bytes) {\n this.__memory.grow(Math.ceil((bytes - mem_size) / (64 * 1024)));\n }\n\n return this.__memory;\n};\n\n\n// Returns instantinated webassembly item by name, with specified memory size\n// and environment.\n// - use cache if available\n// - do sync module init, if async init was not called earlier\n// - allocate memory if not enougth\n// - can export functions to webassembly via \"env_extra\",\n// for example, { exp: Math.exp }\n//\nMultiMath.prototype.__instance = function instance(name, memsize, env_extra) {\n if (memsize) this.__reallocate(memsize);\n\n // If .init() was not called, do sync compile\n if (!this.__wasm[name]) {\n var module = this.__modules[name];\n this.__wasm[name] = new WebAssembly.Module(this.__base64decode(module.wasm_src));\n }\n\n if (!this.__cache[name]) {\n var env_base = {\n memoryBase: 0,\n memory: this.__memory,\n tableBase: 0,\n table: new WebAssembly.Table({ initial: 0, element: 'anyfunc' })\n };\n\n this.__cache[name] = new WebAssembly.Instance(this.__wasm[name], {\n env: assign(env_base, env_extra || {})\n });\n }\n\n return this.__cache[name];\n};\n\n\n// Helper to calculate memory aligh for pointers. Webassembly does not require\n// this, but you may wish to experiment. Default base = 8;\n//\nMultiMath.prototype.__align = function align(number, base) {\n base = base || 8;\n var reminder = number % base;\n return number + (reminder ? base - reminder : 0);\n};\n\n\nmodule.exports = MultiMath;\n\n},{\"./lib/base64decode\":21,\"./lib/wa_detect\":22,\"object-assign\":23}],21:[function(_dereq_,module,exports){\n\n\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n\nmodule.exports = function base64decode(str) {\n var input = str.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length;\n\n var out = new Uint8Array((max * 3) >> 2);\n\n // Collect by 6*4 bits (3 bytes)\n\n var bits = 0;\n var ptr = 0;\n\n for (var idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n out[ptr++] = (bits >> 16) & 0xFF;\n out[ptr++] = (bits >> 8) & 0xFF;\n out[ptr++] = bits & 0xFF;\n }\n\n bits = (bits << 6) | BASE64_MAP.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n var tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n out[ptr++] = (bits >> 16) & 0xFF;\n out[ptr++] = (bits >> 8) & 0xFF;\n out[ptr++] = bits & 0xFF;\n } else if (tailbits === 18) {\n out[ptr++] = (bits >> 10) & 0xFF;\n out[ptr++] = (bits >> 2) & 0xFF;\n } else if (tailbits === 12) {\n out[ptr++] = (bits >> 4) & 0xFF;\n }\n\n return out;\n};\n\n},{}],22:[function(_dereq_,module,exports){\n\n\nvar wa;\n\n\nmodule.exports = function hasWebAssembly() {\n // use cache if called before;\n if (typeof wa !== 'undefined') return wa;\n\n wa = false;\n\n if (typeof WebAssembly === 'undefined') return wa;\n\n // If WebAssenbly is disabled, code can throw on compile\n try {\n // https://github.com/brion/min-wasm-fail/blob/master/min-wasm-fail.in.js\n // Additional check that WA internals are correct\n\n /* eslint-disable comma-spacing, max-len */\n var bin = new Uint8Array([ 0,97,115,109,1,0,0,0,1,6,1,96,1,127,1,127,3,2,1,0,5,3,1,0,1,7,8,1,4,116,101,115,116,0,0,10,16,1,14,0,32,0,65,1,54,2,0,32,0,40,2,0,11 ]);\n var module = new WebAssembly.Module(bin);\n var instance = new WebAssembly.Instance(module, {});\n\n // test storing to and loading from a non-zero location via a parameter.\n // Safari on iOS 11.2.5 returns 0 unexpectedly at non-zero locations\n if (instance.exports.test(4) !== 0) wa = true;\n\n return wa;\n } catch (__) {}\n\n return wa;\n};\n\n},{}],23:[function(_dereq_,module,exports){\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n\n},{}],24:[function(_dereq_,module,exports){\nvar bundleFn = arguments[3];\nvar sources = arguments[4];\nvar cache = arguments[5];\n\nvar stringify = JSON.stringify;\n\nmodule.exports = function (fn, options) {\n var wkey;\n var cacheKeys = Object.keys(cache);\n\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n var exp = cache[key].exports;\n // Using babel as a transpiler to use esmodule, the export will always\n // be an object with the default export as a property of it. To ensure\n // the existing api and babel esmodule exports are both supported we\n // check for both\n if (exp === fn || exp && exp.default === fn) {\n wkey = key;\n break;\n }\n }\n\n if (!wkey) {\n wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n var wcache = {};\n for (var i = 0, l = cacheKeys.length; i < l; i++) {\n var key = cacheKeys[i];\n wcache[key] = key;\n }\n sources[wkey] = [\n 'function(require,module,exports){' + fn + '(self); }',\n wcache\n ];\n }\n var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);\n\n var scache = {}; scache[wkey] = wkey;\n sources[skey] = [\n 'function(require,module,exports){' +\n // try to call default if defined to also support babel esmodule exports\n 'var f = require(' + stringify(wkey) + ');' +\n '(f.default ? f.default : f)(self);' +\n '}',\n scache\n ];\n\n var workerSources = {};\n resolveSources(skey);\n\n function resolveSources(key) {\n workerSources[key] = true;\n\n for (var depPath in sources[key][1]) {\n var depKey = sources[key][1][depPath];\n if (!workerSources[depKey]) {\n resolveSources(depKey);\n }\n }\n }\n\n var src = '(' + bundleFn + ')({'\n + Object.keys(workerSources).map(function (key) {\n return stringify(key) + ':['\n + sources[key][0]\n + ',' + stringify(sources[key][1]) + ']'\n ;\n }).join(',')\n + '},{},[' + stringify(skey) + '])'\n ;\n\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n var blob = new Blob([src], { type: 'text/javascript' });\n if (options && options.bare) { return blob; }\n var workerUrl = URL.createObjectURL(blob);\n var worker = new Worker(workerUrl);\n worker.objectURL = workerUrl;\n return worker;\n};\n\n},{}],\"/index.js\":[function(_dereq_,module,exports){\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nvar assign = _dereq_('object-assign');\n\nvar webworkify = _dereq_('webworkify');\n\nvar MathLib = _dereq_('./lib/mathlib');\n\nvar Pool = _dereq_('./lib/pool');\n\nvar utils = _dereq_('./lib/utils');\n\nvar worker = _dereq_('./lib/worker');\n\nvar createStages = _dereq_('./lib/stepper');\n\nvar createRegions = _dereq_('./lib/tiler'); // Deduplicate pools & limiters with the same configs\n// when user creates multiple pica instances.\n\n\nvar singletones = {};\nvar NEED_SAFARI_FIX = false;\n\ntry {\n if (typeof navigator !== 'undefined' && navigator.userAgent) {\n NEED_SAFARI_FIX = navigator.userAgent.indexOf('Safari') >= 0;\n }\n} catch (e) {}\n\nvar concurrency = 1;\n\nif (typeof navigator !== 'undefined') {\n concurrency = Math.min(navigator.hardwareConcurrency || 1, 4);\n}\n\nvar DEFAULT_PICA_OPTS = {\n tile: 1024,\n concurrency: concurrency,\n features: ['js', 'wasm', 'ww'],\n idle: 2000,\n createCanvas: function createCanvas(width, height) {\n var tmpCanvas = document.createElement('canvas');\n tmpCanvas.width = width;\n tmpCanvas.height = height;\n return tmpCanvas;\n }\n};\nvar DEFAULT_RESIZE_OPTS = {\n quality: 3,\n alpha: false,\n unsharpAmount: 0,\n unsharpRadius: 0.0,\n unsharpThreshold: 0\n};\nvar CAN_NEW_IMAGE_DATA = false;\nvar CAN_CREATE_IMAGE_BITMAP = false;\nvar CAN_USE_CANVAS_GET_IMAGE_DATA = false;\nvar CAN_USE_OFFSCREEN_CANVAS = false;\nvar CAN_USE_CIB_REGION_FOR_IMAGE = false;\n\nfunction workerFabric() {\n return {\n value: webworkify(worker),\n destroy: function destroy() {\n this.value.terminate();\n\n if (typeof window !== 'undefined') {\n var url = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n if (url && url.revokeObjectURL && this.value.objectURL) {\n url.revokeObjectURL(this.value.objectURL);\n }\n }\n }\n };\n} ////////////////////////////////////////////////////////////////////////////////\n// API methods\n\n\nfunction Pica(options) {\n if (!(this instanceof Pica)) return new Pica(options);\n this.options = assign({}, DEFAULT_PICA_OPTS, options || {});\n var limiter_key = \"lk_\".concat(this.options.concurrency); // Share limiters to avoid multiple parallel workers when user creates\n // multiple pica instances.\n\n this.__limit = singletones[limiter_key] || utils.limiter(this.options.concurrency);\n if (!singletones[limiter_key]) singletones[limiter_key] = this.__limit; // List of supported features, according to options & browser/node.js\n\n this.features = {\n js: false,\n // pure JS implementation, can be disabled for testing\n wasm: false,\n // webassembly implementation for heavy functions\n cib: false,\n // resize via createImageBitmap (only FF at this moment)\n ww: false // webworkers\n\n };\n this.__workersPool = null; // Store requested features for webworkers\n\n this.__requested_features = [];\n this.__mathlib = null;\n}\n\nPica.prototype.init = function () {\n var _this = this;\n\n if (this.__initPromise) return this.__initPromise; // Test if we can create ImageData without canvas and memory copy\n\n if (typeof ImageData !== 'undefined' && typeof Uint8ClampedArray !== 'undefined') {\n try {\n /* eslint-disable no-new */\n new ImageData(new Uint8ClampedArray(400), 10, 10);\n CAN_NEW_IMAGE_DATA = true;\n } catch (__) {}\n } // ImageBitmap can be effective in 2 places:\n //\n // 1. Threaded jpeg unpack (basic)\n // 2. Built-in resize (blocked due problem in chrome, see issue #89)\n //\n // For basic use we also need ImageBitmap wo support .close() method,\n // see https://developer.mozilla.org/ru/docs/Web/API/ImageBitmap\n\n\n if (typeof ImageBitmap !== 'undefined') {\n if (ImageBitmap.prototype && ImageBitmap.prototype.close) {\n CAN_CREATE_IMAGE_BITMAP = true;\n } else {\n this.debug('ImageBitmap does not support .close(), disabled');\n }\n }\n\n var features = this.options.features.slice();\n\n if (features.indexOf('all') >= 0) {\n features = ['cib', 'wasm', 'js', 'ww'];\n }\n\n this.__requested_features = features;\n this.__mathlib = new MathLib(features); // Check WebWorker support if requested\n\n if (features.indexOf('ww') >= 0) {\n if (typeof window !== 'undefined' && 'Worker' in window) {\n // IE <= 11 don't allow to create webworkers from string. We should check it.\n // https://connect.microsoft.com/IE/feedback/details/801810/web-workers-from-blob-urls-in-ie-10-and-11\n try {\n var wkr = _dereq_('webworkify')(function () {});\n\n wkr.terminate();\n this.features.ww = true; // pool uniqueness depends on pool config + webworker config\n\n var wpool_key = \"wp_\".concat(JSON.stringify(this.options));\n\n if (singletones[wpool_key]) {\n this.__workersPool = singletones[wpool_key];\n } else {\n this.__workersPool = new Pool(workerFabric, this.options.idle);\n singletones[wpool_key] = this.__workersPool;\n }\n } catch (__) {}\n }\n }\n\n var initMath = this.__mathlib.init().then(function (mathlib) {\n // Copy detected features\n assign(_this.features, mathlib.features);\n });\n\n var checkCibResize;\n\n if (!CAN_CREATE_IMAGE_BITMAP) {\n checkCibResize = Promise.resolve(false);\n } else {\n checkCibResize = utils.cib_support(this.options.createCanvas).then(function (status) {\n if (_this.features.cib && features.indexOf('cib') < 0) {\n _this.debug('createImageBitmap() resize supported, but disabled by config');\n\n return;\n }\n\n if (features.indexOf('cib') >= 0) _this.features.cib = status;\n });\n }\n\n CAN_USE_CANVAS_GET_IMAGE_DATA = utils.can_use_canvas(this.options.createCanvas);\n var checkOffscreenCanvas;\n\n if (CAN_CREATE_IMAGE_BITMAP && CAN_NEW_IMAGE_DATA && features.indexOf('ww') !== -1) {\n checkOffscreenCanvas = utils.worker_offscreen_canvas_support();\n } else {\n checkOffscreenCanvas = Promise.resolve(false);\n }\n\n checkOffscreenCanvas = checkOffscreenCanvas.then(function (result) {\n CAN_USE_OFFSCREEN_CANVAS = result;\n }); // we use createImageBitmap to crop image data and pass it to workers,\n // so need to check whether function works correctly;\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n\n var checkCibRegion = utils.cib_can_use_region().then(function (result) {\n CAN_USE_CIB_REGION_FOR_IMAGE = result;\n }); // Init math lib. That's async because can load some\n\n this.__initPromise = Promise.all([initMath, checkCibResize, checkOffscreenCanvas, checkCibRegion]).then(function () {\n return _this;\n });\n return this.__initPromise;\n}; // Call resizer in webworker or locally, depending on config\n\n\nPica.prototype.__invokeResize = function (tileOpts, opts) {\n var _this2 = this;\n\n // Share cache between calls:\n //\n // - wasm instance\n // - wasm memory object\n //\n opts.__mathCache = opts.__mathCache || {};\n return Promise.resolve().then(function () {\n if (!_this2.features.ww) {\n // not possible to have ImageBitmap here if user disabled WW\n return {\n data: _this2.__mathlib.resizeAndUnsharp(tileOpts, opts.__mathCache)\n };\n }\n\n return new Promise(function (resolve, reject) {\n var w = _this2.__workersPool.acquire();\n\n if (opts.cancelToken) opts.cancelToken[\"catch\"](function (err) {\n return reject(err);\n });\n\n w.value.onmessage = function (ev) {\n w.release();\n if (ev.data.err) reject(ev.data.err);else resolve(ev.data);\n };\n\n var transfer = [];\n if (tileOpts.src) transfer.push(tileOpts.src.buffer);\n if (tileOpts.srcBitmap) transfer.push(tileOpts.srcBitmap);\n w.value.postMessage({\n opts: tileOpts,\n features: _this2.__requested_features,\n preload: {\n wasm_nodule: _this2.__mathlib.__\n }\n }, transfer);\n });\n });\n}; // this function can return promise if createImageBitmap is used\n\n\nPica.prototype.__extractTileData = function (tile, from, opts, stageEnv, extractTo) {\n if (this.features.ww && CAN_USE_OFFSCREEN_CANVAS && ( // createImageBitmap doesn't work for images (Image, ImageBitmap) with Exif orientation in Chrome,\n // can use canvas because canvas doesn't have orientation;\n // see https://bugs.chromium.org/p/chromium/issues/detail?id=1220671\n utils.isCanvas(from) || CAN_USE_CIB_REGION_FOR_IMAGE)) {\n this.debug('Create tile for OffscreenCanvas');\n return createImageBitmap(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height).then(function (bitmap) {\n extractTo.srcBitmap = bitmap;\n return extractTo;\n });\n } // Extract tile RGBA buffer, depending on input type\n\n\n if (utils.isCanvas(from)) {\n if (!stageEnv.srcCtx) stageEnv.srcCtx = from.getContext('2d', {\n alpha: Boolean(opts.alpha)\n }); // If input is Canvas - extract region data directly\n\n this.debug('Get tile pixel data');\n extractTo.src = stageEnv.srcCtx.getImageData(tile.x, tile.y, tile.width, tile.height).data;\n return extractTo;\n } // If input is Image or decoded to ImageBitmap,\n // draw region to temporary canvas and extract data from it\n //\n // Note! Attempt to reuse this canvas causes significant slowdown in chrome\n //\n\n\n this.debug('Draw tile imageBitmap/image to temporary canvas');\n var tmpCanvas = this.options.createCanvas(tile.width, tile.height);\n var tmpCtx = tmpCanvas.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n tmpCtx.globalCompositeOperation = 'copy';\n tmpCtx.drawImage(stageEnv.srcImageBitmap || from, tile.x, tile.y, tile.width, tile.height, 0, 0, tile.width, tile.height);\n this.debug('Get tile pixel data');\n extractTo.src = tmpCtx.getImageData(0, 0, tile.width, tile.height).data; // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n\n tmpCanvas.width = tmpCanvas.height = 0;\n return extractTo;\n};\n\nPica.prototype.__landTileData = function (tile, result, stageEnv) {\n var toImageData;\n this.debug('Convert raw rgba tile result to ImageData');\n\n if (result.bitmap) {\n stageEnv.toCtx.drawImage(result.bitmap, tile.toX, tile.toY);\n return null;\n }\n\n if (CAN_NEW_IMAGE_DATA) {\n // this branch is for modern browsers\n // If `new ImageData()` & Uint8ClampedArray suported\n toImageData = new ImageData(new Uint8ClampedArray(result.data), tile.toWidth, tile.toHeight);\n } else {\n // fallback for `node-canvas` and old browsers\n // (IE11 has ImageData but does not support `new ImageData()`)\n toImageData = stageEnv.toCtx.createImageData(tile.toWidth, tile.toHeight);\n\n if (toImageData.data.set) {\n toImageData.data.set(result.data);\n } else {\n // IE9 don't have `.set()`\n for (var i = toImageData.data.length - 1; i >= 0; i--) {\n toImageData.data[i] = result.data[i];\n }\n }\n }\n\n this.debug('Draw tile');\n\n if (NEED_SAFARI_FIX) {\n // Safari draws thin white stripes between tiles without this fix\n stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth + 1e-5, tile.toInnerHeight + 1e-5);\n } else {\n stageEnv.toCtx.putImageData(toImageData, tile.toX, tile.toY, tile.toInnerX - tile.toX, tile.toInnerY - tile.toY, tile.toInnerWidth, tile.toInnerHeight);\n }\n\n return null;\n};\n\nPica.prototype.__tileAndResize = function (from, to, opts) {\n var _this3 = this;\n\n var stageEnv = {\n srcCtx: null,\n srcImageBitmap: null,\n isImageBitmapReused: false,\n toCtx: null\n };\n\n var processTile = function processTile(tile) {\n return _this3.__limit(function () {\n if (opts.canceled) return opts.cancelToken;\n var tileOpts = {\n width: tile.width,\n height: tile.height,\n toWidth: tile.toWidth,\n toHeight: tile.toHeight,\n scaleX: tile.scaleX,\n scaleY: tile.scaleY,\n offsetX: tile.offsetX,\n offsetY: tile.offsetY,\n quality: opts.quality,\n alpha: opts.alpha,\n unsharpAmount: opts.unsharpAmount,\n unsharpRadius: opts.unsharpRadius,\n unsharpThreshold: opts.unsharpThreshold\n };\n\n _this3.debug('Invoke resize math');\n\n return Promise.resolve(tileOpts).then(function (tileOpts) {\n return _this3.__extractTileData(tile, from, opts, stageEnv, tileOpts);\n }).then(function (tileOpts) {\n _this3.debug('Invoke resize math');\n\n return _this3.__invokeResize(tileOpts, opts);\n }).then(function (result) {\n if (opts.canceled) return opts.cancelToken;\n stageEnv.srcImageData = null;\n return _this3.__landTileData(tile, result, stageEnv);\n });\n });\n }; // Need to normalize data source first. It can be canvas or image.\n // If image - try to decode in background if possible\n\n\n return Promise.resolve().then(function () {\n stageEnv.toCtx = to.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n if (utils.isCanvas(from)) return null;\n\n if (utils.isImageBitmap(from)) {\n stageEnv.srcImageBitmap = from;\n stageEnv.isImageBitmapReused = true;\n return null;\n }\n\n if (utils.isImage(from)) {\n // try do decode image in background for faster next operations;\n // if we're using offscreen canvas, cib is called per tile, so not needed here\n if (!CAN_CREATE_IMAGE_BITMAP) return null;\n\n _this3.debug('Decode image via createImageBitmap');\n\n return createImageBitmap(from).then(function (imageBitmap) {\n stageEnv.srcImageBitmap = imageBitmap;\n }) // Suppress error to use fallback, if method fails\n // https://github.com/nodeca/pica/issues/190\n\n /* eslint-disable no-unused-vars */\n [\"catch\"](function (e) {\n return null;\n });\n }\n\n throw new Error('Pica: \".from\" should be Image, Canvas or ImageBitmap');\n }).then(function () {\n if (opts.canceled) return opts.cancelToken;\n\n _this3.debug('Calculate tiles'); //\n // Here we are with \"normalized\" source,\n // follow to tiling\n //\n\n\n var regions = createRegions({\n width: opts.width,\n height: opts.height,\n srcTileSize: _this3.options.tile,\n toWidth: opts.toWidth,\n toHeight: opts.toHeight,\n destTileBorder: opts.__destTileBorder\n });\n var jobs = regions.map(function (tile) {\n return processTile(tile);\n });\n\n function cleanup(stageEnv) {\n if (stageEnv.srcImageBitmap) {\n if (!stageEnv.isImageBitmapReused) stageEnv.srcImageBitmap.close();\n stageEnv.srcImageBitmap = null;\n }\n }\n\n _this3.debug('Process tiles');\n\n return Promise.all(jobs).then(function () {\n _this3.debug('Finished!');\n\n cleanup(stageEnv);\n return to;\n }, function (err) {\n cleanup(stageEnv);\n throw err;\n });\n });\n};\n\nPica.prototype.__processStages = function (stages, from, to, opts) {\n var _this4 = this;\n\n if (opts.canceled) return opts.cancelToken;\n\n var _stages$shift = stages.shift(),\n _stages$shift2 = _slicedToArray(_stages$shift, 2),\n toWidth = _stages$shift2[0],\n toHeight = _stages$shift2[1];\n\n var isLastStage = stages.length === 0;\n opts = assign({}, opts, {\n toWidth: toWidth,\n toHeight: toHeight,\n // only use user-defined quality for the last stage,\n // use simpler (Hamming) filter for the first stages where\n // scale factor is large enough (more than 2-3)\n quality: isLastStage ? opts.quality : Math.min(1, opts.quality)\n });\n var tmpCanvas;\n\n if (!isLastStage) {\n // create temporary canvas\n tmpCanvas = this.options.createCanvas(toWidth, toHeight);\n }\n\n return this.__tileAndResize(from, isLastStage ? to : tmpCanvas, opts).then(function () {\n if (isLastStage) return to;\n opts.width = toWidth;\n opts.height = toHeight;\n return _this4.__processStages(stages, tmpCanvas, to, opts);\n }).then(function (res) {\n if (tmpCanvas) {\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n tmpCanvas.width = tmpCanvas.height = 0;\n }\n\n return res;\n });\n};\n\nPica.prototype.__resizeViaCreateImageBitmap = function (from, to, opts) {\n var _this5 = this;\n\n var toCtx = to.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n this.debug('Resize via createImageBitmap()');\n return createImageBitmap(from, {\n resizeWidth: opts.toWidth,\n resizeHeight: opts.toHeight,\n resizeQuality: utils.cib_quality_name(opts.quality)\n }).then(function (imageBitmap) {\n if (opts.canceled) return opts.cancelToken; // if no unsharp - draw directly to output canvas\n\n if (!opts.unsharpAmount) {\n toCtx.drawImage(imageBitmap, 0, 0);\n imageBitmap.close();\n toCtx = null;\n\n _this5.debug('Finished!');\n\n return to;\n }\n\n _this5.debug('Unsharp result');\n\n var tmpCanvas = _this5.options.createCanvas(opts.toWidth, opts.toHeight);\n\n var tmpCtx = tmpCanvas.getContext('2d', {\n alpha: Boolean(opts.alpha)\n });\n tmpCtx.drawImage(imageBitmap, 0, 0);\n imageBitmap.close();\n var iData = tmpCtx.getImageData(0, 0, opts.toWidth, opts.toHeight);\n\n _this5.__mathlib.unsharp_mask(iData.data, opts.toWidth, opts.toHeight, opts.unsharpAmount, opts.unsharpRadius, opts.unsharpThreshold);\n\n toCtx.putImageData(iData, 0, 0); // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n\n tmpCanvas.width = tmpCanvas.height = 0;\n iData = tmpCtx = tmpCanvas = toCtx = null;\n\n _this5.debug('Finished!');\n\n return to;\n });\n};\n\nPica.prototype.resize = function (from, to, options) {\n var _this6 = this;\n\n this.debug('Start resize...');\n var opts = assign({}, DEFAULT_RESIZE_OPTS);\n\n if (!isNaN(options)) {\n opts = assign(opts, {\n quality: options\n });\n } else if (options) {\n opts = assign(opts, options);\n }\n\n opts.toWidth = to.width;\n opts.toHeight = to.height;\n opts.width = from.naturalWidth || from.width;\n opts.height = from.naturalHeight || from.height; // Prevent stepper from infinite loop\n\n if (to.width === 0 || to.height === 0) {\n return Promise.reject(new Error(\"Invalid output size: \".concat(to.width, \"x\").concat(to.height)));\n }\n\n if (opts.unsharpRadius > 2) opts.unsharpRadius = 2;\n opts.canceled = false;\n\n if (opts.cancelToken) {\n // Wrap cancelToken to avoid successive resolve & set flag\n opts.cancelToken = opts.cancelToken.then(function (data) {\n opts.canceled = true;\n throw data;\n }, function (err) {\n opts.canceled = true;\n throw err;\n });\n }\n\n var DEST_TILE_BORDER = 3; // Max possible filter window size\n\n opts.__destTileBorder = Math.ceil(Math.max(DEST_TILE_BORDER, 2.5 * opts.unsharpRadius | 0));\n return this.init().then(function () {\n if (opts.canceled) return opts.cancelToken; // if createImageBitmap supports resize, just do it and return\n\n if (_this6.features.cib) {\n return _this6.__resizeViaCreateImageBitmap(from, to, opts);\n }\n\n if (!CAN_USE_CANVAS_GET_IMAGE_DATA) {\n var err = new Error('Pica: cannot use getImageData on canvas, ' + \"make sure fingerprinting protection isn't enabled\");\n err.code = 'ERR_GET_IMAGE_DATA';\n throw err;\n } //\n // No easy way, let's resize manually via arrays\n //\n\n\n var stages = createStages(opts.width, opts.height, opts.toWidth, opts.toHeight, _this6.options.tile, opts.__destTileBorder);\n return _this6.__processStages(stages, from, to, opts);\n });\n}; // RGBA buffer resize\n//\n\n\nPica.prototype.resizeBuffer = function (options) {\n var _this7 = this;\n\n var opts = assign({}, DEFAULT_RESIZE_OPTS, options);\n return this.init().then(function () {\n return _this7.__mathlib.resizeAndUnsharp(opts);\n });\n};\n\nPica.prototype.toBlob = function (canvas, mimeType, quality) {\n mimeType = mimeType || 'image/png';\n return new Promise(function (resolve) {\n if (canvas.toBlob) {\n canvas.toBlob(function (blob) {\n return resolve(blob);\n }, mimeType, quality);\n return;\n }\n\n if (canvas.convertToBlob) {\n resolve(canvas.convertToBlob({\n type: mimeType,\n quality: quality\n }));\n return;\n } // Fallback for old browsers\n\n\n var asString = atob(canvas.toDataURL(mimeType, quality).split(',')[1]);\n var len = asString.length;\n var asBuffer = new Uint8Array(len);\n\n for (var i = 0; i < len; i++) {\n asBuffer[i] = asString.charCodeAt(i);\n }\n\n resolve(new Blob([asBuffer], {\n type: mimeType\n }));\n });\n};\n\nPica.prototype.debug = function () {};\n\nmodule.exports = Pica;\n\n},{\"./lib/mathlib\":1,\"./lib/pool\":13,\"./lib/stepper\":14,\"./lib/tiler\":15,\"./lib/utils\":16,\"./lib/worker\":17,\"object-assign\":23,\"webworkify\":24}]},{},[])(\"/index.js\")\n});\n});\n\nvar image_traverse = createCommonjsModule(function (module) {\n\n//////////////////////////////////////////////////////////////////////////\n// Helpers\n//\nfunction error(message, code) {\n var err = new Error(message);\n err.code = code;\n return err;\n}\n\n\n// Convert number to 0xHH string\n//\nfunction to_hex(number) {\n var n = number.toString(16).toUpperCase();\n for (var i = 2 - n.length; i > 0; i--) n = '0' + n;\n return '0x' + n;\n}\n\n\nfunction utf8_encode(str) {\n try {\n return unescape(encodeURIComponent(str));\n } catch (_) {\n return str;\n }\n}\n\n\nfunction utf8_decode(str) {\n try {\n return decodeURIComponent(escape(str));\n } catch (_) {\n return str;\n }\n}\n\n\n// Check if input is a Uint8Array\n//\nfunction is_uint8array(bin) {\n return Object.prototype.toString.call(bin) === '[object Uint8Array]';\n}\n\n\n//////////////////////////////////////////////////////////////////////////\n// Exif parser\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n// - exif_start: Number - start of TIFF header (after Exif\\0\\0)\n// - exif_end: Number - end of Exif segment\n// - on_entry: Number - callback\n//\nfunction ExifParser(jpeg_bin, exif_start, exif_end) {\n // Uint8Array, exif without signature (which isn't included in offsets)\n this.input = jpeg_bin.subarray(exif_start, exif_end);\n\n // offset correction for `on_entry` callback\n this.start = exif_start;\n\n // Check TIFF header (includes byte alignment and first IFD offset)\n var sig = String.fromCharCode.apply(null, this.input.subarray(0, 4));\n\n if (sig !== 'II\\x2A\\0' && sig !== 'MM\\0\\x2A') {\n throw error('invalid TIFF signature', 'EBADDATA');\n }\n\n // true if motorola (big endian) byte alignment, false if intel\n this.big_endian = sig[0] === 'M';\n}\n\n\nExifParser.prototype.each = function (on_entry) {\n // allow premature exit\n this.aborted = false;\n\n var offset = this.read_uint32(4);\n\n this.ifds_to_read = [ {\n id: 0,\n offset: offset\n } ];\n\n while (this.ifds_to_read.length > 0 && !this.aborted) {\n var i = this.ifds_to_read.shift();\n if (!i.offset) continue;\n this.scan_ifd(i.id, i.offset, on_entry);\n }\n};\n\n\nExifParser.prototype.filter = function (on_entry) {\n var ifds = {};\n\n // make sure IFD0 always exists\n ifds.ifd0 = { id: 0, entries: [] };\n\n this.each(function (entry) {\n if (on_entry(entry) === false && !entry.is_subifd_link) return;\n if (entry.is_subifd_link && entry.count !== 1 && entry.format !== 4) return; // filter out bogus links\n\n if (!ifds['ifd' + entry.ifd]) {\n ifds['ifd' + entry.ifd] = { id: entry.ifd, entries: [] };\n }\n\n ifds['ifd' + entry.ifd].entries.push(entry);\n });\n\n // thumbnails are not supported just yet, so delete all information related to it\n delete ifds.ifd1;\n\n // Calculate output size\n var length = 8;\n Object.keys(ifds).forEach(function (ifd_no) {\n length += 2;\n\n ifds[ifd_no].entries.forEach(function (entry) {\n length += 12 + (entry.data_length > 4 ? Math.ceil(entry.data_length / 2) * 2 : 0);\n });\n\n length += 4;\n });\n\n this.output = new Uint8Array(length);\n this.output[0] = this.output[1] = (this.big_endian ? 'M' : 'I').charCodeAt(0);\n this.write_uint16(2, 0x2A);\n\n var offset = 8;\n var self = this;\n this.write_uint32(4, offset);\n\n Object.keys(ifds).forEach(function (ifd_no) {\n ifds[ifd_no].written_offset = offset;\n\n var ifd_start = offset;\n var ifd_end = ifd_start + 2 + ifds[ifd_no].entries.length * 12 + 4;\n offset = ifd_end;\n\n self.write_uint16(ifd_start, ifds[ifd_no].entries.length);\n\n ifds[ifd_no].entries.sort(function (a, b) {\n // IFD entries must be in order of increasing tag IDs\n return a.tag - b.tag;\n }).forEach(function (entry, idx) {\n var entry_offset = ifd_start + 2 + idx * 12;\n\n self.write_uint16(entry_offset, entry.tag);\n self.write_uint16(entry_offset + 2, entry.format);\n self.write_uint32(entry_offset + 4, entry.count);\n\n if (entry.is_subifd_link) {\n // filled in later\n if (ifds['ifd' + entry.tag]) ifds['ifd' + entry.tag].link_offset = entry_offset + 8;\n } else if (entry.data_length <= 4) {\n self.output.set(\n self.input.subarray(entry.data_offset - self.start, entry.data_offset - self.start + 4),\n entry_offset + 8\n );\n } else {\n self.write_uint32(entry_offset + 8, offset);\n self.output.set(\n self.input.subarray(entry.data_offset - self.start, entry.data_offset - self.start + entry.data_length),\n offset\n );\n offset += Math.ceil(entry.data_length / 2) * 2;\n }\n });\n\n var next_ifd = ifds['ifd' + (ifds[ifd_no].id + 1)];\n if (next_ifd) next_ifd.link_offset = ifd_end - 4;\n });\n\n Object.keys(ifds).forEach(function (ifd_no) {\n if (ifds[ifd_no].written_offset && ifds[ifd_no].link_offset) {\n self.write_uint32(ifds[ifd_no].link_offset, ifds[ifd_no].written_offset);\n }\n });\n\n if (this.output.length !== offset) throw error('internal error: incorrect buffer size allocated');\n\n return this.output;\n};\n\n\nExifParser.prototype.read_uint16 = function (offset) {\n var d = this.input;\n if (offset + 2 > d.length) throw error('unexpected EOF', 'EBADDATA');\n\n return this.big_endian ?\n d[offset] * 0x100 + d[offset + 1] :\n d[offset] + d[offset + 1] * 0x100;\n};\n\n\nExifParser.prototype.read_uint32 = function (offset) {\n var d = this.input;\n if (offset + 4 > d.length) throw error('unexpected EOF', 'EBADDATA');\n\n return this.big_endian ?\n d[offset] * 0x1000000 + d[offset + 1] * 0x10000 + d[offset + 2] * 0x100 + d[offset + 3] :\n d[offset] + d[offset + 1] * 0x100 + d[offset + 2] * 0x10000 + d[offset + 3] * 0x1000000;\n};\n\n\nExifParser.prototype.write_uint16 = function (offset, value) {\n var d = this.output;\n\n if (this.big_endian) {\n d[offset] = (value >>> 8) & 0xFF;\n d[offset + 1] = value & 0xFF;\n } else {\n d[offset] = value & 0xFF;\n d[offset + 1] = (value >>> 8) & 0xFF;\n }\n};\n\n\nExifParser.prototype.write_uint32 = function (offset, value) {\n var d = this.output;\n\n if (this.big_endian) {\n d[offset] = (value >>> 24) & 0xFF;\n d[offset + 1] = (value >>> 16) & 0xFF;\n d[offset + 2] = (value >>> 8) & 0xFF;\n d[offset + 3] = value & 0xFF;\n } else {\n d[offset] = value & 0xFF;\n d[offset + 1] = (value >>> 8) & 0xFF;\n d[offset + 2] = (value >>> 16) & 0xFF;\n d[offset + 3] = (value >>> 24) & 0xFF;\n }\n};\n\n\nExifParser.prototype.is_subifd_link = function (ifd, tag) {\n return (ifd === 0 && tag === 0x8769) || // SubIFD\n (ifd === 0 && tag === 0x8825) || // GPS Info\n (ifd === 0x8769 && tag === 0xA005); // Interop IFD\n};\n\n\n// Returns byte length of a single component of a given format\n//\nExifParser.prototype.exif_format_length = function (format) {\n switch (format) {\n case 1: // byte\n case 2: // ascii\n case 6: // sbyte\n case 7: // undefined\n return 1;\n\n case 3: // short\n case 8: // sshort\n return 2;\n\n case 4: // long\n case 9: // slong\n case 11: // float\n return 4;\n\n case 5: // rational\n case 10: // srational\n case 12: // double\n return 8;\n\n default:\n // unknown type\n return 0;\n }\n};\n\n\n// Reads Exif data\n//\nExifParser.prototype.exif_format_read = function (format, offset) {\n var v;\n\n switch (format) {\n case 1: // byte\n case 2: // ascii\n v = this.input[offset];\n return v;\n\n case 6: // sbyte\n v = this.input[offset];\n return v | (v & 0x80) * 0x1fffffe;\n\n case 3: // short\n v = this.read_uint16(offset);\n return v;\n\n case 8: // sshort\n v = this.read_uint16(offset);\n return v | (v & 0x8000) * 0x1fffe;\n\n case 4: // long\n v = this.read_uint32(offset);\n return v;\n\n case 9: // slong\n v = this.read_uint32(offset);\n return v | 0;\n\n case 5: // rational\n case 10: // srational\n case 11: // float\n case 12: // double\n return null; // not implemented\n\n case 7: // undefined\n return null; // blob\n\n default:\n // unknown type\n return null;\n }\n};\n\n\nExifParser.prototype.scan_ifd = function (ifd_no, offset, on_entry) {\n var entry_count = this.read_uint16(offset);\n\n offset += 2;\n\n for (var i = 0; i < entry_count; i++) {\n var tag = this.read_uint16(offset);\n var format = this.read_uint16(offset + 2);\n var count = this.read_uint32(offset + 4);\n\n var comp_length = this.exif_format_length(format);\n var data_length = count * comp_length;\n var data_offset = data_length <= 4 ? offset + 8 : this.read_uint32(offset + 8);\n var is_subifd_link = false;\n\n if (data_offset + data_length > this.input.length) {\n throw error('unexpected EOF', 'EBADDATA');\n }\n\n var value = [];\n var comp_offset = data_offset;\n\n for (var j = 0; j < count; j++, comp_offset += comp_length) {\n var item = this.exif_format_read(format, comp_offset);\n if (item === null) {\n value = null;\n break;\n }\n value.push(item);\n }\n\n if (Array.isArray(value) && format === 2) {\n try {\n value = utf8_decode(String.fromCharCode.apply(null, value));\n } catch (_) {\n value = null;\n }\n\n if (value && value[value.length - 1] === '\\0') value = value.slice(0, -1);\n }\n\n if (this.is_subifd_link(ifd_no, tag)) {\n if (Array.isArray(value) && Number.isInteger(value[0]) && value[0] > 0) {\n this.ifds_to_read.push({\n id: tag,\n offset: value[0]\n });\n is_subifd_link = true;\n }\n }\n\n var entry = {\n is_big_endian: this.big_endian,\n ifd: ifd_no,\n tag: tag,\n format: format,\n count: count,\n entry_offset: offset + this.start,\n data_length: data_length,\n data_offset: data_offset + this.start,\n value: value,\n is_subifd_link: is_subifd_link\n };\n\n if (on_entry(entry) === false) {\n this.aborted = true;\n return;\n }\n\n offset += 12;\n }\n\n if (ifd_no === 0) {\n this.ifds_to_read.push({\n id: 1,\n offset: this.read_uint32(offset)\n });\n }\n};\n\n\n// Check whether input is a JPEG image\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n//\n// Returns true if it is and false otherwise\n//\nmodule.exports.is_jpeg = function (jpeg_bin) {\n return jpeg_bin.length >= 4 && jpeg_bin[0] === 0xFF && jpeg_bin[1] === 0xD8 && jpeg_bin[2] === 0xFF;\n};\n\n\n// Call an iterator on each segment in the given JPEG image\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n// - on_segment: Function - callback executed on each JPEG marker segment\n// - segment: Object\n// - code: Number - marker type (2nd byte, e.g. 0xE0 for APP0)\n// - offset: Number - offset of the first byte (0xFF) relative to `jpeg_bin` start\n// - length: Number - length of the entire marker segment including first two bytes and length\n// - 2 for standalone markers\n// - 4+length for markers with data\n//\n// Iteration stops when `EOI` (0xFFD9) marker is reached or if `on_segment`\n// function returns `false`.\n//\nmodule.exports.jpeg_segments_each = function (jpeg_bin, on_segment) {\n if (!is_uint8array(jpeg_bin)) {\n throw error('Invalid argument (jpeg_bin), Uint8Array expected', 'EINVAL');\n }\n\n if (typeof on_segment !== 'function') {\n throw error('Invalid argument (on_segment), Function expected', 'EINVAL');\n }\n\n if (!module.exports.is_jpeg(jpeg_bin)) {\n throw error('Unknown file format', 'ENOTJPEG');\n }\n\n var offset = 0, length = jpeg_bin.length, inside_scan = false;\n\n for (;;) {\n var segment_code, segment_length;\n\n if (offset + 1 >= length) throw error('Unexpected EOF', 'EBADDATA');\n var byte1 = jpeg_bin[offset];\n var byte2 = jpeg_bin[offset + 1];\n\n if (byte1 === 0xFF && byte2 === 0xFF) {\n // padding\n segment_code = 0xFF;\n segment_length = 1;\n\n } else if (byte1 === 0xFF && byte2 !== 0) {\n // marker\n segment_code = byte2;\n segment_length = 2;\n\n if ((0xD0 <= segment_code && segment_code <= 0xD9) || segment_code === 0x01) ; else {\n if (offset + 3 >= length) throw error('Unexpected EOF', 'EBADDATA');\n segment_length += jpeg_bin[offset + 2] * 0x100 + jpeg_bin[offset + 3];\n if (segment_length < 2) throw error('Invalid segment length', 'EBADDATA');\n if (offset + segment_length - 1 >= length) throw error('Unexpected EOF', 'EBADDATA');\n }\n\n if (inside_scan) {\n if (segment_code >= 0xD0 && segment_code <= 0xD7) ; else {\n inside_scan = false;\n }\n }\n\n if (segment_code === 0xDA /* SOS */) inside_scan = true;\n } else if (inside_scan) {\n // entropy-encoded segment\n for (var pos = offset + 1; ; pos++) {\n // scan until we find FF\n if (pos >= length) throw error('Unexpected EOF', 'EBADDATA');\n if (jpeg_bin[pos] === 0xFF) {\n if (pos + 1 >= length) throw error('Unexpected EOF', 'EBADDATA');\n if (jpeg_bin[pos + 1] !== 0) {\n segment_code = 0;\n segment_length = pos - offset;\n break;\n }\n }\n }\n } else {\n throw error('Unexpected byte at segment start: ' + to_hex(byte1) +\n ' (offset ' + to_hex(offset) + ')', 'EBADDATA');\n }\n\n if (on_segment({ code: segment_code, offset: offset, length: segment_length }) === false) break;\n if (segment_code === 0xD9 /* EOI */) break;\n offset += segment_length;\n }\n};\n\n\n// Replace or remove segments in the given JPEG image\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n// - on_segment: Function - callback executed on each JPEG marker segment\n// - segment: Object\n// - code: Number - marker type (2nd byte, e.g. 0xE0 for APP0)\n// - offset: Number - offset of the first byte (0xFF) relative to `jpeg_bin` start\n// - length: Number - length of the entire marker segment including first two bytes and length\n// - 2 for standalone markers\n// - 4+length for markers with data\n//\n// `on_segment` function should return one of the following:\n// - `false` - segment is removed from the output\n// - Uint8Array - segment is replaced with the new data\n// - [ Uint8Array ] - segment is replaced with the new data\n// - anything else - segment is copied to the output as is\n//\n// Any data after `EOI` (0xFFD9) marker is removed.\n//\nmodule.exports.jpeg_segments_filter = function (jpeg_bin, on_segment) {\n if (!is_uint8array(jpeg_bin)) {\n throw error('Invalid argument (jpeg_bin), Uint8Array expected', 'EINVAL');\n }\n\n if (typeof on_segment !== 'function') {\n throw error('Invalid argument (on_segment), Function expected', 'EINVAL');\n }\n\n var ranges = [];\n var out_length = 0;\n\n module.exports.jpeg_segments_each(jpeg_bin, function (segment) {\n var new_segment = on_segment(segment);\n\n if (is_uint8array(new_segment)) {\n ranges.push({ data: new_segment });\n out_length += new_segment.length;\n } else if (Array.isArray(new_segment)) {\n new_segment.filter(is_uint8array).forEach(function (s) {\n ranges.push({ data: s });\n out_length += s.length;\n });\n } else if (new_segment !== false) {\n var new_range = { start: segment.offset, end: segment.offset + segment.length };\n\n if (ranges.length > 0 && ranges[ranges.length - 1].end === new_range.start) {\n ranges[ranges.length - 1].end = new_range.end;\n } else {\n ranges.push(new_range);\n }\n\n out_length += segment.length;\n }\n });\n\n var result = new Uint8Array(out_length);\n var offset = 0;\n\n ranges.forEach(function (range) {\n var data = range.data || jpeg_bin.subarray(range.start, range.end);\n result.set(data, offset);\n offset += data.length;\n });\n\n return result;\n};\n\n\n// Call an iterator on each Exif entry in the given JPEG image\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n// - on_entry: Function - callback executed on each Exif entry\n// - entry: Object\n// - is_big_endian: Boolean - whether Exif uses big or little endian byte alignment\n// - ifd: Number - IFD identifier (0 for IFD0, 1 for IFD1, 0x8769 for SubIFD,\n// 0x8825 for GPS Info, 0xA005 for Interop IFD)\n// - tag: Number - exif entry tag (0x0110 - camera name, 0x0112 - orientation, etc. - see Exif spec)\n// - format: Number - exif entry format (1 - byte, 2 - ascii, 3 - short, etc. - see Exif spec)\n// - count: Number - number of components of the given format inside data\n// (usually 1, or string length for ascii format)\n// - entry_offset: Number - start of Exif entry (entry length is always 12, so not included)\n// - data_offset: Number - start of data attached to Exif entry (will overlap with entry if length <= 4)\n// - data_length: Number - length of data attached to Exif entry\n// - value: Array|String|Null - our best attempt at parsing data (not all formats supported right now)\n// - is_subifd_link: Boolean - whether this entry is recognized to be a link to subifd (can't filter these out)\n//\n// Iteration stops early if iterator returns `false`.\n//\n// If Exif wasn't found anywhere (before start of the image data, SOS),\n// iterator is never executed.\n//\nmodule.exports.jpeg_exif_tags_each = function (jpeg_bin, on_exif_entry) {\n if (!is_uint8array(jpeg_bin)) {\n throw error('Invalid argument (jpeg_bin), Uint8Array expected', 'EINVAL');\n }\n\n if (typeof on_exif_entry !== 'function') {\n throw error('Invalid argument (on_exif_entry), Function expected', 'EINVAL');\n }\n\n /* eslint-disable consistent-return */\n module.exports.jpeg_segments_each(jpeg_bin, function (segment) {\n if (segment.code === 0xDA /* SOS */) return false;\n\n // look for APP1 segment and compare header with 'Exif\\0\\0'\n if (segment.code === 0xE1 && segment.length >= 10 &&\n jpeg_bin[segment.offset + 4] === 0x45 && jpeg_bin[segment.offset + 5] === 0x78 &&\n jpeg_bin[segment.offset + 6] === 0x69 && jpeg_bin[segment.offset + 7] === 0x66 &&\n jpeg_bin[segment.offset + 8] === 0x00 && jpeg_bin[segment.offset + 9] === 0x00) {\n\n new ExifParser(jpeg_bin, segment.offset + 10, segment.offset + segment.length).each(on_exif_entry);\n return false;\n }\n });\n};\n\n\n// Remove Exif entries in the given JPEG image\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n// - on_entry: Function - callback executed on each Exif entry\n// - entry: Object\n// - is_big_endian: Boolean - whether Exif uses big or little endian byte alignment\n// - ifd: Number - IFD identifier (0 for IFD0, 1 for IFD1, 0x8769 for SubIFD,\n// 0x8825 for GPS Info, 0xA005 for Interop IFD)\n// - tag: Number - exif entry tag (0x0110 - camera name, 0x0112 - orientation, etc. - see Exif spec)\n// - format: Number - exif entry format (1 - byte, 2 - ascii, 3 - short, etc. - see Exif spec)\n// - count: Number - number of components of the given format inside data\n// (usually 1, or string length for ascii format)\n// - entry_offset: Number - start of Exif entry (entry length is always 12, so not included)\n// - data_offset: Number - start of data attached to Exif entry (will overlap with entry if length <= 4)\n// - data_length: Number - length of data attached to Exif entry\n// - value: Array|String|Null - our best attempt at parsing data (not all formats supported right now)\n// - is_subifd_link: Boolean - whether this entry is recognized to be a link to subifd (can't filter these out)\n//\n// This function removes following from Exif:\n// - all entries where iterator returned false (except subifd links which are mandatory)\n// - IFD1 and thumbnail image (the purpose of this function is to reduce file size,\n// so thumbnail is usually the first thing to go)\n// - all other data that isn't in IFD0, SubIFD, GPSIFD, InteropIFD\n// (theoretically possible proprietary extensions, I haven't seen any of these yet)\n//\n// Changing data inside Exif entries is NOT supported yet (modifying `entry` object inside callback may break stuff).\n//\n// If Exif wasn't found anywhere (before start of the image data, SOS),\n// iterator is never executed, and original JPEG is returned as is.\n//\nmodule.exports.jpeg_exif_tags_filter = function (jpeg_bin, on_exif_entry) {\n if (!is_uint8array(jpeg_bin)) {\n throw error('Invalid argument (jpeg_bin), Uint8Array expected', 'EINVAL');\n }\n\n if (typeof on_exif_entry !== 'function') {\n throw error('Invalid argument (on_exif_entry), Function expected', 'EINVAL');\n }\n\n var stop_search = false;\n\n return module.exports.jpeg_segments_filter(jpeg_bin, function (segment) {\n if (stop_search) return;\n if (segment.code === 0xDA /* SOS */) stop_search = true;\n\n // look for APP1 segment and compare header with 'Exif\\0\\0'\n if (segment.code === 0xE1 && segment.length >= 10 &&\n jpeg_bin[segment.offset + 4] === 0x45 && jpeg_bin[segment.offset + 5] === 0x78 &&\n jpeg_bin[segment.offset + 6] === 0x69 && jpeg_bin[segment.offset + 7] === 0x66 &&\n jpeg_bin[segment.offset + 8] === 0x00 && jpeg_bin[segment.offset + 9] === 0x00) {\n\n var new_exif = new ExifParser(jpeg_bin, segment.offset + 10, segment.offset + segment.length)\n .filter(on_exif_entry);\n if (!new_exif) return false;\n\n var header = new Uint8Array(10);\n\n header.set(jpeg_bin.slice(segment.offset, segment.offset + 10));\n header[2] = ((new_exif.length + 8) >>> 8) & 0xFF;\n header[3] = (new_exif.length + 8) & 0xFF;\n\n stop_search = true;\n return [ header, new_exif ];\n }\n });\n};\n\n\n// Inserts a custom comment marker segment into JPEG file.\n//\n// Input:\n// - jpeg_bin: Uint8Array - jpeg file\n// - comment: String\n//\n// Comment is inserted after first two bytes (FFD8, SOI).\n//\n// If JFIF (APP0) marker exists immediately after SOI (as mandated by the JFIF\n// spec), we insert comment after it instead.\n//\nmodule.exports.jpeg_add_comment = function (jpeg_bin, comment) {\n var comment_inserted = false, segment_count = 0;\n\n return module.exports.jpeg_segments_filter(jpeg_bin, function (segment) {\n segment_count++;\n if (segment_count === 1 && segment.code === 0xD8 /* SOI */) return;\n if (segment_count === 2 && segment.code === 0xE0 /* APP0 */) return;\n\n if (comment_inserted) return;\n comment = utf8_encode(comment);\n\n // comment segment\n var csegment = new Uint8Array(5 + comment.length);\n var offset = 0;\n\n csegment[offset++] = 0xFF;\n csegment[offset++] = 0xFE;\n csegment[offset++] = ((comment.length + 3) >>> 8) & 0xFF;\n csegment[offset++] = (comment.length + 3) & 0xFF;\n\n comment.split('').forEach(function (c) {\n csegment[offset++] = c.charCodeAt(0) & 0xFF;\n });\n\n csegment[offset++] = 0;\n comment_inserted = true;\n\n return [ csegment, jpeg_bin.subarray(segment.offset, segment.offset + segment.length) ];\n });\n};\n});\n\nfunction jpeg_patch_exif(env) {\n return this._getUint8Array(env.blob).then(function (data) {\n env.is_jpeg = image_traverse.is_jpeg(data);\n\n if (!env.is_jpeg) return Promise.resolve(env);\n\n env.orig_blob = env.blob;\n\n try {\n var exif_is_big_endian, orientation_offset;\n\n /* eslint-disable consistent-return */\n image_traverse.jpeg_exif_tags_each(data, function (entry) {\n if (entry.ifd === 0 && entry.tag === 0x112 && Array.isArray(entry.value)) {\n env.orientation = entry.value[0] || 1;\n exif_is_big_endian = entry.is_big_endian;\n orientation_offset = entry.data_offset;\n return false;\n }\n });\n\n if (orientation_offset) {\n var orientation_patch = exif_is_big_endian ?\n new Uint8Array([ 0, 1 ]) :\n new Uint8Array([ 1, 0 ]);\n\n env.blob = new Blob([\n data.slice(0, orientation_offset),\n orientation_patch,\n data.slice(orientation_offset + 2)\n ], { type: 'image/jpeg' });\n }\n } catch (_) {}\n\n return env;\n });\n}\n\n\nfunction jpeg_rotate_canvas(env) {\n if (!env.is_jpeg) return Promise.resolve(env);\n\n var orientation = env.orientation - 1;\n if (!orientation) return Promise.resolve(env);\n\n var canvas;\n\n if (orientation & 4) {\n canvas = this.pica.options.createCanvas(env.out_canvas.height, env.out_canvas.width);\n } else {\n canvas = this.pica.options.createCanvas(env.out_canvas.width, env.out_canvas.height);\n }\n\n var ctx = canvas.getContext('2d');\n\n ctx.save();\n\n if (orientation & 1) ctx.transform(-1, 0, 0, 1, canvas.width, 0);\n if (orientation & 2) ctx.transform(-1, 0, 0, -1, canvas.width, canvas.height);\n if (orientation & 4) ctx.transform(0, 1, 1, 0, 0, 0);\n\n ctx.drawImage(env.out_canvas, 0, 0);\n ctx.restore();\n\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n env.out_canvas.width = env.out_canvas.height = 0;\n\n env.out_canvas = canvas;\n\n return Promise.resolve(env);\n}\n\n\nfunction jpeg_attach_orig_segments(env) {\n if (!env.is_jpeg) return Promise.resolve(env);\n\n return Promise.all([\n this._getUint8Array(env.blob),\n this._getUint8Array(env.out_blob)\n ]).then(function (res) {\n var data = res[0];\n var data_out = res[1];\n\n if (!image_traverse.is_jpeg(data)) return Promise.resolve(env);\n\n var segments = [];\n\n image_traverse.jpeg_segments_each(data, function (segment) {\n if (segment.code === 0xDA /* SOS */) return false;\n segments.push(segment);\n });\n\n segments = segments\n .filter(function (segment) {\n // Drop ICC_PROFILE\n //\n if (segment.code === 0xE2) return false;\n\n // Keep all APPn segments excluding APP2 (ICC_PROFILE),\n // remove others because most of them depend on image data (DCT and such).\n //\n // APP0 - JFIF, APP1 - Exif, the rest are photoshop metadata and such\n //\n // See full list at https://www.w3.org/Graphics/JPEG/itu-t81.pdf (table B.1 on page 32)\n //\n if (segment.code >= 0xE0 && segment.code < 0xF0) return true;\n\n // Keep comments\n //\n if (segment.code === 0xFE) return true;\n\n return false;\n })\n .map(function (segment) {\n return data.slice(segment.offset, segment.offset + segment.length);\n });\n\n env.out_blob = new Blob(\n // intentionally omitting expected JFIF segment (offset 2 to 20)\n [ data_out.slice(0, 2) ].concat(segments).concat([ data_out.slice(20) ]),\n { type: 'image/jpeg' }\n );\n\n return env;\n });\n}\n\n\nfunction assign(reducer) {\n reducer.before('_blob_to_image', jpeg_patch_exif);\n reducer.after('_transform', jpeg_rotate_canvas);\n reducer.after('_create_blob', jpeg_attach_orig_segments);\n}\n\n\nvar jpeg_patch_exif_1 = jpeg_patch_exif;\nvar jpeg_rotate_canvas_1 = jpeg_rotate_canvas;\nvar jpeg_attach_orig_segments_1 = jpeg_attach_orig_segments;\nvar assign_1 = assign;\n\nvar jpeg_plugins = {\n\tjpeg_patch_exif: jpeg_patch_exif_1,\n\tjpeg_rotate_canvas: jpeg_rotate_canvas_1,\n\tjpeg_attach_orig_segments: jpeg_attach_orig_segments_1,\n\tassign: assign_1\n};\n\nfunction ImageBlobReduce(options) {\n if (!(this instanceof ImageBlobReduce)) return new ImageBlobReduce(options);\n\n options = options || {};\n\n this.pica = options.pica || pica({});\n this.initialized = false;\n\n this.utils = utils;\n}\n\n\nImageBlobReduce.prototype.use = function (plugin /*, params, ... */) {\n var args = [ this ].concat(Array.prototype.slice.call(arguments, 1));\n plugin.apply(plugin, args);\n return this;\n};\n\n\nImageBlobReduce.prototype.init = function () {\n this.use(jpeg_plugins.assign);\n};\n\n\nImageBlobReduce.prototype.toBlob = function (blob, options) {\n var opts = utils.assign({ max: Infinity }, options);\n var env = {\n blob: blob,\n opts: opts\n };\n\n if (!this.initialized) {\n this.init();\n this.initialized = true;\n }\n\n return Promise.resolve(env)\n .then(this._blob_to_image)\n .then(this._calculate_size)\n .then(this._transform)\n .then(this._cleanup)\n .then(this._create_blob)\n .then(function (_env) {\n // Safari 12 workaround\n // https://github.com/nodeca/pica/issues/199\n _env.out_canvas.width = _env.out_canvas.height = 0;\n\n return _env.out_blob;\n });\n};\n\n\nImageBlobReduce.prototype.toCanvas = function (blob, options) {\n var opts = utils.assign({ max: Infinity }, options);\n var env = {\n blob: blob,\n opts: opts\n };\n\n if (!this.initialized) {\n this.init();\n this.initialized = true;\n }\n\n return Promise.resolve(env)\n .then(this._blob_to_image)\n .then(this._calculate_size)\n .then(this._transform)\n .then(this._cleanup)\n .then(function (_env) { return _env.out_canvas; });\n};\n\n\nImageBlobReduce.prototype.before = function (method_name, fn) {\n if (!this[method_name]) throw new Error('Method \"' + method_name + '\" does not exist');\n if (typeof fn !== 'function') throw new Error('Invalid argument \"fn\", function expected');\n\n var old_fn = this[method_name];\n var self = this;\n\n this[method_name] = function (env) {\n return fn.call(self, env).then(function (_env) {\n return old_fn.call(self, _env);\n });\n };\n\n return this;\n};\n\n\nImageBlobReduce.prototype.after = function (method_name, fn) {\n if (!this[method_name]) throw new Error('Method \"' + method_name + '\" does not exist');\n if (typeof fn !== 'function') throw new Error('Invalid argument \"fn\", function expected');\n\n var old_fn = this[method_name];\n var self = this;\n\n this[method_name] = function (env) {\n return old_fn.call(self, env).then(function (_env) {\n return fn.call(self, _env);\n });\n };\n\n return this;\n};\n\n\nImageBlobReduce.prototype._blob_to_image = function (env) {\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n\n env.image = document.createElement('img');\n env.image_url = URL.createObjectURL(env.blob);\n env.image.src = env.image_url;\n\n return new Promise(function (resolve, reject) {\n env.image.onerror = function () { reject(new Error('ImageBlobReduce: failed to create Image() from blob')); };\n env.image.onload = function () { resolve(env); };\n });\n};\n\n\nImageBlobReduce.prototype._calculate_size = function (env) {\n //\n // Note, if your need not \"symmetric\" resize logic, you MUST check\n // `env.orientation` (set by plugins) and swap width/height appropriately.\n //\n var scale_factor = env.opts.max / Math.max(env.image.width, env.image.height);\n\n if (scale_factor > 1) scale_factor = 1;\n\n env.transform_width = Math.max(Math.round(env.image.width * scale_factor), 1);\n env.transform_height = Math.max(Math.round(env.image.height * scale_factor), 1);\n\n // Info for user plugins, to check if scaling applied\n env.scale_factor = scale_factor;\n\n return Promise.resolve(env);\n};\n\n\nImageBlobReduce.prototype._transform = function (env) {\n env.out_canvas = this.pica.options.createCanvas(env.transform_width, env.transform_height);\n\n // Dim env temporary vars to prohibit use and avoid confusion when orientation\n // changed. You should take real size from canvas.\n env.transform_width = null;\n env.transform_height = null;\n\n // By default use alpha for png only\n var pica_opts = { alpha: env.blob.type === 'image/png' };\n\n // Extract pica options if been passed\n this.utils.assign(pica_opts, this.utils.pick_pica_resize_options(env.opts));\n\n return this.pica\n .resize(env.image, env.out_canvas, pica_opts)\n .then(function () { return env; });\n};\n\n\nImageBlobReduce.prototype._cleanup = function (env) {\n env.image.src = '';\n env.image = null;\n\n var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;\n if (URL.revokeObjectURL) URL.revokeObjectURL(env.image_url);\n\n env.image_url = null;\n\n return Promise.resolve(env);\n};\n\n\nImageBlobReduce.prototype._create_blob = function (env) {\n return this.pica.toBlob(env.out_canvas, env.blob.type)\n .then(function (blob) {\n env.out_blob = blob;\n return env;\n });\n};\n\n\nImageBlobReduce.prototype._getUint8Array = function (blob) {\n if (blob.arrayBuffer) {\n return blob.arrayBuffer().then(function (buf) {\n return new Uint8Array(buf);\n });\n }\n\n return new Promise(function (resolve, reject) {\n var fr = new FileReader();\n\n fr.readAsArrayBuffer(blob);\n\n fr.onload = function () { resolve(new Uint8Array(fr.result)); };\n fr.onerror = function () {\n reject(new Error('ImageBlobReduce: failed to load data from input blob'));\n fr.abort();\n };\n fr.onabort = function () {\n reject(new Error('ImageBlobReduce: failed to load data from input blob (aborted)'));\n };\n });\n};\n\n\nImageBlobReduce.pica = pica;\n\nvar imageBlobReduce = ImageBlobReduce;\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (imageBlobReduce);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi4vLi4vLi4vbm9kZV9tb2R1bGVzL2ltYWdlLWJsb2ItcmVkdWNlL2Rpc3QvaW1hZ2UtYmxvYi1yZWR1Y2UuZXNtLm1qcy5qcyIsIm1hcHBpbmdzIjoiOzs7OztBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0Isc0JBQXNCO0FBQ3hDOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLGNBQWMscUJBQXFCLGFBQWEsbUJBQW1CLGtCQUFrQixnQkFBZ0IsVUFBVSxVQUFVLDBEQUEwRCx3QkFBd0Isb0JBQW9CLDhDQUE4QyxrQ0FBa0MsWUFBWSxZQUFZLG1DQUFtQyxpQkFBaUIsZUFBZSx1QkFBdUIsb0JBQW9CLGtFQUFrRSxXQUFXLFlBQVksU0FBUyxTQUFTLEtBQUs7O0FBRXJpQjs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBLENBQUMsRUFBRSxtRUFBbUU7QUFDdEU7O0FBRUE7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCOztBQUV0QixpQkFBaUIsYUFBYTtBQUM5QixtQkFBbUI7O0FBRW5CLG9CQUFvQixlQUFlO0FBQ25DO0FBQ0E7QUFDQTtBQUNB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QTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUcsR0FBRztBQUNOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUcsR0FBRzs7QUFFTjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRzs7O0FBR0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTCxHQUFHO0FBQ0gsR0FBRzs7O0FBR0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7OztBQUdKO0FBQ0E7QUFDQTtBQUNBLEtBQUssR0FBRzs7QUFFUjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLDJFQUEyRTtBQUMzRTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsZ0RBQWdELFFBQVE7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztB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QUFHQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1COztBQUVuQjtBQUNBLG1CQUFtQjs7QUFFbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTs7QUFFQSxrQkFBa0IsaUJBQWlCO0FBQ25DO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxvQkFBb0IsV0FBVztBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLFNBQVM7QUFDVDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQSxxRkFBcUY7QUFDckY7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDREQUE0RDtBQUM1RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxNQUFNO0FBQ047QUFDQSxtQ0FBbUM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUEscUJBQXFCLDREQUE0RDtBQUNqRjtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxvQkFBb0IsbUJBQW1CO0FBQ3ZDO0FBQ0EsTUFBTTtBQUNOO0FBQ0Esc0JBQXNCLFNBQVM7QUFDL0I7QUFDQSxPQUFPO0FBQ1AsTUFBTTtBQUNOLHdCQUF3Qjs7QUFFeEI7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsb0JBQW9CO0FBQ2pDO0FBQ0EsTUFBTTs7QUFFTjtBQUNBLEdBQUc7QUFDSDs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxPQUFPOztBQUVQO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjs7QUFFQTtBQUNBLEdBQUc7QUFDSDs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEscUNBQXFDO0FBQ3JDOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQSw0QkFBNEIsZUFBZTtBQUMzQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDs7O0FBR0E7QUFDQSw0QkFBNEIsZUFBZTtBQUMzQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLHlCQUF5QjtBQUNyRDs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHNDQUFzQztBQUN0QyxxQ0FBcUM7QUFDckMsR0FBRztBQUNIOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxvQkFBb0I7O0FBRXBCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHdCQUF3QixhQUFhO0FBQ3JDOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBOztBQUVBLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7O0FBR0E7O0FBRUE7O0FBRUEsaUVBQWUsZUFBZSxFQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9pbWFnZS1ibG9iLXJlZHVjZS9kaXN0L2ltYWdlLWJsb2ItcmVkdWNlLmVzbS5tanM/MGU1NiJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qISBpbWFnZS1ibG9iLXJlZHVjZSAzLjAuMSBodHRwczovL2dpdGh1Yi5jb20vbm9kZWNhL2ltYWdlLWJsb2ItcmVkdWNlIEBsaWNlbnNlIE1JVCAqL1xudmFyIGFzc2lnbiQxID0gZnVuY3Rpb24gYXNzaWduKHRvKSB7XG4gIHZhciBmcm9tO1xuXG4gIGZvciAodmFyIHMgPSAxOyBzIDwgYXJndW1lbnRzLmxlbmd0aDsgcysrKSB7XG4gICAgZnJvbSA9IE9iamVjdChhcmd1bWVudHNbc10pO1xuXG4gICAgZm9yICh2YXIga2V5IGluIGZyb20pIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZnJvbSwga2V5KSkgdG9ba2V5XSA9IGZyb21ba2V5XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdG87XG59O1xuXG5cbmZ1bmN0aW9uIHBpY2soZnJvbSwgcHJvcHMpIHtcbiAgdmFyIHRvID0ge307XG5cbiAgcHJvcHMuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChmcm9tLCBrZXkpKSB0b1trZXldID0gZnJvbVtrZXldO1xuICB9KTtcblxuICByZXR1cm4gdG87XG59XG5cblxuZnVuY3Rpb24gcGlja19waWNhX3Jlc2l6ZV9vcHRpb25zKGZyb20pIHtcbiAgcmV0dXJuIHBpY2soZnJvbSwgW1xuICAgICdhbHBoYScsXG4gICAgJ3Vuc2hhcnBBbW91bnQnLFxuICAgICd1bnNoYXJwUmFkaXVzJyxcbiAgICAndW5zaGFycFRocmVzaG9sZCcsXG4gICAgJ2NhbmNlbFRva2VuJ1xuICBdKTtcbn1cblxuXG52YXIgcGlja18xID0gcGljaztcbnZhciBwaWNrX3BpY2FfcmVzaXplX29wdGlvbnNfMSA9IHBpY2tfcGljYV9yZXNpemVfb3B0aW9ucztcblxudmFyIHV0aWxzID0ge1xuXHRhc3NpZ246IGFzc2lnbiQxLFxuXHRwaWNrOiBwaWNrXzEsXG5cdHBpY2tfcGljYV9yZXNpemVfb3B0aW9uczogcGlja19waWNhX3Jlc2l6ZV9vcHRpb25zXzFcbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZUNvbW1vbmpzTW9kdWxlKGZuKSB7XG4gIHZhciBtb2R1bGUgPSB7IGV4cG9ydHM6IHt9IH07XG5cdHJldHVybiBmbihtb2R1bGUsIG1vZHVsZS5leHBvcnRzKSwgbW9kdWxlLmV4cG9ydHM7XG59XG5cbmZ1bmN0aW9uIGNvbW1vbmpzUmVxdWlyZSAodGFyZ2V0KSB7XG5cdHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGR5bmFtaWNhbGx5IHJlcXVpcmUgXCInICsgdGFyZ2V0ICsgJ1wiLiBQbGVhc2UgY29uZmlndXJlIHRoZSBkeW5hbWljUmVxdWlyZVRhcmdldHMgb3B0aW9uIG9mIEByb2xsdXAvcGx1Z2luLWNvbW1vbmpzIGFwcHJvcHJpYXRlbHkgZm9yIHRoaXMgcmVxdWlyZSBjYWxsIHRvIGJlaGF2ZSBwcm9wZXJseS4nKTtcbn1cblxuLyohXG5cbnBpY2Fcbmh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYVxuXG4qL1xuXG52YXIgcGljYSA9IGNyZWF0ZUNvbW1vbmpzTW9kdWxlKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMpIHtcbihmdW5jdGlvbihmKXt7bW9kdWxlLmV4cG9ydHM9ZigpO319KShmdW5jdGlvbigpe3JldHVybiAoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiBjb21tb25qc1JlcXVpcmUmJmNvbW1vbmpzUmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KTt9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgY29tbW9uanNSZXF1aXJlJiZjb21tb25qc1JlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpKHsxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxudmFyIGluaGVyaXRzID0gX2RlcmVxXygnaW5oZXJpdHMnKTtcblxudmFyIE11bHRpbWF0aCA9IF9kZXJlcV8oJ211bHRpbWF0aCcpO1xuXG52YXIgbW1fdW5zaGFycF9tYXNrID0gX2RlcmVxXygnLi9tbV91bnNoYXJwX21hc2snKTtcblxudmFyIG1tX3Jlc2l6ZSA9IF9kZXJlcV8oJy4vbW1fcmVzaXplJyk7XG5cbmZ1bmN0aW9uIE1hdGhMaWIocmVxdWVzdGVkX2ZlYXR1cmVzKSB7XG4gIHZhciBfX3JlcXVlc3RlZF9mZWF0dXJlcyA9IHJlcXVlc3RlZF9mZWF0dXJlcyB8fCBbXTtcblxuICB2YXIgZmVhdHVyZXMgPSB7XG4gICAganM6IF9fcmVxdWVzdGVkX2ZlYXR1cmVzLmluZGV4T2YoJ2pzJykgPj0gMCxcbiAgICB3YXNtOiBfX3JlcXVlc3RlZF9mZWF0dXJlcy5pbmRleE9mKCd3YXNtJykgPj0gMFxuICB9O1xuICBNdWx0aW1hdGguY2FsbCh0aGlzLCBmZWF0dXJlcyk7XG4gIHRoaXMuZmVhdHVyZXMgPSB7XG4gICAganM6IGZlYXR1cmVzLmpzLFxuICAgIHdhc206IGZlYXR1cmVzLndhc20gJiYgdGhpcy5oYXNfd2FzbSgpXG4gIH07XG4gIHRoaXMudXNlKG1tX3Vuc2hhcnBfbWFzayk7XG4gIHRoaXMudXNlKG1tX3Jlc2l6ZSk7XG59XG5cbmluaGVyaXRzKE1hdGhMaWIsIE11bHRpbWF0aCk7XG5cbk1hdGhMaWIucHJvdG90eXBlLnJlc2l6ZUFuZFVuc2hhcnAgPSBmdW5jdGlvbiByZXNpemVBbmRVbnNoYXJwKG9wdGlvbnMsIGNhY2hlKSB7XG4gIHZhciByZXN1bHQgPSB0aGlzLnJlc2l6ZShvcHRpb25zLCBjYWNoZSk7XG5cbiAgaWYgKG9wdGlvbnMudW5zaGFycEFtb3VudCkge1xuICAgIHRoaXMudW5zaGFycF9tYXNrKHJlc3VsdCwgb3B0aW9ucy50b1dpZHRoLCBvcHRpb25zLnRvSGVpZ2h0LCBvcHRpb25zLnVuc2hhcnBBbW91bnQsIG9wdGlvbnMudW5zaGFycFJhZGl1cywgb3B0aW9ucy51bnNoYXJwVGhyZXNob2xkKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGhMaWI7XG5cbn0se1wiLi9tbV9yZXNpemVcIjo0LFwiLi9tbV91bnNoYXJwX21hc2tcIjo5LFwiaW5oZXJpdHNcIjoxOSxcIm11bHRpbWF0aFwiOjIwfV0sMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vL3ZhciBGSVhFRF9GUkFDX0JJVFMgPSAxNDtcblxuZnVuY3Rpb24gY2xhbXBUbzgoaSkge1xuICByZXR1cm4gaSA8IDAgPyAwIDogaSA+IDI1NSA/IDI1NSA6IGk7XG59IC8vIENvbnZvbHZlIGltYWdlIGluIGhvcml6b250YWwgZGlyZWN0aW9ucyBhbmQgdHJhbnNwb3NlIG91dHB1dC4gSW4gdGhlb3J5LFxuLy8gdHJhbnNwb3NlIGFsbG93OlxuLy9cbi8vIC0gdXNlIHRoZSBzYW1lIGNvbnZvbHZlciBmb3IgYm90aCBwYXNzZXMgKHRoaXMgZmFpbHMgZHVlIGRpZmZlcmVudFxuLy8gICB0eXBlcyBvZiBpbnB1dCBhcnJheSBhbmQgdGVtcG9yYXJ5IGJ1ZmZlcilcbi8vIC0gbWFraW5nIHZlcnRpY2FsIHBhc3MgYnkgaG9yaXNvbmx0YWwgbGluZXMgaW5wcm92ZSBDUFUgY2FjaGUgdXNlLlxuLy9cbi8vIEJ1dCBpbiByZWFsIGxpZmUgdGhpcyBkb2Vzbid0IHdvcmsgOilcbi8vXG5cblxuZnVuY3Rpb24gY29udm9sdmVIb3Jpem9udGFsbHkoc3JjLCBkZXN0LCBzcmNXLCBzcmNILCBkZXN0VywgZmlsdGVycykge1xuICB2YXIgciwgZywgYiwgYTtcbiAgdmFyIGZpbHRlclB0ciwgZmlsdGVyU2hpZnQsIGZpbHRlclNpemU7XG4gIHZhciBzcmNQdHIsIHNyY1ksIGRlc3RYLCBmaWx0ZXJWYWw7XG4gIHZhciBzcmNPZmZzZXQgPSAwLFxuICAgICAgZGVzdE9mZnNldCA9IDA7IC8vIEZvciBlYWNoIHJvd1xuXG4gIGZvciAoc3JjWSA9IDA7IHNyY1kgPCBzcmNIOyBzcmNZKyspIHtcbiAgICBmaWx0ZXJQdHIgPSAwOyAvLyBBcHBseSBwcmVjb21wdXRlZCBmaWx0ZXJzIHRvIGVhY2ggZGVzdGluYXRpb24gcm93IHBvaW50XG5cbiAgICBmb3IgKGRlc3RYID0gMDsgZGVzdFggPCBkZXN0VzsgZGVzdFgrKykge1xuICAgICAgLy8gR2V0IHRoZSBmaWx0ZXIgdGhhdCBkZXRlcm1pbmVzIHRoZSBjdXJyZW50IG91dHB1dCBwaXhlbC5cbiAgICAgIGZpbHRlclNoaWZ0ID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBmaWx0ZXJTaXplID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBzcmNQdHIgPSBzcmNPZmZzZXQgKyBmaWx0ZXJTaGlmdCAqIDQgfCAwO1xuICAgICAgciA9IGcgPSBiID0gYSA9IDA7IC8vIEFwcGx5IHRoZSBmaWx0ZXIgdG8gdGhlIHJvdyB0byBnZXQgdGhlIGRlc3RpbmF0aW9uIHBpeGVsIHIsIGcsIGIsIGFcblxuICAgICAgZm9yICg7IGZpbHRlclNpemUgPiAwOyBmaWx0ZXJTaXplLS0pIHtcbiAgICAgICAgZmlsdGVyVmFsID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107IC8vIFVzZSByZXZlcnNlIG9yZGVyIHRvIHdvcmthcm91bmQgZGVvcHRzIGluIG9sZCB2OCAobm9kZSB2LjEwKVxuICAgICAgICAvLyBCaWcgdGhhbmtzIHRvIEBtcmFsZXBoIChWeWFjaGVzbGF2IEVnb3JvdikgZm9yIHRoZSB0aXAuXG5cbiAgICAgICAgYSA9IGEgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyICsgM10gfCAwO1xuICAgICAgICBiID0gYiArIGZpbHRlclZhbCAqIHNyY1tzcmNQdHIgKyAyXSB8IDA7XG4gICAgICAgIGcgPSBnICsgZmlsdGVyVmFsICogc3JjW3NyY1B0ciArIDFdIHwgMDtcbiAgICAgICAgciA9IHIgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyXSB8IDA7XG4gICAgICAgIHNyY1B0ciA9IHNyY1B0ciArIDQgfCAwO1xuICAgICAgfSAvLyBCcmluZyB0aGlzIHZhbHVlIGJhY2sgaW4gcmFuZ2UuIEFsbCBvZiB0aGUgZmlsdGVyIHNjYWxpbmcgZmFjdG9yc1xuICAgICAgLy8gYXJlIGluIGZpeGVkIHBvaW50IHdpdGggRklYRURfRlJBQ19CSVRTIGJpdHMgb2YgZnJhY3Rpb25hbCBwYXJ0LlxuICAgICAgLy9cbiAgICAgIC8vICghKSBBZGQgMS8yIG9mIHZhbHVlIGJlZm9yZSBjbGFtcGluZyB0byBnZXQgcHJvcGVyIHJvdW5kaW5nLiBJbiBvdGhlclxuICAgICAgLy8gY2FzZSBicmlnaHRuZXNzIGxvc3Mgd2lsbCBiZSBub3RpY2VhYmxlIGlmIHlvdSByZXNpemUgaW1hZ2Ugd2l0aCB3aGl0ZVxuICAgICAgLy8gYm9yZGVyIGFuZCBwbGFjZSBpdCBvbiB3aGl0ZSBiYWNrZ3JvdW5kLlxuICAgICAgLy9cblxuXG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAzXSA9IGNsYW1wVG84KGEgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAyXSA9IGNsYW1wVG84KGIgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAxXSA9IGNsYW1wVG84KGcgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXRdID0gY2xhbXBUbzgociArICgxIDw8IDEzKSA+PiAxNFxuICAgICAgLypGSVhFRF9GUkFDX0JJVFMqL1xuICAgICAgKTtcbiAgICAgIGRlc3RPZmZzZXQgPSBkZXN0T2Zmc2V0ICsgc3JjSCAqIDQgfCAwO1xuICAgIH1cblxuICAgIGRlc3RPZmZzZXQgPSAoc3JjWSArIDEpICogNCB8IDA7XG4gICAgc3JjT2Zmc2V0ID0gKHNyY1kgKyAxKSAqIHNyY1cgKiA0IHwgMDtcbiAgfVxufSAvLyBUZWNobmljYWxseSwgY29udm9sdmVycyBhcmUgdGhlIHNhbWUuIEJ1dCBpbnB1dCBhcnJheSBhbmQgdGVtcG9yYXJ5XG4vLyBidWZmZXIgY2FuIGJlIG9mIGRpZmZlcmVudCB0eXBlIChlc3BlY2lhbGx5LCBpbiBvbGQgYnJvd3NlcnMpLiBTbyxcbi8vIGtlZXAgY29kZSBpbiBzZXBhcmF0ZSBmdW5jdGlvbnMgdG8gYXZvaWQgZGVvcHRpbWl6YXRpb25zICYgc3BlZWQgbG9zcy5cblxuXG5mdW5jdGlvbiBjb252b2x2ZVZlcnRpY2FsbHkoc3JjLCBkZXN0LCBzcmNXLCBzcmNILCBkZXN0VywgZmlsdGVycykge1xuICB2YXIgciwgZywgYiwgYTtcbiAgdmFyIGZpbHRlclB0ciwgZmlsdGVyU2hpZnQsIGZpbHRlclNpemU7XG4gIHZhciBzcmNQdHIsIHNyY1ksIGRlc3RYLCBmaWx0ZXJWYWw7XG4gIHZhciBzcmNPZmZzZXQgPSAwLFxuICAgICAgZGVzdE9mZnNldCA9IDA7IC8vIEZvciBlYWNoIHJvd1xuXG4gIGZvciAoc3JjWSA9IDA7IHNyY1kgPCBzcmNIOyBzcmNZKyspIHtcbiAgICBmaWx0ZXJQdHIgPSAwOyAvLyBBcHBseSBwcmVjb21wdXRlZCBmaWx0ZXJzIHRvIGVhY2ggZGVzdGluYXRpb24gcm93IHBvaW50XG5cbiAgICBmb3IgKGRlc3RYID0gMDsgZGVzdFggPCBkZXN0VzsgZGVzdFgrKykge1xuICAgICAgLy8gR2V0IHRoZSBmaWx0ZXIgdGhhdCBkZXRlcm1pbmVzIHRoZSBjdXJyZW50IG91dHB1dCBwaXhlbC5cbiAgICAgIGZpbHRlclNoaWZ0ID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBmaWx0ZXJTaXplID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107XG4gICAgICBzcmNQdHIgPSBzcmNPZmZzZXQgKyBmaWx0ZXJTaGlmdCAqIDQgfCAwO1xuICAgICAgciA9IGcgPSBiID0gYSA9IDA7IC8vIEFwcGx5IHRoZSBmaWx0ZXIgdG8gdGhlIHJvdyB0byBnZXQgdGhlIGRlc3RpbmF0aW9uIHBpeGVsIHIsIGcsIGIsIGFcblxuICAgICAgZm9yICg7IGZpbHRlclNpemUgPiAwOyBmaWx0ZXJTaXplLS0pIHtcbiAgICAgICAgZmlsdGVyVmFsID0gZmlsdGVyc1tmaWx0ZXJQdHIrK107IC8vIFVzZSByZXZlcnNlIG9yZGVyIHRvIHdvcmthcm91bmQgZGVvcHRzIGluIG9sZCB2OCAobm9kZSB2LjEwKVxuICAgICAgICAvLyBCaWcgdGhhbmtzIHRvIEBtcmFsZXBoIChWeWFjaGVzbGF2IEVnb3JvdikgZm9yIHRoZSB0aXAuXG5cbiAgICAgICAgYSA9IGEgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyICsgM10gfCAwO1xuICAgICAgICBiID0gYiArIGZpbHRlclZhbCAqIHNyY1tzcmNQdHIgKyAyXSB8IDA7XG4gICAgICAgIGcgPSBnICsgZmlsdGVyVmFsICogc3JjW3NyY1B0ciArIDFdIHwgMDtcbiAgICAgICAgciA9IHIgKyBmaWx0ZXJWYWwgKiBzcmNbc3JjUHRyXSB8IDA7XG4gICAgICAgIHNyY1B0ciA9IHNyY1B0ciArIDQgfCAwO1xuICAgICAgfSAvLyBCcmluZyB0aGlzIHZhbHVlIGJhY2sgaW4gcmFuZ2UuIEFsbCBvZiB0aGUgZmlsdGVyIHNjYWxpbmcgZmFjdG9yc1xuICAgICAgLy8gYXJlIGluIGZpeGVkIHBvaW50IHdpdGggRklYRURfRlJBQ19CSVRTIGJpdHMgb2YgZnJhY3Rpb25hbCBwYXJ0LlxuICAgICAgLy9cbiAgICAgIC8vICghKSBBZGQgMS8yIG9mIHZhbHVlIGJlZm9yZSBjbGFtcGluZyB0byBnZXQgcHJvcGVyIHJvdW5kaW5nLiBJbiBvdGhlclxuICAgICAgLy8gY2FzZSBicmlnaHRuZXNzIGxvc3Mgd2lsbCBiZSBub3RpY2VhYmxlIGlmIHlvdSByZXNpemUgaW1hZ2Ugd2l0aCB3aGl0ZVxuICAgICAgLy8gYm9yZGVyIGFuZCBwbGFjZSBpdCBvbiB3aGl0ZSBiYWNrZ3JvdW5kLlxuICAgICAgLy9cblxuXG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAzXSA9IGNsYW1wVG84KGEgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAyXSA9IGNsYW1wVG84KGIgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXQgKyAxXSA9IGNsYW1wVG84KGcgKyAoMSA8PCAxMykgPj4gMTRcbiAgICAgIC8qRklYRURfRlJBQ19CSVRTKi9cbiAgICAgICk7XG4gICAgICBkZXN0W2Rlc3RPZmZzZXRdID0gY2xhbXBUbzgociArICgxIDw8IDEzKSA+PiAxNFxuICAgICAgLypGSVhFRF9GUkFDX0JJVFMqL1xuICAgICAgKTtcbiAgICAgIGRlc3RPZmZzZXQgPSBkZXN0T2Zmc2V0ICsgc3JjSCAqIDQgfCAwO1xuICAgIH1cblxuICAgIGRlc3RPZmZzZXQgPSAoc3JjWSArIDEpICogNCB8IDA7XG4gICAgc3JjT2Zmc2V0ID0gKHNyY1kgKyAxKSAqIHNyY1cgKiA0IHwgMDtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY29udm9sdmVIb3Jpem9udGFsbHk6IGNvbnZvbHZlSG9yaXpvbnRhbGx5LFxuICBjb252b2x2ZVZlcnRpY2FsbHk6IGNvbnZvbHZlVmVydGljYWxseVxufTtcblxufSx7fV0sMzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cbm1vZHVsZS5leHBvcnRzID0gJ0FHRnpiUUVBQUFBQURBWmtlV3hwYm1zQUFBQUFBQUVYQTJBQUFHQUdmMzkvZjM5L0FHQUhmMzkvZjM5L2Z3QUNEd0VEWlc1MkJtMWxiVzl5ZVFJQUFBTUVBd0FCQWdZR0FYOEFRUUFMQjFjRkVWOWZkMkZ6YlY5allXeHNYMk4wYjNKekFBQUlZMjl1ZG05c2RtVUFBUXBqYjI1MmIyeDJaVWhXQUFJTVgxOWtjMjlmYUdGdVpHeGxBd0FZWDE5M1lYTnRYMkZ3Y0d4NVgyUmhkR0ZmY21Wc2IyTnpBQUFLN0FNREF3QUJDOFlEQVE5L0FrQWdBMFVOQUNBRVJRMEFBMEFnRENFTlFRQWhFMEVBSVFjRFFDQUhRUUpxSVFZQ2Z5QUhRUUYwSUFWcUlnY3VBUUlpRkVVRVFFR0F3QUFoQ0VHQXdBQWhDVUdBd0FBaENrR0F3QUFoQ3lBR0RBRUxJQklnQnk0QkFHb2hDRUVBSVFzZ0ZDRUhRUUFoRGlBR0lRbEJBQ0VQUVFBaEVBTkFJQVVnQ1VFQmRHb3VBUUFpRVNBQUlBaEJBblJxS0FJQUlncEJHSFpzSUJCcUlSQWdDa0gvQVhFZ0VXd2dDMm9oQ3lBS1FSQjJRZjhCY1NBUmJDQVBhaUVQSUFwQkNIWkIvd0Z4SUJGc0lBNXFJUTRnQ0VFQmFpRUlJQWxCQVdvaENTQUhRUUZySWdjTkFBc2dDMEdBUUdzaENDQU9RWUJBYXlFSklBOUJnRUJySVFvZ0VFR0FRR3NoQ3lBR0lCUnFDeUVISUFFZ0RVRUNkR29nQ1VFT2RTSUdRZjhCSUFaQi93RklHeUlHUVFBZ0JrRUFTaHRCQ0hSQmdQNERjU0FLUVE1MUlnWkIvd0VnQmtIL0FVZ2JJZ1pCQUNBR1FRQktHMEVRZEVHQWdQd0hjU0FMUVE1MUlnWkIvd0VnQmtIL0FVZ2JJZ1pCQUNBR1FRQktHMEVZZEhKeUlBaEJEblVpQmtIL0FTQUdRZjhCU0JzaUJrRUFJQVpCQUVvYmNqWUNBQ0FESUExcUlRMGdFMEVCYWlJVElBUkhEUUFMSUF4QkFXb2lEQ0FDYkNFU0lBTWdERWNOQUFzTEN4NEFRUUFnQWlBRElBUWdCU0FBRUFFZ0FrRUFJQVFnQlNBR0lBRVFBUXM9JztcblxufSx7fV0sNDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBuYW1lOiAncmVzaXplJyxcbiAgZm46IF9kZXJlcV8oJy4vcmVzaXplJyksXG4gIHdhc21fZm46IF9kZXJlcV8oJy4vcmVzaXplX3dhc20nKSxcbiAgd2FzbV9zcmM6IF9kZXJlcV8oJy4vY29udm9sdmVfd2FzbV9iYXNlNjQnKVxufTtcblxufSx7XCIuL2NvbnZvbHZlX3dhc21fYmFzZTY0XCI6MyxcIi4vcmVzaXplXCI6NSxcIi4vcmVzaXplX3dhc21cIjo4fV0sNTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cbnZhciBjcmVhdGVGaWx0ZXJzID0gX2RlcmVxXygnLi9yZXNpemVfZmlsdGVyX2dlbicpO1xuXG52YXIgY29udm9sdmVIb3Jpem9udGFsbHkgPSBfZGVyZXFfKCcuL2NvbnZvbHZlJykuY29udm9sdmVIb3Jpem9udGFsbHk7XG5cbnZhciBjb252b2x2ZVZlcnRpY2FsbHkgPSBfZGVyZXFfKCcuL2NvbnZvbHZlJykuY29udm9sdmVWZXJ0aWNhbGx5O1xuXG5mdW5jdGlvbiByZXNldEFscGhhKGRzdCwgd2lkdGgsIGhlaWdodCkge1xuICB2YXIgcHRyID0gMyxcbiAgICAgIGxlbiA9IHdpZHRoICogaGVpZ2h0ICogNCB8IDA7XG5cbiAgd2hpbGUgKHB0ciA8IGxlbikge1xuICAgIGRzdFtwdHJdID0gMHhGRjtcbiAgICBwdHIgPSBwdHIgKyA0IHwgMDtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlc2l6ZShvcHRpb25zKSB7XG4gIHZhciBzcmMgPSBvcHRpb25zLnNyYztcbiAgdmFyIHNyY1cgPSBvcHRpb25zLndpZHRoO1xuICB2YXIgc3JjSCA9IG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgZGVzdFcgPSBvcHRpb25zLnRvV2lkdGg7XG4gIHZhciBkZXN0SCA9IG9wdGlvbnMudG9IZWlnaHQ7XG4gIHZhciBzY2FsZVggPSBvcHRpb25zLnNjYWxlWCB8fCBvcHRpb25zLnRvV2lkdGggLyBvcHRpb25zLndpZHRoO1xuICB2YXIgc2NhbGVZID0gb3B0aW9ucy5zY2FsZVkgfHwgb3B0aW9ucy50b0hlaWdodCAvIG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgb2Zmc2V0WCA9IG9wdGlvbnMub2Zmc2V0WCB8fCAwO1xuICB2YXIgb2Zmc2V0WSA9IG9wdGlvbnMub2Zmc2V0WSB8fCAwO1xuICB2YXIgZGVzdCA9IG9wdGlvbnMuZGVzdCB8fCBuZXcgVWludDhBcnJheShkZXN0VyAqIGRlc3RIICogNCk7XG4gIHZhciBxdWFsaXR5ID0gdHlwZW9mIG9wdGlvbnMucXVhbGl0eSA9PT0gJ3VuZGVmaW5lZCcgPyAzIDogb3B0aW9ucy5xdWFsaXR5O1xuICB2YXIgYWxwaGEgPSBvcHRpb25zLmFscGhhIHx8IGZhbHNlO1xuICB2YXIgZmlsdGVyc1ggPSBjcmVhdGVGaWx0ZXJzKHF1YWxpdHksIHNyY1csIGRlc3RXLCBzY2FsZVgsIG9mZnNldFgpLFxuICAgICAgZmlsdGVyc1kgPSBjcmVhdGVGaWx0ZXJzKHF1YWxpdHksIHNyY0gsIGRlc3RILCBzY2FsZVksIG9mZnNldFkpO1xuICB2YXIgdG1wID0gbmV3IFVpbnQ4QXJyYXkoZGVzdFcgKiBzcmNIICogNCk7IC8vIFRvIHVzZSBzaW5nbGUgZnVuY3Rpb24gd2UgbmVlZCBzcmMgJiB0bXAgb2YgdGhlIHNhbWUgdHlwZS5cbiAgLy8gQnV0IHNyYyBjYW4gYmUgQ2FudmFzUGl4ZWxBcnJheSwgYW5kIHRtcCAtIFVpbnQ4QXJyYXkuIFNvLCBrZWVwXG4gIC8vIHZlcnRpY2FsIGFuZCBob3Jpem9udGFsIHBhc3NlcyBzZXBhcmF0ZWx5IHRvIGF2b2lkIGRlb3B0aW1pemF0aW9uLlxuXG4gIGNvbnZvbHZlSG9yaXpvbnRhbGx5KHNyYywgdG1wLCBzcmNXLCBzcmNILCBkZXN0VywgZmlsdGVyc1gpO1xuICBjb252b2x2ZVZlcnRpY2FsbHkodG1wLCBkZXN0LCBzcmNILCBkZXN0VywgZGVzdEgsIGZpbHRlcnNZKTsgLy8gVGhhdCdzIGZhc3RlciB0aGFuIGRvaW5nIGNoZWNrcyBpbiBjb252b2x2ZXIuXG4gIC8vICEhISBOb3RlLCBjYW52YXMgZGF0YSBpcyBub3QgcHJlbXVsdGlwbGVkLiBXZSBkb24ndCBuZWVkIG90aGVyXG4gIC8vIGFscGhhIGNvcnJlY3Rpb25zLlxuXG4gIGlmICghYWxwaGEpIHJlc2V0QWxwaGEoZGVzdCwgZGVzdFcsIGRlc3RIKTtcbiAgcmV0dXJuIGRlc3Q7XG59O1xuXG59LHtcIi4vY29udm9sdmVcIjoyLFwiLi9yZXNpemVfZmlsdGVyX2dlblwiOjZ9XSw2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxudmFyIEZJTFRFUl9JTkZPID0gX2RlcmVxXygnLi9yZXNpemVfZmlsdGVyX2luZm8nKTsgLy8gUHJlY2lzaW9uIG9mIGZpeGVkIEZQIHZhbHVlc1xuXG5cbnZhciBGSVhFRF9GUkFDX0JJVFMgPSAxNDtcblxuZnVuY3Rpb24gdG9GaXhlZFBvaW50KG51bSkge1xuICByZXR1cm4gTWF0aC5yb3VuZChudW0gKiAoKDEgPDwgRklYRURfRlJBQ19CSVRTKSAtIDEpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiByZXNpemVGaWx0ZXJHZW4ocXVhbGl0eSwgc3JjU2l6ZSwgZGVzdFNpemUsIHNjYWxlLCBvZmZzZXQpIHtcbiAgdmFyIGZpbHRlckZ1bmN0aW9uID0gRklMVEVSX0lORk9bcXVhbGl0eV0uZmlsdGVyO1xuICB2YXIgc2NhbGVJbnZlcnRlZCA9IDEuMCAvIHNjYWxlO1xuICB2YXIgc2NhbGVDbGFtcGVkID0gTWF0aC5taW4oMS4wLCBzY2FsZSk7IC8vIEZvciB1cHNjYWxlXG4gIC8vIEZpbHRlciB3aW5kb3cgKGF2ZXJhZ2luZyBpbnRlcnZhbCksIHNjYWxlZCB0byBzcmMgaW1hZ2VcblxuICB2YXIgc3JjV2luZG93ID0gRklMVEVSX0lORk9bcXVhbGl0eV0ud2luIC8gc2NhbGVDbGFtcGVkO1xuICB2YXIgZGVzdFBpeGVsLCBzcmNQaXhlbCwgc3JjRmlyc3QsIHNyY0xhc3QsIGZpbHRlckVsZW1lbnRTaXplLCBmbG9hdEZpbHRlciwgZnhwRmlsdGVyLCB0b3RhbCwgcHhsLCBpZHgsIGZsb2F0VmFsLCBmaWx0ZXJUb3RhbCwgZmlsdGVyVmFsO1xuICB2YXIgbGVmdE5vdEVtcHR5LCByaWdodE5vdEVtcHR5LCBmaWx0ZXJTaGlmdCwgZmlsdGVyU2l6ZTtcbiAgdmFyIG1heEZpbHRlckVsZW1lbnRTaXplID0gTWF0aC5mbG9vcigoc3JjV2luZG93ICsgMSkgKiAyKTtcbiAgdmFyIHBhY2tlZEZpbHRlciA9IG5ldyBJbnQxNkFycmF5KChtYXhGaWx0ZXJFbGVtZW50U2l6ZSArIDIpICogZGVzdFNpemUpO1xuICB2YXIgcGFja2VkRmlsdGVyUHRyID0gMDtcbiAgdmFyIHNsb3dDb3B5ID0gIXBhY2tlZEZpbHRlci5zdWJhcnJheSB8fCAhcGFja2VkRmlsdGVyLnNldDsgLy8gRm9yIGVhY2ggZGVzdGluYXRpb24gcGl4ZWwgY2FsY3VsYXRlIHNvdXJjZSByYW5nZSBhbmQgYnVpbHQgZmlsdGVyIHZhbHVlc1xuXG4gIGZvciAoZGVzdFBpeGVsID0gMDsgZGVzdFBpeGVsIDwgZGVzdFNpemU7IGRlc3RQaXhlbCsrKSB7XG4gICAgLy8gU2NhbGluZyBzaG91bGQgYmUgZG9uZSByZWxhdGl2ZSB0byBjZW50cmFsIHBpeGVsIHBvaW50XG4gICAgc3JjUGl4ZWwgPSAoZGVzdFBpeGVsICsgMC41KSAqIHNjYWxlSW52ZXJ0ZWQgKyBvZmZzZXQ7XG4gICAgc3JjRmlyc3QgPSBNYXRoLm1heCgwLCBNYXRoLmZsb29yKHNyY1BpeGVsIC0gc3JjV2luZG93KSk7XG4gICAgc3JjTGFzdCA9IE1hdGgubWluKHNyY1NpemUgLSAxLCBNYXRoLmNlaWwoc3JjUGl4ZWwgKyBzcmNXaW5kb3cpKTtcbiAgICBmaWx0ZXJFbGVtZW50U2l6ZSA9IHNyY0xhc3QgLSBzcmNGaXJzdCArIDE7XG4gICAgZmxvYXRGaWx0ZXIgPSBuZXcgRmxvYXQzMkFycmF5KGZpbHRlckVsZW1lbnRTaXplKTtcbiAgICBmeHBGaWx0ZXIgPSBuZXcgSW50MTZBcnJheShmaWx0ZXJFbGVtZW50U2l6ZSk7XG4gICAgdG90YWwgPSAwLjA7IC8vIEZpbGwgZmlsdGVyIHZhbHVlcyBmb3IgY2FsY3VsYXRlZCByYW5nZVxuXG4gICAgZm9yIChweGwgPSBzcmNGaXJzdCwgaWR4ID0gMDsgcHhsIDw9IHNyY0xhc3Q7IHB4bCsrLCBpZHgrKykge1xuICAgICAgZmxvYXRWYWwgPSBmaWx0ZXJGdW5jdGlvbigocHhsICsgMC41IC0gc3JjUGl4ZWwpICogc2NhbGVDbGFtcGVkKTtcbiAgICAgIHRvdGFsICs9IGZsb2F0VmFsO1xuICAgICAgZmxvYXRGaWx0ZXJbaWR4XSA9IGZsb2F0VmFsO1xuICAgIH0gLy8gTm9ybWFsaXplIGZpbHRlciwgY29udmVydCB0byBmaXhlZCBwb2ludCBhbmQgYWNjdW11bGF0ZSBjb252ZXJzaW9uIGVycm9yXG5cblxuICAgIGZpbHRlclRvdGFsID0gMDtcblxuICAgIGZvciAoaWR4ID0gMDsgaWR4IDwgZmxvYXRGaWx0ZXIubGVuZ3RoOyBpZHgrKykge1xuICAgICAgZmlsdGVyVmFsID0gZmxvYXRGaWx0ZXJbaWR4XSAvIHRvdGFsO1xuICAgICAgZmlsdGVyVG90YWwgKz0gZmlsdGVyVmFsO1xuICAgICAgZnhwRmlsdGVyW2lkeF0gPSB0b0ZpeGVkUG9pbnQoZmlsdGVyVmFsKTtcbiAgICB9IC8vIENvbXBlbnNhdGUgbm9ybWFsaXphdGlvbiBlcnJvciwgdG8gbWluaW1pemUgYnJpZ2h0bmVzcyBkcmlmdFxuXG5cbiAgICBmeHBGaWx0ZXJbZGVzdFNpemUgPj4gMV0gKz0gdG9GaXhlZFBvaW50KDEuMCAtIGZpbHRlclRvdGFsKTsgLy9cbiAgICAvLyBOb3cgcGFjayBmaWx0ZXIgdG8gdXNlYWJsZSBmb3JtXG4gICAgLy9cbiAgICAvLyAxLiBUcmltIGhlYWRpbmcgYW5kIHRhaWxpbmcgemVybyB2YWx1ZXMsIGFuZCBjb21wZW5zYXRlIHNoaXRmL2xlbmd0aFxuICAgIC8vIDIuIFB1dCBhbGwgdG8gc2luZ2xlIGFycmF5IGluIHRoaXMgZm9ybWF0OlxuICAgIC8vXG4gICAgLy8gICAgWyBwb3Mgc2hpZnQsIGRhdGEgbGVuZ3RoLCB2YWx1ZTEsIHZhbHVlMiwgdmFsdWUzLCAuLi4gXVxuICAgIC8vXG5cbiAgICBsZWZ0Tm90RW1wdHkgPSAwO1xuXG4gICAgd2hpbGUgKGxlZnROb3RFbXB0eSA8IGZ4cEZpbHRlci5sZW5ndGggJiYgZnhwRmlsdGVyW2xlZnROb3RFbXB0eV0gPT09IDApIHtcbiAgICAgIGxlZnROb3RFbXB0eSsrO1xuICAgIH1cblxuICAgIGlmIChsZWZ0Tm90RW1wdHkgPCBmeHBGaWx0ZXIubGVuZ3RoKSB7XG4gICAgICByaWdodE5vdEVtcHR5ID0gZnhwRmlsdGVyLmxlbmd0aCAtIDE7XG5cbiAgICAgIHdoaWxlIChyaWdodE5vdEVtcHR5ID4gMCAmJiBmeHBGaWx0ZXJbcmlnaHROb3RFbXB0eV0gPT09IDApIHtcbiAgICAgICAgcmlnaHROb3RFbXB0eS0tO1xuICAgICAgfVxuXG4gICAgICBmaWx0ZXJTaGlmdCA9IHNyY0ZpcnN0ICsgbGVmdE5vdEVtcHR5O1xuICAgICAgZmlsdGVyU2l6ZSA9IHJpZ2h0Tm90RW1wdHkgLSBsZWZ0Tm90RW1wdHkgKyAxO1xuICAgICAgcGFja2VkRmlsdGVyW3BhY2tlZEZpbHRlclB0cisrXSA9IGZpbHRlclNoaWZ0OyAvLyBzaGlmdFxuXG4gICAgICBwYWNrZWRGaWx0ZXJbcGFja2VkRmlsdGVyUHRyKytdID0gZmlsdGVyU2l6ZTsgLy8gc2l6ZVxuXG4gICAgICBpZiAoIXNsb3dDb3B5KSB7XG4gICAgICAgIHBhY2tlZEZpbHRlci5zZXQoZnhwRmlsdGVyLnN1YmFycmF5KGxlZnROb3RFbXB0eSwgcmlnaHROb3RFbXB0eSArIDEpLCBwYWNrZWRGaWx0ZXJQdHIpO1xuICAgICAgICBwYWNrZWRGaWx0ZXJQdHIgKz0gZmlsdGVyU2l6ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGZhbGxiYWNrIGZvciBvbGQgSUUgPCAxMSwgd2l0aG91dCBzdWJhcnJheS9zZXQgbWV0aG9kc1xuICAgICAgICBmb3IgKGlkeCA9IGxlZnROb3RFbXB0eTsgaWR4IDw9IHJpZ2h0Tm90RW1wdHk7IGlkeCsrKSB7XG4gICAgICAgICAgcGFja2VkRmlsdGVyW3BhY2tlZEZpbHRlclB0cisrXSA9IGZ4cEZpbHRlcltpZHhdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHplcm8gZGF0YSwgd3JpdGUgaGVhZGVyIG9ubHlcbiAgICAgIHBhY2tlZEZpbHRlcltwYWNrZWRGaWx0ZXJQdHIrK10gPSAwOyAvLyBzaGlmdFxuXG4gICAgICBwYWNrZWRGaWx0ZXJbcGFja2VkRmlsdGVyUHRyKytdID0gMDsgLy8gc2l6ZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwYWNrZWRGaWx0ZXI7XG59O1xuXG59LHtcIi4vcmVzaXplX2ZpbHRlcl9pbmZvXCI6N31dLDc6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXG5tb2R1bGUuZXhwb3J0cyA9IFt7XG4gIC8vIE5lYXJlc3QgbmVpYm9yIChCb3gpXG4gIHdpbjogMC41LFxuICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcih4KSB7XG4gICAgcmV0dXJuIHggPj0gLTAuNSAmJiB4IDwgMC41ID8gMS4wIDogMC4wO1xuICB9XG59LCB7XG4gIC8vIEhhbW1pbmdcbiAgd2luOiAxLjAsXG4gIGZpbHRlcjogZnVuY3Rpb24gZmlsdGVyKHgpIHtcbiAgICBpZiAoeCA8PSAtMS4wIHx8IHggPj0gMS4wKSB7XG4gICAgICByZXR1cm4gMC4wO1xuICAgIH1cblxuICAgIGlmICh4ID4gLTEuMTkyMDkyOTBFLTA3ICYmIHggPCAxLjE5MjA5MjkwRS0wNykge1xuICAgICAgcmV0dXJuIDEuMDtcbiAgICB9XG5cbiAgICB2YXIgeHBpID0geCAqIE1hdGguUEk7XG4gICAgcmV0dXJuIE1hdGguc2luKHhwaSkgLyB4cGkgKiAoMC41NCArIDAuNDYgKiBNYXRoLmNvcyh4cGkgLyAxLjApKTtcbiAgfVxufSwge1xuICAvLyBMYW5jem9zLCB3aW4gPSAyXG4gIHdpbjogMi4wLFxuICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcih4KSB7XG4gICAgaWYgKHggPD0gLTIuMCB8fCB4ID49IDIuMCkge1xuICAgICAgcmV0dXJuIDAuMDtcbiAgICB9XG5cbiAgICBpZiAoeCA+IC0xLjE5MjA5MjkwRS0wNyAmJiB4IDwgMS4xOTIwOTI5MEUtMDcpIHtcbiAgICAgIHJldHVybiAxLjA7XG4gICAgfVxuXG4gICAgdmFyIHhwaSA9IHggKiBNYXRoLlBJO1xuICAgIHJldHVybiBNYXRoLnNpbih4cGkpIC8geHBpICogTWF0aC5zaW4oeHBpIC8gMi4wKSAvICh4cGkgLyAyLjApO1xuICB9XG59LCB7XG4gIC8vIExhbmN6b3MsIHdpbiA9IDNcbiAgd2luOiAzLjAsXG4gIGZpbHRlcjogZnVuY3Rpb24gZmlsdGVyKHgpIHtcbiAgICBpZiAoeCA8PSAtMy4wIHx8IHggPj0gMy4wKSB7XG4gICAgICByZXR1cm4gMC4wO1xuICAgIH1cblxuICAgIGlmICh4ID4gLTEuMTkyMDkyOTBFLTA3ICYmIHggPCAxLjE5MjA5MjkwRS0wNykge1xuICAgICAgcmV0dXJuIDEuMDtcbiAgICB9XG5cbiAgICB2YXIgeHBpID0geCAqIE1hdGguUEk7XG4gICAgcmV0dXJuIE1hdGguc2luKHhwaSkgLyB4cGkgKiBNYXRoLnNpbih4cGkgLyAzLjApIC8gKHhwaSAvIDMuMCk7XG4gIH1cbn1dO1xuXG59LHt9XSw4OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxudmFyIGNyZWF0ZUZpbHRlcnMgPSBfZGVyZXFfKCcuL3Jlc2l6ZV9maWx0ZXJfZ2VuJyk7XG5cbmZ1bmN0aW9uIHJlc2V0QWxwaGEoZHN0LCB3aWR0aCwgaGVpZ2h0KSB7XG4gIHZhciBwdHIgPSAzLFxuICAgICAgbGVuID0gd2lkdGggKiBoZWlnaHQgKiA0IHwgMDtcblxuICB3aGlsZSAocHRyIDwgbGVuKSB7XG4gICAgZHN0W3B0cl0gPSAweEZGO1xuICAgIHB0ciA9IHB0ciArIDQgfCAwO1xuICB9XG59XG5cbmZ1bmN0aW9uIGFzVWludDhBcnJheShzcmMpIHtcbiAgcmV0dXJuIG5ldyBVaW50OEFycmF5KHNyYy5idWZmZXIsIDAsIHNyYy5ieXRlTGVuZ3RoKTtcbn1cblxudmFyIElTX0xFID0gdHJ1ZTsgLy8gc2hvdWxkIG5vdCBjcmFzaCBldmVyeXRoaW5nIG9uIG1vZHVsZSBsb2FkIGluIG9sZCBicm93c2Vyc1xuXG50cnkge1xuICBJU19MRSA9IG5ldyBVaW50MzJBcnJheShuZXcgVWludDhBcnJheShbMSwgMCwgMCwgMF0pLmJ1ZmZlcilbMF0gPT09IDE7XG59IGNhdGNoIChfXykge31cblxuZnVuY3Rpb24gY29weUludDE2YXNMRShzcmMsIHRhcmdldCwgdGFyZ2V0X29mZnNldCkge1xuICBpZiAoSVNfTEUpIHtcbiAgICB0YXJnZXQuc2V0KGFzVWludDhBcnJheShzcmMpLCB0YXJnZXRfb2Zmc2V0KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBmb3IgKHZhciBwdHIgPSB0YXJnZXRfb2Zmc2V0LCBpID0gMDsgaSA8IHNyYy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBkYXRhID0gc3JjW2ldO1xuICAgIHRhcmdldFtwdHIrK10gPSBkYXRhICYgMHhGRjtcbiAgICB0YXJnZXRbcHRyKytdID0gZGF0YSA+PiA4ICYgMHhGRjtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlc2l6ZV93YXNtKG9wdGlvbnMpIHtcbiAgdmFyIHNyYyA9IG9wdGlvbnMuc3JjO1xuICB2YXIgc3JjVyA9IG9wdGlvbnMud2lkdGg7XG4gIHZhciBzcmNIID0gb3B0aW9ucy5oZWlnaHQ7XG4gIHZhciBkZXN0VyA9IG9wdGlvbnMudG9XaWR0aDtcbiAgdmFyIGRlc3RIID0gb3B0aW9ucy50b0hlaWdodDtcbiAgdmFyIHNjYWxlWCA9IG9wdGlvbnMuc2NhbGVYIHx8IG9wdGlvbnMudG9XaWR0aCAvIG9wdGlvbnMud2lkdGg7XG4gIHZhciBzY2FsZVkgPSBvcHRpb25zLnNjYWxlWSB8fCBvcHRpb25zLnRvSGVpZ2h0IC8gb3B0aW9ucy5oZWlnaHQ7XG4gIHZhciBvZmZzZXRYID0gb3B0aW9ucy5vZmZzZXRYIHx8IDAuMDtcbiAgdmFyIG9mZnNldFkgPSBvcHRpb25zLm9mZnNldFkgfHwgMC4wO1xuICB2YXIgZGVzdCA9IG9wdGlvbnMuZGVzdCB8fCBuZXcgVWludDhBcnJheShkZXN0VyAqIGRlc3RIICogNCk7XG4gIHZhciBxdWFsaXR5ID0gdHlwZW9mIG9wdGlvbnMucXVhbGl0eSA9PT0gJ3VuZGVmaW5lZCcgPyAzIDogb3B0aW9ucy5xdWFsaXR5O1xuICB2YXIgYWxwaGEgPSBvcHRpb25zLmFscGhhIHx8IGZhbHNlO1xuICB2YXIgZmlsdGVyc1ggPSBjcmVhdGVGaWx0ZXJzKHF1YWxpdHksIHNyY1csIGRlc3RXLCBzY2FsZVgsIG9mZnNldFgpLFxuICAgICAgZmlsdGVyc1kgPSBjcmVhdGVGaWx0ZXJzKHF1YWxpdHksIHNyY0gsIGRlc3RILCBzY2FsZVksIG9mZnNldFkpOyAvLyBkZXN0aW5hdGlvbiBpcyAwIHRvby5cblxuICB2YXIgc3JjX29mZnNldCA9IDA7IC8vIGJ1ZmZlciBiZXR3ZWVuIGNvbnZvbHZlIHBhc3Nlc1xuXG4gIHZhciB0bXBfb2Zmc2V0ID0gdGhpcy5fX2FsaWduKHNyY19vZmZzZXQgKyBNYXRoLm1heChzcmMuYnl0ZUxlbmd0aCwgZGVzdC5ieXRlTGVuZ3RoKSk7XG5cbiAgdmFyIGZpbHRlcnNYX29mZnNldCA9IHRoaXMuX19hbGlnbih0bXBfb2Zmc2V0ICsgc3JjSCAqIGRlc3RXICogNCk7XG5cbiAgdmFyIGZpbHRlcnNZX29mZnNldCA9IHRoaXMuX19hbGlnbihmaWx0ZXJzWF9vZmZzZXQgKyBmaWx0ZXJzWC5ieXRlTGVuZ3RoKTtcblxuICB2YXIgYWxsb2NfYnl0ZXMgPSBmaWx0ZXJzWV9vZmZzZXQgKyBmaWx0ZXJzWS5ieXRlTGVuZ3RoO1xuXG4gIHZhciBpbnN0YW5jZSA9IHRoaXMuX19pbnN0YW5jZSgncmVzaXplJywgYWxsb2NfYnl0ZXMpOyAvL1xuICAvLyBGaWxsIG1lbW9yeSBibG9jayB3aXRoIGRhdGEgdG8gcHJvY2Vzc1xuICAvL1xuXG5cbiAgdmFyIG1lbSA9IG5ldyBVaW50OEFycmF5KHRoaXMuX19tZW1vcnkuYnVmZmVyKTtcbiAgdmFyIG1lbTMyID0gbmV3IFVpbnQzMkFycmF5KHRoaXMuX19tZW1vcnkuYnVmZmVyKTsgLy8gMzItYml0IGNvcHkgaXMgbXVjaCBmYXN0ZXIgaW4gY2hyb21lXG5cbiAgdmFyIHNyYzMyID0gbmV3IFVpbnQzMkFycmF5KHNyYy5idWZmZXIpO1xuICBtZW0zMi5zZXQoc3JjMzIpOyAvLyBXZSBzaG91bGQgZ3VhcmFudGVlIExFIGJ5dGVzIG9yZGVyLiBGaWx0ZXJzIGFyZSBub3QgYmlnLCBzb1xuICAvLyBzcGVlZCBkaWZmZXJlbmNlIGlzIG5vdCBzaWduaWZpY2FudCB2cyBkaXJlY3QgLnNldCgpXG5cbiAgY29weUludDE2YXNMRShmaWx0ZXJzWCwgbWVtLCBmaWx0ZXJzWF9vZmZzZXQpO1xuICBjb3B5SW50MTZhc0xFKGZpbHRlcnNZLCBtZW0sIGZpbHRlcnNZX29mZnNldCk7IC8vXG4gIC8vIE5vdyBjYWxsIHdlYmFzc2VtYmx5IG1ldGhvZFxuICAvLyBlbXNkayBkb2VzIG1ldGhvZCBuYW1lcyB3aXRoICdfJ1xuXG4gIHZhciBmbiA9IGluc3RhbmNlLmV4cG9ydHMuY29udm9sdmVIViB8fCBpbnN0YW5jZS5leHBvcnRzLl9jb252b2x2ZUhWO1xuICBmbihmaWx0ZXJzWF9vZmZzZXQsIGZpbHRlcnNZX29mZnNldCwgdG1wX29mZnNldCwgc3JjVywgc3JjSCwgZGVzdFcsIGRlc3RIKTsgLy9cbiAgLy8gQ29weSBkYXRhIGJhY2sgdG8gdHlwZWQgYXJyYXlcbiAgLy9cbiAgLy8gMzItYml0IGNvcHkgaXMgbXVjaCBmYXN0ZXIgaW4gY2hyb21lXG5cbiAgdmFyIGRlc3QzMiA9IG5ldyBVaW50MzJBcnJheShkZXN0LmJ1ZmZlcik7XG4gIGRlc3QzMi5zZXQobmV3IFVpbnQzMkFycmF5KHRoaXMuX19tZW1vcnkuYnVmZmVyLCAwLCBkZXN0SCAqIGRlc3RXKSk7IC8vIFRoYXQncyBmYXN0ZXIgdGhhbiBkb2luZyBjaGVja3MgaW4gY29udm9sdmVyLlxuICAvLyAhISEgTm90ZSwgY2FudmFzIGRhdGEgaXMgbm90IHByZW11bHRpcGxlZC4gV2UgZG9uJ3QgbmVlZCBvdGhlclxuICAvLyBhbHBoYSBjb3JyZWN0aW9ucy5cblxuICBpZiAoIWFscGhhKSByZXNldEFscGhhKGRlc3QsIGRlc3RXLCBkZXN0SCk7XG4gIHJldHVybiBkZXN0O1xufTtcblxufSx7XCIuL3Jlc2l6ZV9maWx0ZXJfZ2VuXCI6Nn1dLDk6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgbmFtZTogJ3Vuc2hhcnBfbWFzaycsXG4gIGZuOiBfZGVyZXFfKCcuL3Vuc2hhcnBfbWFzaycpLFxuICB3YXNtX2ZuOiBfZGVyZXFfKCcuL3Vuc2hhcnBfbWFza193YXNtJyksXG4gIHdhc21fc3JjOiBfZGVyZXFfKCcuL3Vuc2hhcnBfbWFza193YXNtX2Jhc2U2NCcpXG59O1xuXG59LHtcIi4vdW5zaGFycF9tYXNrXCI6MTAsXCIuL3Vuc2hhcnBfbWFza193YXNtXCI6MTEsXCIuL3Vuc2hhcnBfbWFza193YXNtX2Jhc2U2NFwiOjEyfV0sMTA6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXG52YXIgZ2x1cl9tb25vMTYgPSBfZGVyZXFfKCdnbHVyL21vbm8xNicpO1xuXG5mdW5jdGlvbiBoc3ZfdjE2KGltZywgd2lkdGgsIGhlaWdodCkge1xuICB2YXIgc2l6ZSA9IHdpZHRoICogaGVpZ2h0O1xuICB2YXIgb3V0ID0gbmV3IFVpbnQxNkFycmF5KHNpemUpO1xuICB2YXIgciwgZywgYiwgbWF4O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgciA9IGltZ1s0ICogaV07XG4gICAgZyA9IGltZ1s0ICogaSArIDFdO1xuICAgIGIgPSBpbWdbNCAqIGkgKyAyXTtcbiAgICBtYXggPSByID49IGcgJiYgciA+PSBiID8gciA6IGcgPj0gYiAmJiBnID49IHIgPyBnIDogYjtcbiAgICBvdXRbaV0gPSBtYXggPDwgODtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gdW5zaGFycChpbWcsIHdpZHRoLCBoZWlnaHQsIGFtb3VudCwgcmFkaXVzLCB0aHJlc2hvbGQpIHtcbiAgdmFyIHYxLCB2Miwgdm11bDtcbiAgdmFyIGRpZmYsIGlUaW1lczQ7XG5cbiAgaWYgKGFtb3VudCA9PT0gMCB8fCByYWRpdXMgPCAwLjUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAocmFkaXVzID4gMi4wKSB7XG4gICAgcmFkaXVzID0gMi4wO1xuICB9XG5cbiAgdmFyIGJyaWdodG5lc3MgPSBoc3ZfdjE2KGltZywgd2lkdGgsIGhlaWdodCk7XG4gIHZhciBibHVyZWQgPSBuZXcgVWludDE2QXJyYXkoYnJpZ2h0bmVzcyk7IC8vIGNvcHksIGJlY2F1c2UgYmx1ciBtb2RpZnkgc3JjXG5cbiAgZ2x1cl9tb25vMTYoYmx1cmVkLCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpO1xuICB2YXIgYW1vdW50RnAgPSBhbW91bnQgLyAxMDAgKiAweDEwMDAgKyAwLjUgfCAwO1xuICB2YXIgdGhyZXNob2xkRnAgPSB0aHJlc2hvbGQgPDwgODtcbiAgdmFyIHNpemUgPSB3aWR0aCAqIGhlaWdodDtcbiAgLyogZXNsaW50LWRpc2FibGUgaW5kZW50ICovXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICB2MSA9IGJyaWdodG5lc3NbaV07XG4gICAgZGlmZiA9IHYxIC0gYmx1cmVkW2ldO1xuXG4gICAgaWYgKE1hdGguYWJzKGRpZmYpID49IHRocmVzaG9sZEZwKSB7XG4gICAgICAvLyBhZGQgdW5zaGFycCBtYXNrIHRvIHRoZSBicmlnaHRuZXNzIGNoYW5uZWxcbiAgICAgIHYyID0gdjEgKyAoYW1vdW50RnAgKiBkaWZmICsgMHg4MDAgPj4gMTIpOyAvLyBCb3RoIHYxIGFuZCB2MiBhcmUgd2l0aGluIFswLjAgLi4gMjU1LjBdICgwMDAwLUZGMDApIHJhbmdlLCBuZXZlciBnb2luZyBpbnRvXG4gICAgICAvLyBbMjU1LjAwMyAuLiAyNTUuOTk2XSAoRkYwMS1GRkZGKS4gVGhpcyBhbGxvd3MgdG8gcm91bmQgdGhpcyB2YWx1ZSBhcyAoeCsuNSl8MFxuICAgICAgLy8gbGF0ZXIgd2l0aG91dCBvdmVyZmxvd2luZy5cblxuICAgICAgdjIgPSB2MiA+IDB4ZmYwMCA/IDB4ZmYwMCA6IHYyO1xuICAgICAgdjIgPSB2MiA8IDB4MDAwMCA/IDB4MDAwMCA6IHYyOyAvLyBBdm9pZCBkaXZpc2lvbiBieSAwLiBWPTAgbWVhbnMgcmdiKDAsMCwwKSwgdW5zaGFycCB3aXRoIHVuc2hhcnBBbW91bnQ+MCBjYW5ub3RcbiAgICAgIC8vIGNoYW5nZSB0aGlzIHZhbHVlIChiZWNhdXNlIGRpZmYgYmV0d2VlbiBjb2xvcnMgZ2V0cyBpbmZsYXRlZCksIHNvIG5vIG5lZWQgdG8gdmVyaWZ5IGNvcnJlY3RuZXNzLlxuXG4gICAgICB2MSA9IHYxICE9PSAwID8gdjEgOiAxOyAvLyBNdWx0aXBseWluZyBWIGluIEhTViBtb2RlbCBieSBhIGNvbnN0YW50IGlzIGVxdWl2YWxlbnQgdG8gbXVsdGlwbHlpbmcgZWFjaCBjb21wb25lbnRcbiAgICAgIC8vIGluIFJHQiBieSB0aGUgc2FtZSBjb25zdGFudCAoc2FtZSBmb3IgSFNMKSwgc2VlIGFsc286XG4gICAgICAvLyBodHRwczovL2JlZXNidXp6LmJpei9jb2RlLzE2LWhzdi1jb2xvci10cmFuc2Zvcm1zXG5cbiAgICAgIHZtdWwgPSAodjIgPDwgMTIpIC8gdjEgfCAwOyAvLyBSZXN1bHQgd2lsbCBiZSBpbiBbMC4uMjU1XSByYW5nZSBiZWNhdXNlOlxuICAgICAgLy8gIC0gYWxsIG51bWJlcnMgYXJlIHBvc2l0aXZlXG4gICAgICAvLyAgLSByLGcsYiA8PSAodjEvMjU2KVxuICAgICAgLy8gIC0gcixnLGIsKHYxLzI1NiksKHYyLzI1NikgPD0gMjU1XG4gICAgICAvLyBTbyBoaWdoZXN0IHRoaXMgbnVtYmVyIGNhbiBnZXQgaXMgWCoyNTUvWCswLjU9MjU1LjUgd2hpY2ggaXMgPCAyNTYgYW5kIHJvdW5kcyBkb3duLlxuXG4gICAgICBpVGltZXM0ID0gaSAqIDQ7XG4gICAgICBpbWdbaVRpbWVzNF0gPSBpbWdbaVRpbWVzNF0gKiB2bXVsICsgMHg4MDAgPj4gMTI7IC8vIFJcblxuICAgICAgaW1nW2lUaW1lczQgKyAxXSA9IGltZ1tpVGltZXM0ICsgMV0gKiB2bXVsICsgMHg4MDAgPj4gMTI7IC8vIEdcblxuICAgICAgaW1nW2lUaW1lczQgKyAyXSA9IGltZ1tpVGltZXM0ICsgMl0gKiB2bXVsICsgMHg4MDAgPj4gMTI7IC8vIEJcbiAgICB9XG4gIH1cbn07XG5cbn0se1wiZ2x1ci9tb25vMTZcIjoxOH1dLDExOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB1bnNoYXJwKGltZywgd2lkdGgsIGhlaWdodCwgYW1vdW50LCByYWRpdXMsIHRocmVzaG9sZCkge1xuICBpZiAoYW1vdW50ID09PSAwIHx8IHJhZGl1cyA8IDAuNSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChyYWRpdXMgPiAyLjApIHtcbiAgICByYWRpdXMgPSAyLjA7XG4gIH1cblxuICB2YXIgcGl4ZWxzID0gd2lkdGggKiBoZWlnaHQ7XG4gIHZhciBpbWdfYnl0ZXNfY250ID0gcGl4ZWxzICogNDtcbiAgdmFyIGhzdl9ieXRlc19jbnQgPSBwaXhlbHMgKiAyO1xuICB2YXIgYmx1cl9ieXRlc19jbnQgPSBwaXhlbHMgKiAyO1xuICB2YXIgYmx1cl9saW5lX2J5dGVfY250ID0gTWF0aC5tYXgod2lkdGgsIGhlaWdodCkgKiA0OyAvLyBmbG9hdDMyIGFycmF5XG5cbiAgdmFyIGJsdXJfY29lZmZzX2J5dGVfY250ID0gOCAqIDQ7IC8vIGZsb2F0MzIgYXJyYXlcblxuICB2YXIgaW1nX29mZnNldCA9IDA7XG4gIHZhciBoc3Zfb2Zmc2V0ID0gaW1nX2J5dGVzX2NudDtcbiAgdmFyIGJsdXJfb2Zmc2V0ID0gaHN2X29mZnNldCArIGhzdl9ieXRlc19jbnQ7XG4gIHZhciBibHVyX3RtcF9vZmZzZXQgPSBibHVyX29mZnNldCArIGJsdXJfYnl0ZXNfY250O1xuICB2YXIgYmx1cl9saW5lX29mZnNldCA9IGJsdXJfdG1wX29mZnNldCArIGJsdXJfYnl0ZXNfY250O1xuICB2YXIgYmx1cl9jb2VmZnNfb2Zmc2V0ID0gYmx1cl9saW5lX29mZnNldCArIGJsdXJfbGluZV9ieXRlX2NudDtcblxuICB2YXIgaW5zdGFuY2UgPSB0aGlzLl9faW5zdGFuY2UoJ3Vuc2hhcnBfbWFzaycsIGltZ19ieXRlc19jbnQgKyBoc3ZfYnl0ZXNfY250ICsgYmx1cl9ieXRlc19jbnQgKiAyICsgYmx1cl9saW5lX2J5dGVfY250ICsgYmx1cl9jb2VmZnNfYnl0ZV9jbnQsIHtcbiAgICBleHA6IE1hdGguZXhwXG4gIH0pOyAvLyAzMi1iaXQgY29weSBpcyBtdWNoIGZhc3RlciBpbiBjaHJvbWVcblxuXG4gIHZhciBpbWczMiA9IG5ldyBVaW50MzJBcnJheShpbWcuYnVmZmVyKTtcbiAgdmFyIG1lbTMyID0gbmV3IFVpbnQzMkFycmF5KHRoaXMuX19tZW1vcnkuYnVmZmVyKTtcbiAgbWVtMzIuc2V0KGltZzMyKTsgLy8gSFNMXG5cbiAgdmFyIGZuID0gaW5zdGFuY2UuZXhwb3J0cy5oc3ZfdjE2IHx8IGluc3RhbmNlLmV4cG9ydHMuX2hzdl92MTY7XG4gIGZuKGltZ19vZmZzZXQsIGhzdl9vZmZzZXQsIHdpZHRoLCBoZWlnaHQpOyAvLyBCTFVSXG5cbiAgZm4gPSBpbnN0YW5jZS5leHBvcnRzLmJsdXJNb25vMTYgfHwgaW5zdGFuY2UuZXhwb3J0cy5fYmx1ck1vbm8xNjtcbiAgZm4oaHN2X29mZnNldCwgYmx1cl9vZmZzZXQsIGJsdXJfdG1wX29mZnNldCwgYmx1cl9saW5lX29mZnNldCwgYmx1cl9jb2VmZnNfb2Zmc2V0LCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpOyAvLyBVTlNIQVJQXG5cbiAgZm4gPSBpbnN0YW5jZS5leHBvcnRzLnVuc2hhcnAgfHwgaW5zdGFuY2UuZXhwb3J0cy5fdW5zaGFycDtcbiAgZm4oaW1nX29mZnNldCwgaW1nX29mZnNldCwgaHN2X29mZnNldCwgYmx1cl9vZmZzZXQsIHdpZHRoLCBoZWlnaHQsIGFtb3VudCwgdGhyZXNob2xkKTsgLy8gMzItYml0IGNvcHkgaXMgbXVjaCBmYXN0ZXIgaW4gY2hyb21lXG5cbiAgaW1nMzIuc2V0KG5ldyBVaW50MzJBcnJheSh0aGlzLl9fbWVtb3J5LmJ1ZmZlciwgMCwgcGl4ZWxzKSk7XG59O1xuXG59LHt9XSwxMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cbm1vZHVsZS5leHBvcnRzID0gJ0FHRnpiUUVBQUFBQURBWmtlV3hwYm1zQUFBQUFBQUUwQjJBQUFHQUVmMzkvZndCZ0JuOS9mMzkvZndCZ0NIOS9mMzkvZjM5L0FHQUlmMzkvZjM5L2YzMEFZQUo5ZndCZ0FYd0JmQUlaQWdObGJuWURaWGh3QUFZRFpXNTJCbTFsYlc5eWVRSUFBQU1IQmdBRkFnUUJBd1lHQVg4QVFRQUxCNG9CQ0JGZlgzZGhjMjFmWTJGc2JGOWpkRzl5Y3dBQkZsOWZZblZwYkdSZloyRjFjM05wWVc1ZlkyOWxabk1BQWc1ZlgyZGhkWE56TVRaZmJHbHVaUUFEQ21Kc2RYSk5iMjV2TVRZQUJBZG9jM1pmZGpFMkFBVUhkVzV6YUdGeWNBQUdERjlmWkhOdlgyaGhibVJzWlFNQUdGOWZkMkZ6YlY5aGNIQnNlVjlrWVhSaFgzSmxiRzlqY3dBQkNzVU1CZ01BQVF2V0FRRUhmQ0FCUk51R3VrT0NHdnMvSUFDN295SUNSQUFBQUFBQUFBREFvaEFBSWdXMmpEZ0NGQ0FCSUFLYUVBQWlBeUFEb0NJR3RqZ0NFQ0FCUkFBQUFBQUFBUEEvSUFPaElnUWdCS0lnQXlBQ0lBS2dva1FBQUFBQUFBRHdQNkFnQmFHaklnUzJPQUlBSUFFZ0JTQUVtcUlpQjdZNEFnd2dBU0FESUFKRUFBQUFBQUFBOEQrZ0lBU2lvaUlJdGpnQ0NDQUJJQU1nQWtRQUFBQUFBQUR3djZBZ0JLS2lJZ0syT0FJRUlBRWdCeUFJb0NBRlJBQUFBQUFBQVBBL0lBYWhvQ0lEbzdZNEFod2dBU0FFSUFLZ0lBT2p0amdDR0F1R0JRTUdmd2w4QW4wZ0F5b0NEQ0VWSUFNcUFnZ2hGaUFES2dJVXV5RVJJQU1xQWhDN0lSQUNRQ0FFUVFGcklnaEJBRWdpQ1FSQUlBSWhCeUFBSVFZTUFRc2dBaUFBTHdFQXVDSVBJQU1xQWhpN29pSU1JQkdpSWcwZ0RDQVFvaUFQSUFNcUFnUzdJaE9pSWhRZ0F5b0NBTHNpRWlBUG9xQ2dvQ0lPdGpnQ0FDQUNRUVJxSVFjZ0FFRUNhaUVHSUFoRkRRQWdDRUVCSUFoQkFVZ2JJZ3BCZjNNaEN3Si9JQVFnQ210QkFYRkZCRUFnRGlFTklBZ01BUXNnQWlBTklBNGdFS0lnRkNBU0lBQXZBUUs0SWcraW9LQ2dJZzIyT0FJRUlBSkJDR29oQnlBQVFRUnFJUVlnRGlFTUlBUkJBbXNMSVFJZ0MwRUFJQVJyUmcwQUEwQWdCeUFNSUJHaUlBMGdFS0lnRHlBVG9pQVNJQVl2QVFDNElnNmlvS0NnSWd5Mk9BSUFJQWNnRFNBUm9pQU1JQkNpSUE0Z0U2SWdFaUFHTHdFQ3VDSVBvcUNnb0NJTnRqZ0NCQ0FIUVFocUlRY2dCa0VFYWlFR0lBSkJBa29oQUNBQ1FRSnJJUUlnQUEwQUN3c0NRQ0FKRFFBZ0FTQUZJQWhzUVFGMGFpSUFBbjhnQmtFQ2F5OEJBQ0lDdUNJTklCVzdJaEtpSUEwZ0Zyc2lFNktnSUEwZ0F5b0NITHVpSWd3Z0VLS2dJQXdnRWFLZ0lnOGdCMEVFYXlJSEtnSUF1NkFpRGtRQUFBQUFBQUR3UVdNZ0RrUUFBQUFBQUFBQUFHWnhCRUFnRHFzTUFRdEJBQXM3QVFBZ0NFVU5BQ0FHUVFScklRWkJBQ0FGYTBFQmRDRUJBMEFDZnlBTklCS2lJQUpCLy84RGNiZ2lEU0FUb3FBZ0R5SU9JQkNpb0NBTUlCR2lvQ0lQSUFkQkJHc2lCeW9DQUx1Z0lneEVBQUFBQUFBQThFRmpJQXhFQUFBQUFBQUFBQUJtY1FSQUlBeXJEQUVMUVFBTElRTWdCaThCQUNFQ0lBQWdBV29pQUNBRE93RUFJQVpCQW1zaEJpQUlRUUZLSVFNZ0RpRU1JQWhCQVdzaENDQUREUUFMQ3d2UkFnSUJmd2Q4QWtBZ0IwTUFBQUFBV3cwQUlBUkUyNGE2UTRJYSt6OGdCME1BQUFBL2w3dWpJZ2xFQUFBQUFBQUFBTUNpRUFBaURMYU1PQUlVSUFRZ0Nab1FBQ0lLSUFxZ0lnMjJPQUlRSUFSRUFBQUFBQUFBOEQ4Z0NxRWlDeUFMb2lBS0lBa2dDYUNpUkFBQUFBQUFBUEEvb0NBTW9hTWlDN1k0QWdBZ0JDQU1JQXVhb2lJT3RqZ0NEQ0FFSUFvZ0NVUUFBQUFBQUFEd1A2QWdDNktpSWcrMk9BSUlJQVFnQ2lBSlJBQUFBQUFBQVBDL29DQUxvcUlpQ2JZNEFnUWdCQ0FPSUErZ0lBeEVBQUFBQUFBQThEOGdEYUdnSWdxanRqZ0NIQ0FFSUFzZ0NhQWdDcU8yT0FJWUlBWUVRQU5BSUFBZ0JTQUliRUVCZEdvZ0FpQUlRUUYwYWlBRElBUWdCU0FHRUFNZ0NFRUJhaUlJSUFaSERRQUxDeUFGUlEwQVFRQWhDQU5BSUFJZ0JpQUliRUVCZEdvZ0FTQUlRUUYwYWlBRElBUWdCaUFGRUFNZ0NFRUJhaUlJSUFWSERRQUxDd3R4QVFOL0lBSWdBMndpQlFSQUEwQWdBU0FBS0FJQUlnUkJFSFpCL3dGeElnSWdBaUFFUVFoMlFmOEJjU0lESUFNZ0JFSC9BWEVpQkVrYklBSWdBMHNiSWdZZ0JpQUVJQUlnQkVzYklBTWdCRXNiUVFoME93RUFJQUZCQW1vaEFTQUFRUVJxSVFBZ0JVRUJheUlGRFFBTEN3dVpBZ0lEZndGOElBUWdCV3doQkFKL0lBYXpRd0FBZ0VXVVF3QUF5RUtWdTBRQUFBQUFBQURnUDZBaUM1bEVBQUFBQUFBQTRFRmpCRUFnQzZvTUFRdEJnSUNBZ0hnTElRVWdCQVJBSUFkQkNIUWhDVUVBSVFZRFFDQUpJQUlnQmtFQmRDSUhhaThCQUNJQklBTWdCMm92QVFCcklnY2dCMEVmZFNJSWFpQUljMDBFUUNBQUlBWkJBblFpQ0dvaUNpQUZJQWRzUVlBUWFrRU1kU0FCYWlJSFFZRCtBeUFIUVlEK0EwZ2JJZ2RCQUNBSFFRQktHMEVNZENBQlFRRWdBUnR1SWdFZ0NpMEFBR3hCZ0JCcVFReDJPZ0FBSUFBZ0NFRUJjbW9pQnlBQklBY3RBQUJzUVlBUWFrRU1kam9BQUNBQUlBaEJBbkpxSWdjZ0FTQUhMUUFBYkVHQUVHcEJESFk2QUFBTElBWkJBV29pQmlBRVJ3MEFDd3NMJztcblxufSx7fV0sMTM6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuXG52YXIgR0NfSU5URVJWQUwgPSAxMDA7XG5cbmZ1bmN0aW9uIFBvb2woY3JlYXRlLCBpZGxlKSB7XG4gIHRoaXMuY3JlYXRlID0gY3JlYXRlO1xuICB0aGlzLmF2YWlsYWJsZSA9IFtdO1xuICB0aGlzLmFjcXVpcmVkID0ge307XG4gIHRoaXMubGFzdElkID0gMTtcbiAgdGhpcy50aW1lb3V0SWQgPSAwO1xuICB0aGlzLmlkbGUgPSBpZGxlIHx8IDIwMDA7XG59XG5cblBvb2wucHJvdG90eXBlLmFjcXVpcmUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgdmFyIHJlc291cmNlO1xuXG4gIGlmICh0aGlzLmF2YWlsYWJsZS5sZW5ndGggIT09IDApIHtcbiAgICByZXNvdXJjZSA9IHRoaXMuYXZhaWxhYmxlLnBvcCgpO1xuICB9IGVsc2Uge1xuICAgIHJlc291cmNlID0gdGhpcy5jcmVhdGUoKTtcbiAgICByZXNvdXJjZS5pZCA9IHRoaXMubGFzdElkKys7XG5cbiAgICByZXNvdXJjZS5yZWxlYXNlID0gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIF90aGlzLnJlbGVhc2UocmVzb3VyY2UpO1xuICAgIH07XG4gIH1cblxuICB0aGlzLmFjcXVpcmVkW3Jlc291cmNlLmlkXSA9IHJlc291cmNlO1xuICByZXR1cm4gcmVzb3VyY2U7XG59O1xuXG5Qb29sLnByb3RvdHlwZS5yZWxlYXNlID0gZnVuY3Rpb24gKHJlc291cmNlKSB7XG4gIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gIGRlbGV0ZSB0aGlzLmFjcXVpcmVkW3Jlc291cmNlLmlkXTtcbiAgcmVzb3VyY2UubGFzdFVzZWQgPSBEYXRlLm5vdygpO1xuICB0aGlzLmF2YWlsYWJsZS5wdXNoKHJlc291cmNlKTtcblxuICBpZiAodGhpcy50aW1lb3V0SWQgPT09IDApIHtcbiAgICB0aGlzLnRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIF90aGlzMi5nYygpO1xuICAgIH0sIEdDX0lOVEVSVkFMKTtcbiAgfVxufTtcblxuUG9vbC5wcm90b3R5cGUuZ2MgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gIHZhciBub3cgPSBEYXRlLm5vdygpO1xuICB0aGlzLmF2YWlsYWJsZSA9IHRoaXMuYXZhaWxhYmxlLmZpbHRlcihmdW5jdGlvbiAocmVzb3VyY2UpIHtcbiAgICBpZiAobm93IC0gcmVzb3VyY2UubGFzdFVzZWQgPiBfdGhpczMuaWRsZSkge1xuICAgICAgcmVzb3VyY2UuZGVzdHJveSgpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9KTtcblxuICBpZiAodGhpcy5hdmFpbGFibGUubGVuZ3RoICE9PSAwKSB7XG4gICAgdGhpcy50aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBfdGhpczMuZ2MoKTtcbiAgICB9LCBHQ19JTlRFUlZBTCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy50aW1lb3V0SWQgPSAwO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBvb2w7XG5cbn0se31dLDE0OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIG1pbiBzaXplID0gMSBjYW4gY29uc3VtZSBsYXJnZSBhbW91bnQgb2YgbWVtb3J5XG5cbnZhciBNSU5fSU5ORVJfVElMRV9TSVpFID0gMjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjcmVhdGVTdGFnZXMoZnJvbVdpZHRoLCBmcm9tSGVpZ2h0LCB0b1dpZHRoLCB0b0hlaWdodCwgc3JjVGlsZVNpemUsIGRlc3RUaWxlQm9yZGVyKSB7XG4gIHZhciBzY2FsZVggPSB0b1dpZHRoIC8gZnJvbVdpZHRoO1xuICB2YXIgc2NhbGVZID0gdG9IZWlnaHQgLyBmcm9tSGVpZ2h0OyAvLyBkZXJpdmVkIGZyb20gY3JlYXRlUmVnaW9ucyBlcXVhdGlvbjpcbiAgLy8gaW5uZXJUaWxlV2lkdGggPSBwaXhlbEZsb29yKHNyY1RpbGVTaXplICogc2NhbGVYKSAtIDIgKiBkZXN0VGlsZUJvcmRlcjtcblxuICB2YXIgbWluU2NhbGUgPSAoMiAqIGRlc3RUaWxlQm9yZGVyICsgTUlOX0lOTkVSX1RJTEVfU0laRSArIDEpIC8gc3JjVGlsZVNpemU7IC8vIHJlZnVzZSB0byBzY2FsZSBpbWFnZSBtdWx0aXBsZSB0aW1lcyBieSBsZXNzIHRoYW4gdHdpY2UgZWFjaCB0aW1lLFxuICAvLyBpdCBjb3VsZCBvbmx5IGhhcHBlbiBiZWNhdXNlIG9mIGludmFsaWQgb3B0aW9uc1xuXG4gIGlmIChtaW5TY2FsZSA+IDAuNSkgcmV0dXJuIFtbdG9XaWR0aCwgdG9IZWlnaHRdXTtcbiAgdmFyIHN0YWdlQ291bnQgPSBNYXRoLmNlaWwoTWF0aC5sb2coTWF0aC5taW4oc2NhbGVYLCBzY2FsZVkpKSAvIE1hdGgubG9nKG1pblNjYWxlKSk7IC8vIG5vIGFkZGl0aW9uYWwgcmVzaXplcyBhcmUgbmVjZXNzYXJ5LFxuICAvLyBzdGFnZUNvdW50IGNhbiBiZSB6ZXJvIG9yIGJlIG5lZ2F0aXZlIHdoZW4gZW5sYXJnaW5nIHRoZSBpbWFnZVxuXG4gIGlmIChzdGFnZUNvdW50IDw9IDEpIHJldHVybiBbW3RvV2lkdGgsIHRvSGVpZ2h0XV07XG4gIHZhciByZXN1bHQgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YWdlQ291bnQ7IGkrKykge1xuICAgIHZhciB3aWR0aCA9IE1hdGgucm91bmQoTWF0aC5wb3coTWF0aC5wb3coZnJvbVdpZHRoLCBzdGFnZUNvdW50IC0gaSAtIDEpICogTWF0aC5wb3codG9XaWR0aCwgaSArIDEpLCAxIC8gc3RhZ2VDb3VudCkpO1xuICAgIHZhciBoZWlnaHQgPSBNYXRoLnJvdW5kKE1hdGgucG93KE1hdGgucG93KGZyb21IZWlnaHQsIHN0YWdlQ291bnQgLSBpIC0gMSkgKiBNYXRoLnBvdyh0b0hlaWdodCwgaSArIDEpLCAxIC8gc3RhZ2VDb3VudCkpO1xuICAgIHJlc3VsdC5wdXNoKFt3aWR0aCwgaGVpZ2h0XSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxufSx7fV0sMTU6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLypcbiAqIHBpeGVsRmxvb3IgYW5kIHBpeGVsQ2VpbCBhcmUgbW9kaWZpZWQgdmVyc2lvbnMgb2YgTWF0aC5mbG9vciBhbmQgTWF0aC5jZWlsXG4gKiBmdW5jdGlvbnMgd2hpY2ggdGFrZSBpbnRvIGFjY291bnQgZmxvYXRpbmcgcG9pbnQgYXJpdGhtZXRpYyBlcnJvcnMuXG4gKiBUaG9zZSBlcnJvcnMgY2FuIGNhdXNlIHVuZGVzaXJlZCBpbmNyZW1lbnRzL2RlY3JlbWVudHMgb2Ygc2l6ZXMgYW5kIG9mZnNldHM6XG4gKiBNYXRoLmNlaWwoMzYgLyAoMzYgLyA1MDApKSA9IDUwMVxuICogcGl4ZWxDZWlsKDM2IC8gKDM2IC8gNTAwKSkgPSA1MDBcbiAqL1xuXG52YXIgUElYRUxfRVBTSUxPTiA9IDFlLTU7XG5cbmZ1bmN0aW9uIHBpeGVsRmxvb3IoeCkge1xuICB2YXIgbmVhcmVzdCA9IE1hdGgucm91bmQoeCk7XG5cbiAgaWYgKE1hdGguYWJzKHggLSBuZWFyZXN0KSA8IFBJWEVMX0VQU0lMT04pIHtcbiAgICByZXR1cm4gbmVhcmVzdDtcbiAgfVxuXG4gIHJldHVybiBNYXRoLmZsb29yKHgpO1xufVxuXG5mdW5jdGlvbiBwaXhlbENlaWwoeCkge1xuICB2YXIgbmVhcmVzdCA9IE1hdGgucm91bmQoeCk7XG5cbiAgaWYgKE1hdGguYWJzKHggLSBuZWFyZXN0KSA8IFBJWEVMX0VQU0lMT04pIHtcbiAgICByZXR1cm4gbmVhcmVzdDtcbiAgfVxuXG4gIHJldHVybiBNYXRoLmNlaWwoeCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlUmVnaW9ucyhvcHRpb25zKSB7XG4gIHZhciBzY2FsZVggPSBvcHRpb25zLnRvV2lkdGggLyBvcHRpb25zLndpZHRoO1xuICB2YXIgc2NhbGVZID0gb3B0aW9ucy50b0hlaWdodCAvIG9wdGlvbnMuaGVpZ2h0O1xuICB2YXIgaW5uZXJUaWxlV2lkdGggPSBwaXhlbEZsb29yKG9wdGlvbnMuc3JjVGlsZVNpemUgKiBzY2FsZVgpIC0gMiAqIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7XG4gIHZhciBpbm5lclRpbGVIZWlnaHQgPSBwaXhlbEZsb29yKG9wdGlvbnMuc3JjVGlsZVNpemUgKiBzY2FsZVkpIC0gMiAqIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7IC8vIHByZXZlbnQgaW5maW5pdGUgbG9vcCwgdGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuXG5cbiAgaWYgKGlubmVyVGlsZVdpZHRoIDwgMSB8fCBpbm5lclRpbGVIZWlnaHQgPCAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnRlcm5hbCBlcnJvciBpbiBwaWNhOiB0YXJnZXQgdGlsZSB3aWR0aC9oZWlnaHQgaXMgdG9vIHNtYWxsLicpO1xuICB9XG5cbiAgdmFyIHgsIHk7XG4gIHZhciBpbm5lclgsIGlubmVyWSwgdG9UaWxlV2lkdGgsIHRvVGlsZUhlaWdodDtcbiAgdmFyIHRpbGVzID0gW107XG4gIHZhciB0aWxlOyAvLyB3ZSBnbyB0b3AtdG8tZG93biBpbnN0ZWFkIG9mIGxlZnQtdG8tcmlnaHQgdG8gbWFrZSBpbWFnZSBkaXNwbGF5ZWQgZnJvbSB0b3AgdG9cbiAgLy8gZG9lc24gaW4gdGhlIGJyb3dzZXJcblxuICBmb3IgKGlubmVyWSA9IDA7IGlubmVyWSA8IG9wdGlvbnMudG9IZWlnaHQ7IGlubmVyWSArPSBpbm5lclRpbGVIZWlnaHQpIHtcbiAgICBmb3IgKGlubmVyWCA9IDA7IGlubmVyWCA8IG9wdGlvbnMudG9XaWR0aDsgaW5uZXJYICs9IGlubmVyVGlsZVdpZHRoKSB7XG4gICAgICB4ID0gaW5uZXJYIC0gb3B0aW9ucy5kZXN0VGlsZUJvcmRlcjtcblxuICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgIHggPSAwO1xuICAgICAgfVxuXG4gICAgICB0b1RpbGVXaWR0aCA9IGlubmVyWCArIGlubmVyVGlsZVdpZHRoICsgb3B0aW9ucy5kZXN0VGlsZUJvcmRlciAtIHg7XG5cbiAgICAgIGlmICh4ICsgdG9UaWxlV2lkdGggPj0gb3B0aW9ucy50b1dpZHRoKSB7XG4gICAgICAgIHRvVGlsZVdpZHRoID0gb3B0aW9ucy50b1dpZHRoIC0geDtcbiAgICAgIH1cblxuICAgICAgeSA9IGlubmVyWSAtIG9wdGlvbnMuZGVzdFRpbGVCb3JkZXI7XG5cbiAgICAgIGlmICh5IDwgMCkge1xuICAgICAgICB5ID0gMDtcbiAgICAgIH1cblxuICAgICAgdG9UaWxlSGVpZ2h0ID0gaW5uZXJZICsgaW5uZXJUaWxlSGVpZ2h0ICsgb3B0aW9ucy5kZXN0VGlsZUJvcmRlciAtIHk7XG5cbiAgICAgIGlmICh5ICsgdG9UaWxlSGVpZ2h0ID49IG9wdGlvbnMudG9IZWlnaHQpIHtcbiAgICAgICAgdG9UaWxlSGVpZ2h0ID0gb3B0aW9ucy50b0hlaWdodCAtIHk7XG4gICAgICB9XG5cbiAgICAgIHRpbGUgPSB7XG4gICAgICAgIHRvWDogeCxcbiAgICAgICAgdG9ZOiB5LFxuICAgICAgICB0b1dpZHRoOiB0b1RpbGVXaWR0aCxcbiAgICAgICAgdG9IZWlnaHQ6IHRvVGlsZUhlaWdodCxcbiAgICAgICAgdG9Jbm5lclg6IGlubmVyWCxcbiAgICAgICAgdG9Jbm5lclk6IGlubmVyWSxcbiAgICAgICAgdG9Jbm5lcldpZHRoOiBpbm5lclRpbGVXaWR0aCxcbiAgICAgICAgdG9Jbm5lckhlaWdodDogaW5uZXJUaWxlSGVpZ2h0LFxuICAgICAgICBvZmZzZXRYOiB4IC8gc2NhbGVYIC0gcGl4ZWxGbG9vcih4IC8gc2NhbGVYKSxcbiAgICAgICAgb2Zmc2V0WTogeSAvIHNjYWxlWSAtIHBpeGVsRmxvb3IoeSAvIHNjYWxlWSksXG4gICAgICAgIHNjYWxlWDogc2NhbGVYLFxuICAgICAgICBzY2FsZVk6IHNjYWxlWSxcbiAgICAgICAgeDogcGl4ZWxGbG9vcih4IC8gc2NhbGVYKSxcbiAgICAgICAgeTogcGl4ZWxGbG9vcih5IC8gc2NhbGVZKSxcbiAgICAgICAgd2lkdGg6IHBpeGVsQ2VpbCh0b1RpbGVXaWR0aCAvIHNjYWxlWCksXG4gICAgICAgIGhlaWdodDogcGl4ZWxDZWlsKHRvVGlsZUhlaWdodCAvIHNjYWxlWSlcbiAgICAgIH07XG4gICAgICB0aWxlcy5wdXNoKHRpbGUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aWxlcztcbn07XG5cbn0se31dLDE2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxuZnVuY3Rpb24gb2JqQ2xhc3Mob2JqKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKTtcbn1cblxubW9kdWxlLmV4cG9ydHMuaXNDYW52YXMgPSBmdW5jdGlvbiBpc0NhbnZhcyhlbGVtZW50KSB7XG4gIHZhciBjbmFtZSA9IG9iakNsYXNzKGVsZW1lbnQpO1xuICByZXR1cm4gY25hbWUgPT09ICdbb2JqZWN0IEhUTUxDYW52YXNFbGVtZW50XSdcbiAgLyogYnJvd3NlciAqL1xuICB8fCBjbmFtZSA9PT0gJ1tvYmplY3QgT2Zmc2NyZWVuQ2FudmFzXScgfHwgY25hbWUgPT09ICdbb2JqZWN0IENhbnZhc10nXG4gIC8qIG5vZGUtY2FudmFzICovXG4gIDtcbn07XG5cbm1vZHVsZS5leHBvcnRzLmlzSW1hZ2UgPSBmdW5jdGlvbiBpc0ltYWdlKGVsZW1lbnQpIHtcbiAgcmV0dXJuIG9iakNsYXNzKGVsZW1lbnQpID09PSAnW29iamVjdCBIVE1MSW1hZ2VFbGVtZW50XSc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5pc0ltYWdlQml0bWFwID0gZnVuY3Rpb24gaXNJbWFnZUJpdG1hcChlbGVtZW50KSB7XG4gIHJldHVybiBvYmpDbGFzcyhlbGVtZW50KSA9PT0gJ1tvYmplY3QgSW1hZ2VCaXRtYXBdJztcbn07XG5cbm1vZHVsZS5leHBvcnRzLmxpbWl0ZXIgPSBmdW5jdGlvbiBsaW1pdGVyKGNvbmN1cnJlbmN5KSB7XG4gIHZhciBhY3RpdmUgPSAwLFxuICAgICAgcXVldWUgPSBbXTtcblxuICBmdW5jdGlvbiByb2xsKCkge1xuICAgIGlmIChhY3RpdmUgPCBjb25jdXJyZW5jeSAmJiBxdWV1ZS5sZW5ndGgpIHtcbiAgICAgIGFjdGl2ZSsrO1xuICAgICAgcXVldWUuc2hpZnQoKSgpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiBsaW1pdChmbikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBxdWV1ZS5wdXNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZm4oKS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgYWN0aXZlLS07XG4gICAgICAgICAgcm9sbCgpO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgYWN0aXZlLS07XG4gICAgICAgICAgcm9sbCgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgcm9sbCgpO1xuICAgIH0pO1xuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMuY2liX3F1YWxpdHlfbmFtZSA9IGZ1bmN0aW9uIGNpYl9xdWFsaXR5X25hbWUobnVtKSB7XG4gIHN3aXRjaCAobnVtKSB7XG4gICAgY2FzZSAwOlxuICAgICAgcmV0dXJuICdwaXhlbGF0ZWQnO1xuXG4gICAgY2FzZSAxOlxuICAgICAgcmV0dXJuICdsb3cnO1xuXG4gICAgY2FzZSAyOlxuICAgICAgcmV0dXJuICdtZWRpdW0nO1xuICB9XG5cbiAgcmV0dXJuICdoaWdoJztcbn07XG5cbm1vZHVsZS5leHBvcnRzLmNpYl9zdXBwb3J0ID0gZnVuY3Rpb24gY2liX3N1cHBvcnQoY3JlYXRlQ2FudmFzKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodHlwZW9mIGNyZWF0ZUltYWdlQml0bWFwID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBjID0gY3JlYXRlQ2FudmFzKDEwMCwgMTAwKTtcbiAgICByZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAoYywgMCwgMCwgMTAwLCAxMDAsIHtcbiAgICAgIHJlc2l6ZVdpZHRoOiAxMCxcbiAgICAgIHJlc2l6ZUhlaWdodDogMTAsXG4gICAgICByZXNpemVRdWFsaXR5OiAnaGlnaCdcbiAgICB9KS50aGVuKGZ1bmN0aW9uIChiaXRtYXApIHtcbiAgICAgIHZhciBzdGF0dXMgPSBiaXRtYXAud2lkdGggPT09IDEwOyAvLyBCcmFuY2ggYmVsb3cgaXMgZmlsdGVyZWQgb24gdXBwZXIgbGV2ZWwuIFdlIGRvIG5vdCBjYWxsIHJlc2l6ZVxuICAgICAgLy8gZGV0ZWN0aW9uIGZvciBiYXNpYyBJbWFnZUJpdG1hcC5cbiAgICAgIC8vXG4gICAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSW1hZ2VCaXRtYXBcbiAgICAgIC8vIG9sZCBDcm9tZSA1MSBoYXMgSW1hZ2VCaXRtYXAgd2l0aG91dCAuY2xvc2UoKS4gVGhlbiB0aGlzIGNvZGVcbiAgICAgIC8vIHdpbGwgdGhyb3cgYW5kIHJldHVybiAnZmFsc2UnIGFzIGV4cGVjdGVkLlxuICAgICAgLy9cblxuICAgICAgYml0bWFwLmNsb3NlKCk7XG4gICAgICBjID0gbnVsbDtcbiAgICAgIHJldHVybiBzdGF0dXM7XG4gICAgfSk7XG4gIH0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy53b3JrZXJfb2Zmc2NyZWVuX2NhbnZhc19zdXBwb3J0ID0gZnVuY3Rpb24gd29ya2VyX29mZnNjcmVlbl9jYW52YXNfc3VwcG9ydCgpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBpZiAodHlwZW9mIE9mZnNjcmVlbkNhbnZhcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIC8vIGlmIE9mZnNjcmVlbkNhbnZhcyBpcyBwcmVzZW50LCB3ZSBhc3N1bWUgYnJvd3NlciBzdXBwb3J0cyBXb3JrZXIgYW5kIGJ1aWx0LWluIFByb21pc2UgYXMgd2VsbFxuICAgICAgcmVzb2x2ZShmYWxzZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gd29ya2VyUGF5bG9hZChzZWxmKSB7XG4gICAgICBpZiAodHlwZW9mIGNyZWF0ZUltYWdlQml0bWFwID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBzZWxmLnBvc3RNZXNzYWdlKGZhbHNlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNhbnZhcyA9IG5ldyBPZmZzY3JlZW5DYW52YXMoMTAsIDEwKTsgLy8gdGVzdCB0aGF0IDJkIGNvbnRleHQgY2FuIGJlIHVzZWQgaW4gd29ya2VyXG5cbiAgICAgICAgdmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgICBjdHgucmVjdCgwLCAwLCAxLCAxKTsgLy8gdGVzdCB0aGF0IGNpYiBjYW4gYmUgdXNlZCB0byByZXR1cm4gaW1hZ2UgYml0bWFwIGZyb20gd29ya2VyXG5cbiAgICAgICAgcmV0dXJuIGNyZWF0ZUltYWdlQml0bWFwKGNhbnZhcywgMCwgMCwgMSwgMSk7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYucG9zdE1lc3NhZ2UodHJ1ZSk7XG4gICAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBzZWxmLnBvc3RNZXNzYWdlKGZhbHNlKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHZhciBjb2RlID0gYnRvYShcIihcIi5jb25jYXQod29ya2VyUGF5bG9hZC50b1N0cmluZygpLCBcIikoc2VsZik7XCIpKTtcbiAgICB2YXIgdyA9IG5ldyBXb3JrZXIoXCJkYXRhOnRleHQvamF2YXNjcmlwdDtiYXNlNjQsXCIuY29uY2F0KGNvZGUpKTtcblxuICAgIHcub25tZXNzYWdlID0gZnVuY3Rpb24gKGV2KSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZShldi5kYXRhKTtcbiAgICB9O1xuXG4gICAgdy5vbmVycm9yID0gcmVqZWN0O1xuICB9KS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9KTtcbn07IC8vIENoZWNrIGlmIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpLmdldEltYWdlRGF0YSBjYW4gYmUgdXNlZCxcbi8vIEZpcmVGb3ggcmFuZG9taXplcyB0aGUgb3V0cHV0IG9mIHRoYXQgZnVuY3Rpb24gaW4gYHByaXZhY3kucmVzaXN0RmluZ2VycHJpbnRpbmdgIG1vZGVcblxuXG5tb2R1bGUuZXhwb3J0cy5jYW5fdXNlX2NhbnZhcyA9IGZ1bmN0aW9uIGNhbl91c2VfY2FudmFzKGNyZWF0ZUNhbnZhcykge1xuICB2YXIgdXNhYmxlID0gZmFsc2U7XG5cbiAgdHJ5IHtcbiAgICB2YXIgY2FudmFzID0gY3JlYXRlQ2FudmFzKDIsIDEpO1xuICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICB2YXIgZCA9IGN0eC5jcmVhdGVJbWFnZURhdGEoMiwgMSk7XG4gICAgZC5kYXRhWzBdID0gMTI7XG4gICAgZC5kYXRhWzFdID0gMjM7XG4gICAgZC5kYXRhWzJdID0gMzQ7XG4gICAgZC5kYXRhWzNdID0gMjU1O1xuICAgIGQuZGF0YVs0XSA9IDQ1O1xuICAgIGQuZGF0YVs1XSA9IDU2O1xuICAgIGQuZGF0YVs2XSA9IDY3O1xuICAgIGQuZGF0YVs3XSA9IDI1NTtcbiAgICBjdHgucHV0SW1hZ2VEYXRhKGQsIDAsIDApO1xuICAgIGQgPSBudWxsO1xuICAgIGQgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIDIsIDEpO1xuXG4gICAgaWYgKGQuZGF0YVswXSA9PT0gMTIgJiYgZC5kYXRhWzFdID09PSAyMyAmJiBkLmRhdGFbMl0gPT09IDM0ICYmIGQuZGF0YVszXSA9PT0gMjU1ICYmIGQuZGF0YVs0XSA9PT0gNDUgJiYgZC5kYXRhWzVdID09PSA1NiAmJiBkLmRhdGFbNl0gPT09IDY3ICYmIGQuZGF0YVs3XSA9PT0gMjU1KSB7XG4gICAgICB1c2FibGUgPSB0cnVlO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7fVxuXG4gIHJldHVybiB1c2FibGU7XG59OyAvLyBDaGVjayBpZiBjcmVhdGVJbWFnZUJpdG1hcChpbWcsIHN4LCBzeSwgc3csIHNoKSBzaWduYXR1cmUgd29ya3MgY29ycmVjdGx5XG4vLyB3aXRoIEpQRUcgaW1hZ2VzIG9yaWVudGVkIHdpdGggRXhpZjtcbi8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTEyMjA2NzFcbi8vIFRPRE86IHJlbW92ZSBhZnRlciBpdCdzIGZpeGVkIGluIGNocm9tZSBmb3IgYXQgbGVhc3QgMiByZWxlYXNlc1xuXG5cbm1vZHVsZS5leHBvcnRzLmNpYl9jYW5fdXNlX3JlZ2lvbiA9IGZ1bmN0aW9uIGNpYl9jYW5fdXNlX3JlZ2lvbigpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgaWYgKHR5cGVvZiBjcmVhdGVJbWFnZUJpdG1hcCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBpbWFnZSA9IG5ldyBJbWFnZSgpO1xuICAgIGltYWdlLnNyYyA9ICdkYXRhOmltYWdlL2pwZWc7YmFzZTY0LCcgKyAnLzlqLzRRQmlSWGhwWmdBQVRVMEFLZ0FBQUFnQUJRRVNBQU1BQUFBQkFBWUFBQUVhQUFVQUFBQUJBQUFBU2dFYkFBVUFBJyArICdBQUJBQUFBVWdFb0FBTUFBQUFCQUFJQUFBSVRBQU1BQUFBQkFBRUFBQUFBQUFBQUFBQklBQUFBQVFBQUFFZ0FBQUFCLzknICsgJ3NBUXdBRUF3TUVBd01FQkFNRUJRUUVCUVlLQndZR0JnWU5DUW9JQ2c4TkVCQVBEUThPRVJNWUZCRVNGeElPRHhVY0ZSYycgKyAnWkdSc2JHeEFVSFI4ZEdoOFlHaHNhLzlzQVF3RUVCUVVHQlFZTUJ3Y01HaEVQRVJvYUdob2FHaG9hR2hvYUdob2FHaG9hJyArICdHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYUdob2FHaG9hR2hvYS84SUFFUWdBQVFBQ0F3RVJBQUlSQVFNUkEnICsgJ2YvRUFCUUFBUUFBQUFBQUFBQUFBQUFBQUFBQUFBZi94QUFVQVFFQUFBQUFBQUFBQUFBQUFBQUFBQUFBLzlvQURBTUJBQScgKyAnSVFBeEFBQUFGL1AvL0VBQlFRQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUQvMmdBSUFRRUFBUVVDZi8vRUFCUVJBUUFBQUFBJyArICdBQUFBQUFBQUFBQUFBQUFELzJnQUlBUU1CQVQ4QmYvL0VBQlFSQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUQvMmdBSUFRSUInICsgJ0FUOEJmLy9FQUJRUUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFELzJnQUlBUUVBQmo4Q2YvL0VBQlFRQVFBQUFBQUFBQUFBQScgKyAnQUFBQUFBQUFBRC8yZ0FJQVFFQUFUOGhmLy9hQUF3REFRQUNBQU1BQUFBUUgvL0VBQlFSQVFBQUFBQUFBQUFBQUFBQUFBJyArICdBQUFBRC8yZ0FJQVFNQkFUOFFmLy9FQUJRUkFRQUFBQUFBQUFBQUFBQUFBQUFBQUFELzJnQUlBUUlCQVQ4UWYvL0VBQlEnICsgJ1FBUUFBQUFBQUFBQUFBQUFBQUFBQUFBRC8yZ0FJQVFFQUFUOFFmLy9aJztcblxuICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGNyZWF0ZUltYWdlQml0bWFwKGltYWdlLCAwLCAwLCBpbWFnZS53aWR0aCwgaW1hZ2UuaGVpZ2h0KS50aGVuKGZ1bmN0aW9uIChiaXRtYXApIHtcbiAgICAgICAgaWYgKGJpdG1hcC53aWR0aCA9PT0gaW1hZ2Uud2lkdGggJiYgYml0bWFwLmhlaWdodCA9PT0gaW1hZ2UuaGVpZ2h0KSB7XG4gICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShmYWxzZSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgaW1hZ2Uub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiByZXNvbHZlKGZhbHNlKTtcbiAgICB9O1xuICB9KTtcbn07XG5cbn0se31dLDE3OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBNYXRoTGliID0gX2RlcmVxXygnLi9tYXRobGliJyk7XG5cbiAgdmFyIG1hdGhMaWI7XG4gIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG5cbiAgb25tZXNzYWdlID0gZnVuY3Rpb24gb25tZXNzYWdlKGV2KSB7XG4gICAgdmFyIHRpbGVPcHRzID0gZXYuZGF0YS5vcHRzO1xuICAgIHZhciByZXR1cm5CaXRtYXAgPSBmYWxzZTtcblxuICAgIGlmICghdGlsZU9wdHMuc3JjICYmIHRpbGVPcHRzLnNyY0JpdG1hcCkge1xuICAgICAgdmFyIGNhbnZhcyA9IG5ldyBPZmZzY3JlZW5DYW52YXModGlsZU9wdHMud2lkdGgsIHRpbGVPcHRzLmhlaWdodCk7XG4gICAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJywge1xuICAgICAgICBhbHBoYTogQm9vbGVhbih0aWxlT3B0cy5hbHBoYSlcbiAgICAgIH0pO1xuICAgICAgY3R4LmRyYXdJbWFnZSh0aWxlT3B0cy5zcmNCaXRtYXAsIDAsIDApO1xuICAgICAgdGlsZU9wdHMuc3JjID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCB0aWxlT3B0cy53aWR0aCwgdGlsZU9wdHMuaGVpZ2h0KS5kYXRhO1xuICAgICAgY2FudmFzLndpZHRoID0gY2FudmFzLmhlaWdodCA9IDA7XG4gICAgICBjYW52YXMgPSBudWxsO1xuICAgICAgdGlsZU9wdHMuc3JjQml0bWFwLmNsb3NlKCk7XG4gICAgICB0aWxlT3B0cy5zcmNCaXRtYXAgPSBudWxsO1xuICAgICAgcmV0dXJuQml0bWFwID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoIW1hdGhMaWIpIG1hdGhMaWIgPSBuZXcgTWF0aExpYihldi5kYXRhLmZlYXR1cmVzKTsgLy8gVXNlIG11bHRpbWF0aCdzIHN5bmMgYXV0by1pbml0LiBBdm9pZCBQcm9taXNlIHVzZSBpbiBvbGQgYnJvd3NlcnMsXG4gICAgLy8gYmVjYXVzZSBwb2x5ZmlsbHMgYXJlIG5vdCBwcm9wYWdhdGVkIHRvIHdlYndvcmtlci5cblxuICAgIHZhciBkYXRhID0gbWF0aExpYi5yZXNpemVBbmRVbnNoYXJwKHRpbGVPcHRzKTtcblxuICAgIGlmIChyZXR1cm5CaXRtYXApIHtcbiAgICAgIHZhciB0b0ltYWdlRGF0YSA9IG5ldyBJbWFnZURhdGEobmV3IFVpbnQ4Q2xhbXBlZEFycmF5KGRhdGEpLCB0aWxlT3B0cy50b1dpZHRoLCB0aWxlT3B0cy50b0hlaWdodCk7XG5cbiAgICAgIHZhciBfY2FudmFzID0gbmV3IE9mZnNjcmVlbkNhbnZhcyh0aWxlT3B0cy50b1dpZHRoLCB0aWxlT3B0cy50b0hlaWdodCk7XG5cbiAgICAgIHZhciBfY3R4ID0gX2NhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICAgICAgYWxwaGE6IEJvb2xlYW4odGlsZU9wdHMuYWxwaGEpXG4gICAgICB9KTtcblxuICAgICAgX2N0eC5wdXRJbWFnZURhdGEodG9JbWFnZURhdGEsIDAsIDApO1xuXG4gICAgICBjcmVhdGVJbWFnZUJpdG1hcChfY2FudmFzKS50aGVuKGZ1bmN0aW9uIChiaXRtYXApIHtcbiAgICAgICAgcG9zdE1lc3NhZ2Uoe1xuICAgICAgICAgIGJpdG1hcDogYml0bWFwXG4gICAgICAgIH0sIFtiaXRtYXBdKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBwb3N0TWVzc2FnZSh7XG4gICAgICAgIGRhdGE6IGRhdGFcbiAgICAgIH0sIFtkYXRhLmJ1ZmZlcl0pO1xuICAgIH1cbiAgfTtcbn07XG5cbn0se1wiLi9tYXRobGliXCI6MX1dLDE4OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8vIENhbGN1bGF0ZSBHYXVzc2lhbiBibHVyIG9mIGFuIGltYWdlIHVzaW5nIElJUiBmaWx0ZXJcbi8vIFRoZSBtZXRob2QgaXMgdGFrZW4gZnJvbSBJbnRlbCdzIHdoaXRlIHBhcGVyIGFuZCBjb2RlIGV4YW1wbGUgYXR0YWNoZWQgdG8gaXQ6XG4vLyBodHRwczovL3NvZnR3YXJlLmludGVsLmNvbS9lbi11cy9hcnRpY2xlcy9paXItZ2F1c3NpYW4tYmx1ci1maWx0ZXJcbi8vIC1pbXBsZW1lbnRhdGlvbi11c2luZy1pbnRlbC1hZHZhbmNlZC12ZWN0b3ItZXh0ZW5zaW9uc1xuXG52YXIgYTAsIGExLCBhMiwgYTMsIGIxLCBiMiwgbGVmdF9jb3JuZXIsIHJpZ2h0X2Nvcm5lcjtcblxuZnVuY3Rpb24gZ2F1c3NDb2VmKHNpZ21hKSB7XG4gIGlmIChzaWdtYSA8IDAuNSkge1xuICAgIHNpZ21hID0gMC41O1xuICB9XG5cbiAgdmFyIGEgPSBNYXRoLmV4cCgwLjcyNiAqIDAuNzI2KSAvIHNpZ21hLFxuICAgICAgZzEgPSBNYXRoLmV4cCgtYSksXG4gICAgICBnMiA9IE1hdGguZXhwKC0yICogYSksXG4gICAgICBrID0gKDEgLSBnMSkgKiAoMSAtIGcxKSAvICgxICsgMiAqIGEgKiBnMSAtIGcyKTtcblxuICBhMCA9IGs7XG4gIGExID0gayAqIChhIC0gMSkgKiBnMTtcbiAgYTIgPSBrICogKGEgKyAxKSAqIGcxO1xuICBhMyA9IC1rICogZzI7XG4gIGIxID0gMiAqIGcxO1xuICBiMiA9IC1nMjtcbiAgbGVmdF9jb3JuZXIgPSAoYTAgKyBhMSkgLyAoMSAtIGIxIC0gYjIpO1xuICByaWdodF9jb3JuZXIgPSAoYTIgKyBhMykgLyAoMSAtIGIxIC0gYjIpO1xuXG4gIC8vIEF0dGVtcHQgdG8gZm9yY2UgdHlwZSB0byBGUDMyLlxuICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShbIGEwLCBhMSwgYTIsIGEzLCBiMSwgYjIsIGxlZnRfY29ybmVyLCByaWdodF9jb3JuZXIgXSk7XG59XG5cbmZ1bmN0aW9uIGNvbnZvbHZlTW9ubzE2KHNyYywgb3V0LCBsaW5lLCBjb2VmZiwgd2lkdGgsIGhlaWdodCkge1xuICAvLyB0YWtlcyBzcmMgaW1hZ2UgYW5kIHdyaXRlcyB0aGUgYmx1cnJlZCBhbmQgdHJhbnNwb3NlZCByZXN1bHQgaW50byBvdXRcblxuICB2YXIgcHJldl9zcmMsIGN1cnJfc3JjLCBjdXJyX291dCwgcHJldl9vdXQsIHByZXZfcHJldl9vdXQ7XG4gIHZhciBzcmNfaW5kZXgsIG91dF9pbmRleCwgbGluZV9pbmRleDtcbiAgdmFyIGksIGo7XG4gIHZhciBjb2VmZl9hMCwgY29lZmZfYTEsIGNvZWZmX2IxLCBjb2VmZl9iMjtcblxuICBmb3IgKGkgPSAwOyBpIDwgaGVpZ2h0OyBpKyspIHtcbiAgICBzcmNfaW5kZXggPSBpICogd2lkdGg7XG4gICAgb3V0X2luZGV4ID0gaTtcbiAgICBsaW5lX2luZGV4ID0gMDtcblxuICAgIC8vIGxlZnQgdG8gcmlnaHRcbiAgICBwcmV2X3NyYyA9IHNyY1tzcmNfaW5kZXhdO1xuICAgIHByZXZfcHJldl9vdXQgPSBwcmV2X3NyYyAqIGNvZWZmWzZdO1xuICAgIHByZXZfb3V0ID0gcHJldl9wcmV2X291dDtcblxuICAgIGNvZWZmX2EwID0gY29lZmZbMF07XG4gICAgY29lZmZfYTEgPSBjb2VmZlsxXTtcbiAgICBjb2VmZl9iMSA9IGNvZWZmWzRdO1xuICAgIGNvZWZmX2IyID0gY29lZmZbNV07XG5cbiAgICBmb3IgKGogPSAwOyBqIDwgd2lkdGg7IGorKykge1xuICAgICAgY3Vycl9zcmMgPSBzcmNbc3JjX2luZGV4XTtcblxuICAgICAgY3Vycl9vdXQgPSBjdXJyX3NyYyAqIGNvZWZmX2EwICtcbiAgICAgICAgICAgICAgICAgcHJldl9zcmMgKiBjb2VmZl9hMSArXG4gICAgICAgICAgICAgICAgIHByZXZfb3V0ICogY29lZmZfYjEgK1xuICAgICAgICAgICAgICAgICBwcmV2X3ByZXZfb3V0ICogY29lZmZfYjI7XG5cbiAgICAgIHByZXZfcHJldl9vdXQgPSBwcmV2X291dDtcbiAgICAgIHByZXZfb3V0ID0gY3Vycl9vdXQ7XG4gICAgICBwcmV2X3NyYyA9IGN1cnJfc3JjO1xuXG4gICAgICBsaW5lW2xpbmVfaW5kZXhdID0gcHJldl9vdXQ7XG4gICAgICBsaW5lX2luZGV4Kys7XG4gICAgICBzcmNfaW5kZXgrKztcbiAgICB9XG5cbiAgICBzcmNfaW5kZXgtLTtcbiAgICBsaW5lX2luZGV4LS07XG4gICAgb3V0X2luZGV4ICs9IGhlaWdodCAqICh3aWR0aCAtIDEpO1xuXG4gICAgLy8gcmlnaHQgdG8gbGVmdFxuICAgIHByZXZfc3JjID0gc3JjW3NyY19pbmRleF07XG4gICAgcHJldl9wcmV2X291dCA9IHByZXZfc3JjICogY29lZmZbN107XG4gICAgcHJldl9vdXQgPSBwcmV2X3ByZXZfb3V0O1xuICAgIGN1cnJfc3JjID0gcHJldl9zcmM7XG5cbiAgICBjb2VmZl9hMCA9IGNvZWZmWzJdO1xuICAgIGNvZWZmX2ExID0gY29lZmZbM107XG5cbiAgICBmb3IgKGogPSB3aWR0aCAtIDE7IGogPj0gMDsgai0tKSB7XG4gICAgICBjdXJyX291dCA9IGN1cnJfc3JjICogY29lZmZfYTAgK1xuICAgICAgICAgICAgICAgICBwcmV2X3NyYyAqIGNvZWZmX2ExICtcbiAgICAgICAgICAgICAgICAgcHJldl9vdXQgKiBjb2VmZl9iMSArXG4gICAgICAgICAgICAgICAgIHByZXZfcHJldl9vdXQgKiBjb2VmZl9iMjtcblxuICAgICAgcHJldl9wcmV2X291dCA9IHByZXZfb3V0O1xuICAgICAgcHJldl9vdXQgPSBjdXJyX291dDtcblxuICAgICAgcHJldl9zcmMgPSBjdXJyX3NyYztcbiAgICAgIGN1cnJfc3JjID0gc3JjW3NyY19pbmRleF07XG5cbiAgICAgIG91dFtvdXRfaW5kZXhdID0gbGluZVtsaW5lX2luZGV4XSArIHByZXZfb3V0O1xuXG4gICAgICBzcmNfaW5kZXgtLTtcbiAgICAgIGxpbmVfaW5kZXgtLTtcbiAgICAgIG91dF9pbmRleCAtPSBoZWlnaHQ7XG4gICAgfVxuICB9XG59XG5cblxuZnVuY3Rpb24gYmx1ck1vbm8xNihzcmMsIHdpZHRoLCBoZWlnaHQsIHJhZGl1cykge1xuICAvLyBRdWljayBleGl0IG9uIHplcm8gcmFkaXVzXG4gIGlmICghcmFkaXVzKSB7IHJldHVybjsgfVxuXG4gIHZhciBvdXQgICAgICA9IG5ldyBVaW50MTZBcnJheShzcmMubGVuZ3RoKSxcbiAgICAgIHRtcF9saW5lID0gbmV3IEZsb2F0MzJBcnJheShNYXRoLm1heCh3aWR0aCwgaGVpZ2h0KSk7XG5cbiAgdmFyIGNvZWZmID0gZ2F1c3NDb2VmKHJhZGl1cyk7XG5cbiAgY29udm9sdmVNb25vMTYoc3JjLCBvdXQsIHRtcF9saW5lLCBjb2VmZiwgd2lkdGgsIGhlaWdodCk7XG4gIGNvbnZvbHZlTW9ubzE2KG91dCwgc3JjLCB0bXBfbGluZSwgY29lZmYsIGhlaWdodCwgd2lkdGgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJsdXJNb25vMTY7XG5cbn0se31dLDE5OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbmlmICh0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyBpbXBsZW1lbnRhdGlvbiBmcm9tIHN0YW5kYXJkIG5vZGUuanMgJ3V0aWwnIG1vZHVsZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yO1xuICAgICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcbiAgICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvcjtcbiAgICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZTtcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKCk7XG4gICAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3I7XG4gICAgfVxuICB9O1xufVxuXG59LHt9XSwyMDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cblxudmFyIGFzc2lnbiAgICAgICAgID0gX2RlcmVxXygnb2JqZWN0LWFzc2lnbicpO1xudmFyIGJhc2U2NGRlY29kZSAgID0gX2RlcmVxXygnLi9saWIvYmFzZTY0ZGVjb2RlJyk7XG52YXIgaGFzV2ViQXNzZW1ibHkgPSBfZGVyZXFfKCcuL2xpYi93YV9kZXRlY3QnKTtcblxuXG52YXIgREVGQVVMVF9PUFRJT05TID0ge1xuICBqczogdHJ1ZSxcbiAgd2FzbTogdHJ1ZVxufTtcblxuXG5mdW5jdGlvbiBNdWx0aU1hdGgob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTXVsdGlNYXRoKSkgcmV0dXJuIG5ldyBNdWx0aU1hdGgob3B0aW9ucyk7XG5cbiAgdmFyIG9wdHMgPSBhc3NpZ24oe30sIERFRkFVTFRfT1BUSU9OUywgb3B0aW9ucyB8fCB7fSk7XG5cbiAgdGhpcy5vcHRpb25zICAgICAgICAgPSBvcHRzO1xuXG4gIHRoaXMuX19jYWNoZSAgICAgICAgID0ge307XG5cbiAgdGhpcy5fX2luaXRfcHJvbWlzZSAgPSBudWxsO1xuICB0aGlzLl9fbW9kdWxlcyAgICAgICA9IG9wdHMubW9kdWxlcyB8fCB7fTtcbiAgdGhpcy5fX21lbW9yeSAgICAgICAgPSBudWxsO1xuICB0aGlzLl9fd2FzbSAgICAgICAgICA9IHt9O1xuXG4gIHRoaXMuX19pc0xFID0gKChuZXcgVWludDMyQXJyYXkoKG5ldyBVaW50OEFycmF5KFsgMSwgMCwgMCwgMCBdKSkuYnVmZmVyKSlbMF0gPT09IDEpO1xuXG4gIGlmICghdGhpcy5vcHRpb25zLmpzICYmICF0aGlzLm9wdGlvbnMud2FzbSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbWF0aGxpYjogYXQgbGVhc3QgXCJqc1wiIG9yIFwid2FzbVwiIHNob3VsZCBiZSBlbmFibGVkJyk7XG4gIH1cbn1cblxuXG5NdWx0aU1hdGgucHJvdG90eXBlLmhhc193YXNtID0gaGFzV2ViQXNzZW1ibHk7XG5cblxuTXVsdGlNYXRoLnByb3RvdHlwZS51c2UgPSBmdW5jdGlvbiAobW9kdWxlKSB7XG4gIHRoaXMuX19tb2R1bGVzW21vZHVsZS5uYW1lXSA9IG1vZHVsZTtcblxuICAvLyBQaW4gdGhlIGJlc3QgcG9zc2libGUgaW1wbGVtZW50YXRpb25cbiAgaWYgKHRoaXMub3B0aW9ucy53YXNtICYmIHRoaXMuaGFzX3dhc20oKSAmJiBtb2R1bGUud2FzbV9mbikge1xuICAgIHRoaXNbbW9kdWxlLm5hbWVdID0gbW9kdWxlLndhc21fZm47XG4gIH0gZWxzZSB7XG4gICAgdGhpc1ttb2R1bGUubmFtZV0gPSBtb2R1bGUuZm47XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cblxuTXVsdGlNYXRoLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5fX2luaXRfcHJvbWlzZSkgcmV0dXJuIHRoaXMuX19pbml0X3Byb21pc2U7XG5cbiAgaWYgKCF0aGlzLm9wdGlvbnMuanMgJiYgdGhpcy5vcHRpb25zLndhc20gJiYgIXRoaXMuaGFzX3dhc20oKSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ21hdGhsaWI6IG9ubHkgXCJ3YXNtXCIgd2FzIGVuYWJsZWQsIGJ1dCBpdFxcJ3Mgbm90IHN1cHBvcnRlZCcpKTtcbiAgfVxuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLl9faW5pdF9wcm9taXNlID0gUHJvbWlzZS5hbGwoT2JqZWN0LmtleXMoc2VsZi5fX21vZHVsZXMpLm1hcChmdW5jdGlvbiAobmFtZSkge1xuICAgIHZhciBtb2R1bGUgPSBzZWxmLl9fbW9kdWxlc1tuYW1lXTtcblxuICAgIGlmICghc2VsZi5vcHRpb25zLndhc20gfHwgIXNlbGYuaGFzX3dhc20oKSB8fCAhbW9kdWxlLndhc21fZm4pIHJldHVybiBudWxsO1xuXG4gICAgLy8gSWYgYWxyZWFkeSBjb21waWxlZCAtIGV4aXRcbiAgICBpZiAoc2VsZi5fX3dhc21bbmFtZV0pIHJldHVybiBudWxsO1xuXG4gICAgLy8gQ29tcGlsZSB3YXNtIHNvdXJjZVxuICAgIHJldHVybiBXZWJBc3NlbWJseS5jb21waWxlKHNlbGYuX19iYXNlNjRkZWNvZGUobW9kdWxlLndhc21fc3JjKSlcbiAgICAgIC50aGVuKGZ1bmN0aW9uIChtKSB7IHNlbGYuX193YXNtW25hbWVdID0gbTsgfSk7XG4gIH0pKVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlbGY7IH0pO1xuXG4gIHJldHVybiB0aGlzLl9faW5pdF9wcm9taXNlO1xufTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gTWV0aG9kcyBiZWxvdyBhcmUgZm9yIGludGVybmFsIHVzZSBmcm9tIHBsdWdpbnNcblxuXG4vLyBTaW1wbGUgZGVjb2RlIGJhc2U2NCB0byB0eXBlZCBhcnJheS4gVXNlZnVsIHRvIGxvYWQgZW1iZWRkZWQgd2ViYXNzZW1ibHlcbi8vIGNvZGUuIFlvdSBwcm9iYWJseSBkb24ndCBuZWVkIHRvIGNhbGwgdGhpcyBtZXRob2QgZGlyZWN0bHkuXG4vL1xuTXVsdGlNYXRoLnByb3RvdHlwZS5fX2Jhc2U2NGRlY29kZSA9IGJhc2U2NGRlY29kZTtcblxuXG4vLyBJbmNyZWFzZSBjdXJyZW50IG1lbW9yeSB0byBpbmNsdWRlIHNwZWNpZmllZCBudW1iZXIgb2YgYnl0ZXMuIERvIG5vdGhpbmcgaWZcbi8vIHNpemUgaXMgYWxyZWFkeSBvay4gWW91IHByb2JhYmx5IGRvbid0IG5lZWQgdG8gY2FsbCB0aGlzIG1ldGhvZCBkaXJlY3RseSxcbi8vIGJlY2F1c2UgaXQgd2lsbCBiZSBpbnZva2VkIGZyb20gYC5fX2luc3RhbmNlKClgLlxuLy9cbk11bHRpTWF0aC5wcm90b3R5cGUuX19yZWFsbG9jYXRlID0gZnVuY3Rpb24gbWVtX2dyb3dfdG8oYnl0ZXMpIHtcbiAgaWYgKCF0aGlzLl9fbWVtb3J5KSB7XG4gICAgdGhpcy5fX21lbW9yeSA9IG5ldyBXZWJBc3NlbWJseS5NZW1vcnkoe1xuICAgICAgaW5pdGlhbDogTWF0aC5jZWlsKGJ5dGVzIC8gKDY0ICogMTAyNCkpXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMuX19tZW1vcnk7XG4gIH1cblxuICB2YXIgbWVtX3NpemUgPSB0aGlzLl9fbWVtb3J5LmJ1ZmZlci5ieXRlTGVuZ3RoO1xuXG4gIGlmIChtZW1fc2l6ZSA8IGJ5dGVzKSB7XG4gICAgdGhpcy5fX21lbW9yeS5ncm93KE1hdGguY2VpbCgoYnl0ZXMgLSBtZW1fc2l6ZSkgLyAoNjQgKiAxMDI0KSkpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX19tZW1vcnk7XG59O1xuXG5cbi8vIFJldHVybnMgaW5zdGFudGluYXRlZCB3ZWJhc3NlbWJseSBpdGVtIGJ5IG5hbWUsIHdpdGggc3BlY2lmaWVkIG1lbW9yeSBzaXplXG4vLyBhbmQgZW52aXJvbm1lbnQuXG4vLyAtIHVzZSBjYWNoZSBpZiBhdmFpbGFibGVcbi8vIC0gZG8gc3luYyBtb2R1bGUgaW5pdCwgaWYgYXN5bmMgaW5pdCB3YXMgbm90IGNhbGxlZCBlYXJsaWVyXG4vLyAtIGFsbG9jYXRlIG1lbW9yeSBpZiBub3QgZW5vdWd0aFxuLy8gLSBjYW4gZXhwb3J0IGZ1bmN0aW9ucyB0byB3ZWJhc3NlbWJseSB2aWEgXCJlbnZfZXh0cmFcIixcbi8vICAgZm9yIGV4YW1wbGUsIHsgZXhwOiBNYXRoLmV4cCB9XG4vL1xuTXVsdGlNYXRoLnByb3RvdHlwZS5fX2luc3RhbmNlID0gZnVuY3Rpb24gaW5zdGFuY2UobmFtZSwgbWVtc2l6ZSwgZW52X2V4dHJhKSB7XG4gIGlmIChtZW1zaXplKSB0aGlzLl9fcmVhbGxvY2F0ZShtZW1zaXplKTtcblxuICAvLyBJZiAuaW5pdCgpIHdhcyBub3QgY2FsbGVkLCBkbyBzeW5jIGNvbXBpbGVcbiAgaWYgKCF0aGlzLl9fd2FzbVtuYW1lXSkge1xuICAgIHZhciBtb2R1bGUgPSB0aGlzLl9fbW9kdWxlc1tuYW1lXTtcbiAgICB0aGlzLl9fd2FzbVtuYW1lXSA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUodGhpcy5fX2Jhc2U2NGRlY29kZShtb2R1bGUud2FzbV9zcmMpKTtcbiAgfVxuXG4gIGlmICghdGhpcy5fX2NhY2hlW25hbWVdKSB7XG4gICAgdmFyIGVudl9iYXNlID0ge1xuICAgICAgbWVtb3J5QmFzZTogMCxcbiAgICAgIG1lbW9yeTogdGhpcy5fX21lbW9yeSxcbiAgICAgIHRhYmxlQmFzZTogMCxcbiAgICAgIHRhYmxlOiBuZXcgV2ViQXNzZW1ibHkuVGFibGUoeyBpbml0aWFsOiAwLCBlbGVtZW50OiAnYW55ZnVuYycgfSlcbiAgICB9O1xuXG4gICAgdGhpcy5fX2NhY2hlW25hbWVdID0gbmV3IFdlYkFzc2VtYmx5Lkluc3RhbmNlKHRoaXMuX193YXNtW25hbWVdLCB7XG4gICAgICBlbnY6IGFzc2lnbihlbnZfYmFzZSwgZW52X2V4dHJhIHx8IHt9KVxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX19jYWNoZVtuYW1lXTtcbn07XG5cblxuLy8gSGVscGVyIHRvIGNhbGN1bGF0ZSBtZW1vcnkgYWxpZ2ggZm9yIHBvaW50ZXJzLiBXZWJhc3NlbWJseSBkb2VzIG5vdCByZXF1aXJlXG4vLyB0aGlzLCBidXQgeW91IG1heSB3aXNoIHRvIGV4cGVyaW1lbnQuIERlZmF1bHQgYmFzZSA9IDg7XG4vL1xuTXVsdGlNYXRoLnByb3RvdHlwZS5fX2FsaWduID0gZnVuY3Rpb24gYWxpZ24obnVtYmVyLCBiYXNlKSB7XG4gIGJhc2UgPSBiYXNlIHx8IDg7XG4gIHZhciByZW1pbmRlciA9IG51bWJlciAlIGJhc2U7XG4gIHJldHVybiBudW1iZXIgKyAocmVtaW5kZXIgPyBiYXNlIC0gcmVtaW5kZXIgOiAwKTtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBNdWx0aU1hdGg7XG5cbn0se1wiLi9saWIvYmFzZTY0ZGVjb2RlXCI6MjEsXCIuL2xpYi93YV9kZXRlY3RcIjoyMixcIm9iamVjdC1hc3NpZ25cIjoyM31dLDIxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxuXG52YXIgQkFTRTY0X01BUCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJztcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGJhc2U2NGRlY29kZShzdHIpIHtcbiAgdmFyIGlucHV0ID0gc3RyLnJlcGxhY2UoL1tcXHJcXG49XS9nLCAnJyksIC8vIHJlbW92ZSBDUi9MRiAmIHBhZGRpbmcgdG8gc2ltcGxpZnkgc2NhblxuICAgICAgbWF4ICAgPSBpbnB1dC5sZW5ndGg7XG5cbiAgdmFyIG91dCA9IG5ldyBVaW50OEFycmF5KChtYXggKiAzKSA+PiAyKTtcblxuICAvLyBDb2xsZWN0IGJ5IDYqNCBiaXRzICgzIGJ5dGVzKVxuXG4gIHZhciBiaXRzID0gMDtcbiAgdmFyIHB0ciAgPSAwO1xuXG4gIGZvciAodmFyIGlkeCA9IDA7IGlkeCA8IG1heDsgaWR4KyspIHtcbiAgICBpZiAoKGlkeCAlIDQgPT09IDApICYmIGlkeCkge1xuICAgICAgb3V0W3B0cisrXSA9IChiaXRzID4+IDE2KSAmIDB4RkY7XG4gICAgICBvdXRbcHRyKytdID0gKGJpdHMgPj4gOCkgJiAweEZGO1xuICAgICAgb3V0W3B0cisrXSA9IGJpdHMgJiAweEZGO1xuICAgIH1cblxuICAgIGJpdHMgPSAoYml0cyA8PCA2KSB8IEJBU0U2NF9NQVAuaW5kZXhPZihpbnB1dC5jaGFyQXQoaWR4KSk7XG4gIH1cblxuICAvLyBEdW1wIHRhaWxcblxuICB2YXIgdGFpbGJpdHMgPSAobWF4ICUgNCkgKiA2O1xuXG4gIGlmICh0YWlsYml0cyA9PT0gMCkge1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAxNikgJiAweEZGO1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiA4KSAmIDB4RkY7XG4gICAgb3V0W3B0cisrXSA9IGJpdHMgJiAweEZGO1xuICB9IGVsc2UgaWYgKHRhaWxiaXRzID09PSAxOCkge1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAxMCkgJiAweEZGO1xuICAgIG91dFtwdHIrK10gPSAoYml0cyA+PiAyKSAmIDB4RkY7XG4gIH0gZWxzZSBpZiAodGFpbGJpdHMgPT09IDEyKSB7XG4gICAgb3V0W3B0cisrXSA9IChiaXRzID4+IDQpICYgMHhGRjtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59O1xuXG59LHt9XSwyMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG5cblxudmFyIHdhO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaGFzV2ViQXNzZW1ibHkoKSB7XG4gIC8vIHVzZSBjYWNoZSBpZiBjYWxsZWQgYmVmb3JlO1xuICBpZiAodHlwZW9mIHdhICE9PSAndW5kZWZpbmVkJykgcmV0dXJuIHdhO1xuXG4gIHdhID0gZmFsc2U7XG5cbiAgaWYgKHR5cGVvZiBXZWJBc3NlbWJseSA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiB3YTtcblxuICAvLyBJZiBXZWJBc3NlbmJseSBpcyBkaXNhYmxlZCwgY29kZSBjYW4gdGhyb3cgb24gY29tcGlsZVxuICB0cnkge1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9icmlvbi9taW4td2FzbS1mYWlsL2Jsb2IvbWFzdGVyL21pbi13YXNtLWZhaWwuaW4uanNcbiAgICAvLyBBZGRpdGlvbmFsIGNoZWNrIHRoYXQgV0EgaW50ZXJuYWxzIGFyZSBjb3JyZWN0XG5cbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBjb21tYS1zcGFjaW5nLCBtYXgtbGVuICovXG4gICAgdmFyIGJpbiAgICAgID0gbmV3IFVpbnQ4QXJyYXkoWyAwLDk3LDExNSwxMDksMSwwLDAsMCwxLDYsMSw5NiwxLDEyNywxLDEyNywzLDIsMSwwLDUsMywxLDAsMSw3LDgsMSw0LDExNiwxMDEsMTE1LDExNiwwLDAsMTAsMTYsMSwxNCwwLDMyLDAsNjUsMSw1NCwyLDAsMzIsMCw0MCwyLDAsMTEgXSk7XG4gICAgdmFyIG1vZHVsZSAgID0gbmV3IFdlYkFzc2VtYmx5Lk1vZHVsZShiaW4pO1xuICAgIHZhciBpbnN0YW5jZSA9IG5ldyBXZWJBc3NlbWJseS5JbnN0YW5jZShtb2R1bGUsIHt9KTtcblxuICAgIC8vIHRlc3Qgc3RvcmluZyB0byBhbmQgbG9hZGluZyBmcm9tIGEgbm9uLXplcm8gbG9jYXRpb24gdmlhIGEgcGFyYW1ldGVyLlxuICAgIC8vIFNhZmFyaSBvbiBpT1MgMTEuMi41IHJldHVybnMgMCB1bmV4cGVjdGVkbHkgYXQgbm9uLXplcm8gbG9jYXRpb25zXG4gICAgaWYgKGluc3RhbmNlLmV4cG9ydHMudGVzdCg0KSAhPT0gMCkgd2EgPSB0cnVlO1xuXG4gICAgcmV0dXJuIHdhO1xuICB9IGNhdGNoIChfXykge31cblxuICByZXR1cm4gd2E7XG59O1xuXG59LHt9XSwyMzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xudmFyIGdldE93blByb3BlcnR5U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIHByb3BJc0VudW1lcmFibGUgPSBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG5mdW5jdGlvbiB0b09iamVjdCh2YWwpIHtcblx0aWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IHVuZGVmaW5lZCkge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoJ09iamVjdC5hc3NpZ24gY2Fubm90IGJlIGNhbGxlZCB3aXRoIG51bGwgb3IgdW5kZWZpbmVkJyk7XG5cdH1cblxuXHRyZXR1cm4gT2JqZWN0KHZhbCk7XG59XG5cbmZ1bmN0aW9uIHNob3VsZFVzZU5hdGl2ZSgpIHtcblx0dHJ5IHtcblx0XHRpZiAoIU9iamVjdC5hc3NpZ24pIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBEZXRlY3QgYnVnZ3kgcHJvcGVydHkgZW51bWVyYXRpb24gb3JkZXIgaW4gb2xkZXIgVjggdmVyc2lvbnMuXG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD00MTE4XG5cdFx0dmFyIHRlc3QxID0gbmV3IFN0cmluZygnYWJjJyk7ICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ldy13cmFwcGVyc1xuXHRcdHRlc3QxWzVdID0gJ2RlJztcblx0XHRpZiAoT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGVzdDEpWzBdID09PSAnNScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMDU2XG5cdFx0dmFyIHRlc3QyID0ge307XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCAxMDsgaSsrKSB7XG5cdFx0XHR0ZXN0MlsnXycgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGkpXSA9IGk7XG5cdFx0fVxuXHRcdHZhciBvcmRlcjIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0ZXN0MikubWFwKGZ1bmN0aW9uIChuKSB7XG5cdFx0XHRyZXR1cm4gdGVzdDJbbl07XG5cdFx0fSk7XG5cdFx0aWYgKG9yZGVyMi5qb2luKCcnKSAhPT0gJzAxMjM0NTY3ODknKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzA1NlxuXHRcdHZhciB0ZXN0MyA9IHt9O1xuXHRcdCdhYmNkZWZnaGlqa2xtbm9wcXJzdCcuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24gKGxldHRlcikge1xuXHRcdFx0dGVzdDNbbGV0dGVyXSA9IGxldHRlcjtcblx0XHR9KTtcblx0XHRpZiAoT2JqZWN0LmtleXMoT2JqZWN0LmFzc2lnbih7fSwgdGVzdDMpKS5qb2luKCcnKSAhPT1cblx0XHRcdFx0J2FiY2RlZmdoaWprbG1ub3BxcnN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlcnIpIHtcblx0XHQvLyBXZSBkb24ndCBleHBlY3QgYW55IG9mIHRoZSBhYm92ZSB0byB0aHJvdywgYnV0IGJldHRlciB0byBiZSBzYWZlLlxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNob3VsZFVzZU5hdGl2ZSgpID8gT2JqZWN0LmFzc2lnbiA6IGZ1bmN0aW9uICh0YXJnZXQsIHNvdXJjZSkge1xuXHR2YXIgZnJvbTtcblx0dmFyIHRvID0gdG9PYmplY3QodGFyZ2V0KTtcblx0dmFyIHN5bWJvbHM7XG5cblx0Zm9yICh2YXIgcyA9IDE7IHMgPCBhcmd1bWVudHMubGVuZ3RoOyBzKyspIHtcblx0XHRmcm9tID0gT2JqZWN0KGFyZ3VtZW50c1tzXSk7XG5cblx0XHRmb3IgKHZhciBrZXkgaW4gZnJvbSkge1xuXHRcdFx0aWYgKGhhc093blByb3BlcnR5LmNhbGwoZnJvbSwga2V5KSkge1xuXHRcdFx0XHR0b1trZXldID0gZnJvbVtrZXldO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChnZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcblx0XHRcdHN5bWJvbHMgPSBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMoZnJvbSk7XG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHN5bWJvbHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0aWYgKHByb3BJc0VudW1lcmFibGUuY2FsbChmcm9tLCBzeW1ib2xzW2ldKSkge1xuXHRcdFx0XHRcdHRvW3N5bWJvbHNbaV1dID0gZnJvbVtzeW1ib2xzW2ldXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0bztcbn07XG5cbn0se31dLDI0OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbnZhciBidW5kbGVGbiA9IGFyZ3VtZW50c1szXTtcbnZhciBzb3VyY2VzID0gYXJndW1lbnRzWzRdO1xudmFyIGNhY2hlID0gYXJndW1lbnRzWzVdO1xuXG52YXIgc3RyaW5naWZ5ID0gSlNPTi5zdHJpbmdpZnk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGZuLCBvcHRpb25zKSB7XG4gICAgdmFyIHdrZXk7XG4gICAgdmFyIGNhY2hlS2V5cyA9IE9iamVjdC5rZXlzKGNhY2hlKTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBsID0gY2FjaGVLZXlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICB2YXIga2V5ID0gY2FjaGVLZXlzW2ldO1xuICAgICAgICB2YXIgZXhwID0gY2FjaGVba2V5XS5leHBvcnRzO1xuICAgICAgICAvLyBVc2luZyBiYWJlbCBhcyBhIHRyYW5zcGlsZXIgdG8gdXNlIGVzbW9kdWxlLCB0aGUgZXhwb3J0IHdpbGwgYWx3YXlzXG4gICAgICAgIC8vIGJlIGFuIG9iamVjdCB3aXRoIHRoZSBkZWZhdWx0IGV4cG9ydCBhcyBhIHByb3BlcnR5IG9mIGl0LiBUbyBlbnN1cmVcbiAgICAgICAgLy8gdGhlIGV4aXN0aW5nIGFwaSBhbmQgYmFiZWwgZXNtb2R1bGUgZXhwb3J0cyBhcmUgYm90aCBzdXBwb3J0ZWQgd2VcbiAgICAgICAgLy8gY2hlY2sgZm9yIGJvdGhcbiAgICAgICAgaWYgKGV4cCA9PT0gZm4gfHwgZXhwICYmIGV4cC5kZWZhdWx0ID09PSBmbikge1xuICAgICAgICAgICAgd2tleSA9IGtleTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF3a2V5KSB7XG4gICAgICAgIHdrZXkgPSBNYXRoLmZsb29yKE1hdGgucG93KDE2LCA4KSAqIE1hdGgucmFuZG9tKCkpLnRvU3RyaW5nKDE2KTtcbiAgICAgICAgdmFyIHdjYWNoZSA9IHt9O1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGNhY2hlS2V5cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBjYWNoZUtleXNbaV07XG4gICAgICAgICAgICB3Y2FjaGVba2V5XSA9IGtleTtcbiAgICAgICAgfVxuICAgICAgICBzb3VyY2VzW3drZXldID0gW1xuICAgICAgICAgICAgJ2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeycgKyBmbiArICcoc2VsZik7IH0nLFxuICAgICAgICAgICAgd2NhY2hlXG4gICAgICAgIF07XG4gICAgfVxuICAgIHZhciBza2V5ID0gTWF0aC5mbG9vcihNYXRoLnBvdygxNiwgOCkgKiBNYXRoLnJhbmRvbSgpKS50b1N0cmluZygxNik7XG5cbiAgICB2YXIgc2NhY2hlID0ge307IHNjYWNoZVt3a2V5XSA9IHdrZXk7XG4gICAgc291cmNlc1tza2V5XSA9IFtcbiAgICAgICAgJ2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeycgK1xuICAgICAgICAgICAgLy8gdHJ5IHRvIGNhbGwgZGVmYXVsdCBpZiBkZWZpbmVkIHRvIGFsc28gc3VwcG9ydCBiYWJlbCBlc21vZHVsZSBleHBvcnRzXG4gICAgICAgICAgICAndmFyIGYgPSByZXF1aXJlKCcgKyBzdHJpbmdpZnkod2tleSkgKyAnKTsnICtcbiAgICAgICAgICAgICcoZi5kZWZhdWx0ID8gZi5kZWZhdWx0IDogZikoc2VsZik7JyArXG4gICAgICAgICd9JyxcbiAgICAgICAgc2NhY2hlXG4gICAgXTtcblxuICAgIHZhciB3b3JrZXJTb3VyY2VzID0ge307XG4gICAgcmVzb2x2ZVNvdXJjZXMoc2tleSk7XG5cbiAgICBmdW5jdGlvbiByZXNvbHZlU291cmNlcyhrZXkpIHtcbiAgICAgICAgd29ya2VyU291cmNlc1trZXldID0gdHJ1ZTtcblxuICAgICAgICBmb3IgKHZhciBkZXBQYXRoIGluIHNvdXJjZXNba2V5XVsxXSkge1xuICAgICAgICAgICAgdmFyIGRlcEtleSA9IHNvdXJjZXNba2V5XVsxXVtkZXBQYXRoXTtcbiAgICAgICAgICAgIGlmICghd29ya2VyU291cmNlc1tkZXBLZXldKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZVNvdXJjZXMoZGVwS2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBzcmMgPSAnKCcgKyBidW5kbGVGbiArICcpKHsnXG4gICAgICAgICsgT2JqZWN0LmtleXMod29ya2VyU291cmNlcykubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBzdHJpbmdpZnkoa2V5KSArICc6WydcbiAgICAgICAgICAgICAgICArIHNvdXJjZXNba2V5XVswXVxuICAgICAgICAgICAgICAgICsgJywnICsgc3RyaW5naWZ5KHNvdXJjZXNba2V5XVsxXSkgKyAnXSdcbiAgICAgICAgICAgIDtcbiAgICAgICAgfSkuam9pbignLCcpXG4gICAgICAgICsgJ30se30sWycgKyBzdHJpbmdpZnkoc2tleSkgKyAnXSknXG4gICAgO1xuXG4gICAgdmFyIFVSTCA9IHdpbmRvdy5VUkwgfHwgd2luZG93LndlYmtpdFVSTCB8fCB3aW5kb3cubW96VVJMIHx8IHdpbmRvdy5tc1VSTDtcblxuICAgIHZhciBibG9iID0gbmV3IEJsb2IoW3NyY10sIHsgdHlwZTogJ3RleHQvamF2YXNjcmlwdCcgfSk7XG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5iYXJlKSB7IHJldHVybiBibG9iOyB9XG4gICAgdmFyIHdvcmtlclVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgdmFyIHdvcmtlciA9IG5ldyBXb3JrZXIod29ya2VyVXJsKTtcbiAgICB3b3JrZXIub2JqZWN0VVJMID0gd29ya2VyVXJsO1xuICAgIHJldHVybiB3b3JrZXI7XG59O1xuXG59LHt9XSxcIi9pbmRleC5qc1wiOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcblxuZnVuY3Rpb24gX3NsaWNlZFRvQXJyYXkoYXJyLCBpKSB7IHJldHVybiBfYXJyYXlXaXRoSG9sZXMoYXJyKSB8fCBfaXRlcmFibGVUb0FycmF5TGltaXQoYXJyLCBpKSB8fCBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkoYXJyLCBpKSB8fCBfbm9uSXRlcmFibGVSZXN0KCk7IH1cblxuZnVuY3Rpb24gX25vbkl0ZXJhYmxlUmVzdCgpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBkZXN0cnVjdHVyZSBub24taXRlcmFibGUgaW5zdGFuY2UuXFxuSW4gb3JkZXIgdG8gYmUgaXRlcmFibGUsIG5vbi1hcnJheSBvYmplY3RzIG11c3QgaGF2ZSBhIFtTeW1ib2wuaXRlcmF0b3JdKCkgbWV0aG9kLlwiKTsgfVxuXG5mdW5jdGlvbiBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkobywgbWluTGVuKSB7IGlmICghbykgcmV0dXJuOyBpZiAodHlwZW9mIG8gPT09IFwic3RyaW5nXCIpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pOyB2YXIgbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKS5zbGljZSg4LCAtMSk7IGlmIChuID09PSBcIk9iamVjdFwiICYmIG8uY29uc3RydWN0b3IpIG4gPSBvLmNvbnN0cnVjdG9yLm5hbWU7IGlmIChuID09PSBcIk1hcFwiIHx8IG4gPT09IFwiU2V0XCIpIHJldHVybiBBcnJheS5mcm9tKG8pOyBpZiAobiA9PT0gXCJBcmd1bWVudHNcIiB8fCAvXig/OlVpfEkpbnQoPzo4fDE2fDMyKSg/OkNsYW1wZWQpP0FycmF5JC8udGVzdChuKSkgcmV0dXJuIF9hcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7IH1cblxuZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkoYXJyLCBsZW4pIHsgaWYgKGxlbiA9PSBudWxsIHx8IGxlbiA+IGFyci5sZW5ndGgpIGxlbiA9IGFyci5sZW5ndGg7IGZvciAodmFyIGkgPSAwLCBhcnIyID0gbmV3IEFycmF5KGxlbik7IGkgPCBsZW47IGkrKykgeyBhcnIyW2ldID0gYXJyW2ldOyB9IHJldHVybiBhcnIyOyB9XG5cbmZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHsgdmFyIF9pID0gYXJyID09IG51bGwgPyBudWxsIDogdHlwZW9mIFN5bWJvbCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBhcnJbU3ltYm9sLml0ZXJhdG9yXSB8fCBhcnJbXCJAQGl0ZXJhdG9yXCJdOyBpZiAoX2kgPT0gbnVsbCkgcmV0dXJuOyB2YXIgX2FyciA9IFtdOyB2YXIgX24gPSB0cnVlOyB2YXIgX2QgPSBmYWxzZTsgdmFyIF9zLCBfZTsgdHJ5IHsgZm9yIChfaSA9IF9pLmNhbGwoYXJyKTsgIShfbiA9IChfcyA9IF9pLm5leHQoKSkuZG9uZSk7IF9uID0gdHJ1ZSkgeyBfYXJyLnB1c2goX3MudmFsdWUpOyBpZiAoaSAmJiBfYXJyLmxlbmd0aCA9PT0gaSkgYnJlYWs7IH0gfSBjYXRjaCAoZXJyKSB7IF9kID0gdHJ1ZTsgX2UgPSBlcnI7IH0gZmluYWxseSB7IHRyeSB7IGlmICghX24gJiYgX2lbXCJyZXR1cm5cIl0gIT0gbnVsbCkgX2lbXCJyZXR1cm5cIl0oKTsgfSBmaW5hbGx5IHsgaWYgKF9kKSB0aHJvdyBfZTsgfSB9IHJldHVybiBfYXJyOyB9XG5cbmZ1bmN0aW9uIF9hcnJheVdpdGhIb2xlcyhhcnIpIHsgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgcmV0dXJuIGFycjsgfVxuXG52YXIgYXNzaWduID0gX2RlcmVxXygnb2JqZWN0LWFzc2lnbicpO1xuXG52YXIgd2Vid29ya2lmeSA9IF9kZXJlcV8oJ3dlYndvcmtpZnknKTtcblxudmFyIE1hdGhMaWIgPSBfZGVyZXFfKCcuL2xpYi9tYXRobGliJyk7XG5cbnZhciBQb29sID0gX2RlcmVxXygnLi9saWIvcG9vbCcpO1xuXG52YXIgdXRpbHMgPSBfZGVyZXFfKCcuL2xpYi91dGlscycpO1xuXG52YXIgd29ya2VyID0gX2RlcmVxXygnLi9saWIvd29ya2VyJyk7XG5cbnZhciBjcmVhdGVTdGFnZXMgPSBfZGVyZXFfKCcuL2xpYi9zdGVwcGVyJyk7XG5cbnZhciBjcmVhdGVSZWdpb25zID0gX2RlcmVxXygnLi9saWIvdGlsZXInKTsgLy8gRGVkdXBsaWNhdGUgcG9vbHMgJiBsaW1pdGVycyB3aXRoIHRoZSBzYW1lIGNvbmZpZ3Ncbi8vIHdoZW4gdXNlciBjcmVhdGVzIG11bHRpcGxlIHBpY2EgaW5zdGFuY2VzLlxuXG5cbnZhciBzaW5nbGV0b25lcyA9IHt9O1xudmFyIE5FRURfU0FGQVJJX0ZJWCA9IGZhbHNlO1xuXG50cnkge1xuICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCkge1xuICAgIE5FRURfU0FGQVJJX0ZJWCA9IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignU2FmYXJpJykgPj0gMDtcbiAgfVxufSBjYXRjaCAoZSkge31cblxudmFyIGNvbmN1cnJlbmN5ID0gMTtcblxuaWYgKHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnKSB7XG4gIGNvbmN1cnJlbmN5ID0gTWF0aC5taW4obmF2aWdhdG9yLmhhcmR3YXJlQ29uY3VycmVuY3kgfHwgMSwgNCk7XG59XG5cbnZhciBERUZBVUxUX1BJQ0FfT1BUUyA9IHtcbiAgdGlsZTogMTAyNCxcbiAgY29uY3VycmVuY3k6IGNvbmN1cnJlbmN5LFxuICBmZWF0dXJlczogWydqcycsICd3YXNtJywgJ3d3J10sXG4gIGlkbGU6IDIwMDAsXG4gIGNyZWF0ZUNhbnZhczogZnVuY3Rpb24gY3JlYXRlQ2FudmFzKHdpZHRoLCBoZWlnaHQpIHtcbiAgICB2YXIgdG1wQ2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgdG1wQ2FudmFzLndpZHRoID0gd2lkdGg7XG4gICAgdG1wQ2FudmFzLmhlaWdodCA9IGhlaWdodDtcbiAgICByZXR1cm4gdG1wQ2FudmFzO1xuICB9XG59O1xudmFyIERFRkFVTFRfUkVTSVpFX09QVFMgPSB7XG4gIHF1YWxpdHk6IDMsXG4gIGFscGhhOiBmYWxzZSxcbiAgdW5zaGFycEFtb3VudDogMCxcbiAgdW5zaGFycFJhZGl1czogMC4wLFxuICB1bnNoYXJwVGhyZXNob2xkOiAwXG59O1xudmFyIENBTl9ORVdfSU1BR0VfREFUQSA9IGZhbHNlO1xudmFyIENBTl9DUkVBVEVfSU1BR0VfQklUTUFQID0gZmFsc2U7XG52YXIgQ0FOX1VTRV9DQU5WQVNfR0VUX0lNQUdFX0RBVEEgPSBmYWxzZTtcbnZhciBDQU5fVVNFX09GRlNDUkVFTl9DQU5WQVMgPSBmYWxzZTtcbnZhciBDQU5fVVNFX0NJQl9SRUdJT05fRk9SX0lNQUdFID0gZmFsc2U7XG5cbmZ1bmN0aW9uIHdvcmtlckZhYnJpYygpIHtcbiAgcmV0dXJuIHtcbiAgICB2YWx1ZTogd2Vid29ya2lmeSh3b3JrZXIpLFxuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICB0aGlzLnZhbHVlLnRlcm1pbmF0ZSgpO1xuXG4gICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdmFyIHVybCA9IHdpbmRvdy5VUkwgfHwgd2luZG93LndlYmtpdFVSTCB8fCB3aW5kb3cubW96VVJMIHx8IHdpbmRvdy5tc1VSTDtcblxuICAgICAgICBpZiAodXJsICYmIHVybC5yZXZva2VPYmplY3RVUkwgJiYgdGhpcy52YWx1ZS5vYmplY3RVUkwpIHtcbiAgICAgICAgICB1cmwucmV2b2tlT2JqZWN0VVJMKHRoaXMudmFsdWUub2JqZWN0VVJMKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcbn0gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIEFQSSBtZXRob2RzXG5cblxuZnVuY3Rpb24gUGljYShvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBQaWNhKSkgcmV0dXJuIG5ldyBQaWNhKG9wdGlvbnMpO1xuICB0aGlzLm9wdGlvbnMgPSBhc3NpZ24oe30sIERFRkFVTFRfUElDQV9PUFRTLCBvcHRpb25zIHx8IHt9KTtcbiAgdmFyIGxpbWl0ZXJfa2V5ID0gXCJsa19cIi5jb25jYXQodGhpcy5vcHRpb25zLmNvbmN1cnJlbmN5KTsgLy8gU2hhcmUgbGltaXRlcnMgdG8gYXZvaWQgbXVsdGlwbGUgcGFyYWxsZWwgd29ya2VycyB3aGVuIHVzZXIgY3JlYXRlc1xuICAvLyBtdWx0aXBsZSBwaWNhIGluc3RhbmNlcy5cblxuICB0aGlzLl9fbGltaXQgPSBzaW5nbGV0b25lc1tsaW1pdGVyX2tleV0gfHwgdXRpbHMubGltaXRlcih0aGlzLm9wdGlvbnMuY29uY3VycmVuY3kpO1xuICBpZiAoIXNpbmdsZXRvbmVzW2xpbWl0ZXJfa2V5XSkgc2luZ2xldG9uZXNbbGltaXRlcl9rZXldID0gdGhpcy5fX2xpbWl0OyAvLyBMaXN0IG9mIHN1cHBvcnRlZCBmZWF0dXJlcywgYWNjb3JkaW5nIHRvIG9wdGlvbnMgJiBicm93c2VyL25vZGUuanNcblxuICB0aGlzLmZlYXR1cmVzID0ge1xuICAgIGpzOiBmYWxzZSxcbiAgICAvLyBwdXJlIEpTIGltcGxlbWVudGF0aW9uLCBjYW4gYmUgZGlzYWJsZWQgZm9yIHRlc3RpbmdcbiAgICB3YXNtOiBmYWxzZSxcbiAgICAvLyB3ZWJhc3NlbWJseSBpbXBsZW1lbnRhdGlvbiBmb3IgaGVhdnkgZnVuY3Rpb25zXG4gICAgY2liOiBmYWxzZSxcbiAgICAvLyByZXNpemUgdmlhIGNyZWF0ZUltYWdlQml0bWFwIChvbmx5IEZGIGF0IHRoaXMgbW9tZW50KVxuICAgIHd3OiBmYWxzZSAvLyB3ZWJ3b3JrZXJzXG5cbiAgfTtcbiAgdGhpcy5fX3dvcmtlcnNQb29sID0gbnVsbDsgLy8gU3RvcmUgcmVxdWVzdGVkIGZlYXR1cmVzIGZvciB3ZWJ3b3JrZXJzXG5cbiAgdGhpcy5fX3JlcXVlc3RlZF9mZWF0dXJlcyA9IFtdO1xuICB0aGlzLl9fbWF0aGxpYiA9IG51bGw7XG59XG5cblBpY2EucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgaWYgKHRoaXMuX19pbml0UHJvbWlzZSkgcmV0dXJuIHRoaXMuX19pbml0UHJvbWlzZTsgLy8gVGVzdCBpZiB3ZSBjYW4gY3JlYXRlIEltYWdlRGF0YSB3aXRob3V0IGNhbnZhcyBhbmQgbWVtb3J5IGNvcHlcblxuICBpZiAodHlwZW9mIEltYWdlRGF0YSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIFVpbnQ4Q2xhbXBlZEFycmF5ICE9PSAndW5kZWZpbmVkJykge1xuICAgIHRyeSB7XG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1uZXcgKi9cbiAgICAgIG5ldyBJbWFnZURhdGEobmV3IFVpbnQ4Q2xhbXBlZEFycmF5KDQwMCksIDEwLCAxMCk7XG4gICAgICBDQU5fTkVXX0lNQUdFX0RBVEEgPSB0cnVlO1xuICAgIH0gY2F0Y2ggKF9fKSB7fVxuICB9IC8vIEltYWdlQml0bWFwIGNhbiBiZSBlZmZlY3RpdmUgaW4gMiBwbGFjZXM6XG4gIC8vXG4gIC8vIDEuIFRocmVhZGVkIGpwZWcgdW5wYWNrIChiYXNpYylcbiAgLy8gMi4gQnVpbHQtaW4gcmVzaXplIChibG9ja2VkIGR1ZSBwcm9ibGVtIGluIGNocm9tZSwgc2VlIGlzc3VlICM4OSlcbiAgLy9cbiAgLy8gRm9yIGJhc2ljIHVzZSB3ZSBhbHNvIG5lZWQgSW1hZ2VCaXRtYXAgd28gc3VwcG9ydCAuY2xvc2UoKSBtZXRob2QsXG4gIC8vIHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9ydS9kb2NzL1dlYi9BUEkvSW1hZ2VCaXRtYXBcblxuXG4gIGlmICh0eXBlb2YgSW1hZ2VCaXRtYXAgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKEltYWdlQml0bWFwLnByb3RvdHlwZSAmJiBJbWFnZUJpdG1hcC5wcm90b3R5cGUuY2xvc2UpIHtcbiAgICAgIENBTl9DUkVBVEVfSU1BR0VfQklUTUFQID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kZWJ1ZygnSW1hZ2VCaXRtYXAgZG9lcyBub3Qgc3VwcG9ydCAuY2xvc2UoKSwgZGlzYWJsZWQnKTtcbiAgICB9XG4gIH1cblxuICB2YXIgZmVhdHVyZXMgPSB0aGlzLm9wdGlvbnMuZmVhdHVyZXMuc2xpY2UoKTtcblxuICBpZiAoZmVhdHVyZXMuaW5kZXhPZignYWxsJykgPj0gMCkge1xuICAgIGZlYXR1cmVzID0gWydjaWInLCAnd2FzbScsICdqcycsICd3dyddO1xuICB9XG5cbiAgdGhpcy5fX3JlcXVlc3RlZF9mZWF0dXJlcyA9IGZlYXR1cmVzO1xuICB0aGlzLl9fbWF0aGxpYiA9IG5ldyBNYXRoTGliKGZlYXR1cmVzKTsgLy8gQ2hlY2sgV2ViV29ya2VyIHN1cHBvcnQgaWYgcmVxdWVzdGVkXG5cbiAgaWYgKGZlYXR1cmVzLmluZGV4T2YoJ3d3JykgPj0gMCkge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiAnV29ya2VyJyBpbiB3aW5kb3cpIHtcbiAgICAgIC8vIElFIDw9IDExIGRvbid0IGFsbG93IHRvIGNyZWF0ZSB3ZWJ3b3JrZXJzIGZyb20gc3RyaW5nLiBXZSBzaG91bGQgY2hlY2sgaXQuXG4gICAgICAvLyBodHRwczovL2Nvbm5lY3QubWljcm9zb2Z0LmNvbS9JRS9mZWVkYmFjay9kZXRhaWxzLzgwMTgxMC93ZWItd29ya2Vycy1mcm9tLWJsb2ItdXJscy1pbi1pZS0xMC1hbmQtMTFcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciB3a3IgPSBfZGVyZXFfKCd3ZWJ3b3JraWZ5JykoZnVuY3Rpb24gKCkge30pO1xuXG4gICAgICAgIHdrci50ZXJtaW5hdGUoKTtcbiAgICAgICAgdGhpcy5mZWF0dXJlcy53dyA9IHRydWU7IC8vIHBvb2wgdW5pcXVlbmVzcyBkZXBlbmRzIG9uIHBvb2wgY29uZmlnICsgd2Vid29ya2VyIGNvbmZpZ1xuXG4gICAgICAgIHZhciB3cG9vbF9rZXkgPSBcIndwX1wiLmNvbmNhdChKU09OLnN0cmluZ2lmeSh0aGlzLm9wdGlvbnMpKTtcblxuICAgICAgICBpZiAoc2luZ2xldG9uZXNbd3Bvb2xfa2V5XSkge1xuICAgICAgICAgIHRoaXMuX193b3JrZXJzUG9vbCA9IHNpbmdsZXRvbmVzW3dwb29sX2tleV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5fX3dvcmtlcnNQb29sID0gbmV3IFBvb2wod29ya2VyRmFicmljLCB0aGlzLm9wdGlvbnMuaWRsZSk7XG4gICAgICAgICAgc2luZ2xldG9uZXNbd3Bvb2xfa2V5XSA9IHRoaXMuX193b3JrZXJzUG9vbDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoX18pIHt9XG4gICAgfVxuICB9XG5cbiAgdmFyIGluaXRNYXRoID0gdGhpcy5fX21hdGhsaWIuaW5pdCgpLnRoZW4oZnVuY3Rpb24gKG1hdGhsaWIpIHtcbiAgICAvLyBDb3B5IGRldGVjdGVkIGZlYXR1cmVzXG4gICAgYXNzaWduKF90aGlzLmZlYXR1cmVzLCBtYXRobGliLmZlYXR1cmVzKTtcbiAgfSk7XG5cbiAgdmFyIGNoZWNrQ2liUmVzaXplO1xuXG4gIGlmICghQ0FOX0NSRUFURV9JTUFHRV9CSVRNQVApIHtcbiAgICBjaGVja0NpYlJlc2l6ZSA9IFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gIH0gZWxzZSB7XG4gICAgY2hlY2tDaWJSZXNpemUgPSB1dGlscy5jaWJfc3VwcG9ydCh0aGlzLm9wdGlvbnMuY3JlYXRlQ2FudmFzKS50aGVuKGZ1bmN0aW9uIChzdGF0dXMpIHtcbiAgICAgIGlmIChfdGhpcy5mZWF0dXJlcy5jaWIgJiYgZmVhdHVyZXMuaW5kZXhPZignY2liJykgPCAwKSB7XG4gICAgICAgIF90aGlzLmRlYnVnKCdjcmVhdGVJbWFnZUJpdG1hcCgpIHJlc2l6ZSBzdXBwb3J0ZWQsIGJ1dCBkaXNhYmxlZCBieSBjb25maWcnKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChmZWF0dXJlcy5pbmRleE9mKCdjaWInKSA+PSAwKSBfdGhpcy5mZWF0dXJlcy5jaWIgPSBzdGF0dXM7XG4gICAgfSk7XG4gIH1cblxuICBDQU5fVVNFX0NBTlZBU19HRVRfSU1BR0VfREFUQSA9IHV0aWxzLmNhbl91c2VfY2FudmFzKHRoaXMub3B0aW9ucy5jcmVhdGVDYW52YXMpO1xuICB2YXIgY2hlY2tPZmZzY3JlZW5DYW52YXM7XG5cbiAgaWYgKENBTl9DUkVBVEVfSU1BR0VfQklUTUFQICYmIENBTl9ORVdfSU1BR0VfREFUQSAmJiBmZWF0dXJlcy5pbmRleE9mKCd3dycpICE9PSAtMSkge1xuICAgIGNoZWNrT2Zmc2NyZWVuQ2FudmFzID0gdXRpbHMud29ya2VyX29mZnNjcmVlbl9jYW52YXNfc3VwcG9ydCgpO1xuICB9IGVsc2Uge1xuICAgIGNoZWNrT2Zmc2NyZWVuQ2FudmFzID0gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgfVxuXG4gIGNoZWNrT2Zmc2NyZWVuQ2FudmFzID0gY2hlY2tPZmZzY3JlZW5DYW52YXMudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgQ0FOX1VTRV9PRkZTQ1JFRU5fQ0FOVkFTID0gcmVzdWx0O1xuICB9KTsgLy8gd2UgdXNlIGNyZWF0ZUltYWdlQml0bWFwIHRvIGNyb3AgaW1hZ2UgZGF0YSBhbmQgcGFzcyBpdCB0byB3b3JrZXJzLFxuICAvLyBzbyBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgZnVuY3Rpb24gd29ya3MgY29ycmVjdGx5O1xuICAvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0xMjIwNjcxXG5cbiAgdmFyIGNoZWNrQ2liUmVnaW9uID0gdXRpbHMuY2liX2Nhbl91c2VfcmVnaW9uKCkudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgQ0FOX1VTRV9DSUJfUkVHSU9OX0ZPUl9JTUFHRSA9IHJlc3VsdDtcbiAgfSk7IC8vIEluaXQgbWF0aCBsaWIuIFRoYXQncyBhc3luYyBiZWNhdXNlIGNhbiBsb2FkIHNvbWVcblxuICB0aGlzLl9faW5pdFByb21pc2UgPSBQcm9taXNlLmFsbChbaW5pdE1hdGgsIGNoZWNrQ2liUmVzaXplLCBjaGVja09mZnNjcmVlbkNhbnZhcywgY2hlY2tDaWJSZWdpb25dKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH0pO1xuICByZXR1cm4gdGhpcy5fX2luaXRQcm9taXNlO1xufTsgLy8gQ2FsbCByZXNpemVyIGluIHdlYndvcmtlciBvciBsb2NhbGx5LCBkZXBlbmRpbmcgb24gY29uZmlnXG5cblxuUGljYS5wcm90b3R5cGUuX19pbnZva2VSZXNpemUgPSBmdW5jdGlvbiAodGlsZU9wdHMsIG9wdHMpIHtcbiAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgLy8gU2hhcmUgY2FjaGUgYmV0d2VlbiBjYWxsczpcbiAgLy9cbiAgLy8gLSB3YXNtIGluc3RhbmNlXG4gIC8vIC0gd2FzbSBtZW1vcnkgb2JqZWN0XG4gIC8vXG4gIG9wdHMuX19tYXRoQ2FjaGUgPSBvcHRzLl9fbWF0aENhY2hlIHx8IHt9O1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFfdGhpczIuZmVhdHVyZXMud3cpIHtcbiAgICAgIC8vIG5vdCBwb3NzaWJsZSB0byBoYXZlIEltYWdlQml0bWFwIGhlcmUgaWYgdXNlciBkaXNhYmxlZCBXV1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGF0YTogX3RoaXMyLl9fbWF0aGxpYi5yZXNpemVBbmRVbnNoYXJwKHRpbGVPcHRzLCBvcHRzLl9fbWF0aENhY2hlKVxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgdmFyIHcgPSBfdGhpczIuX193b3JrZXJzUG9vbC5hY3F1aXJlKCk7XG5cbiAgICAgIGlmIChvcHRzLmNhbmNlbFRva2VuKSBvcHRzLmNhbmNlbFRva2VuW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKGVycikge1xuICAgICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICB9KTtcblxuICAgICAgdy52YWx1ZS5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgdy5yZWxlYXNlKCk7XG4gICAgICAgIGlmIChldi5kYXRhLmVycikgcmVqZWN0KGV2LmRhdGEuZXJyKTtlbHNlIHJlc29sdmUoZXYuZGF0YSk7XG4gICAgICB9O1xuXG4gICAgICB2YXIgdHJhbnNmZXIgPSBbXTtcbiAgICAgIGlmICh0aWxlT3B0cy5zcmMpIHRyYW5zZmVyLnB1c2godGlsZU9wdHMuc3JjLmJ1ZmZlcik7XG4gICAgICBpZiAodGlsZU9wdHMuc3JjQml0bWFwKSB0cmFuc2Zlci5wdXNoKHRpbGVPcHRzLnNyY0JpdG1hcCk7XG4gICAgICB3LnZhbHVlLnBvc3RNZXNzYWdlKHtcbiAgICAgICAgb3B0czogdGlsZU9wdHMsXG4gICAgICAgIGZlYXR1cmVzOiBfdGhpczIuX19yZXF1ZXN0ZWRfZmVhdHVyZXMsXG4gICAgICAgIHByZWxvYWQ6IHtcbiAgICAgICAgICB3YXNtX25vZHVsZTogX3RoaXMyLl9fbWF0aGxpYi5fX1xuICAgICAgICB9XG4gICAgICB9LCB0cmFuc2Zlcik7XG4gICAgfSk7XG4gIH0pO1xufTsgLy8gdGhpcyBmdW5jdGlvbiBjYW4gcmV0dXJuIHByb21pc2UgaWYgY3JlYXRlSW1hZ2VCaXRtYXAgaXMgdXNlZFxuXG5cblBpY2EucHJvdG90eXBlLl9fZXh0cmFjdFRpbGVEYXRhID0gZnVuY3Rpb24gKHRpbGUsIGZyb20sIG9wdHMsIHN0YWdlRW52LCBleHRyYWN0VG8pIHtcbiAgaWYgKHRoaXMuZmVhdHVyZXMud3cgJiYgQ0FOX1VTRV9PRkZTQ1JFRU5fQ0FOVkFTICYmICggLy8gY3JlYXRlSW1hZ2VCaXRtYXAgZG9lc24ndCB3b3JrIGZvciBpbWFnZXMgKEltYWdlLCBJbWFnZUJpdG1hcCkgd2l0aCBFeGlmIG9yaWVudGF0aW9uIGluIENocm9tZSxcbiAgLy8gY2FuIHVzZSBjYW52YXMgYmVjYXVzZSBjYW52YXMgZG9lc24ndCBoYXZlIG9yaWVudGF0aW9uO1xuICAvLyBzZWUgaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9MTIyMDY3MVxuICB1dGlscy5pc0NhbnZhcyhmcm9tKSB8fCBDQU5fVVNFX0NJQl9SRUdJT05fRk9SX0lNQUdFKSkge1xuICAgIHRoaXMuZGVidWcoJ0NyZWF0ZSB0aWxlIGZvciBPZmZzY3JlZW5DYW52YXMnKTtcbiAgICByZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAoc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXAgfHwgZnJvbSwgdGlsZS54LCB0aWxlLnksIHRpbGUud2lkdGgsIHRpbGUuaGVpZ2h0KS50aGVuKGZ1bmN0aW9uIChiaXRtYXApIHtcbiAgICAgIGV4dHJhY3RUby5zcmNCaXRtYXAgPSBiaXRtYXA7XG4gICAgICByZXR1cm4gZXh0cmFjdFRvO1xuICAgIH0pO1xuICB9IC8vIEV4dHJhY3QgdGlsZSBSR0JBIGJ1ZmZlciwgZGVwZW5kaW5nIG9uIGlucHV0IHR5cGVcblxuXG4gIGlmICh1dGlscy5pc0NhbnZhcyhmcm9tKSkge1xuICAgIGlmICghc3RhZ2VFbnYuc3JjQ3R4KSBzdGFnZUVudi5zcmNDdHggPSBmcm9tLmdldENvbnRleHQoJzJkJywge1xuICAgICAgYWxwaGE6IEJvb2xlYW4ob3B0cy5hbHBoYSlcbiAgICB9KTsgLy8gSWYgaW5wdXQgaXMgQ2FudmFzIC0gZXh0cmFjdCByZWdpb24gZGF0YSBkaXJlY3RseVxuXG4gICAgdGhpcy5kZWJ1ZygnR2V0IHRpbGUgcGl4ZWwgZGF0YScpO1xuICAgIGV4dHJhY3RUby5zcmMgPSBzdGFnZUVudi5zcmNDdHguZ2V0SW1hZ2VEYXRhKHRpbGUueCwgdGlsZS55LCB0aWxlLndpZHRoLCB0aWxlLmhlaWdodCkuZGF0YTtcbiAgICByZXR1cm4gZXh0cmFjdFRvO1xuICB9IC8vIElmIGlucHV0IGlzIEltYWdlIG9yIGRlY29kZWQgdG8gSW1hZ2VCaXRtYXAsXG4gIC8vIGRyYXcgcmVnaW9uIHRvIHRlbXBvcmFyeSBjYW52YXMgYW5kIGV4dHJhY3QgZGF0YSBmcm9tIGl0XG4gIC8vXG4gIC8vIE5vdGUhIEF0dGVtcHQgdG8gcmV1c2UgdGhpcyBjYW52YXMgY2F1c2VzIHNpZ25pZmljYW50IHNsb3dkb3duIGluIGNocm9tZVxuICAvL1xuXG5cbiAgdGhpcy5kZWJ1ZygnRHJhdyB0aWxlIGltYWdlQml0bWFwL2ltYWdlIHRvIHRlbXBvcmFyeSBjYW52YXMnKTtcbiAgdmFyIHRtcENhbnZhcyA9IHRoaXMub3B0aW9ucy5jcmVhdGVDYW52YXModGlsZS53aWR0aCwgdGlsZS5oZWlnaHQpO1xuICB2YXIgdG1wQ3R4ID0gdG1wQ2FudmFzLmdldENvbnRleHQoJzJkJywge1xuICAgIGFscGhhOiBCb29sZWFuKG9wdHMuYWxwaGEpXG4gIH0pO1xuICB0bXBDdHguZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gJ2NvcHknO1xuICB0bXBDdHguZHJhd0ltYWdlKHN0YWdlRW52LnNyY0ltYWdlQml0bWFwIHx8IGZyb20sIHRpbGUueCwgdGlsZS55LCB0aWxlLndpZHRoLCB0aWxlLmhlaWdodCwgMCwgMCwgdGlsZS53aWR0aCwgdGlsZS5oZWlnaHQpO1xuICB0aGlzLmRlYnVnKCdHZXQgdGlsZSBwaXhlbCBkYXRhJyk7XG4gIGV4dHJhY3RUby5zcmMgPSB0bXBDdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIHRpbGUud2lkdGgsIHRpbGUuaGVpZ2h0KS5kYXRhOyAvLyBTYWZhcmkgMTIgd29ya2Fyb3VuZFxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vbm9kZWNhL3BpY2EvaXNzdWVzLzE5OVxuXG4gIHRtcENhbnZhcy53aWR0aCA9IHRtcENhbnZhcy5oZWlnaHQgPSAwO1xuICByZXR1cm4gZXh0cmFjdFRvO1xufTtcblxuUGljYS5wcm90b3R5cGUuX19sYW5kVGlsZURhdGEgPSBmdW5jdGlvbiAodGlsZSwgcmVzdWx0LCBzdGFnZUVudikge1xuICB2YXIgdG9JbWFnZURhdGE7XG4gIHRoaXMuZGVidWcoJ0NvbnZlcnQgcmF3IHJnYmEgdGlsZSByZXN1bHQgdG8gSW1hZ2VEYXRhJyk7XG5cbiAgaWYgKHJlc3VsdC5iaXRtYXApIHtcbiAgICBzdGFnZUVudi50b0N0eC5kcmF3SW1hZ2UocmVzdWx0LmJpdG1hcCwgdGlsZS50b1gsIHRpbGUudG9ZKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChDQU5fTkVXX0lNQUdFX0RBVEEpIHtcbiAgICAvLyB0aGlzIGJyYW5jaCBpcyBmb3IgbW9kZXJuIGJyb3dzZXJzXG4gICAgLy8gSWYgYG5ldyBJbWFnZURhdGEoKWAgJiBVaW50OENsYW1wZWRBcnJheSBzdXBvcnRlZFxuICAgIHRvSW1hZ2VEYXRhID0gbmV3IEltYWdlRGF0YShuZXcgVWludDhDbGFtcGVkQXJyYXkocmVzdWx0LmRhdGEpLCB0aWxlLnRvV2lkdGgsIHRpbGUudG9IZWlnaHQpO1xuICB9IGVsc2Uge1xuICAgIC8vIGZhbGxiYWNrIGZvciBgbm9kZS1jYW52YXNgIGFuZCBvbGQgYnJvd3NlcnNcbiAgICAvLyAoSUUxMSBoYXMgSW1hZ2VEYXRhIGJ1dCBkb2VzIG5vdCBzdXBwb3J0IGBuZXcgSW1hZ2VEYXRhKClgKVxuICAgIHRvSW1hZ2VEYXRhID0gc3RhZ2VFbnYudG9DdHguY3JlYXRlSW1hZ2VEYXRhKHRpbGUudG9XaWR0aCwgdGlsZS50b0hlaWdodCk7XG5cbiAgICBpZiAodG9JbWFnZURhdGEuZGF0YS5zZXQpIHtcbiAgICAgIHRvSW1hZ2VEYXRhLmRhdGEuc2V0KHJlc3VsdC5kYXRhKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSUU5IGRvbid0IGhhdmUgYC5zZXQoKWBcbiAgICAgIGZvciAodmFyIGkgPSB0b0ltYWdlRGF0YS5kYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIHRvSW1hZ2VEYXRhLmRhdGFbaV0gPSByZXN1bHQuZGF0YVtpXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aGlzLmRlYnVnKCdEcmF3IHRpbGUnKTtcblxuICBpZiAoTkVFRF9TQUZBUklfRklYKSB7XG4gICAgLy8gU2FmYXJpIGRyYXdzIHRoaW4gd2hpdGUgc3RyaXBlcyBiZXR3ZWVuIHRpbGVzIHdpdGhvdXQgdGhpcyBmaXhcbiAgICBzdGFnZUVudi50b0N0eC5wdXRJbWFnZURhdGEodG9JbWFnZURhdGEsIHRpbGUudG9YLCB0aWxlLnRvWSwgdGlsZS50b0lubmVyWCAtIHRpbGUudG9YLCB0aWxlLnRvSW5uZXJZIC0gdGlsZS50b1ksIHRpbGUudG9Jbm5lcldpZHRoICsgMWUtNSwgdGlsZS50b0lubmVySGVpZ2h0ICsgMWUtNSk7XG4gIH0gZWxzZSB7XG4gICAgc3RhZ2VFbnYudG9DdHgucHV0SW1hZ2VEYXRhKHRvSW1hZ2VEYXRhLCB0aWxlLnRvWCwgdGlsZS50b1ksIHRpbGUudG9Jbm5lclggLSB0aWxlLnRvWCwgdGlsZS50b0lubmVyWSAtIHRpbGUudG9ZLCB0aWxlLnRvSW5uZXJXaWR0aCwgdGlsZS50b0lubmVySGVpZ2h0KTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufTtcblxuUGljYS5wcm90b3R5cGUuX190aWxlQW5kUmVzaXplID0gZnVuY3Rpb24gKGZyb20sIHRvLCBvcHRzKSB7XG4gIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gIHZhciBzdGFnZUVudiA9IHtcbiAgICBzcmNDdHg6IG51bGwsXG4gICAgc3JjSW1hZ2VCaXRtYXA6IG51bGwsXG4gICAgaXNJbWFnZUJpdG1hcFJldXNlZDogZmFsc2UsXG4gICAgdG9DdHg6IG51bGxcbiAgfTtcblxuICB2YXIgcHJvY2Vzc1RpbGUgPSBmdW5jdGlvbiBwcm9jZXNzVGlsZSh0aWxlKSB7XG4gICAgcmV0dXJuIF90aGlzMy5fX2xpbWl0KGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChvcHRzLmNhbmNlbGVkKSByZXR1cm4gb3B0cy5jYW5jZWxUb2tlbjtcbiAgICAgIHZhciB0aWxlT3B0cyA9IHtcbiAgICAgICAgd2lkdGg6IHRpbGUud2lkdGgsXG4gICAgICAgIGhlaWdodDogdGlsZS5oZWlnaHQsXG4gICAgICAgIHRvV2lkdGg6IHRpbGUudG9XaWR0aCxcbiAgICAgICAgdG9IZWlnaHQ6IHRpbGUudG9IZWlnaHQsXG4gICAgICAgIHNjYWxlWDogdGlsZS5zY2FsZVgsXG4gICAgICAgIHNjYWxlWTogdGlsZS5zY2FsZVksXG4gICAgICAgIG9mZnNldFg6IHRpbGUub2Zmc2V0WCxcbiAgICAgICAgb2Zmc2V0WTogdGlsZS5vZmZzZXRZLFxuICAgICAgICBxdWFsaXR5OiBvcHRzLnF1YWxpdHksXG4gICAgICAgIGFscGhhOiBvcHRzLmFscGhhLFxuICAgICAgICB1bnNoYXJwQW1vdW50OiBvcHRzLnVuc2hhcnBBbW91bnQsXG4gICAgICAgIHVuc2hhcnBSYWRpdXM6IG9wdHMudW5zaGFycFJhZGl1cyxcbiAgICAgICAgdW5zaGFycFRocmVzaG9sZDogb3B0cy51bnNoYXJwVGhyZXNob2xkXG4gICAgICB9O1xuXG4gICAgICBfdGhpczMuZGVidWcoJ0ludm9rZSByZXNpemUgbWF0aCcpO1xuXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRpbGVPcHRzKS50aGVuKGZ1bmN0aW9uICh0aWxlT3B0cykge1xuICAgICAgICByZXR1cm4gX3RoaXMzLl9fZXh0cmFjdFRpbGVEYXRhKHRpbGUsIGZyb20sIG9wdHMsIHN0YWdlRW52LCB0aWxlT3B0cyk7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uICh0aWxlT3B0cykge1xuICAgICAgICBfdGhpczMuZGVidWcoJ0ludm9rZSByZXNpemUgbWF0aCcpO1xuXG4gICAgICAgIHJldHVybiBfdGhpczMuX19pbnZva2VSZXNpemUodGlsZU9wdHMsIG9wdHMpO1xuICAgICAgfSkudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgIGlmIChvcHRzLmNhbmNlbGVkKSByZXR1cm4gb3B0cy5jYW5jZWxUb2tlbjtcbiAgICAgICAgc3RhZ2VFbnYuc3JjSW1hZ2VEYXRhID0gbnVsbDtcbiAgICAgICAgcmV0dXJuIF90aGlzMy5fX2xhbmRUaWxlRGF0YSh0aWxlLCByZXN1bHQsIHN0YWdlRW52KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9OyAvLyBOZWVkIHRvIG5vcm1hbGl6ZSBkYXRhIHNvdXJjZSBmaXJzdC4gSXQgY2FuIGJlIGNhbnZhcyBvciBpbWFnZS5cbiAgLy8gSWYgaW1hZ2UgLSB0cnkgdG8gZGVjb2RlIGluIGJhY2tncm91bmQgaWYgcG9zc2libGVcblxuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBzdGFnZUVudi50b0N0eCA9IHRvLmdldENvbnRleHQoJzJkJywge1xuICAgICAgYWxwaGE6IEJvb2xlYW4ob3B0cy5hbHBoYSlcbiAgICB9KTtcbiAgICBpZiAodXRpbHMuaXNDYW52YXMoZnJvbSkpIHJldHVybiBudWxsO1xuXG4gICAgaWYgKHV0aWxzLmlzSW1hZ2VCaXRtYXAoZnJvbSkpIHtcbiAgICAgIHN0YWdlRW52LnNyY0ltYWdlQml0bWFwID0gZnJvbTtcbiAgICAgIHN0YWdlRW52LmlzSW1hZ2VCaXRtYXBSZXVzZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHV0aWxzLmlzSW1hZ2UoZnJvbSkpIHtcbiAgICAgIC8vIHRyeSBkbyBkZWNvZGUgaW1hZ2UgaW4gYmFja2dyb3VuZCBmb3IgZmFzdGVyIG5leHQgb3BlcmF0aW9ucztcbiAgICAgIC8vIGlmIHdlJ3JlIHVzaW5nIG9mZnNjcmVlbiBjYW52YXMsIGNpYiBpcyBjYWxsZWQgcGVyIHRpbGUsIHNvIG5vdCBuZWVkZWQgaGVyZVxuICAgICAgaWYgKCFDQU5fQ1JFQVRFX0lNQUdFX0JJVE1BUCkgcmV0dXJuIG51bGw7XG5cbiAgICAgIF90aGlzMy5kZWJ1ZygnRGVjb2RlIGltYWdlIHZpYSBjcmVhdGVJbWFnZUJpdG1hcCcpO1xuXG4gICAgICByZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAoZnJvbSkudGhlbihmdW5jdGlvbiAoaW1hZ2VCaXRtYXApIHtcbiAgICAgICAgc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXAgPSBpbWFnZUJpdG1hcDtcbiAgICAgIH0pIC8vIFN1cHByZXNzIGVycm9yIHRvIHVzZSBmYWxsYmFjaywgaWYgbWV0aG9kIGZhaWxzXG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbm9kZWNhL3BpY2EvaXNzdWVzLzE5MFxuXG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xuICAgICAgW1wiY2F0Y2hcIl0oZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BpY2E6IFwiLmZyb21cIiBzaG91bGQgYmUgSW1hZ2UsIENhbnZhcyBvciBJbWFnZUJpdG1hcCcpO1xuICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAob3B0cy5jYW5jZWxlZCkgcmV0dXJuIG9wdHMuY2FuY2VsVG9rZW47XG5cbiAgICBfdGhpczMuZGVidWcoJ0NhbGN1bGF0ZSB0aWxlcycpOyAvL1xuICAgIC8vIEhlcmUgd2UgYXJlIHdpdGggXCJub3JtYWxpemVkXCIgc291cmNlLFxuICAgIC8vIGZvbGxvdyB0byB0aWxpbmdcbiAgICAvL1xuXG5cbiAgICB2YXIgcmVnaW9ucyA9IGNyZWF0ZVJlZ2lvbnMoe1xuICAgICAgd2lkdGg6IG9wdHMud2lkdGgsXG4gICAgICBoZWlnaHQ6IG9wdHMuaGVpZ2h0LFxuICAgICAgc3JjVGlsZVNpemU6IF90aGlzMy5vcHRpb25zLnRpbGUsXG4gICAgICB0b1dpZHRoOiBvcHRzLnRvV2lkdGgsXG4gICAgICB0b0hlaWdodDogb3B0cy50b0hlaWdodCxcbiAgICAgIGRlc3RUaWxlQm9yZGVyOiBvcHRzLl9fZGVzdFRpbGVCb3JkZXJcbiAgICB9KTtcbiAgICB2YXIgam9icyA9IHJlZ2lvbnMubWFwKGZ1bmN0aW9uICh0aWxlKSB7XG4gICAgICByZXR1cm4gcHJvY2Vzc1RpbGUodGlsZSk7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBjbGVhbnVwKHN0YWdlRW52KSB7XG4gICAgICBpZiAoc3RhZ2VFbnYuc3JjSW1hZ2VCaXRtYXApIHtcbiAgICAgICAgaWYgKCFzdGFnZUVudi5pc0ltYWdlQml0bWFwUmV1c2VkKSBzdGFnZUVudi5zcmNJbWFnZUJpdG1hcC5jbG9zZSgpO1xuICAgICAgICBzdGFnZUVudi5zcmNJbWFnZUJpdG1hcCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX3RoaXMzLmRlYnVnKCdQcm9jZXNzIHRpbGVzJyk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoam9icykudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICBfdGhpczMuZGVidWcoJ0ZpbmlzaGVkIScpO1xuXG4gICAgICBjbGVhbnVwKHN0YWdlRW52KTtcbiAgICAgIHJldHVybiB0bztcbiAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBjbGVhbnVwKHN0YWdlRW52KTtcbiAgICAgIHRocm93IGVycjtcbiAgICB9KTtcbiAgfSk7XG59O1xuXG5QaWNhLnByb3RvdHlwZS5fX3Byb2Nlc3NTdGFnZXMgPSBmdW5jdGlvbiAoc3RhZ2VzLCBmcm9tLCB0bywgb3B0cykge1xuICB2YXIgX3RoaXM0ID0gdGhpcztcblxuICBpZiAob3B0cy5jYW5jZWxlZCkgcmV0dXJuIG9wdHMuY2FuY2VsVG9rZW47XG5cbiAgdmFyIF9zdGFnZXMkc2hpZnQgPSBzdGFnZXMuc2hpZnQoKSxcbiAgICAgIF9zdGFnZXMkc2hpZnQyID0gX3NsaWNlZFRvQXJyYXkoX3N0YWdlcyRzaGlmdCwgMiksXG4gICAgICB0b1dpZHRoID0gX3N0YWdlcyRzaGlmdDJbMF0sXG4gICAgICB0b0hlaWdodCA9IF9zdGFnZXMkc2hpZnQyWzFdO1xuXG4gIHZhciBpc0xhc3RTdGFnZSA9IHN0YWdlcy5sZW5ndGggPT09IDA7XG4gIG9wdHMgPSBhc3NpZ24oe30sIG9wdHMsIHtcbiAgICB0b1dpZHRoOiB0b1dpZHRoLFxuICAgIHRvSGVpZ2h0OiB0b0hlaWdodCxcbiAgICAvLyBvbmx5IHVzZSB1c2VyLWRlZmluZWQgcXVhbGl0eSBmb3IgdGhlIGxhc3Qgc3RhZ2UsXG4gICAgLy8gdXNlIHNpbXBsZXIgKEhhbW1pbmcpIGZpbHRlciBmb3IgdGhlIGZpcnN0IHN0YWdlcyB3aGVyZVxuICAgIC8vIHNjYWxlIGZhY3RvciBpcyBsYXJnZSBlbm91Z2ggKG1vcmUgdGhhbiAyLTMpXG4gICAgcXVhbGl0eTogaXNMYXN0U3RhZ2UgPyBvcHRzLnF1YWxpdHkgOiBNYXRoLm1pbigxLCBvcHRzLnF1YWxpdHkpXG4gIH0pO1xuICB2YXIgdG1wQ2FudmFzO1xuXG4gIGlmICghaXNMYXN0U3RhZ2UpIHtcbiAgICAvLyBjcmVhdGUgdGVtcG9yYXJ5IGNhbnZhc1xuICAgIHRtcENhbnZhcyA9IHRoaXMub3B0aW9ucy5jcmVhdGVDYW52YXModG9XaWR0aCwgdG9IZWlnaHQpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuX190aWxlQW5kUmVzaXplKGZyb20sIGlzTGFzdFN0YWdlID8gdG8gOiB0bXBDYW52YXMsIG9wdHMpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIGlmIChpc0xhc3RTdGFnZSkgcmV0dXJuIHRvO1xuICAgIG9wdHMud2lkdGggPSB0b1dpZHRoO1xuICAgIG9wdHMuaGVpZ2h0ID0gdG9IZWlnaHQ7XG4gICAgcmV0dXJuIF90aGlzNC5fX3Byb2Nlc3NTdGFnZXMoc3RhZ2VzLCB0bXBDYW52YXMsIHRvLCBvcHRzKTtcbiAgfSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgaWYgKHRtcENhbnZhcykge1xuICAgICAgLy8gU2FmYXJpIDEyIHdvcmthcm91bmRcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGljYS9pc3N1ZXMvMTk5XG4gICAgICB0bXBDYW52YXMud2lkdGggPSB0bXBDYW52YXMuaGVpZ2h0ID0gMDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9KTtcbn07XG5cblBpY2EucHJvdG90eXBlLl9fcmVzaXplVmlhQ3JlYXRlSW1hZ2VCaXRtYXAgPSBmdW5jdGlvbiAoZnJvbSwgdG8sIG9wdHMpIHtcbiAgdmFyIF90aGlzNSA9IHRoaXM7XG5cbiAgdmFyIHRvQ3R4ID0gdG8uZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgYWxwaGE6IEJvb2xlYW4ob3B0cy5hbHBoYSlcbiAgfSk7XG4gIHRoaXMuZGVidWcoJ1Jlc2l6ZSB2aWEgY3JlYXRlSW1hZ2VCaXRtYXAoKScpO1xuICByZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAoZnJvbSwge1xuICAgIHJlc2l6ZVdpZHRoOiBvcHRzLnRvV2lkdGgsXG4gICAgcmVzaXplSGVpZ2h0OiBvcHRzLnRvSGVpZ2h0LFxuICAgIHJlc2l6ZVF1YWxpdHk6IHV0aWxzLmNpYl9xdWFsaXR5X25hbWUob3B0cy5xdWFsaXR5KVxuICB9KS50aGVuKGZ1bmN0aW9uIChpbWFnZUJpdG1hcCkge1xuICAgIGlmIChvcHRzLmNhbmNlbGVkKSByZXR1cm4gb3B0cy5jYW5jZWxUb2tlbjsgLy8gaWYgbm8gdW5zaGFycCAtIGRyYXcgZGlyZWN0bHkgdG8gb3V0cHV0IGNhbnZhc1xuXG4gICAgaWYgKCFvcHRzLnVuc2hhcnBBbW91bnQpIHtcbiAgICAgIHRvQ3R4LmRyYXdJbWFnZShpbWFnZUJpdG1hcCwgMCwgMCk7XG4gICAgICBpbWFnZUJpdG1hcC5jbG9zZSgpO1xuICAgICAgdG9DdHggPSBudWxsO1xuXG4gICAgICBfdGhpczUuZGVidWcoJ0ZpbmlzaGVkIScpO1xuXG4gICAgICByZXR1cm4gdG87XG4gICAgfVxuXG4gICAgX3RoaXM1LmRlYnVnKCdVbnNoYXJwIHJlc3VsdCcpO1xuXG4gICAgdmFyIHRtcENhbnZhcyA9IF90aGlzNS5vcHRpb25zLmNyZWF0ZUNhbnZhcyhvcHRzLnRvV2lkdGgsIG9wdHMudG9IZWlnaHQpO1xuXG4gICAgdmFyIHRtcEN0eCA9IHRtcENhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICAgIGFscGhhOiBCb29sZWFuKG9wdHMuYWxwaGEpXG4gICAgfSk7XG4gICAgdG1wQ3R4LmRyYXdJbWFnZShpbWFnZUJpdG1hcCwgMCwgMCk7XG4gICAgaW1hZ2VCaXRtYXAuY2xvc2UoKTtcbiAgICB2YXIgaURhdGEgPSB0bXBDdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIG9wdHMudG9XaWR0aCwgb3B0cy50b0hlaWdodCk7XG5cbiAgICBfdGhpczUuX19tYXRobGliLnVuc2hhcnBfbWFzayhpRGF0YS5kYXRhLCBvcHRzLnRvV2lkdGgsIG9wdHMudG9IZWlnaHQsIG9wdHMudW5zaGFycEFtb3VudCwgb3B0cy51bnNoYXJwUmFkaXVzLCBvcHRzLnVuc2hhcnBUaHJlc2hvbGQpO1xuXG4gICAgdG9DdHgucHV0SW1hZ2VEYXRhKGlEYXRhLCAwLCAwKTsgLy8gU2FmYXJpIDEyIHdvcmthcm91bmRcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbm9kZWNhL3BpY2EvaXNzdWVzLzE5OVxuXG4gICAgdG1wQ2FudmFzLndpZHRoID0gdG1wQ2FudmFzLmhlaWdodCA9IDA7XG4gICAgaURhdGEgPSB0bXBDdHggPSB0bXBDYW52YXMgPSB0b0N0eCA9IG51bGw7XG5cbiAgICBfdGhpczUuZGVidWcoJ0ZpbmlzaGVkIScpO1xuXG4gICAgcmV0dXJuIHRvO1xuICB9KTtcbn07XG5cblBpY2EucHJvdG90eXBlLnJlc2l6ZSA9IGZ1bmN0aW9uIChmcm9tLCB0bywgb3B0aW9ucykge1xuICB2YXIgX3RoaXM2ID0gdGhpcztcblxuICB0aGlzLmRlYnVnKCdTdGFydCByZXNpemUuLi4nKTtcbiAgdmFyIG9wdHMgPSBhc3NpZ24oe30sIERFRkFVTFRfUkVTSVpFX09QVFMpO1xuXG4gIGlmICghaXNOYU4ob3B0aW9ucykpIHtcbiAgICBvcHRzID0gYXNzaWduKG9wdHMsIHtcbiAgICAgIHF1YWxpdHk6IG9wdGlvbnNcbiAgICB9KTtcbiAgfSBlbHNlIGlmIChvcHRpb25zKSB7XG4gICAgb3B0cyA9IGFzc2lnbihvcHRzLCBvcHRpb25zKTtcbiAgfVxuXG4gIG9wdHMudG9XaWR0aCA9IHRvLndpZHRoO1xuICBvcHRzLnRvSGVpZ2h0ID0gdG8uaGVpZ2h0O1xuICBvcHRzLndpZHRoID0gZnJvbS5uYXR1cmFsV2lkdGggfHwgZnJvbS53aWR0aDtcbiAgb3B0cy5oZWlnaHQgPSBmcm9tLm5hdHVyYWxIZWlnaHQgfHwgZnJvbS5oZWlnaHQ7IC8vIFByZXZlbnQgc3RlcHBlciBmcm9tIGluZmluaXRlIGxvb3BcblxuICBpZiAodG8ud2lkdGggPT09IDAgfHwgdG8uaGVpZ2h0ID09PSAwKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkludmFsaWQgb3V0cHV0IHNpemU6IFwiLmNvbmNhdCh0by53aWR0aCwgXCJ4XCIpLmNvbmNhdCh0by5oZWlnaHQpKSk7XG4gIH1cblxuICBpZiAob3B0cy51bnNoYXJwUmFkaXVzID4gMikgb3B0cy51bnNoYXJwUmFkaXVzID0gMjtcbiAgb3B0cy5jYW5jZWxlZCA9IGZhbHNlO1xuXG4gIGlmIChvcHRzLmNhbmNlbFRva2VuKSB7XG4gICAgLy8gV3JhcCBjYW5jZWxUb2tlbiB0byBhdm9pZCBzdWNjZXNzaXZlIHJlc29sdmUgJiBzZXQgZmxhZ1xuICAgIG9wdHMuY2FuY2VsVG9rZW4gPSBvcHRzLmNhbmNlbFRva2VuLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgIG9wdHMuY2FuY2VsZWQgPSB0cnVlO1xuICAgICAgdGhyb3cgZGF0YTtcbiAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBvcHRzLmNhbmNlbGVkID0gdHJ1ZTtcbiAgICAgIHRocm93IGVycjtcbiAgICB9KTtcbiAgfVxuXG4gIHZhciBERVNUX1RJTEVfQk9SREVSID0gMzsgLy8gTWF4IHBvc3NpYmxlIGZpbHRlciB3aW5kb3cgc2l6ZVxuXG4gIG9wdHMuX19kZXN0VGlsZUJvcmRlciA9IE1hdGguY2VpbChNYXRoLm1heChERVNUX1RJTEVfQk9SREVSLCAyLjUgKiBvcHRzLnVuc2hhcnBSYWRpdXMgfCAwKSk7XG4gIHJldHVybiB0aGlzLmluaXQoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAob3B0cy5jYW5jZWxlZCkgcmV0dXJuIG9wdHMuY2FuY2VsVG9rZW47IC8vIGlmIGNyZWF0ZUltYWdlQml0bWFwIHN1cHBvcnRzIHJlc2l6ZSwganVzdCBkbyBpdCBhbmQgcmV0dXJuXG5cbiAgICBpZiAoX3RoaXM2LmZlYXR1cmVzLmNpYikge1xuICAgICAgcmV0dXJuIF90aGlzNi5fX3Jlc2l6ZVZpYUNyZWF0ZUltYWdlQml0bWFwKGZyb20sIHRvLCBvcHRzKTtcbiAgICB9XG5cbiAgICBpZiAoIUNBTl9VU0VfQ0FOVkFTX0dFVF9JTUFHRV9EQVRBKSB7XG4gICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdQaWNhOiBjYW5ub3QgdXNlIGdldEltYWdlRGF0YSBvbiBjYW52YXMsICcgKyBcIm1ha2Ugc3VyZSBmaW5nZXJwcmludGluZyBwcm90ZWN0aW9uIGlzbid0IGVuYWJsZWRcIik7XG4gICAgICBlcnIuY29kZSA9ICdFUlJfR0VUX0lNQUdFX0RBVEEnO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH0gLy9cbiAgICAvLyBObyBlYXN5IHdheSwgbGV0J3MgcmVzaXplIG1hbnVhbGx5IHZpYSBhcnJheXNcbiAgICAvL1xuXG5cbiAgICB2YXIgc3RhZ2VzID0gY3JlYXRlU3RhZ2VzKG9wdHMud2lkdGgsIG9wdHMuaGVpZ2h0LCBvcHRzLnRvV2lkdGgsIG9wdHMudG9IZWlnaHQsIF90aGlzNi5vcHRpb25zLnRpbGUsIG9wdHMuX19kZXN0VGlsZUJvcmRlcik7XG4gICAgcmV0dXJuIF90aGlzNi5fX3Byb2Nlc3NTdGFnZXMoc3RhZ2VzLCBmcm9tLCB0bywgb3B0cyk7XG4gIH0pO1xufTsgLy8gUkdCQSBidWZmZXIgcmVzaXplXG4vL1xuXG5cblBpY2EucHJvdG90eXBlLnJlc2l6ZUJ1ZmZlciA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIHZhciBfdGhpczcgPSB0aGlzO1xuXG4gIHZhciBvcHRzID0gYXNzaWduKHt9LCBERUZBVUxUX1JFU0laRV9PUFRTLCBvcHRpb25zKTtcbiAgcmV0dXJuIHRoaXMuaW5pdCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdGhpczcuX19tYXRobGliLnJlc2l6ZUFuZFVuc2hhcnAob3B0cyk7XG4gIH0pO1xufTtcblxuUGljYS5wcm90b3R5cGUudG9CbG9iID0gZnVuY3Rpb24gKGNhbnZhcywgbWltZVR5cGUsIHF1YWxpdHkpIHtcbiAgbWltZVR5cGUgPSBtaW1lVHlwZSB8fCAnaW1hZ2UvcG5nJztcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgaWYgKGNhbnZhcy50b0Jsb2IpIHtcbiAgICAgIGNhbnZhcy50b0Jsb2IoZnVuY3Rpb24gKGJsb2IpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoYmxvYik7XG4gICAgICB9LCBtaW1lVHlwZSwgcXVhbGl0eSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGNhbnZhcy5jb252ZXJ0VG9CbG9iKSB7XG4gICAgICByZXNvbHZlKGNhbnZhcy5jb252ZXJ0VG9CbG9iKHtcbiAgICAgICAgdHlwZTogbWltZVR5cGUsXG4gICAgICAgIHF1YWxpdHk6IHF1YWxpdHlcbiAgICAgIH0pKTtcbiAgICAgIHJldHVybjtcbiAgICB9IC8vIEZhbGxiYWNrIGZvciBvbGQgYnJvd3NlcnNcblxuXG4gICAgdmFyIGFzU3RyaW5nID0gYXRvYihjYW52YXMudG9EYXRhVVJMKG1pbWVUeXBlLCBxdWFsaXR5KS5zcGxpdCgnLCcpWzFdKTtcbiAgICB2YXIgbGVuID0gYXNTdHJpbmcubGVuZ3RoO1xuICAgIHZhciBhc0J1ZmZlciA9IG5ldyBVaW50OEFycmF5KGxlbik7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBhc0J1ZmZlcltpXSA9IGFzU3RyaW5nLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuXG4gICAgcmVzb2x2ZShuZXcgQmxvYihbYXNCdWZmZXJdLCB7XG4gICAgICB0eXBlOiBtaW1lVHlwZVxuICAgIH0pKTtcbiAgfSk7XG59O1xuXG5QaWNhLnByb3RvdHlwZS5kZWJ1ZyA9IGZ1bmN0aW9uICgpIHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBpY2E7XG5cbn0se1wiLi9saWIvbWF0aGxpYlwiOjEsXCIuL2xpYi9wb29sXCI6MTMsXCIuL2xpYi9zdGVwcGVyXCI6MTQsXCIuL2xpYi90aWxlclwiOjE1LFwiLi9saWIvdXRpbHNcIjoxNixcIi4vbGliL3dvcmtlclwiOjE3LFwib2JqZWN0LWFzc2lnblwiOjIzLFwid2Vid29ya2lmeVwiOjI0fV19LHt9LFtdKShcIi9pbmRleC5qc1wiKVxufSk7XG59KTtcblxudmFyIGltYWdlX3RyYXZlcnNlID0gY3JlYXRlQ29tbW9uanNNb2R1bGUoZnVuY3Rpb24gKG1vZHVsZSkge1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gSGVscGVyc1xuLy9cbmZ1bmN0aW9uIGVycm9yKG1lc3NhZ2UsIGNvZGUpIHtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgZXJyLmNvZGUgPSBjb2RlO1xuICByZXR1cm4gZXJyO1xufVxuXG5cbi8vIENvbnZlcnQgbnVtYmVyIHRvIDB4SEggc3RyaW5nXG4vL1xuZnVuY3Rpb24gdG9faGV4KG51bWJlcikge1xuICB2YXIgbiA9IG51bWJlci50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTtcbiAgZm9yICh2YXIgaSA9IDIgLSBuLmxlbmd0aDsgaSA+IDA7IGktLSkgbiA9ICcwJyArIG47XG4gIHJldHVybiAnMHgnICsgbjtcbn1cblxuXG5mdW5jdGlvbiB1dGY4X2VuY29kZShzdHIpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KHN0cikpO1xuICB9IGNhdGNoIChfKSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHV0ZjhfZGVjb2RlKHN0cikge1xuICB0cnkge1xuICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKHN0cikpO1xuICB9IGNhdGNoIChfKSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufVxuXG5cbi8vIENoZWNrIGlmIGlucHV0IGlzIGEgVWludDhBcnJheVxuLy9cbmZ1bmN0aW9uIGlzX3VpbnQ4YXJyYXkoYmluKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYmluKSA9PT0gJ1tvYmplY3QgVWludDhBcnJheV0nO1xufVxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBFeGlmIHBhcnNlclxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46ICAgVWludDhBcnJheSAtIGpwZWcgZmlsZVxuLy8gIC0gZXhpZl9zdGFydDogTnVtYmVyICAgICAtIHN0YXJ0IG9mIFRJRkYgaGVhZGVyIChhZnRlciBFeGlmXFwwXFwwKVxuLy8gIC0gZXhpZl9lbmQ6ICAgTnVtYmVyICAgICAtIGVuZCBvZiBFeGlmIHNlZ21lbnRcbi8vICAtIG9uX2VudHJ5OiAgIE51bWJlciAgICAgLSBjYWxsYmFja1xuLy9cbmZ1bmN0aW9uIEV4aWZQYXJzZXIoanBlZ19iaW4sIGV4aWZfc3RhcnQsIGV4aWZfZW5kKSB7XG4gIC8vIFVpbnQ4QXJyYXksIGV4aWYgd2l0aG91dCBzaWduYXR1cmUgKHdoaWNoIGlzbid0IGluY2x1ZGVkIGluIG9mZnNldHMpXG4gIHRoaXMuaW5wdXQgICAgICA9IGpwZWdfYmluLnN1YmFycmF5KGV4aWZfc3RhcnQsIGV4aWZfZW5kKTtcblxuICAvLyBvZmZzZXQgY29ycmVjdGlvbiBmb3IgYG9uX2VudHJ5YCBjYWxsYmFja1xuICB0aGlzLnN0YXJ0ICAgICAgPSBleGlmX3N0YXJ0O1xuXG4gIC8vIENoZWNrIFRJRkYgaGVhZGVyIChpbmNsdWRlcyBieXRlIGFsaWdubWVudCBhbmQgZmlyc3QgSUZEIG9mZnNldClcbiAgdmFyIHNpZyA9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgdGhpcy5pbnB1dC5zdWJhcnJheSgwLCA0KSk7XG5cbiAgaWYgKHNpZyAhPT0gJ0lJXFx4MkFcXDAnICYmIHNpZyAhPT0gJ01NXFwwXFx4MkEnKSB7XG4gICAgdGhyb3cgZXJyb3IoJ2ludmFsaWQgVElGRiBzaWduYXR1cmUnLCAnRUJBRERBVEEnKTtcbiAgfVxuXG4gIC8vIHRydWUgaWYgbW90b3JvbGEgKGJpZyBlbmRpYW4pIGJ5dGUgYWxpZ25tZW50LCBmYWxzZSBpZiBpbnRlbFxuICB0aGlzLmJpZ19lbmRpYW4gPSBzaWdbMF0gPT09ICdNJztcbn1cblxuXG5FeGlmUGFyc2VyLnByb3RvdHlwZS5lYWNoID0gZnVuY3Rpb24gKG9uX2VudHJ5KSB7XG4gIC8vIGFsbG93IHByZW1hdHVyZSBleGl0XG4gIHRoaXMuYWJvcnRlZCA9IGZhbHNlO1xuXG4gIHZhciBvZmZzZXQgPSB0aGlzLnJlYWRfdWludDMyKDQpO1xuXG4gIHRoaXMuaWZkc190b19yZWFkID0gWyB7XG4gICAgaWQ6ICAgICAwLFxuICAgIG9mZnNldDogb2Zmc2V0XG4gIH0gXTtcblxuICB3aGlsZSAodGhpcy5pZmRzX3RvX3JlYWQubGVuZ3RoID4gMCAmJiAhdGhpcy5hYm9ydGVkKSB7XG4gICAgdmFyIGkgPSB0aGlzLmlmZHNfdG9fcmVhZC5zaGlmdCgpO1xuICAgIGlmICghaS5vZmZzZXQpIGNvbnRpbnVlO1xuICAgIHRoaXMuc2Nhbl9pZmQoaS5pZCwgaS5vZmZzZXQsIG9uX2VudHJ5KTtcbiAgfVxufTtcblxuXG5FeGlmUGFyc2VyLnByb3RvdHlwZS5maWx0ZXIgPSBmdW5jdGlvbiAob25fZW50cnkpIHtcbiAgdmFyIGlmZHMgPSB7fTtcblxuICAvLyBtYWtlIHN1cmUgSUZEMCBhbHdheXMgZXhpc3RzXG4gIGlmZHMuaWZkMCA9IHsgaWQ6IDAsIGVudHJpZXM6IFtdIH07XG5cbiAgdGhpcy5lYWNoKGZ1bmN0aW9uIChlbnRyeSkge1xuICAgIGlmIChvbl9lbnRyeShlbnRyeSkgPT09IGZhbHNlICYmICFlbnRyeS5pc19zdWJpZmRfbGluaykgcmV0dXJuO1xuICAgIGlmIChlbnRyeS5pc19zdWJpZmRfbGluayAmJiBlbnRyeS5jb3VudCAhPT0gMSAmJiBlbnRyeS5mb3JtYXQgIT09IDQpIHJldHVybjsgLy8gZmlsdGVyIG91dCBib2d1cyBsaW5rc1xuXG4gICAgaWYgKCFpZmRzWydpZmQnICsgZW50cnkuaWZkXSkge1xuICAgICAgaWZkc1snaWZkJyArIGVudHJ5LmlmZF0gPSB7IGlkOiBlbnRyeS5pZmQsIGVudHJpZXM6IFtdIH07XG4gICAgfVxuXG4gICAgaWZkc1snaWZkJyArIGVudHJ5LmlmZF0uZW50cmllcy5wdXNoKGVudHJ5KTtcbiAgfSk7XG5cbiAgLy8gdGh1bWJuYWlscyBhcmUgbm90IHN1cHBvcnRlZCBqdXN0IHlldCwgc28gZGVsZXRlIGFsbCBpbmZvcm1hdGlvbiByZWxhdGVkIHRvIGl0XG4gIGRlbGV0ZSBpZmRzLmlmZDE7XG5cbiAgLy8gQ2FsY3VsYXRlIG91dHB1dCBzaXplXG4gIHZhciBsZW5ndGggPSA4O1xuICBPYmplY3Qua2V5cyhpZmRzKS5mb3JFYWNoKGZ1bmN0aW9uIChpZmRfbm8pIHtcbiAgICBsZW5ndGggKz0gMjtcblxuICAgIGlmZHNbaWZkX25vXS5lbnRyaWVzLmZvckVhY2goZnVuY3Rpb24gKGVudHJ5KSB7XG4gICAgICBsZW5ndGggKz0gMTIgKyAoZW50cnkuZGF0YV9sZW5ndGggPiA0ID8gTWF0aC5jZWlsKGVudHJ5LmRhdGFfbGVuZ3RoIC8gMikgKiAyIDogMCk7XG4gICAgfSk7XG5cbiAgICBsZW5ndGggKz0gNDtcbiAgfSk7XG5cbiAgdGhpcy5vdXRwdXQgPSBuZXcgVWludDhBcnJheShsZW5ndGgpO1xuICB0aGlzLm91dHB1dFswXSA9IHRoaXMub3V0cHV0WzFdID0gKHRoaXMuYmlnX2VuZGlhbiA/ICdNJyA6ICdJJykuY2hhckNvZGVBdCgwKTtcbiAgdGhpcy53cml0ZV91aW50MTYoMiwgMHgyQSk7XG5cbiAgdmFyIG9mZnNldCA9IDg7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy53cml0ZV91aW50MzIoNCwgb2Zmc2V0KTtcblxuICBPYmplY3Qua2V5cyhpZmRzKS5mb3JFYWNoKGZ1bmN0aW9uIChpZmRfbm8pIHtcbiAgICBpZmRzW2lmZF9ub10ud3JpdHRlbl9vZmZzZXQgPSBvZmZzZXQ7XG5cbiAgICB2YXIgaWZkX3N0YXJ0ID0gb2Zmc2V0O1xuICAgIHZhciBpZmRfZW5kICAgPSBpZmRfc3RhcnQgKyAyICsgaWZkc1tpZmRfbm9dLmVudHJpZXMubGVuZ3RoICogMTIgKyA0O1xuICAgIG9mZnNldCA9IGlmZF9lbmQ7XG5cbiAgICBzZWxmLndyaXRlX3VpbnQxNihpZmRfc3RhcnQsIGlmZHNbaWZkX25vXS5lbnRyaWVzLmxlbmd0aCk7XG5cbiAgICBpZmRzW2lmZF9ub10uZW50cmllcy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAvLyBJRkQgZW50cmllcyBtdXN0IGJlIGluIG9yZGVyIG9mIGluY3JlYXNpbmcgdGFnIElEc1xuICAgICAgcmV0dXJuIGEudGFnIC0gYi50YWc7XG4gICAgfSkuZm9yRWFjaChmdW5jdGlvbiAoZW50cnksIGlkeCkge1xuICAgICAgdmFyIGVudHJ5X29mZnNldCA9IGlmZF9zdGFydCArIDIgKyBpZHggKiAxMjtcblxuICAgICAgc2VsZi53cml0ZV91aW50MTYoZW50cnlfb2Zmc2V0LCBlbnRyeS50YWcpO1xuICAgICAgc2VsZi53cml0ZV91aW50MTYoZW50cnlfb2Zmc2V0ICsgMiwgZW50cnkuZm9ybWF0KTtcbiAgICAgIHNlbGYud3JpdGVfdWludDMyKGVudHJ5X29mZnNldCArIDQsIGVudHJ5LmNvdW50KTtcblxuICAgICAgaWYgKGVudHJ5LmlzX3N1YmlmZF9saW5rKSB7XG4gICAgICAgIC8vIGZpbGxlZCBpbiBsYXRlclxuICAgICAgICBpZiAoaWZkc1snaWZkJyArIGVudHJ5LnRhZ10pIGlmZHNbJ2lmZCcgKyBlbnRyeS50YWddLmxpbmtfb2Zmc2V0ID0gZW50cnlfb2Zmc2V0ICsgODtcbiAgICAgIH0gZWxzZSBpZiAoZW50cnkuZGF0YV9sZW5ndGggPD0gNCkge1xuICAgICAgICBzZWxmLm91dHB1dC5zZXQoXG4gICAgICAgICAgc2VsZi5pbnB1dC5zdWJhcnJheShlbnRyeS5kYXRhX29mZnNldCAtIHNlbGYuc3RhcnQsIGVudHJ5LmRhdGFfb2Zmc2V0IC0gc2VsZi5zdGFydCArIDQpLFxuICAgICAgICAgIGVudHJ5X29mZnNldCArIDhcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlbGYud3JpdGVfdWludDMyKGVudHJ5X29mZnNldCArIDgsIG9mZnNldCk7XG4gICAgICAgIHNlbGYub3V0cHV0LnNldChcbiAgICAgICAgICBzZWxmLmlucHV0LnN1YmFycmF5KGVudHJ5LmRhdGFfb2Zmc2V0IC0gc2VsZi5zdGFydCwgZW50cnkuZGF0YV9vZmZzZXQgLSBzZWxmLnN0YXJ0ICsgZW50cnkuZGF0YV9sZW5ndGgpLFxuICAgICAgICAgIG9mZnNldFxuICAgICAgICApO1xuICAgICAgICBvZmZzZXQgKz0gTWF0aC5jZWlsKGVudHJ5LmRhdGFfbGVuZ3RoIC8gMikgKiAyO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdmFyIG5leHRfaWZkID0gaWZkc1snaWZkJyArIChpZmRzW2lmZF9ub10uaWQgKyAxKV07XG4gICAgaWYgKG5leHRfaWZkKSBuZXh0X2lmZC5saW5rX29mZnNldCA9IGlmZF9lbmQgLSA0O1xuICB9KTtcblxuICBPYmplY3Qua2V5cyhpZmRzKS5mb3JFYWNoKGZ1bmN0aW9uIChpZmRfbm8pIHtcbiAgICBpZiAoaWZkc1tpZmRfbm9dLndyaXR0ZW5fb2Zmc2V0ICYmIGlmZHNbaWZkX25vXS5saW5rX29mZnNldCkge1xuICAgICAgc2VsZi53cml0ZV91aW50MzIoaWZkc1tpZmRfbm9dLmxpbmtfb2Zmc2V0LCBpZmRzW2lmZF9ub10ud3JpdHRlbl9vZmZzZXQpO1xuICAgIH1cbiAgfSk7XG5cbiAgaWYgKHRoaXMub3V0cHV0Lmxlbmd0aCAhPT0gb2Zmc2V0KSB0aHJvdyBlcnJvcignaW50ZXJuYWwgZXJyb3I6IGluY29ycmVjdCBidWZmZXIgc2l6ZSBhbGxvY2F0ZWQnKTtcblxuICByZXR1cm4gdGhpcy5vdXRwdXQ7XG59O1xuXG5cbkV4aWZQYXJzZXIucHJvdG90eXBlLnJlYWRfdWludDE2ID0gZnVuY3Rpb24gKG9mZnNldCkge1xuICB2YXIgZCA9IHRoaXMuaW5wdXQ7XG4gIGlmIChvZmZzZXQgKyAyID4gZC5sZW5ndGgpIHRocm93IGVycm9yKCd1bmV4cGVjdGVkIEVPRicsICdFQkFEREFUQScpO1xuXG4gIHJldHVybiB0aGlzLmJpZ19lbmRpYW4gP1xuICAgIGRbb2Zmc2V0XSAqIDB4MTAwICsgZFtvZmZzZXQgKyAxXSA6XG4gICAgZFtvZmZzZXRdICsgZFtvZmZzZXQgKyAxXSAqIDB4MTAwO1xufTtcblxuXG5FeGlmUGFyc2VyLnByb3RvdHlwZS5yZWFkX3VpbnQzMiA9IGZ1bmN0aW9uIChvZmZzZXQpIHtcbiAgdmFyIGQgPSB0aGlzLmlucHV0O1xuICBpZiAob2Zmc2V0ICsgNCA+IGQubGVuZ3RoKSB0aHJvdyBlcnJvcigndW5leHBlY3RlZCBFT0YnLCAnRUJBRERBVEEnKTtcblxuICByZXR1cm4gdGhpcy5iaWdfZW5kaWFuID9cbiAgICBkW29mZnNldF0gKiAweDEwMDAwMDAgKyBkW29mZnNldCArIDFdICogMHgxMDAwMCArIGRbb2Zmc2V0ICsgMl0gKiAweDEwMCArIGRbb2Zmc2V0ICsgM10gOlxuICAgIGRbb2Zmc2V0XSArIGRbb2Zmc2V0ICsgMV0gKiAweDEwMCArIGRbb2Zmc2V0ICsgMl0gKiAweDEwMDAwICsgZFtvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMDtcbn07XG5cblxuRXhpZlBhcnNlci5wcm90b3R5cGUud3JpdGVfdWludDE2ID0gZnVuY3Rpb24gKG9mZnNldCwgdmFsdWUpIHtcbiAgdmFyIGQgPSB0aGlzLm91dHB1dDtcblxuICBpZiAodGhpcy5iaWdfZW5kaWFuKSB7XG4gICAgZFtvZmZzZXRdICAgICA9ICh2YWx1ZSA+Pj4gOCkgJiAweEZGO1xuICAgIGRbb2Zmc2V0ICsgMV0gPSB2YWx1ZSAmIDB4RkY7XG4gIH0gZWxzZSB7XG4gICAgZFtvZmZzZXRdICAgICA9IHZhbHVlICYgMHhGRjtcbiAgICBkW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KSAmIDB4RkY7XG4gIH1cbn07XG5cblxuRXhpZlBhcnNlci5wcm90b3R5cGUud3JpdGVfdWludDMyID0gZnVuY3Rpb24gKG9mZnNldCwgdmFsdWUpIHtcbiAgdmFyIGQgPSB0aGlzLm91dHB1dDtcblxuICBpZiAodGhpcy5iaWdfZW5kaWFuKSB7XG4gICAgZFtvZmZzZXRdICAgICA9ICh2YWx1ZSA+Pj4gMjQpICYgMHhGRjtcbiAgICBkW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNikgJiAweEZGO1xuICAgIGRbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpICYgMHhGRjtcbiAgICBkW29mZnNldCArIDNdID0gdmFsdWUgJiAweEZGO1xuICB9IGVsc2Uge1xuICAgIGRbb2Zmc2V0XSAgICAgPSB2YWx1ZSAmIDB4RkY7XG4gICAgZFtvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOCkgJiAweEZGO1xuICAgIGRbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDE2KSAmIDB4RkY7XG4gICAgZFtvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpICYgMHhGRjtcbiAgfVxufTtcblxuXG5FeGlmUGFyc2VyLnByb3RvdHlwZS5pc19zdWJpZmRfbGluayA9IGZ1bmN0aW9uIChpZmQsIHRhZykge1xuICByZXR1cm4gKGlmZCA9PT0gMCAmJiB0YWcgPT09IDB4ODc2OSkgfHwgLy8gU3ViSUZEXG4gICAgICAgICAoaWZkID09PSAwICYmIHRhZyA9PT0gMHg4ODI1KSB8fCAvLyBHUFMgSW5mb1xuICAgICAgICAgKGlmZCA9PT0gMHg4NzY5ICYmIHRhZyA9PT0gMHhBMDA1KTsgLy8gSW50ZXJvcCBJRkRcbn07XG5cblxuLy8gUmV0dXJucyBieXRlIGxlbmd0aCBvZiBhIHNpbmdsZSBjb21wb25lbnQgb2YgYSBnaXZlbiBmb3JtYXRcbi8vXG5FeGlmUGFyc2VyLnByb3RvdHlwZS5leGlmX2Zvcm1hdF9sZW5ndGggPSBmdW5jdGlvbiAoZm9ybWF0KSB7XG4gIHN3aXRjaCAoZm9ybWF0KSB7XG4gICAgY2FzZSAxOiAvLyBieXRlXG4gICAgY2FzZSAyOiAvLyBhc2NpaVxuICAgIGNhc2UgNjogLy8gc2J5dGVcbiAgICBjYXNlIDc6IC8vIHVuZGVmaW5lZFxuICAgICAgcmV0dXJuIDE7XG5cbiAgICBjYXNlIDM6IC8vIHNob3J0XG4gICAgY2FzZSA4OiAvLyBzc2hvcnRcbiAgICAgIHJldHVybiAyO1xuXG4gICAgY2FzZSA0OiAgLy8gbG9uZ1xuICAgIGNhc2UgOTogIC8vIHNsb25nXG4gICAgY2FzZSAxMTogLy8gZmxvYXRcbiAgICAgIHJldHVybiA0O1xuXG4gICAgY2FzZSA1OiAgLy8gcmF0aW9uYWxcbiAgICBjYXNlIDEwOiAvLyBzcmF0aW9uYWxcbiAgICBjYXNlIDEyOiAvLyBkb3VibGVcbiAgICAgIHJldHVybiA4O1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIHVua25vd24gdHlwZVxuICAgICAgcmV0dXJuIDA7XG4gIH1cbn07XG5cblxuLy8gUmVhZHMgRXhpZiBkYXRhXG4vL1xuRXhpZlBhcnNlci5wcm90b3R5cGUuZXhpZl9mb3JtYXRfcmVhZCA9IGZ1bmN0aW9uIChmb3JtYXQsIG9mZnNldCkge1xuICB2YXIgdjtcblxuICBzd2l0Y2ggKGZvcm1hdCkge1xuICAgIGNhc2UgMTogLy8gYnl0ZVxuICAgIGNhc2UgMjogLy8gYXNjaWlcbiAgICAgIHYgPSB0aGlzLmlucHV0W29mZnNldF07XG4gICAgICByZXR1cm4gdjtcblxuICAgIGNhc2UgNjogLy8gc2J5dGVcbiAgICAgIHYgPSB0aGlzLmlucHV0W29mZnNldF07XG4gICAgICByZXR1cm4gdiB8ICh2ICYgMHg4MCkgKiAweDFmZmZmZmU7XG5cbiAgICBjYXNlIDM6IC8vIHNob3J0XG4gICAgICB2ID0gdGhpcy5yZWFkX3VpbnQxNihvZmZzZXQpO1xuICAgICAgcmV0dXJuIHY7XG5cbiAgICBjYXNlIDg6IC8vIHNzaG9ydFxuICAgICAgdiA9IHRoaXMucmVhZF91aW50MTYob2Zmc2V0KTtcbiAgICAgIHJldHVybiB2IHwgKHYgJiAweDgwMDApICogMHgxZmZmZTtcblxuICAgIGNhc2UgNDogLy8gbG9uZ1xuICAgICAgdiA9IHRoaXMucmVhZF91aW50MzIob2Zmc2V0KTtcbiAgICAgIHJldHVybiB2O1xuXG4gICAgY2FzZSA5OiAvLyBzbG9uZ1xuICAgICAgdiA9IHRoaXMucmVhZF91aW50MzIob2Zmc2V0KTtcbiAgICAgIHJldHVybiB2IHwgMDtcblxuICAgIGNhc2UgNTogIC8vIHJhdGlvbmFsXG4gICAgY2FzZSAxMDogLy8gc3JhdGlvbmFsXG4gICAgY2FzZSAxMTogLy8gZmxvYXRcbiAgICBjYXNlIDEyOiAvLyBkb3VibGVcbiAgICAgIHJldHVybiBudWxsOyAvLyBub3QgaW1wbGVtZW50ZWRcblxuICAgIGNhc2UgNzogLy8gdW5kZWZpbmVkXG4gICAgICByZXR1cm4gbnVsbDsgLy8gYmxvYlxuXG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIHVua25vd24gdHlwZVxuICAgICAgcmV0dXJuIG51bGw7XG4gIH1cbn07XG5cblxuRXhpZlBhcnNlci5wcm90b3R5cGUuc2Nhbl9pZmQgPSBmdW5jdGlvbiAoaWZkX25vLCBvZmZzZXQsIG9uX2VudHJ5KSB7XG4gIHZhciBlbnRyeV9jb3VudCA9IHRoaXMucmVhZF91aW50MTYob2Zmc2V0KTtcblxuICBvZmZzZXQgKz0gMjtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGVudHJ5X2NvdW50OyBpKyspIHtcbiAgICB2YXIgdGFnICAgID0gdGhpcy5yZWFkX3VpbnQxNihvZmZzZXQpO1xuICAgIHZhciBmb3JtYXQgPSB0aGlzLnJlYWRfdWludDE2KG9mZnNldCArIDIpO1xuICAgIHZhciBjb3VudCAgPSB0aGlzLnJlYWRfdWludDMyKG9mZnNldCArIDQpO1xuXG4gICAgdmFyIGNvbXBfbGVuZ3RoICAgID0gdGhpcy5leGlmX2Zvcm1hdF9sZW5ndGgoZm9ybWF0KTtcbiAgICB2YXIgZGF0YV9sZW5ndGggICAgPSBjb3VudCAqIGNvbXBfbGVuZ3RoO1xuICAgIHZhciBkYXRhX29mZnNldCAgICA9IGRhdGFfbGVuZ3RoIDw9IDQgPyBvZmZzZXQgKyA4IDogdGhpcy5yZWFkX3VpbnQzMihvZmZzZXQgKyA4KTtcbiAgICB2YXIgaXNfc3ViaWZkX2xpbmsgPSBmYWxzZTtcblxuICAgIGlmIChkYXRhX29mZnNldCArIGRhdGFfbGVuZ3RoID4gdGhpcy5pbnB1dC5sZW5ndGgpIHtcbiAgICAgIHRocm93IGVycm9yKCd1bmV4cGVjdGVkIEVPRicsICdFQkFEREFUQScpO1xuICAgIH1cblxuICAgIHZhciB2YWx1ZSA9IFtdO1xuICAgIHZhciBjb21wX29mZnNldCA9IGRhdGFfb2Zmc2V0O1xuXG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBjb3VudDsgaisrLCBjb21wX29mZnNldCArPSBjb21wX2xlbmd0aCkge1xuICAgICAgdmFyIGl0ZW0gPSB0aGlzLmV4aWZfZm9ybWF0X3JlYWQoZm9ybWF0LCBjb21wX29mZnNldCk7XG4gICAgICBpZiAoaXRlbSA9PT0gbnVsbCkge1xuICAgICAgICB2YWx1ZSA9IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgdmFsdWUucHVzaChpdGVtKTtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgZm9ybWF0ID09PSAyKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YWx1ZSA9IHV0ZjhfZGVjb2RlKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgdmFsdWUpKTtcbiAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgdmFsdWUgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBpZiAodmFsdWUgJiYgdmFsdWVbdmFsdWUubGVuZ3RoIC0gMV0gPT09ICdcXDAnKSB2YWx1ZSA9IHZhbHVlLnNsaWNlKDAsIC0xKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc19zdWJpZmRfbGluayhpZmRfbm8sIHRhZykpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSAmJiBOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlWzBdKSAmJiB2YWx1ZVswXSA+IDApIHtcbiAgICAgICAgdGhpcy5pZmRzX3RvX3JlYWQucHVzaCh7XG4gICAgICAgICAgaWQ6ICAgICB0YWcsXG4gICAgICAgICAgb2Zmc2V0OiB2YWx1ZVswXVxuICAgICAgICB9KTtcbiAgICAgICAgaXNfc3ViaWZkX2xpbmsgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBlbnRyeSA9IHtcbiAgICAgIGlzX2JpZ19lbmRpYW46ICB0aGlzLmJpZ19lbmRpYW4sXG4gICAgICBpZmQ6ICAgICAgICAgICAgaWZkX25vLFxuICAgICAgdGFnOiAgICAgICAgICAgIHRhZyxcbiAgICAgIGZvcm1hdDogICAgICAgICBmb3JtYXQsXG4gICAgICBjb3VudDogICAgICAgICAgY291bnQsXG4gICAgICBlbnRyeV9vZmZzZXQ6ICAgb2Zmc2V0ICsgdGhpcy5zdGFydCxcbiAgICAgIGRhdGFfbGVuZ3RoOiAgICBkYXRhX2xlbmd0aCxcbiAgICAgIGRhdGFfb2Zmc2V0OiAgICBkYXRhX29mZnNldCArIHRoaXMuc3RhcnQsXG4gICAgICB2YWx1ZTogICAgICAgICAgdmFsdWUsXG4gICAgICBpc19zdWJpZmRfbGluazogaXNfc3ViaWZkX2xpbmtcbiAgICB9O1xuXG4gICAgaWYgKG9uX2VudHJ5KGVudHJ5KSA9PT0gZmFsc2UpIHtcbiAgICAgIHRoaXMuYWJvcnRlZCA9IHRydWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgb2Zmc2V0ICs9IDEyO1xuICB9XG5cbiAgaWYgKGlmZF9ubyA9PT0gMCkge1xuICAgIHRoaXMuaWZkc190b19yZWFkLnB1c2goe1xuICAgICAgaWQ6ICAgICAxLFxuICAgICAgb2Zmc2V0OiB0aGlzLnJlYWRfdWludDMyKG9mZnNldClcbiAgICB9KTtcbiAgfVxufTtcblxuXG4vLyBDaGVjayB3aGV0aGVyIGlucHV0IGlzIGEgSlBFRyBpbWFnZVxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46IFVpbnQ4QXJyYXkgLSBqcGVnIGZpbGVcbi8vXG4vLyBSZXR1cm5zIHRydWUgaWYgaXQgaXMgYW5kIGZhbHNlIG90aGVyd2lzZVxuLy9cbm1vZHVsZS5leHBvcnRzLmlzX2pwZWcgPSBmdW5jdGlvbiAoanBlZ19iaW4pIHtcbiAgcmV0dXJuIGpwZWdfYmluLmxlbmd0aCA+PSA0ICYmIGpwZWdfYmluWzBdID09PSAweEZGICYmIGpwZWdfYmluWzFdID09PSAweEQ4ICYmIGpwZWdfYmluWzJdID09PSAweEZGO1xufTtcblxuXG4vLyBDYWxsIGFuIGl0ZXJhdG9yIG9uIGVhY2ggc2VnbWVudCBpbiB0aGUgZ2l2ZW4gSlBFRyBpbWFnZVxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46ICAgVWludDhBcnJheSAtIGpwZWcgZmlsZVxuLy8gIC0gb25fc2VnbWVudDogRnVuY3Rpb24gLSBjYWxsYmFjayBleGVjdXRlZCBvbiBlYWNoIEpQRUcgbWFya2VyIHNlZ21lbnRcbi8vICAgIC0gc2VnbWVudDogIE9iamVjdFxuLy8gICAgICAtIGNvZGU6ICAgTnVtYmVyIC0gbWFya2VyIHR5cGUgKDJuZCBieXRlLCBlLmcuIDB4RTAgZm9yIEFQUDApXG4vLyAgICAgIC0gb2Zmc2V0OiBOdW1iZXIgLSBvZmZzZXQgb2YgdGhlIGZpcnN0IGJ5dGUgKDB4RkYpIHJlbGF0aXZlIHRvIGBqcGVnX2JpbmAgc3RhcnRcbi8vICAgICAgLSBsZW5ndGg6IE51bWJlciAtIGxlbmd0aCBvZiB0aGUgZW50aXJlIG1hcmtlciBzZWdtZW50IGluY2x1ZGluZyBmaXJzdCB0d28gYnl0ZXMgYW5kIGxlbmd0aFxuLy8gICAgICAgIC0gMiBmb3Igc3RhbmRhbG9uZSBtYXJrZXJzXG4vLyAgICAgICAgLSA0K2xlbmd0aCBmb3IgbWFya2VycyB3aXRoIGRhdGFcbi8vXG4vLyBJdGVyYXRpb24gc3RvcHMgd2hlbiBgRU9JYCAoMHhGRkQ5KSBtYXJrZXIgaXMgcmVhY2hlZCBvciBpZiBgb25fc2VnbWVudGBcbi8vIGZ1bmN0aW9uIHJldHVybnMgYGZhbHNlYC5cbi8vXG5tb2R1bGUuZXhwb3J0cy5qcGVnX3NlZ21lbnRzX2VhY2ggPSBmdW5jdGlvbiAoanBlZ19iaW4sIG9uX3NlZ21lbnQpIHtcbiAgaWYgKCFpc191aW50OGFycmF5KGpwZWdfYmluKSkge1xuICAgIHRocm93IGVycm9yKCdJbnZhbGlkIGFyZ3VtZW50IChqcGVnX2JpbiksIFVpbnQ4QXJyYXkgZXhwZWN0ZWQnLCAnRUlOVkFMJyk7XG4gIH1cblxuICBpZiAodHlwZW9mIG9uX3NlZ21lbnQgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBlcnJvcignSW52YWxpZCBhcmd1bWVudCAob25fc2VnbWVudCksIEZ1bmN0aW9uIGV4cGVjdGVkJywgJ0VJTlZBTCcpO1xuICB9XG5cbiAgaWYgKCFtb2R1bGUuZXhwb3J0cy5pc19qcGVnKGpwZWdfYmluKSkge1xuICAgIHRocm93IGVycm9yKCdVbmtub3duIGZpbGUgZm9ybWF0JywgJ0VOT1RKUEVHJyk7XG4gIH1cblxuICB2YXIgb2Zmc2V0ID0gMCwgbGVuZ3RoID0ganBlZ19iaW4ubGVuZ3RoLCBpbnNpZGVfc2NhbiA9IGZhbHNlO1xuXG4gIGZvciAoOzspIHtcbiAgICB2YXIgc2VnbWVudF9jb2RlLCBzZWdtZW50X2xlbmd0aDtcblxuICAgIGlmIChvZmZzZXQgKyAxID49IGxlbmd0aCkgdGhyb3cgZXJyb3IoJ1VuZXhwZWN0ZWQgRU9GJywgJ0VCQUREQVRBJyk7XG4gICAgdmFyIGJ5dGUxID0ganBlZ19iaW5bb2Zmc2V0XTtcbiAgICB2YXIgYnl0ZTIgPSBqcGVnX2JpbltvZmZzZXQgKyAxXTtcblxuICAgIGlmIChieXRlMSA9PT0gMHhGRiAmJiBieXRlMiA9PT0gMHhGRikge1xuICAgICAgLy8gcGFkZGluZ1xuICAgICAgc2VnbWVudF9jb2RlID0gMHhGRjtcbiAgICAgIHNlZ21lbnRfbGVuZ3RoID0gMTtcblxuICAgIH0gZWxzZSBpZiAoYnl0ZTEgPT09IDB4RkYgJiYgYnl0ZTIgIT09IDApIHtcbiAgICAgIC8vIG1hcmtlclxuICAgICAgc2VnbWVudF9jb2RlID0gYnl0ZTI7XG4gICAgICBzZWdtZW50X2xlbmd0aCA9IDI7XG5cbiAgICAgIGlmICgoMHhEMCA8PSBzZWdtZW50X2NvZGUgJiYgc2VnbWVudF9jb2RlIDw9IDB4RDkpIHx8IHNlZ21lbnRfY29kZSA9PT0gMHgwMSkgOyBlbHNlIHtcbiAgICAgICAgaWYgKG9mZnNldCArIDMgPj0gbGVuZ3RoKSB0aHJvdyBlcnJvcignVW5leHBlY3RlZCBFT0YnLCAnRUJBRERBVEEnKTtcbiAgICAgICAgc2VnbWVudF9sZW5ndGggKz0ganBlZ19iaW5bb2Zmc2V0ICsgMl0gKiAweDEwMCArIGpwZWdfYmluW29mZnNldCArIDNdO1xuICAgICAgICBpZiAoc2VnbWVudF9sZW5ndGggPCAyKSB0aHJvdyBlcnJvcignSW52YWxpZCBzZWdtZW50IGxlbmd0aCcsICdFQkFEREFUQScpO1xuICAgICAgICBpZiAob2Zmc2V0ICsgc2VnbWVudF9sZW5ndGggLSAxID49IGxlbmd0aCkgdGhyb3cgZXJyb3IoJ1VuZXhwZWN0ZWQgRU9GJywgJ0VCQUREQVRBJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbnNpZGVfc2Nhbikge1xuICAgICAgICBpZiAoc2VnbWVudF9jb2RlID49IDB4RDAgJiYgc2VnbWVudF9jb2RlIDw9IDB4RDcpIDsgZWxzZSB7XG4gICAgICAgICAgaW5zaWRlX3NjYW4gPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoc2VnbWVudF9jb2RlID09PSAweERBIC8qIFNPUyAqLykgaW5zaWRlX3NjYW4gPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoaW5zaWRlX3NjYW4pIHtcbiAgICAgIC8vIGVudHJvcHktZW5jb2RlZCBzZWdtZW50XG4gICAgICBmb3IgKHZhciBwb3MgPSBvZmZzZXQgKyAxOyA7IHBvcysrKSB7XG4gICAgICAgIC8vIHNjYW4gdW50aWwgd2UgZmluZCBGRlxuICAgICAgICBpZiAocG9zID49IGxlbmd0aCkgdGhyb3cgZXJyb3IoJ1VuZXhwZWN0ZWQgRU9GJywgJ0VCQUREQVRBJyk7XG4gICAgICAgIGlmIChqcGVnX2Jpbltwb3NdID09PSAweEZGKSB7XG4gICAgICAgICAgaWYgKHBvcyArIDEgPj0gbGVuZ3RoKSB0aHJvdyBlcnJvcignVW5leHBlY3RlZCBFT0YnLCAnRUJBRERBVEEnKTtcbiAgICAgICAgICBpZiAoanBlZ19iaW5bcG9zICsgMV0gIT09IDApIHtcbiAgICAgICAgICAgIHNlZ21lbnRfY29kZSA9IDA7XG4gICAgICAgICAgICBzZWdtZW50X2xlbmd0aCA9IHBvcyAtIG9mZnNldDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBlcnJvcignVW5leHBlY3RlZCBieXRlIGF0IHNlZ21lbnQgc3RhcnQ6ICcgKyB0b19oZXgoYnl0ZTEpICtcbiAgICAgICAgJyAob2Zmc2V0ICcgKyB0b19oZXgob2Zmc2V0KSArICcpJywgJ0VCQUREQVRBJyk7XG4gICAgfVxuXG4gICAgaWYgKG9uX3NlZ21lbnQoeyBjb2RlOiBzZWdtZW50X2NvZGUsIG9mZnNldDogb2Zmc2V0LCBsZW5ndGg6IHNlZ21lbnRfbGVuZ3RoIH0pID09PSBmYWxzZSkgYnJlYWs7XG4gICAgaWYgKHNlZ21lbnRfY29kZSA9PT0gMHhEOSAvKiBFT0kgKi8pIGJyZWFrO1xuICAgIG9mZnNldCArPSBzZWdtZW50X2xlbmd0aDtcbiAgfVxufTtcblxuXG4vLyBSZXBsYWNlIG9yIHJlbW92ZSBzZWdtZW50cyBpbiB0aGUgZ2l2ZW4gSlBFRyBpbWFnZVxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46ICAgVWludDhBcnJheSAtIGpwZWcgZmlsZVxuLy8gIC0gb25fc2VnbWVudDogRnVuY3Rpb24gLSBjYWxsYmFjayBleGVjdXRlZCBvbiBlYWNoIEpQRUcgbWFya2VyIHNlZ21lbnRcbi8vICAgIC0gc2VnbWVudDogIE9iamVjdFxuLy8gICAgICAtIGNvZGU6ICAgTnVtYmVyIC0gbWFya2VyIHR5cGUgKDJuZCBieXRlLCBlLmcuIDB4RTAgZm9yIEFQUDApXG4vLyAgICAgIC0gb2Zmc2V0OiBOdW1iZXIgLSBvZmZzZXQgb2YgdGhlIGZpcnN0IGJ5dGUgKDB4RkYpIHJlbGF0aXZlIHRvIGBqcGVnX2JpbmAgc3RhcnRcbi8vICAgICAgLSBsZW5ndGg6IE51bWJlciAtIGxlbmd0aCBvZiB0aGUgZW50aXJlIG1hcmtlciBzZWdtZW50IGluY2x1ZGluZyBmaXJzdCB0d28gYnl0ZXMgYW5kIGxlbmd0aFxuLy8gICAgICAgIC0gMiBmb3Igc3RhbmRhbG9uZSBtYXJrZXJzXG4vLyAgICAgICAgLSA0K2xlbmd0aCBmb3IgbWFya2VycyB3aXRoIGRhdGFcbi8vXG4vLyBgb25fc2VnbWVudGAgZnVuY3Rpb24gc2hvdWxkIHJldHVybiBvbmUgb2YgdGhlIGZvbGxvd2luZzpcbi8vICAtIGBmYWxzZWAgICAgICAgIC0gc2VnbWVudCBpcyByZW1vdmVkIGZyb20gdGhlIG91dHB1dFxuLy8gIC0gVWludDhBcnJheSAgICAgLSBzZWdtZW50IGlzIHJlcGxhY2VkIHdpdGggdGhlIG5ldyBkYXRhXG4vLyAgLSBbIFVpbnQ4QXJyYXkgXSAtIHNlZ21lbnQgaXMgcmVwbGFjZWQgd2l0aCB0aGUgbmV3IGRhdGFcbi8vICAtIGFueXRoaW5nIGVsc2UgIC0gc2VnbWVudCBpcyBjb3BpZWQgdG8gdGhlIG91dHB1dCBhcyBpc1xuLy9cbi8vIEFueSBkYXRhIGFmdGVyIGBFT0lgICgweEZGRDkpIG1hcmtlciBpcyByZW1vdmVkLlxuLy9cbm1vZHVsZS5leHBvcnRzLmpwZWdfc2VnbWVudHNfZmlsdGVyID0gZnVuY3Rpb24gKGpwZWdfYmluLCBvbl9zZWdtZW50KSB7XG4gIGlmICghaXNfdWludDhhcnJheShqcGVnX2JpbikpIHtcbiAgICB0aHJvdyBlcnJvcignSW52YWxpZCBhcmd1bWVudCAoanBlZ19iaW4pLCBVaW50OEFycmF5IGV4cGVjdGVkJywgJ0VJTlZBTCcpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvbl9zZWdtZW50ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgZXJyb3IoJ0ludmFsaWQgYXJndW1lbnQgKG9uX3NlZ21lbnQpLCBGdW5jdGlvbiBleHBlY3RlZCcsICdFSU5WQUwnKTtcbiAgfVxuXG4gIHZhciByYW5nZXMgPSBbXTtcbiAgdmFyIG91dF9sZW5ndGggPSAwO1xuXG4gIG1vZHVsZS5leHBvcnRzLmpwZWdfc2VnbWVudHNfZWFjaChqcGVnX2JpbiwgZnVuY3Rpb24gKHNlZ21lbnQpIHtcbiAgICB2YXIgbmV3X3NlZ21lbnQgPSBvbl9zZWdtZW50KHNlZ21lbnQpO1xuXG4gICAgaWYgKGlzX3VpbnQ4YXJyYXkobmV3X3NlZ21lbnQpKSB7XG4gICAgICByYW5nZXMucHVzaCh7IGRhdGE6IG5ld19zZWdtZW50IH0pO1xuICAgICAgb3V0X2xlbmd0aCArPSBuZXdfc2VnbWVudC5sZW5ndGg7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KG5ld19zZWdtZW50KSkge1xuICAgICAgbmV3X3NlZ21lbnQuZmlsdGVyKGlzX3VpbnQ4YXJyYXkpLmZvckVhY2goZnVuY3Rpb24gKHMpIHtcbiAgICAgICAgcmFuZ2VzLnB1c2goeyBkYXRhOiBzIH0pO1xuICAgICAgICBvdXRfbGVuZ3RoICs9IHMubGVuZ3RoO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChuZXdfc2VnbWVudCAhPT0gZmFsc2UpIHtcbiAgICAgIHZhciBuZXdfcmFuZ2UgPSB7IHN0YXJ0OiBzZWdtZW50Lm9mZnNldCwgZW5kOiBzZWdtZW50Lm9mZnNldCArIHNlZ21lbnQubGVuZ3RoIH07XG5cbiAgICAgIGlmIChyYW5nZXMubGVuZ3RoID4gMCAmJiByYW5nZXNbcmFuZ2VzLmxlbmd0aCAtIDFdLmVuZCA9PT0gbmV3X3JhbmdlLnN0YXJ0KSB7XG4gICAgICAgIHJhbmdlc1tyYW5nZXMubGVuZ3RoIC0gMV0uZW5kID0gbmV3X3JhbmdlLmVuZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJhbmdlcy5wdXNoKG5ld19yYW5nZSk7XG4gICAgICB9XG5cbiAgICAgIG91dF9sZW5ndGggKz0gc2VnbWVudC5sZW5ndGg7XG4gICAgfVxuICB9KTtcblxuICB2YXIgcmVzdWx0ID0gbmV3IFVpbnQ4QXJyYXkob3V0X2xlbmd0aCk7XG4gIHZhciBvZmZzZXQgPSAwO1xuXG4gIHJhbmdlcy5mb3JFYWNoKGZ1bmN0aW9uIChyYW5nZSkge1xuICAgIHZhciBkYXRhID0gcmFuZ2UuZGF0YSB8fCBqcGVnX2Jpbi5zdWJhcnJheShyYW5nZS5zdGFydCwgcmFuZ2UuZW5kKTtcbiAgICByZXN1bHQuc2V0KGRhdGEsIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IGRhdGEubGVuZ3RoO1xuICB9KTtcblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuXG4vLyBDYWxsIGFuIGl0ZXJhdG9yIG9uIGVhY2ggRXhpZiBlbnRyeSBpbiB0aGUgZ2l2ZW4gSlBFRyBpbWFnZVxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46IFVpbnQ4QXJyYXkgLSBqcGVnIGZpbGVcbi8vICAtIG9uX2VudHJ5OiBGdW5jdGlvbiAtIGNhbGxiYWNrIGV4ZWN1dGVkIG9uIGVhY2ggRXhpZiBlbnRyeVxuLy8gICAgLSBlbnRyeTogIE9iamVjdFxuLy8gICAgICAtIGlzX2JpZ19lbmRpYW46ICBCb29sZWFuIC0gd2hldGhlciBFeGlmIHVzZXMgYmlnIG9yIGxpdHRsZSBlbmRpYW4gYnl0ZSBhbGlnbm1lbnRcbi8vICAgICAgLSBpZmQ6ICAgICAgICAgICAgTnVtYmVyICAtIElGRCBpZGVudGlmaWVyICgwIGZvciBJRkQwLCAxIGZvciBJRkQxLCAweDg3NjkgZm9yIFN1YklGRCxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4ODI1IGZvciBHUFMgSW5mbywgMHhBMDA1IGZvciBJbnRlcm9wIElGRClcbi8vICAgICAgLSB0YWc6ICAgICAgICAgICAgTnVtYmVyICAtIGV4aWYgZW50cnkgdGFnICgweDAxMTAgLSBjYW1lcmEgbmFtZSwgMHgwMTEyIC0gb3JpZW50YXRpb24sIGV0Yy4gLSBzZWUgRXhpZiBzcGVjKVxuLy8gICAgICAtIGZvcm1hdDogICAgICAgICBOdW1iZXIgIC0gZXhpZiBlbnRyeSBmb3JtYXQgKDEgLSBieXRlLCAyIC0gYXNjaWksIDMgLSBzaG9ydCwgZXRjLiAtIHNlZSBFeGlmIHNwZWMpXG4vLyAgICAgIC0gY291bnQ6ICAgICAgICAgIE51bWJlciAgLSBudW1iZXIgb2YgY29tcG9uZW50cyBvZiB0aGUgZ2l2ZW4gZm9ybWF0IGluc2lkZSBkYXRhXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1c3VhbGx5IDEsIG9yIHN0cmluZyBsZW5ndGggZm9yIGFzY2lpIGZvcm1hdClcbi8vICAgICAgLSBlbnRyeV9vZmZzZXQ6ICAgTnVtYmVyICAtIHN0YXJ0IG9mIEV4aWYgZW50cnkgKGVudHJ5IGxlbmd0aCBpcyBhbHdheXMgMTIsIHNvIG5vdCBpbmNsdWRlZClcbi8vICAgICAgLSBkYXRhX29mZnNldDogICAgTnVtYmVyICAtIHN0YXJ0IG9mIGRhdGEgYXR0YWNoZWQgdG8gRXhpZiBlbnRyeSAod2lsbCBvdmVybGFwIHdpdGggZW50cnkgaWYgbGVuZ3RoIDw9IDQpXG4vLyAgICAgIC0gZGF0YV9sZW5ndGg6ICAgIE51bWJlciAgLSBsZW5ndGggb2YgZGF0YSBhdHRhY2hlZCB0byBFeGlmIGVudHJ5XG4vLyAgICAgIC0gdmFsdWU6ICAgICAgICAgIEFycmF5fFN0cmluZ3xOdWxsIC0gb3VyIGJlc3QgYXR0ZW1wdCBhdCBwYXJzaW5nIGRhdGEgKG5vdCBhbGwgZm9ybWF0cyBzdXBwb3J0ZWQgcmlnaHQgbm93KVxuLy8gICAgICAtIGlzX3N1YmlmZF9saW5rOiBCb29sZWFuIC0gd2hldGhlciB0aGlzIGVudHJ5IGlzIHJlY29nbml6ZWQgdG8gYmUgYSBsaW5rIHRvIHN1YmlmZCAoY2FuJ3QgZmlsdGVyIHRoZXNlIG91dClcbi8vXG4vLyBJdGVyYXRpb24gc3RvcHMgZWFybHkgaWYgaXRlcmF0b3IgcmV0dXJucyBgZmFsc2VgLlxuLy9cbi8vIElmIEV4aWYgd2Fzbid0IGZvdW5kIGFueXdoZXJlIChiZWZvcmUgc3RhcnQgb2YgdGhlIGltYWdlIGRhdGEsIFNPUyksXG4vLyBpdGVyYXRvciBpcyBuZXZlciBleGVjdXRlZC5cbi8vXG5tb2R1bGUuZXhwb3J0cy5qcGVnX2V4aWZfdGFnc19lYWNoID0gZnVuY3Rpb24gKGpwZWdfYmluLCBvbl9leGlmX2VudHJ5KSB7XG4gIGlmICghaXNfdWludDhhcnJheShqcGVnX2JpbikpIHtcbiAgICB0aHJvdyBlcnJvcignSW52YWxpZCBhcmd1bWVudCAoanBlZ19iaW4pLCBVaW50OEFycmF5IGV4cGVjdGVkJywgJ0VJTlZBTCcpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvbl9leGlmX2VudHJ5ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgZXJyb3IoJ0ludmFsaWQgYXJndW1lbnQgKG9uX2V4aWZfZW50cnkpLCBGdW5jdGlvbiBleHBlY3RlZCcsICdFSU5WQUwnKTtcbiAgfVxuXG4gIC8qIGVzbGludC1kaXNhYmxlIGNvbnNpc3RlbnQtcmV0dXJuICovXG4gIG1vZHVsZS5leHBvcnRzLmpwZWdfc2VnbWVudHNfZWFjaChqcGVnX2JpbiwgZnVuY3Rpb24gKHNlZ21lbnQpIHtcbiAgICBpZiAoc2VnbWVudC5jb2RlID09PSAweERBIC8qIFNPUyAqLykgcmV0dXJuIGZhbHNlO1xuXG4gICAgLy8gbG9vayBmb3IgQVBQMSBzZWdtZW50IGFuZCBjb21wYXJlIGhlYWRlciB3aXRoICdFeGlmXFwwXFwwJ1xuICAgIGlmIChzZWdtZW50LmNvZGUgPT09IDB4RTEgJiYgc2VnbWVudC5sZW5ndGggPj0gMTAgJiZcbiAgICAgICAganBlZ19iaW5bc2VnbWVudC5vZmZzZXQgKyA0XSA9PT0gMHg0NSAmJiBqcGVnX2JpbltzZWdtZW50Lm9mZnNldCArIDVdID09PSAweDc4ICYmXG4gICAgICAgIGpwZWdfYmluW3NlZ21lbnQub2Zmc2V0ICsgNl0gPT09IDB4NjkgJiYganBlZ19iaW5bc2VnbWVudC5vZmZzZXQgKyA3XSA9PT0gMHg2NiAmJlxuICAgICAgICBqcGVnX2JpbltzZWdtZW50Lm9mZnNldCArIDhdID09PSAweDAwICYmIGpwZWdfYmluW3NlZ21lbnQub2Zmc2V0ICsgOV0gPT09IDB4MDApIHtcblxuICAgICAgbmV3IEV4aWZQYXJzZXIoanBlZ19iaW4sIHNlZ21lbnQub2Zmc2V0ICsgMTAsIHNlZ21lbnQub2Zmc2V0ICsgc2VnbWVudC5sZW5ndGgpLmVhY2gob25fZXhpZl9lbnRyeSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcbn07XG5cblxuLy8gUmVtb3ZlIEV4aWYgZW50cmllcyBpbiB0aGUgZ2l2ZW4gSlBFRyBpbWFnZVxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46IFVpbnQ4QXJyYXkgLSBqcGVnIGZpbGVcbi8vICAtIG9uX2VudHJ5OiBGdW5jdGlvbiAtIGNhbGxiYWNrIGV4ZWN1dGVkIG9uIGVhY2ggRXhpZiBlbnRyeVxuLy8gICAgLSBlbnRyeTogIE9iamVjdFxuLy8gICAgICAtIGlzX2JpZ19lbmRpYW46ICBCb29sZWFuIC0gd2hldGhlciBFeGlmIHVzZXMgYmlnIG9yIGxpdHRsZSBlbmRpYW4gYnl0ZSBhbGlnbm1lbnRcbi8vICAgICAgLSBpZmQ6ICAgICAgICAgICAgTnVtYmVyICAtIElGRCBpZGVudGlmaWVyICgwIGZvciBJRkQwLCAxIGZvciBJRkQxLCAweDg3NjkgZm9yIFN1YklGRCxcbi8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODgyNSBmb3IgR1BTIEluZm8sIDB4QTAwNSBmb3IgSW50ZXJvcCBJRkQpXG4vLyAgICAgIC0gdGFnOiAgICAgICAgICAgIE51bWJlciAgLSBleGlmIGVudHJ5IHRhZyAoMHgwMTEwIC0gY2FtZXJhIG5hbWUsIDB4MDExMiAtIG9yaWVudGF0aW9uLCBldGMuIC0gc2VlIEV4aWYgc3BlYylcbi8vICAgICAgLSBmb3JtYXQ6ICAgICAgICAgTnVtYmVyICAtIGV4aWYgZW50cnkgZm9ybWF0ICgxIC0gYnl0ZSwgMiAtIGFzY2lpLCAzIC0gc2hvcnQsIGV0Yy4gLSBzZWUgRXhpZiBzcGVjKVxuLy8gICAgICAtIGNvdW50OiAgICAgICAgICBOdW1iZXIgIC0gbnVtYmVyIG9mIGNvbXBvbmVudHMgb2YgdGhlIGdpdmVuIGZvcm1hdCBpbnNpZGUgZGF0YVxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVzdWFsbHkgMSwgb3Igc3RyaW5nIGxlbmd0aCBmb3IgYXNjaWkgZm9ybWF0KVxuLy8gICAgICAtIGVudHJ5X29mZnNldDogICBOdW1iZXIgIC0gc3RhcnQgb2YgRXhpZiBlbnRyeSAoZW50cnkgbGVuZ3RoIGlzIGFsd2F5cyAxMiwgc28gbm90IGluY2x1ZGVkKVxuLy8gICAgICAtIGRhdGFfb2Zmc2V0OiAgICBOdW1iZXIgIC0gc3RhcnQgb2YgZGF0YSBhdHRhY2hlZCB0byBFeGlmIGVudHJ5ICh3aWxsIG92ZXJsYXAgd2l0aCBlbnRyeSBpZiBsZW5ndGggPD0gNClcbi8vICAgICAgLSBkYXRhX2xlbmd0aDogICAgTnVtYmVyICAtIGxlbmd0aCBvZiBkYXRhIGF0dGFjaGVkIHRvIEV4aWYgZW50cnlcbi8vICAgICAgLSB2YWx1ZTogICAgICAgICAgQXJyYXl8U3RyaW5nfE51bGwgLSBvdXIgYmVzdCBhdHRlbXB0IGF0IHBhcnNpbmcgZGF0YSAobm90IGFsbCBmb3JtYXRzIHN1cHBvcnRlZCByaWdodCBub3cpXG4vLyAgICAgIC0gaXNfc3ViaWZkX2xpbms6IEJvb2xlYW4gLSB3aGV0aGVyIHRoaXMgZW50cnkgaXMgcmVjb2duaXplZCB0byBiZSBhIGxpbmsgdG8gc3ViaWZkIChjYW4ndCBmaWx0ZXIgdGhlc2Ugb3V0KVxuLy9cbi8vIFRoaXMgZnVuY3Rpb24gcmVtb3ZlcyBmb2xsb3dpbmcgZnJvbSBFeGlmOlxuLy8gIC0gYWxsIGVudHJpZXMgd2hlcmUgaXRlcmF0b3IgcmV0dXJuZWQgZmFsc2UgKGV4Y2VwdCBzdWJpZmQgbGlua3Mgd2hpY2ggYXJlIG1hbmRhdG9yeSlcbi8vICAtIElGRDEgYW5kIHRodW1ibmFpbCBpbWFnZSAodGhlIHB1cnBvc2Ugb2YgdGhpcyBmdW5jdGlvbiBpcyB0byByZWR1Y2UgZmlsZSBzaXplLFxuLy8gICAgc28gdGh1bWJuYWlsIGlzIHVzdWFsbHkgdGhlIGZpcnN0IHRoaW5nIHRvIGdvKVxuLy8gIC0gYWxsIG90aGVyIGRhdGEgdGhhdCBpc24ndCBpbiBJRkQwLCBTdWJJRkQsIEdQU0lGRCwgSW50ZXJvcElGRFxuLy8gICAgKHRoZW9yZXRpY2FsbHkgcG9zc2libGUgcHJvcHJpZXRhcnkgZXh0ZW5zaW9ucywgSSBoYXZlbid0IHNlZW4gYW55IG9mIHRoZXNlIHlldClcbi8vXG4vLyBDaGFuZ2luZyBkYXRhIGluc2lkZSBFeGlmIGVudHJpZXMgaXMgTk9UIHN1cHBvcnRlZCB5ZXQgKG1vZGlmeWluZyBgZW50cnlgIG9iamVjdCBpbnNpZGUgY2FsbGJhY2sgbWF5IGJyZWFrIHN0dWZmKS5cbi8vXG4vLyBJZiBFeGlmIHdhc24ndCBmb3VuZCBhbnl3aGVyZSAoYmVmb3JlIHN0YXJ0IG9mIHRoZSBpbWFnZSBkYXRhLCBTT1MpLFxuLy8gaXRlcmF0b3IgaXMgbmV2ZXIgZXhlY3V0ZWQsIGFuZCBvcmlnaW5hbCBKUEVHIGlzIHJldHVybmVkIGFzIGlzLlxuLy9cbm1vZHVsZS5leHBvcnRzLmpwZWdfZXhpZl90YWdzX2ZpbHRlciA9IGZ1bmN0aW9uIChqcGVnX2Jpbiwgb25fZXhpZl9lbnRyeSkge1xuICBpZiAoIWlzX3VpbnQ4YXJyYXkoanBlZ19iaW4pKSB7XG4gICAgdGhyb3cgZXJyb3IoJ0ludmFsaWQgYXJndW1lbnQgKGpwZWdfYmluKSwgVWludDhBcnJheSBleHBlY3RlZCcsICdFSU5WQUwnKTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb25fZXhpZl9lbnRyeSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IGVycm9yKCdJbnZhbGlkIGFyZ3VtZW50IChvbl9leGlmX2VudHJ5KSwgRnVuY3Rpb24gZXhwZWN0ZWQnLCAnRUlOVkFMJyk7XG4gIH1cblxuICB2YXIgc3RvcF9zZWFyY2ggPSBmYWxzZTtcblxuICByZXR1cm4gbW9kdWxlLmV4cG9ydHMuanBlZ19zZWdtZW50c19maWx0ZXIoanBlZ19iaW4sIGZ1bmN0aW9uIChzZWdtZW50KSB7XG4gICAgaWYgKHN0b3Bfc2VhcmNoKSByZXR1cm47XG4gICAgaWYgKHNlZ21lbnQuY29kZSA9PT0gMHhEQSAvKiBTT1MgKi8pIHN0b3Bfc2VhcmNoID0gdHJ1ZTtcblxuICAgIC8vIGxvb2sgZm9yIEFQUDEgc2VnbWVudCBhbmQgY29tcGFyZSBoZWFkZXIgd2l0aCAnRXhpZlxcMFxcMCdcbiAgICBpZiAoc2VnbWVudC5jb2RlID09PSAweEUxICYmIHNlZ21lbnQubGVuZ3RoID49IDEwICYmXG4gICAgICAgIGpwZWdfYmluW3NlZ21lbnQub2Zmc2V0ICsgNF0gPT09IDB4NDUgJiYganBlZ19iaW5bc2VnbWVudC5vZmZzZXQgKyA1XSA9PT0gMHg3OCAmJlxuICAgICAgICBqcGVnX2JpbltzZWdtZW50Lm9mZnNldCArIDZdID09PSAweDY5ICYmIGpwZWdfYmluW3NlZ21lbnQub2Zmc2V0ICsgN10gPT09IDB4NjYgJiZcbiAgICAgICAganBlZ19iaW5bc2VnbWVudC5vZmZzZXQgKyA4XSA9PT0gMHgwMCAmJiBqcGVnX2JpbltzZWdtZW50Lm9mZnNldCArIDldID09PSAweDAwKSB7XG5cbiAgICAgIHZhciBuZXdfZXhpZiA9IG5ldyBFeGlmUGFyc2VyKGpwZWdfYmluLCBzZWdtZW50Lm9mZnNldCArIDEwLCBzZWdtZW50Lm9mZnNldCArIHNlZ21lbnQubGVuZ3RoKVxuICAgICAgICAuZmlsdGVyKG9uX2V4aWZfZW50cnkpO1xuICAgICAgaWYgKCFuZXdfZXhpZikgcmV0dXJuIGZhbHNlO1xuXG4gICAgICB2YXIgaGVhZGVyID0gbmV3IFVpbnQ4QXJyYXkoMTApO1xuXG4gICAgICBoZWFkZXIuc2V0KGpwZWdfYmluLnNsaWNlKHNlZ21lbnQub2Zmc2V0LCBzZWdtZW50Lm9mZnNldCArIDEwKSk7XG4gICAgICBoZWFkZXJbMl0gPSAoKG5ld19leGlmLmxlbmd0aCArIDgpID4+PiA4KSAmIDB4RkY7XG4gICAgICBoZWFkZXJbM10gPSAobmV3X2V4aWYubGVuZ3RoICsgOCkgJiAweEZGO1xuXG4gICAgICBzdG9wX3NlYXJjaCA9IHRydWU7XG4gICAgICByZXR1cm4gWyBoZWFkZXIsIG5ld19leGlmIF07XG4gICAgfVxuICB9KTtcbn07XG5cblxuLy8gSW5zZXJ0cyBhIGN1c3RvbSBjb21tZW50IG1hcmtlciBzZWdtZW50IGludG8gSlBFRyBmaWxlLlxuLy9cbi8vIElucHV0OlxuLy8gIC0ganBlZ19iaW46IFVpbnQ4QXJyYXkgLSBqcGVnIGZpbGVcbi8vICAtIGNvbW1lbnQ6ICBTdHJpbmdcbi8vXG4vLyBDb21tZW50IGlzIGluc2VydGVkIGFmdGVyIGZpcnN0IHR3byBieXRlcyAoRkZEOCwgU09JKS5cbi8vXG4vLyBJZiBKRklGIChBUFAwKSBtYXJrZXIgZXhpc3RzIGltbWVkaWF0ZWx5IGFmdGVyIFNPSSAoYXMgbWFuZGF0ZWQgYnkgdGhlIEpGSUZcbi8vIHNwZWMpLCB3ZSBpbnNlcnQgY29tbWVudCBhZnRlciBpdCBpbnN0ZWFkLlxuLy9cbm1vZHVsZS5leHBvcnRzLmpwZWdfYWRkX2NvbW1lbnQgPSBmdW5jdGlvbiAoanBlZ19iaW4sIGNvbW1lbnQpIHtcbiAgdmFyIGNvbW1lbnRfaW5zZXJ0ZWQgPSBmYWxzZSwgc2VnbWVudF9jb3VudCA9IDA7XG5cbiAgcmV0dXJuIG1vZHVsZS5leHBvcnRzLmpwZWdfc2VnbWVudHNfZmlsdGVyKGpwZWdfYmluLCBmdW5jdGlvbiAoc2VnbWVudCkge1xuICAgIHNlZ21lbnRfY291bnQrKztcbiAgICBpZiAoc2VnbWVudF9jb3VudCA9PT0gMSAmJiBzZWdtZW50LmNvZGUgPT09IDB4RDggLyogU09JICAqLykgcmV0dXJuO1xuICAgIGlmIChzZWdtZW50X2NvdW50ID09PSAyICYmIHNlZ21lbnQuY29kZSA9PT0gMHhFMCAvKiBBUFAwICovKSByZXR1cm47XG5cbiAgICBpZiAoY29tbWVudF9pbnNlcnRlZCkgcmV0dXJuO1xuICAgIGNvbW1lbnQgPSB1dGY4X2VuY29kZShjb21tZW50KTtcblxuICAgIC8vIGNvbW1lbnQgc2VnbWVudFxuICAgIHZhciBjc2VnbWVudCA9IG5ldyBVaW50OEFycmF5KDUgKyBjb21tZW50Lmxlbmd0aCk7XG4gICAgdmFyIG9mZnNldCA9IDA7XG5cbiAgICBjc2VnbWVudFtvZmZzZXQrK10gPSAweEZGO1xuICAgIGNzZWdtZW50W29mZnNldCsrXSA9IDB4RkU7XG4gICAgY3NlZ21lbnRbb2Zmc2V0KytdID0gKChjb21tZW50Lmxlbmd0aCArIDMpID4+PiA4KSAmIDB4RkY7XG4gICAgY3NlZ21lbnRbb2Zmc2V0KytdID0gKGNvbW1lbnQubGVuZ3RoICsgMykgJiAweEZGO1xuXG4gICAgY29tbWVudC5zcGxpdCgnJykuZm9yRWFjaChmdW5jdGlvbiAoYykge1xuICAgICAgY3NlZ21lbnRbb2Zmc2V0KytdID0gYy5jaGFyQ29kZUF0KDApICYgMHhGRjtcbiAgICB9KTtcblxuICAgIGNzZWdtZW50W29mZnNldCsrXSA9IDA7XG4gICAgY29tbWVudF9pbnNlcnRlZCA9IHRydWU7XG5cbiAgICByZXR1cm4gWyBjc2VnbWVudCwganBlZ19iaW4uc3ViYXJyYXkoc2VnbWVudC5vZmZzZXQsIHNlZ21lbnQub2Zmc2V0ICsgc2VnbWVudC5sZW5ndGgpIF07XG4gIH0pO1xufTtcbn0pO1xuXG5mdW5jdGlvbiBqcGVnX3BhdGNoX2V4aWYoZW52KSB7XG4gIHJldHVybiB0aGlzLl9nZXRVaW50OEFycmF5KGVudi5ibG9iKS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgZW52LmlzX2pwZWcgPSBpbWFnZV90cmF2ZXJzZS5pc19qcGVnKGRhdGEpO1xuXG4gICAgaWYgKCFlbnYuaXNfanBlZykgcmV0dXJuIFByb21pc2UucmVzb2x2ZShlbnYpO1xuXG4gICAgZW52Lm9yaWdfYmxvYiA9IGVudi5ibG9iO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciBleGlmX2lzX2JpZ19lbmRpYW4sIG9yaWVudGF0aW9uX29mZnNldDtcblxuICAgICAgLyogZXNsaW50LWRpc2FibGUgY29uc2lzdGVudC1yZXR1cm4gKi9cbiAgICAgIGltYWdlX3RyYXZlcnNlLmpwZWdfZXhpZl90YWdzX2VhY2goZGF0YSwgZnVuY3Rpb24gKGVudHJ5KSB7XG4gICAgICAgIGlmIChlbnRyeS5pZmQgPT09IDAgJiYgZW50cnkudGFnID09PSAweDExMiAmJiBBcnJheS5pc0FycmF5KGVudHJ5LnZhbHVlKSkge1xuICAgICAgICAgIGVudi5vcmllbnRhdGlvbiAgICA9IGVudHJ5LnZhbHVlWzBdIHx8IDE7XG4gICAgICAgICAgZXhpZl9pc19iaWdfZW5kaWFuID0gZW50cnkuaXNfYmlnX2VuZGlhbjtcbiAgICAgICAgICBvcmllbnRhdGlvbl9vZmZzZXQgPSBlbnRyeS5kYXRhX29mZnNldDtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAob3JpZW50YXRpb25fb2Zmc2V0KSB7XG4gICAgICAgIHZhciBvcmllbnRhdGlvbl9wYXRjaCA9IGV4aWZfaXNfYmlnX2VuZGlhbiA/XG4gICAgICAgICAgbmV3IFVpbnQ4QXJyYXkoWyAwLCAxIF0pIDpcbiAgICAgICAgICBuZXcgVWludDhBcnJheShbIDEsIDAgXSk7XG5cbiAgICAgICAgZW52LmJsb2IgPSBuZXcgQmxvYihbXG4gICAgICAgICAgZGF0YS5zbGljZSgwLCBvcmllbnRhdGlvbl9vZmZzZXQpLFxuICAgICAgICAgIG9yaWVudGF0aW9uX3BhdGNoLFxuICAgICAgICAgIGRhdGEuc2xpY2Uob3JpZW50YXRpb25fb2Zmc2V0ICsgMilcbiAgICAgICAgXSwgeyB0eXBlOiAnaW1hZ2UvanBlZycgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoXykge31cblxuICAgIHJldHVybiBlbnY7XG4gIH0pO1xufVxuXG5cbmZ1bmN0aW9uIGpwZWdfcm90YXRlX2NhbnZhcyhlbnYpIHtcbiAgaWYgKCFlbnYuaXNfanBlZykgcmV0dXJuIFByb21pc2UucmVzb2x2ZShlbnYpO1xuXG4gIHZhciBvcmllbnRhdGlvbiA9IGVudi5vcmllbnRhdGlvbiAtIDE7XG4gIGlmICghb3JpZW50YXRpb24pIHJldHVybiBQcm9taXNlLnJlc29sdmUoZW52KTtcblxuICB2YXIgY2FudmFzO1xuXG4gIGlmIChvcmllbnRhdGlvbiAmIDQpIHtcbiAgICBjYW52YXMgPSB0aGlzLnBpY2Eub3B0aW9ucy5jcmVhdGVDYW52YXMoZW52Lm91dF9jYW52YXMuaGVpZ2h0LCBlbnYub3V0X2NhbnZhcy53aWR0aCk7XG4gIH0gZWxzZSB7XG4gICAgY2FudmFzID0gdGhpcy5waWNhLm9wdGlvbnMuY3JlYXRlQ2FudmFzKGVudi5vdXRfY2FudmFzLndpZHRoLCBlbnYub3V0X2NhbnZhcy5oZWlnaHQpO1xuICB9XG5cbiAgdmFyIGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuXG4gIGN0eC5zYXZlKCk7XG5cbiAgaWYgKG9yaWVudGF0aW9uICYgMSkgY3R4LnRyYW5zZm9ybSgtMSwgMCwgMCwgMSwgY2FudmFzLndpZHRoLCAwKTtcbiAgaWYgKG9yaWVudGF0aW9uICYgMikgY3R4LnRyYW5zZm9ybSgtMSwgMCwgMCwgLTEsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XG4gIGlmIChvcmllbnRhdGlvbiAmIDQpIGN0eC50cmFuc2Zvcm0oMCwgMSwgMSwgMCwgMCwgMCk7XG5cbiAgY3R4LmRyYXdJbWFnZShlbnYub3V0X2NhbnZhcywgMCwgMCk7XG4gIGN0eC5yZXN0b3JlKCk7XG5cbiAgLy8gU2FmYXJpIDEyIHdvcmthcm91bmRcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhL2lzc3Vlcy8xOTlcbiAgZW52Lm91dF9jYW52YXMud2lkdGggPSBlbnYub3V0X2NhbnZhcy5oZWlnaHQgPSAwO1xuXG4gIGVudi5vdXRfY2FudmFzID0gY2FudmFzO1xuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoZW52KTtcbn1cblxuXG5mdW5jdGlvbiBqcGVnX2F0dGFjaF9vcmlnX3NlZ21lbnRzKGVudikge1xuICBpZiAoIWVudi5pc19qcGVnKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGVudik7XG5cbiAgcmV0dXJuIFByb21pc2UuYWxsKFtcbiAgICB0aGlzLl9nZXRVaW50OEFycmF5KGVudi5ibG9iKSxcbiAgICB0aGlzLl9nZXRVaW50OEFycmF5KGVudi5vdXRfYmxvYilcbiAgXSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgdmFyIGRhdGEgPSByZXNbMF07XG4gICAgdmFyIGRhdGFfb3V0ID0gcmVzWzFdO1xuXG4gICAgaWYgKCFpbWFnZV90cmF2ZXJzZS5pc19qcGVnKGRhdGEpKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGVudik7XG5cbiAgICB2YXIgc2VnbWVudHMgPSBbXTtcblxuICAgIGltYWdlX3RyYXZlcnNlLmpwZWdfc2VnbWVudHNfZWFjaChkYXRhLCBmdW5jdGlvbiAoc2VnbWVudCkge1xuICAgICAgaWYgKHNlZ21lbnQuY29kZSA9PT0gMHhEQSAvKiBTT1MgKi8pIHJldHVybiBmYWxzZTtcbiAgICAgIHNlZ21lbnRzLnB1c2goc2VnbWVudCk7XG4gICAgfSk7XG5cbiAgICBzZWdtZW50cyA9IHNlZ21lbnRzXG4gICAgICAuZmlsdGVyKGZ1bmN0aW9uIChzZWdtZW50KSB7XG4gICAgICAgIC8vIERyb3AgSUNDX1BST0ZJTEVcbiAgICAgICAgLy9cbiAgICAgICAgaWYgKHNlZ21lbnQuY29kZSA9PT0gMHhFMikgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIC8vIEtlZXAgYWxsIEFQUG4gc2VnbWVudHMgZXhjbHVkaW5nIEFQUDIgKElDQ19QUk9GSUxFKSxcbiAgICAgICAgLy8gcmVtb3ZlIG90aGVycyBiZWNhdXNlIG1vc3Qgb2YgdGhlbSBkZXBlbmQgb24gaW1hZ2UgZGF0YSAoRENUIGFuZCBzdWNoKS5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gQVBQMCAtIEpGSUYsIEFQUDEgLSBFeGlmLCB0aGUgcmVzdCBhcmUgcGhvdG9zaG9wIG1ldGFkYXRhIGFuZCBzdWNoXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFNlZSBmdWxsIGxpc3QgYXQgaHR0cHM6Ly93d3cudzMub3JnL0dyYXBoaWNzL0pQRUcvaXR1LXQ4MS5wZGYgKHRhYmxlIEIuMSBvbiBwYWdlIDMyKVxuICAgICAgICAvL1xuICAgICAgICBpZiAoc2VnbWVudC5jb2RlID49IDB4RTAgJiYgc2VnbWVudC5jb2RlIDwgMHhGMCkgcmV0dXJuIHRydWU7XG5cbiAgICAgICAgLy8gS2VlcCBjb21tZW50c1xuICAgICAgICAvL1xuICAgICAgICBpZiAoc2VnbWVudC5jb2RlID09PSAweEZFKSByZXR1cm4gdHJ1ZTtcblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9KVxuICAgICAgLm1hcChmdW5jdGlvbiAoc2VnbWVudCkge1xuICAgICAgICByZXR1cm4gZGF0YS5zbGljZShzZWdtZW50Lm9mZnNldCwgc2VnbWVudC5vZmZzZXQgKyBzZWdtZW50Lmxlbmd0aCk7XG4gICAgICB9KTtcblxuICAgIGVudi5vdXRfYmxvYiA9IG5ldyBCbG9iKFxuICAgICAgLy8gaW50ZW50aW9uYWxseSBvbWl0dGluZyBleHBlY3RlZCBKRklGIHNlZ21lbnQgKG9mZnNldCAyIHRvIDIwKVxuICAgICAgWyBkYXRhX291dC5zbGljZSgwLCAyKSBdLmNvbmNhdChzZWdtZW50cykuY29uY2F0KFsgZGF0YV9vdXQuc2xpY2UoMjApIF0pLFxuICAgICAgeyB0eXBlOiAnaW1hZ2UvanBlZycgfVxuICAgICk7XG5cbiAgICByZXR1cm4gZW52O1xuICB9KTtcbn1cblxuXG5mdW5jdGlvbiBhc3NpZ24ocmVkdWNlcikge1xuICByZWR1Y2VyLmJlZm9yZSgnX2Jsb2JfdG9faW1hZ2UnLCBqcGVnX3BhdGNoX2V4aWYpO1xuICByZWR1Y2VyLmFmdGVyKCdfdHJhbnNmb3JtJywgICAgICBqcGVnX3JvdGF0ZV9jYW52YXMpO1xuICByZWR1Y2VyLmFmdGVyKCdfY3JlYXRlX2Jsb2InLCAgICBqcGVnX2F0dGFjaF9vcmlnX3NlZ21lbnRzKTtcbn1cblxuXG52YXIganBlZ19wYXRjaF9leGlmXzEgPSBqcGVnX3BhdGNoX2V4aWY7XG52YXIganBlZ19yb3RhdGVfY2FudmFzXzEgPSBqcGVnX3JvdGF0ZV9jYW52YXM7XG52YXIganBlZ19hdHRhY2hfb3JpZ19zZWdtZW50c18xID0ganBlZ19hdHRhY2hfb3JpZ19zZWdtZW50cztcbnZhciBhc3NpZ25fMSA9IGFzc2lnbjtcblxudmFyIGpwZWdfcGx1Z2lucyA9IHtcblx0anBlZ19wYXRjaF9leGlmOiBqcGVnX3BhdGNoX2V4aWZfMSxcblx0anBlZ19yb3RhdGVfY2FudmFzOiBqcGVnX3JvdGF0ZV9jYW52YXNfMSxcblx0anBlZ19hdHRhY2hfb3JpZ19zZWdtZW50czoganBlZ19hdHRhY2hfb3JpZ19zZWdtZW50c18xLFxuXHRhc3NpZ246IGFzc2lnbl8xXG59O1xuXG5mdW5jdGlvbiBJbWFnZUJsb2JSZWR1Y2Uob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgSW1hZ2VCbG9iUmVkdWNlKSkgcmV0dXJuIG5ldyBJbWFnZUJsb2JSZWR1Y2Uob3B0aW9ucyk7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgdGhpcy5waWNhID0gb3B0aW9ucy5waWNhIHx8IHBpY2Eoe30pO1xuICB0aGlzLmluaXRpYWxpemVkID0gZmFsc2U7XG5cbiAgdGhpcy51dGlscyA9IHV0aWxzO1xufVxuXG5cbkltYWdlQmxvYlJlZHVjZS5wcm90b3R5cGUudXNlID0gZnVuY3Rpb24gKHBsdWdpbiAvKiwgcGFyYW1zLCAuLi4gKi8pIHtcbiAgdmFyIGFyZ3MgPSBbIHRoaXMgXS5jb25jYXQoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSk7XG4gIHBsdWdpbi5hcHBseShwbHVnaW4sIGFyZ3MpO1xuICByZXR1cm4gdGhpcztcbn07XG5cblxuSW1hZ2VCbG9iUmVkdWNlLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnVzZShqcGVnX3BsdWdpbnMuYXNzaWduKTtcbn07XG5cblxuSW1hZ2VCbG9iUmVkdWNlLnByb3RvdHlwZS50b0Jsb2IgPSBmdW5jdGlvbiAoYmxvYiwgb3B0aW9ucykge1xuICB2YXIgb3B0cyA9IHV0aWxzLmFzc2lnbih7IG1heDogSW5maW5pdHkgfSwgb3B0aW9ucyk7XG4gIHZhciBlbnYgPSB7XG4gICAgYmxvYjogYmxvYixcbiAgICBvcHRzOiBvcHRzXG4gIH07XG5cbiAgaWYgKCF0aGlzLmluaXRpYWxpemVkKSB7XG4gICAgdGhpcy5pbml0KCk7XG4gICAgdGhpcy5pbml0aWFsaXplZCA9IHRydWU7XG4gIH1cblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGVudilcbiAgICAudGhlbih0aGlzLl9ibG9iX3RvX2ltYWdlKVxuICAgIC50aGVuKHRoaXMuX2NhbGN1bGF0ZV9zaXplKVxuICAgIC50aGVuKHRoaXMuX3RyYW5zZm9ybSlcbiAgICAudGhlbih0aGlzLl9jbGVhbnVwKVxuICAgIC50aGVuKHRoaXMuX2NyZWF0ZV9ibG9iKVxuICAgIC50aGVuKGZ1bmN0aW9uIChfZW52KSB7XG4gICAgICAvLyBTYWZhcmkgMTIgd29ya2Fyb3VuZFxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25vZGVjYS9waWNhL2lzc3Vlcy8xOTlcbiAgICAgIF9lbnYub3V0X2NhbnZhcy53aWR0aCA9IF9lbnYub3V0X2NhbnZhcy5oZWlnaHQgPSAwO1xuXG4gICAgICByZXR1cm4gX2Vudi5vdXRfYmxvYjtcbiAgICB9KTtcbn07XG5cblxuSW1hZ2VCbG9iUmVkdWNlLnByb3RvdHlwZS50b0NhbnZhcyA9IGZ1bmN0aW9uIChibG9iLCBvcHRpb25zKSB7XG4gIHZhciBvcHRzID0gdXRpbHMuYXNzaWduKHsgbWF4OiBJbmZpbml0eSB9LCBvcHRpb25zKTtcbiAgdmFyIGVudiA9IHtcbiAgICBibG9iOiBibG9iLFxuICAgIG9wdHM6IG9wdHNcbiAgfTtcblxuICBpZiAoIXRoaXMuaW5pdGlhbGl6ZWQpIHtcbiAgICB0aGlzLmluaXQoKTtcbiAgICB0aGlzLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoZW52KVxuICAgIC50aGVuKHRoaXMuX2Jsb2JfdG9faW1hZ2UpXG4gICAgLnRoZW4odGhpcy5fY2FsY3VsYXRlX3NpemUpXG4gICAgLnRoZW4odGhpcy5fdHJhbnNmb3JtKVxuICAgIC50aGVuKHRoaXMuX2NsZWFudXApXG4gICAgLnRoZW4oZnVuY3Rpb24gKF9lbnYpIHsgcmV0dXJuIF9lbnYub3V0X2NhbnZhczsgfSk7XG59O1xuXG5cbkltYWdlQmxvYlJlZHVjZS5wcm90b3R5cGUuYmVmb3JlID0gZnVuY3Rpb24gKG1ldGhvZF9uYW1lLCBmbikge1xuICBpZiAoIXRoaXNbbWV0aG9kX25hbWVdKSB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBcIicgKyBtZXRob2RfbmFtZSArICdcIiBkb2VzIG5vdCBleGlzdCcpO1xuICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYXJndW1lbnQgXCJmblwiLCBmdW5jdGlvbiBleHBlY3RlZCcpO1xuXG4gIHZhciBvbGRfZm4gPSB0aGlzW21ldGhvZF9uYW1lXTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXNbbWV0aG9kX25hbWVdID0gZnVuY3Rpb24gKGVudikge1xuICAgIHJldHVybiBmbi5jYWxsKHNlbGYsIGVudikudGhlbihmdW5jdGlvbiAoX2Vudikge1xuICAgICAgcmV0dXJuIG9sZF9mbi5jYWxsKHNlbGYsIF9lbnYpO1xuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuXG5JbWFnZUJsb2JSZWR1Y2UucHJvdG90eXBlLmFmdGVyID0gZnVuY3Rpb24gKG1ldGhvZF9uYW1lLCBmbikge1xuICBpZiAoIXRoaXNbbWV0aG9kX25hbWVdKSB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBcIicgKyBtZXRob2RfbmFtZSArICdcIiBkb2VzIG5vdCBleGlzdCcpO1xuICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYXJndW1lbnQgXCJmblwiLCBmdW5jdGlvbiBleHBlY3RlZCcpO1xuXG4gIHZhciBvbGRfZm4gPSB0aGlzW21ldGhvZF9uYW1lXTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXNbbWV0aG9kX25hbWVdID0gZnVuY3Rpb24gKGVudikge1xuICAgIHJldHVybiBvbGRfZm4uY2FsbChzZWxmLCBlbnYpLnRoZW4oZnVuY3Rpb24gKF9lbnYpIHtcbiAgICAgIHJldHVybiBmbi5jYWxsKHNlbGYsIF9lbnYpO1xuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuXG5JbWFnZUJsb2JSZWR1Y2UucHJvdG90eXBlLl9ibG9iX3RvX2ltYWdlID0gZnVuY3Rpb24gKGVudikge1xuICB2YXIgVVJMID0gd2luZG93LlVSTCB8fCB3aW5kb3cud2Via2l0VVJMIHx8IHdpbmRvdy5tb3pVUkwgfHwgd2luZG93Lm1zVVJMO1xuXG4gIGVudi5pbWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICBlbnYuaW1hZ2VfdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChlbnYuYmxvYik7XG4gIGVudi5pbWFnZS5zcmMgPSBlbnYuaW1hZ2VfdXJsO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgZW52LmltYWdlLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7IHJlamVjdChuZXcgRXJyb3IoJ0ltYWdlQmxvYlJlZHVjZTogZmFpbGVkIHRvIGNyZWF0ZSBJbWFnZSgpIGZyb20gYmxvYicpKTsgfTtcbiAgICBlbnYuaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkgeyByZXNvbHZlKGVudik7IH07XG4gIH0pO1xufTtcblxuXG5JbWFnZUJsb2JSZWR1Y2UucHJvdG90eXBlLl9jYWxjdWxhdGVfc2l6ZSA9IGZ1bmN0aW9uIChlbnYpIHtcbiAgLy9cbiAgLy8gTm90ZSwgaWYgeW91ciBuZWVkIG5vdCBcInN5bW1ldHJpY1wiIHJlc2l6ZSBsb2dpYywgeW91IE1VU1QgY2hlY2tcbiAgLy8gYGVudi5vcmllbnRhdGlvbmAgKHNldCBieSBwbHVnaW5zKSBhbmQgc3dhcCB3aWR0aC9oZWlnaHQgYXBwcm9wcmlhdGVseS5cbiAgLy9cbiAgdmFyIHNjYWxlX2ZhY3RvciA9IGVudi5vcHRzLm1heCAvIE1hdGgubWF4KGVudi5pbWFnZS53aWR0aCwgZW52LmltYWdlLmhlaWdodCk7XG5cbiAgaWYgKHNjYWxlX2ZhY3RvciA+IDEpIHNjYWxlX2ZhY3RvciA9IDE7XG5cbiAgZW52LnRyYW5zZm9ybV93aWR0aCA9IE1hdGgubWF4KE1hdGgucm91bmQoZW52LmltYWdlLndpZHRoICogc2NhbGVfZmFjdG9yKSwgMSk7XG4gIGVudi50cmFuc2Zvcm1faGVpZ2h0ID0gTWF0aC5tYXgoTWF0aC5yb3VuZChlbnYuaW1hZ2UuaGVpZ2h0ICogc2NhbGVfZmFjdG9yKSwgMSk7XG5cbiAgLy8gSW5mbyBmb3IgdXNlciBwbHVnaW5zLCB0byBjaGVjayBpZiBzY2FsaW5nIGFwcGxpZWRcbiAgZW52LnNjYWxlX2ZhY3RvciA9IHNjYWxlX2ZhY3RvcjtcblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGVudik7XG59O1xuXG5cbkltYWdlQmxvYlJlZHVjZS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChlbnYpIHtcbiAgZW52Lm91dF9jYW52YXMgPSB0aGlzLnBpY2Eub3B0aW9ucy5jcmVhdGVDYW52YXMoZW52LnRyYW5zZm9ybV93aWR0aCwgZW52LnRyYW5zZm9ybV9oZWlnaHQpO1xuXG4gIC8vIERpbSBlbnYgdGVtcG9yYXJ5IHZhcnMgdG8gcHJvaGliaXQgdXNlIGFuZCBhdm9pZCBjb25mdXNpb24gd2hlbiBvcmllbnRhdGlvblxuICAvLyBjaGFuZ2VkLiBZb3Ugc2hvdWxkIHRha2UgcmVhbCBzaXplIGZyb20gY2FudmFzLlxuICBlbnYudHJhbnNmb3JtX3dpZHRoID0gbnVsbDtcbiAgZW52LnRyYW5zZm9ybV9oZWlnaHQgPSBudWxsO1xuXG4gIC8vIEJ5IGRlZmF1bHQgdXNlIGFscGhhIGZvciBwbmcgb25seVxuICB2YXIgcGljYV9vcHRzID0geyBhbHBoYTogZW52LmJsb2IudHlwZSA9PT0gJ2ltYWdlL3BuZycgfTtcblxuICAvLyBFeHRyYWN0IHBpY2Egb3B0aW9ucyBpZiBiZWVuIHBhc3NlZFxuICB0aGlzLnV0aWxzLmFzc2lnbihwaWNhX29wdHMsIHRoaXMudXRpbHMucGlja19waWNhX3Jlc2l6ZV9vcHRpb25zKGVudi5vcHRzKSk7XG5cbiAgcmV0dXJuIHRoaXMucGljYVxuICAgIC5yZXNpemUoZW52LmltYWdlLCBlbnYub3V0X2NhbnZhcywgcGljYV9vcHRzKVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGVudjsgfSk7XG59O1xuXG5cbkltYWdlQmxvYlJlZHVjZS5wcm90b3R5cGUuX2NsZWFudXAgPSBmdW5jdGlvbiAoZW52KSB7XG4gIGVudi5pbWFnZS5zcmMgPSAnJztcbiAgZW52LmltYWdlID0gbnVsbDtcblxuICB2YXIgVVJMID0gd2luZG93LlVSTCB8fCB3aW5kb3cud2Via2l0VVJMIHx8IHdpbmRvdy5tb3pVUkwgfHwgd2luZG93Lm1zVVJMO1xuICBpZiAoVVJMLnJldm9rZU9iamVjdFVSTCkgVVJMLnJldm9rZU9iamVjdFVSTChlbnYuaW1hZ2VfdXJsKTtcblxuICBlbnYuaW1hZ2VfdXJsID0gbnVsbDtcblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGVudik7XG59O1xuXG5cbkltYWdlQmxvYlJlZHVjZS5wcm90b3R5cGUuX2NyZWF0ZV9ibG9iID0gZnVuY3Rpb24gKGVudikge1xuICByZXR1cm4gdGhpcy5waWNhLnRvQmxvYihlbnYub3V0X2NhbnZhcywgZW52LmJsb2IudHlwZSlcbiAgICAudGhlbihmdW5jdGlvbiAoYmxvYikge1xuICAgICAgZW52Lm91dF9ibG9iID0gYmxvYjtcbiAgICAgIHJldHVybiBlbnY7XG4gICAgfSk7XG59O1xuXG5cbkltYWdlQmxvYlJlZHVjZS5wcm90b3R5cGUuX2dldFVpbnQ4QXJyYXkgPSBmdW5jdGlvbiAoYmxvYikge1xuICBpZiAoYmxvYi5hcnJheUJ1ZmZlcikge1xuICAgIHJldHVybiBibG9iLmFycmF5QnVmZmVyKCkudGhlbihmdW5jdGlvbiAoYnVmKSB7XG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYnVmKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgdmFyIGZyID0gbmV3IEZpbGVSZWFkZXIoKTtcblxuICAgIGZyLnJlYWRBc0FycmF5QnVmZmVyKGJsb2IpO1xuXG4gICAgZnIub25sb2FkID0gZnVuY3Rpb24gKCkgeyByZXNvbHZlKG5ldyBVaW50OEFycmF5KGZyLnJlc3VsdCkpOyB9O1xuICAgIGZyLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZWplY3QobmV3IEVycm9yKCdJbWFnZUJsb2JSZWR1Y2U6IGZhaWxlZCB0byBsb2FkIGRhdGEgZnJvbSBpbnB1dCBibG9iJykpO1xuICAgICAgZnIuYWJvcnQoKTtcbiAgICB9O1xuICAgIGZyLm9uYWJvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICByZWplY3QobmV3IEVycm9yKCdJbWFnZUJsb2JSZWR1Y2U6IGZhaWxlZCB0byBsb2FkIGRhdGEgZnJvbSBpbnB1dCBibG9iIChhYm9ydGVkKScpKTtcbiAgICB9O1xuICB9KTtcbn07XG5cblxuSW1hZ2VCbG9iUmVkdWNlLnBpY2EgPSBwaWNhO1xuXG52YXIgaW1hZ2VCbG9iUmVkdWNlID0gSW1hZ2VCbG9iUmVkdWNlO1xuXG5leHBvcnQgZGVmYXVsdCBpbWFnZUJsb2JSZWR1Y2U7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///../../../node_modules/image-blob-reduce/dist/image-blob-reduce.esm.mjs\n");
29
29
 
30
30
  /***/ }),
31
31