@colijnit/configurator 261.1.0 → 261.1.1

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 (553) hide show
  1. package/bundles/colijnit-configurator.umd.js +18012 -1838
  2. package/bundles/colijnit-configurator.umd.js.map +1 -1
  3. package/colijnit-configurator.d.ts +2 -6
  4. package/esm2015/colijnit-configurator.js +2 -7
  5. package/esm2015/lib/builder.js +795 -0
  6. package/esm2015/lib/components/answer-card/answer-card.component.js +313 -0
  7. package/esm2015/lib/components/answer-card/answer-card.module.js +50 -0
  8. package/esm2015/lib/components/answer-info-dialog/answer-info-dialog.component.js +182 -0
  9. package/esm2015/lib/components/answer-info-dialog/answer-info-dialog.module.js +34 -0
  10. package/esm2015/lib/components/answers-slideout/answers-slideout.component.js +490 -0
  11. package/esm2015/lib/components/answers-slideout/answers-slideout.module.js +61 -0
  12. package/esm2015/lib/components/color-filter/color-filter.component.js +59 -0
  13. package/esm2015/lib/components/color-filter/color-filter.module.js +26 -0
  14. package/esm2015/lib/components/configurator/configurator.component.js +133 -0
  15. package/esm2015/lib/components/configurator/configurator.module.js +42 -0
  16. package/esm2015/lib/components/configurator-dialog/configurator-camera-settings.component.js +222 -0
  17. package/esm2015/lib/components/configurator-dialog/configurator-dialog.module.js +48 -0
  18. package/esm2015/lib/components/configurator-dialog/configurator-error-dialog.component.js +82 -0
  19. package/esm2015/lib/components/configurator-dialog/configurator-export-dialog.component.js +163 -0
  20. package/esm2015/lib/components/configurator-loader/configurator-loader.component.js +49 -0
  21. package/esm2015/lib/components/configurator-loader/configurator-loader.module.js +33 -0
  22. package/esm2015/lib/components/configurator-scene/configurator-scene.component.js +60 -0
  23. package/esm2015/lib/components/configurator-scene/configurator-scene.module.js +17 -0
  24. package/esm2015/lib/components/configurator-scene-loader/configurator-scene-loader.component.js +46 -0
  25. package/esm2015/lib/components/configurator-scene-loader/configurator-scene-loader.module.js +26 -0
  26. package/esm2015/lib/components/element-buttons/element-buttons.component.js +168 -0
  27. package/esm2015/lib/components/element-buttons/element-buttons.module.js +30 -0
  28. package/esm2015/lib/components/element-toolbar/element-toolbar.component.js +186 -0
  29. package/esm2015/lib/components/element-toolbar/element-toolbar.module.js +34 -0
  30. package/esm2015/lib/components/image-zoom/image-zoom.component.js +61 -0
  31. package/esm2015/lib/components/image-zoom/image-zoom.module.js +30 -0
  32. package/esm2015/lib/components/lite-selector/lite-selector.component.js +206 -0
  33. package/esm2015/lib/components/lite-selector/lite-selector.module.js +34 -0
  34. package/esm2015/lib/components/product-configurator/product-configurator.component.js +184 -0
  35. package/esm2015/lib/components/product-configurator/product-configurator.module.js +72 -0
  36. package/esm2015/lib/components/product-configurator-selector/product-configurator-selector.component.js +237 -0
  37. package/esm2015/lib/components/product-configurator-selector/product-configurator-selector.module.js +38 -0
  38. package/esm2015/lib/components/product-configurator-selector-option/product-configurator-selector-option.component.js +284 -0
  39. package/esm2015/lib/components/product-configurator-selector-option/product-configurator-selector-option.module.js +42 -0
  40. package/esm2015/lib/components/product-configurator-selector-option-button/product-configurator-selector-option-button.component.js +72 -0
  41. package/esm2015/lib/components/product-configurator-selector-option-button/product-configurator-selector-option-button.module.js +34 -0
  42. package/esm2015/lib/components/product-configurator-selector-option-checkbox/product-configurator-selector-option-checkbox.component.js +82 -0
  43. package/esm2015/lib/components/product-configurator-selector-option-checkbox/product-configurator-selector-option-checkbox.module.js +30 -0
  44. package/esm2015/lib/components/product-configurator-selector-option-dropdown/product-configurator-selector-option-dropdown.component.js +80 -0
  45. package/esm2015/lib/components/product-configurator-selector-option-dropdown/product-configurator-selector-option-dropdown.module.js +34 -0
  46. package/esm2015/lib/components/product-configurator-selector-option-tile/product-configurator-selector-option-tile.component.js +93 -0
  47. package/esm2015/lib/components/product-configurator-selector-option-tile/product-configurator-selector-option-tile.module.js +34 -0
  48. package/esm2015/lib/components/progress-bar/progress-bar.component.js +55 -0
  49. package/esm2015/lib/components/progress-bar/progress-bar.module.js +29 -0
  50. package/esm2015/lib/components/scene-options/scene-options.component.js +164 -0
  51. package/esm2015/lib/components/scene-options/scene-options.module.js +38 -0
  52. package/esm2015/lib/components/selections-summary/selections-summary.component.js +163 -0
  53. package/esm2015/lib/components/selections-summary/selections-summary.module.js +45 -0
  54. package/esm2015/lib/components/selections-summary-line/selections-summary-line.component.js +171 -0
  55. package/esm2015/lib/components/selections-summary-line/selections-summary-line.module.js +34 -0
  56. package/esm2015/lib/components/slideout/slideout.component.js +83 -0
  57. package/esm2015/lib/components/slideout/slideout.module.js +17 -0
  58. package/esm2015/lib/components/summary-line/summary-line.component.js +273 -0
  59. package/esm2015/lib/components/summary-line/summary-line.module.js +44 -0
  60. package/esm2015/lib/components/tag-filter/tag-filter.component.js +39 -0
  61. package/esm2015/lib/components/tag-filter/tag-filter.module.js +21 -0
  62. package/esm2015/lib/components/threedselector/threedselector.component.js +155 -0
  63. package/esm2015/lib/components/threedselector/threedselector.module.js +34 -0
  64. package/esm2015/lib/core/helper/variation-helper.js +553 -0
  65. package/esm2015/lib/core/shader/floor-fade.shader.js +33 -0
  66. package/esm2015/lib/core/textures/depth-data-texture.js +19 -0
  67. package/esm2015/lib/directives/directives.module.js +26 -0
  68. package/esm2015/lib/directives/visibility-observer-master.directive.js +53 -0
  69. package/esm2015/lib/directives/visibility-observer.directive.js +54 -0
  70. package/esm2015/lib/enum/ar-feature.enum.js +14 -0
  71. package/esm2015/lib/enum/configuration-key.enum.js +41 -0
  72. package/esm2015/lib/enum/configuration-template.enum.js +6 -0
  73. package/esm2015/lib/enum/device-size-type.js +7 -0
  74. package/esm2015/lib/enum/device-tier.enum.js +7 -0
  75. package/esm2015/lib/enum/icon.enum.js +113 -0
  76. package/esm2015/lib/enum/item-type.enum.js +23 -0
  77. package/esm2015/lib/enum/light.enum.js +9 -0
  78. package/esm2015/lib/enum/navigator-type.enum.js +6 -0
  79. package/esm2015/lib/enum/output-encoding.enum.js +9 -0
  80. package/esm2015/lib/enum/result-type.enum.js +21 -0
  81. package/esm2015/lib/enum/scene-event.enum.js +12 -0
  82. package/esm2015/lib/enum/shadow-map-type.enum.js +8 -0
  83. package/esm2015/lib/enum/texture-type.js +9 -0
  84. package/esm2015/lib/enum/tone-mapping-local.enum.js +12 -0
  85. package/esm2015/lib/enum/view-mode.enum.js +7 -0
  86. package/esm2015/lib/enum/xr-mode.enum.js +6 -0
  87. package/esm2015/lib/environments/environment.js +8 -0
  88. package/esm2015/lib/interfaces/aa-options.interface.js +2 -0
  89. package/esm2015/lib/interfaces/adjustable-element.interface.js +2 -0
  90. package/esm2015/lib/interfaces/ao-options.interface.js +2 -0
  91. package/esm2015/lib/interfaces/changes.interface.js +2 -0
  92. package/esm2015/lib/interfaces/configuration-data.interface.js +2 -0
  93. package/esm2015/lib/interfaces/light-preset.interface.js +2 -0
  94. package/esm2015/lib/interfaces/post-processing-setting.interface.js +2 -0
  95. package/esm2015/lib/interfaces/scene-option-button.interface.js +6 -0
  96. package/esm2015/lib/interfaces/screen-size-info.js +2 -0
  97. package/esm2015/lib/interfaces/setting.interface.js +2 -0
  98. package/esm2015/lib/interfaces/texture.interface.js +2 -0
  99. package/esm2015/lib/interfaces/vignette-options.interface.js +2 -0
  100. package/esm2015/lib/model/ar-position-indicator.js +18 -0
  101. package/esm2015/lib/model/camera-settings.js +14 -0
  102. package/esm2015/lib/model/configuration-result-object.js +6 -0
  103. package/esm2015/lib/model/configurator-error-message.js +9 -0
  104. package/esm2015/lib/model/configurator-settings.js +25 -0
  105. package/esm2015/lib/model/custom-button.js +16 -0
  106. package/esm2015/lib/model/factory.js +28 -0
  107. package/esm2015/lib/model/icon.js +112 -0
  108. package/esm2015/lib/model/intersected-objects.js +7 -0
  109. package/esm2015/lib/model/light-preset.js +73 -0
  110. package/esm2015/lib/model/light-properties.js +45 -0
  111. package/esm2015/lib/model/material.js +11 -0
  112. package/esm2015/lib/model/metadata.js +2 -0
  113. package/esm2015/lib/model/render-parameters.js +16 -0
  114. package/esm2015/lib/model/setting-options.js +71 -0
  115. package/esm2015/lib/model/settings.js +16 -0
  116. package/esm2015/lib/model/shadow-properties.js +10 -0
  117. package/esm2015/lib/model/skin.js +3 -0
  118. package/esm2015/lib/model/texture.js +76 -0
  119. package/esm2015/lib/model/variation-settings.js +54 -0
  120. package/esm2015/lib/model/variation.js +3 -0
  121. package/esm2015/lib/model/xr-reticle.js +79 -0
  122. package/esm2015/lib/modules/render/enum/scene-type.enum.js +6 -0
  123. package/esm2015/lib/modules/render/model/ar-parameters.js +12 -0
  124. package/esm2015/lib/modules/render/model/scene-setting.js +6 -0
  125. package/esm2015/lib/modules/render/model/scene-settings.js +3 -0
  126. package/esm2015/lib/pipes/append.pipe.js +21 -0
  127. package/esm2015/lib/pipes/google-translate.pipe.js +21 -0
  128. package/esm2015/lib/pipes/localize.pipe.js +28 -0
  129. package/esm2015/lib/pipes/pipes.module.js +41 -0
  130. package/esm2015/lib/pipes/prepend.pipe.js +21 -0
  131. package/esm2015/lib/pipes/strip-html.pipe.js +17 -0
  132. package/esm2015/lib/services/app-event.service.js +36 -0
  133. package/esm2015/lib/services/app-initializer.service.js +27 -0
  134. package/esm2015/lib/services/ar.service.js +844 -0
  135. package/esm2015/lib/services/build-furniture-base.service.js +1181 -0
  136. package/esm2015/lib/services/build-furniture-without-scene.service.js +86 -0
  137. package/esm2015/lib/services/build-furniture.service.js +169 -0
  138. package/esm2015/lib/services/bundle-initialzer.service.js +113 -0
  139. package/esm2015/lib/services/camera.service.js +123 -0
  140. package/esm2015/lib/services/configuration.service.js +79 -0
  141. package/esm2015/lib/services/configurator-connector.service.js +830 -0
  142. package/esm2015/lib/services/configurator.service.js +285 -0
  143. package/esm2015/lib/services/configuring.service.js +119 -0
  144. package/esm2015/lib/services/controls.js +799 -0
  145. package/esm2015/lib/services/debug.service.js +43 -0
  146. package/esm2015/lib/services/dictionary.service.js +65 -0
  147. package/esm2015/lib/services/dynamic-camera.service.js +96 -0
  148. package/esm2015/lib/services/floor-plane.service.js +252 -0
  149. package/esm2015/lib/services/font.service.js +27 -0
  150. package/esm2015/lib/services/google-translate.service.js +79 -0
  151. package/esm2015/lib/services/icon-cache.service.js +44 -0
  152. package/esm2015/lib/services/intersection.service.js +47 -0
  153. package/esm2015/lib/services/item.service.js +75 -0
  154. package/esm2015/lib/services/json-utils.service.js +48 -0
  155. package/esm2015/lib/services/light-creation.service.js +35 -0
  156. package/esm2015/lib/services/light-presets.service.js +157 -0
  157. package/esm2015/lib/services/lights.service.js +146 -0
  158. package/esm2015/lib/services/load-furniture-base.service.js +164 -0
  159. package/esm2015/lib/services/load-furniture-without-scene.service.js +45 -0
  160. package/esm2015/lib/services/load-furniture.service.js +72 -0
  161. package/esm2015/lib/services/loader.service.js +32 -0
  162. package/esm2015/lib/services/locator.service.js +11 -0
  163. package/esm2015/lib/services/message-board.service.js +50 -0
  164. package/esm2015/lib/services/post-processing.service.js +378 -0
  165. package/esm2015/lib/services/product-configurator.service.js +16 -0
  166. package/esm2015/lib/services/progress.service.js +20 -0
  167. package/esm2015/lib/services/scene-event.service.js +246 -0
  168. package/esm2015/lib/services/scene-options.service.js +24 -0
  169. package/esm2015/lib/services/scene.service.js +313 -0
  170. package/esm2015/lib/services/screen-size-analysis.service.js +97 -0
  171. package/esm2015/lib/services/settings.service.js +142 -0
  172. package/esm2015/lib/services/switch-build-furniture.service.js +37 -0
  173. package/esm2015/lib/services/switch-load-furniture.service.js +35 -0
  174. package/esm2015/lib/services/threedselector.service.js +72 -0
  175. package/esm2015/lib/services/utils.service.js +207 -0
  176. package/esm2015/lib/services/variation-cache.service.js +143 -0
  177. package/esm2015/lib/services/variation.service.js +490 -0
  178. package/esm2015/lib/services/view-mode.service.js +37 -0
  179. package/esm2015/lib/services/vr.service.js +191 -0
  180. package/esm2015/lib/services/xr.service.js +294 -0
  181. package/esm2015/lib/utils/asset.utils.js +120 -0
  182. package/esm2015/lib/utils/base-utils.js +9 -0
  183. package/esm2015/lib/utils/color.utils.js +30 -0
  184. package/esm2015/lib/utils/debug.utils.js +9 -0
  185. package/esm2015/lib/utils/device.utils.js +25 -0
  186. package/esm2015/lib/utils/file.utils.js +167 -0
  187. package/esm2015/lib/utils/image.utils.js +61 -0
  188. package/esm2015/lib/utils/json-parser.utils.js +180 -0
  189. package/esm2015/lib/utils/material.utils.js +433 -0
  190. package/esm2015/lib/utils/object.utils.js +360 -0
  191. package/esm2015/lib/utils/relative-position.utils.js +75 -0
  192. package/esm2015/lib/utils/rotation-helper.utils.js +15 -0
  193. package/esm2015/lib/utils/scene-3d.utils.js +213 -0
  194. package/esm2015/lib/utils/scene-utils.js +191 -0
  195. package/esm2015/lib/utils/text-utils.js +68 -0
  196. package/esm2015/lib/utils/threed.utils.js +281 -0
  197. package/esm2015/lib/utils/variation-utils.js +459 -0
  198. package/esm2015/public-api.js +65 -0
  199. package/fesm2015/colijnit-configurator.js +17512 -1451
  200. package/fesm2015/colijnit-configurator.js.map +1 -1
  201. package/{app → lib}/builder.d.ts +9 -1
  202. package/lib/components/answer-card/answer-card.component.d.ts +58 -0
  203. package/lib/components/answer-card/answer-card.module.d.ts +11 -0
  204. package/lib/components/answer-card/style/_layout.scss +88 -0
  205. package/lib/components/answer-card/style/_material-definition.scss +3 -0
  206. package/lib/components/answer-card/style/_theme.scss +67 -0
  207. package/lib/components/answer-card/style/material.scss +2 -0
  208. package/lib/components/answer-info-dialog/answer-info-dialog.component.d.ts +38 -0
  209. package/lib/components/answer-info-dialog/answer-info-dialog.module.d.ts +10 -0
  210. package/lib/components/answer-info-dialog/style/_layout.scss +88 -0
  211. package/lib/components/answer-info-dialog/style/_material-definition.scss +3 -0
  212. package/lib/components/answer-info-dialog/style/_theme.scss +44 -0
  213. package/lib/components/answer-info-dialog/style/material.scss +3 -0
  214. package/lib/components/answers-slideout/answers-slideout.component.d.ts +86 -0
  215. package/lib/components/answers-slideout/answers-slideout.module.d.ts +16 -0
  216. package/lib/components/answers-slideout/style/_layout.scss +198 -0
  217. package/lib/components/answers-slideout/style/_material-definition.scss +3 -0
  218. package/lib/components/answers-slideout/style/_theme.scss +54 -0
  219. package/lib/components/answers-slideout/style/material.scss +3 -0
  220. package/lib/components/color-filter/color-filter.component.d.ts +20 -0
  221. package/lib/components/color-filter/color-filter.module.d.ts +8 -0
  222. package/lib/components/color-filter/style/_layout.scss +41 -0
  223. package/lib/components/color-filter/style/_material-definition.scss +3 -0
  224. package/lib/components/color-filter/style/_theme.scss +7 -0
  225. package/lib/components/color-filter/style/material.scss +3 -0
  226. package/lib/components/configurator/configurator.component.d.ts +37 -0
  227. package/lib/components/configurator/configurator.module.d.ts +12 -0
  228. package/lib/components/configurator/style/_layout.scss +7 -0
  229. package/lib/components/configurator/style/_material-definition.scss +3 -0
  230. package/lib/components/configurator/style/_theme.scss +7 -0
  231. package/lib/components/configurator/style/material.scss +3 -0
  232. package/lib/components/configurator-dialog/configurator-camera-settings.component.d.ts +30 -0
  233. package/lib/components/configurator-dialog/configurator-dialog.module.d.ts +13 -0
  234. package/lib/components/configurator-dialog/configurator-error-dialog.component.d.ts +16 -0
  235. package/lib/components/configurator-dialog/configurator-export-dialog.component.d.ts +26 -0
  236. package/lib/components/configurator-dialog/style/_layout.scss +129 -0
  237. package/lib/components/configurator-dialog/style/_material-definition.scss +4 -0
  238. package/lib/components/configurator-dialog/style/_theme.scss +89 -0
  239. package/lib/components/configurator-dialog/style/material.scss +3 -0
  240. package/lib/components/configurator-loader/configurator-loader.component.d.ts +7 -0
  241. package/lib/components/configurator-loader/configurator-loader.module.d.ts +9 -0
  242. package/lib/components/configurator-loader/style/_layout.scss +72 -0
  243. package/lib/components/configurator-loader/style/_material-definition.scss +5 -0
  244. package/lib/components/configurator-loader/style/_theme.scss +26 -0
  245. package/lib/components/configurator-loader/style/material.scss +14 -0
  246. package/lib/components/configurator-scene/configurator-scene.component.d.ts +24 -0
  247. package/lib/components/configurator-scene/configurator-scene.module.d.ts +7 -0
  248. package/lib/components/configurator-scene/style/_layout.scss +22 -0
  249. package/lib/components/configurator-scene/style/_material-definition.scss +3 -0
  250. package/lib/components/configurator-scene/style/_theme.scss +7 -0
  251. package/lib/components/configurator-scene/style/material.scss +3 -0
  252. package/lib/components/configurator-scene-loader/configurator-scene-loader.component.d.ts +7 -0
  253. package/lib/components/configurator-scene-loader/configurator-scene-loader.module.d.ts +8 -0
  254. package/lib/components/configurator-scene-loader/style/_layout.scss +72 -0
  255. package/lib/components/configurator-scene-loader/style/_material-definition.scss +5 -0
  256. package/lib/components/configurator-scene-loader/style/_theme.scss +26 -0
  257. package/lib/components/configurator-scene-loader/style/material.scss +14 -0
  258. package/lib/components/element-buttons/element-buttons.component.d.ts +32 -0
  259. package/lib/components/element-buttons/element-buttons.module.d.ts +9 -0
  260. package/lib/components/element-buttons/style/_layout.scss +52 -0
  261. package/lib/components/element-buttons/style/_material-definition.scss +3 -0
  262. package/lib/components/element-buttons/style/_theme.scss +23 -0
  263. package/lib/components/element-buttons/style/material.scss +3 -0
  264. package/lib/components/element-toolbar/element-toolbar.component.d.ts +27 -0
  265. package/lib/components/element-toolbar/element-toolbar.component.scss +59 -0
  266. package/lib/components/element-toolbar/element-toolbar.module.d.ts +10 -0
  267. package/lib/components/element-toolbar/style/_layout.scss +107 -0
  268. package/lib/components/element-toolbar/style/_material-definition.scss +3 -0
  269. package/lib/components/element-toolbar/style/_theme.scss +47 -0
  270. package/lib/components/element-toolbar/style/material.scss +3 -0
  271. package/lib/components/image-zoom/image-zoom.component.d.ts +15 -0
  272. package/lib/components/image-zoom/image-zoom.module.d.ts +9 -0
  273. package/lib/components/image-zoom/style/_layout.scss +51 -0
  274. package/lib/components/image-zoom/style/_material-definition.scss +3 -0
  275. package/lib/components/image-zoom/style/_theme.scss +17 -0
  276. package/lib/components/image-zoom/style/material.scss +3 -0
  277. package/lib/components/lite-selector/lite-selector.component.d.ts +40 -0
  278. package/lib/components/lite-selector/lite-selector.module.d.ts +10 -0
  279. package/lib/components/lite-selector/style/_layout.scss +21 -0
  280. package/lib/components/lite-selector/style/_material-definition.scss +3 -0
  281. package/lib/components/lite-selector/style/_theme.scss +7 -0
  282. package/lib/components/lite-selector/style/material.scss +3 -0
  283. package/lib/components/product-configurator/product-configurator.component.d.ts +50 -0
  284. package/lib/components/product-configurator/product-configurator.module.d.ts +15 -0
  285. package/lib/components/product-configurator/style/_layout.scss +46 -0
  286. package/lib/components/product-configurator/style/_material-definition.scss +3 -0
  287. package/lib/components/product-configurator/style/_theme.scss +22 -0
  288. package/lib/components/product-configurator/style/material.scss +3 -0
  289. package/lib/components/product-configurator-selector/product-configurator-selector.component.d.ts +35 -0
  290. package/lib/components/product-configurator-selector/product-configurator-selector.module.d.ts +11 -0
  291. package/lib/components/product-configurator-selector/style/_layout.scss +145 -0
  292. package/lib/components/product-configurator-selector/style/_material-definition.scss +3 -0
  293. package/lib/components/product-configurator-selector/style/_theme.scss +57 -0
  294. package/lib/components/product-configurator-selector/style/material.scss +3 -0
  295. package/lib/components/product-configurator-selector-option/product-configurator-selector-option.component.d.ts +31 -0
  296. package/lib/components/product-configurator-selector-option/product-configurator-selector-option.module.d.ts +13 -0
  297. package/lib/components/product-configurator-selector-option/style/_layout.scss +7 -0
  298. package/lib/components/product-configurator-selector-option/style/_material-definition.scss +3 -0
  299. package/lib/components/product-configurator-selector-option/style/_theme.scss +7 -0
  300. package/lib/components/product-configurator-selector-option/style/material.scss +3 -0
  301. package/lib/components/product-configurator-selector-option-button/product-configurator-selector-option-button.component.d.ts +20 -0
  302. package/lib/components/product-configurator-selector-option-button/product-configurator-selector-option-button.module.d.ts +10 -0
  303. package/lib/components/product-configurator-selector-option-button/style/_layout.scss +28 -0
  304. package/lib/components/product-configurator-selector-option-button/style/_material-definition.scss +3 -0
  305. package/lib/components/product-configurator-selector-option-button/style/_theme.scss +33 -0
  306. package/lib/components/product-configurator-selector-option-button/style/material.scss +3 -0
  307. package/lib/components/product-configurator-selector-option-checkbox/product-configurator-selector-option-checkbox.component.d.ts +20 -0
  308. package/lib/components/product-configurator-selector-option-checkbox/product-configurator-selector-option-checkbox.module.d.ts +10 -0
  309. package/lib/components/product-configurator-selector-option-checkbox/style/_layout.scss +28 -0
  310. package/lib/components/product-configurator-selector-option-checkbox/style/_material-definition.scss +3 -0
  311. package/lib/components/product-configurator-selector-option-checkbox/style/_theme.scss +27 -0
  312. package/lib/components/product-configurator-selector-option-checkbox/style/material.scss +3 -0
  313. package/lib/components/product-configurator-selector-option-dropdown/product-configurator-selector-option-dropdown.component.d.ts +21 -0
  314. package/lib/components/product-configurator-selector-option-dropdown/product-configurator-selector-option-dropdown.module.d.ts +10 -0
  315. package/lib/components/product-configurator-selector-option-dropdown/style/_layout.scss +34 -0
  316. package/lib/components/product-configurator-selector-option-dropdown/style/_material-definition.scss +3 -0
  317. package/lib/components/product-configurator-selector-option-dropdown/style/_theme.scss +28 -0
  318. package/lib/components/product-configurator-selector-option-dropdown/style/material.scss +3 -0
  319. package/lib/components/product-configurator-selector-option-tile/product-configurator-selector-option-tile.component.d.ts +21 -0
  320. package/lib/components/product-configurator-selector-option-tile/product-configurator-selector-option-tile.module.d.ts +10 -0
  321. package/lib/components/product-configurator-selector-option-tile/style/_layout.scss +58 -0
  322. package/lib/components/product-configurator-selector-option-tile/style/_material-definition.scss +3 -0
  323. package/lib/components/product-configurator-selector-option-tile/style/_theme.scss +56 -0
  324. package/lib/components/product-configurator-selector-option-tile/style/material.scss +3 -0
  325. package/lib/components/progress-bar/progress-bar.component.d.ts +10 -0
  326. package/lib/components/progress-bar/progress-bar.component.scss +14 -0
  327. package/lib/components/progress-bar/progress-bar.module.d.ts +8 -0
  328. package/lib/components/progress-bar/style/_layout.scss +18 -0
  329. package/lib/components/progress-bar/style/_material-definition.scss +3 -0
  330. package/lib/components/progress-bar/style/_theme.scss +10 -0
  331. package/lib/components/progress-bar/style/material.scss +3 -0
  332. package/lib/components/scene-options/scene-options.component.d.ts +24 -0
  333. package/lib/components/scene-options/scene-options.module.d.ts +11 -0
  334. package/lib/components/scene-options/style/_layout.scss +52 -0
  335. package/lib/components/scene-options/style/_material-definition.scss +3 -0
  336. package/lib/components/scene-options/style/_theme.scss +7 -0
  337. package/lib/components/scene-options/style/material.scss +3 -0
  338. package/lib/components/selections-summary/selections-summary.component.d.ts +38 -0
  339. package/lib/components/selections-summary/selections-summary.module.d.ts +12 -0
  340. package/lib/components/selections-summary/style/_layout.scss +87 -0
  341. package/lib/components/selections-summary/style/_material-definition.scss +5 -0
  342. package/lib/components/selections-summary/style/_theme.scss +13 -0
  343. package/lib/components/selections-summary/style/material.scss +3 -0
  344. package/lib/components/selections-summary-line/selections-summary-line.component.d.ts +27 -0
  345. package/lib/components/selections-summary-line/selections-summary-line.module.d.ts +10 -0
  346. package/lib/components/selections-summary-line/style/_layout.scss +12 -0
  347. package/lib/components/selections-summary-line/style/_material-definition.scss +4 -0
  348. package/lib/components/selections-summary-line/style/_theme.scss +12 -0
  349. package/lib/components/selections-summary-line/style/material.scss +3 -0
  350. package/lib/components/slideout/slideout.component.d.ts +22 -0
  351. package/lib/components/slideout/slideout.module.d.ts +7 -0
  352. package/lib/components/slideout/style/_layout.scss +27 -0
  353. package/lib/components/slideout/style/_material-definition.scss +3 -0
  354. package/lib/components/slideout/style/_theme.scss +5 -0
  355. package/lib/components/slideout/style/material.scss +3 -0
  356. package/lib/components/summary-line/style/_layout.scss +137 -0
  357. package/lib/components/summary-line/style/_material-definition.scss +4 -0
  358. package/lib/components/summary-line/style/_theme.scss +56 -0
  359. package/lib/components/summary-line/style/material.scss +3 -0
  360. package/lib/components/summary-line/summary-line.component.d.ts +50 -0
  361. package/lib/components/summary-line/summary-line.module.d.ts +11 -0
  362. package/lib/components/tag-filter/style/_layout.scss +14 -0
  363. package/lib/components/tag-filter/style/_material-definition.scss +3 -0
  364. package/lib/components/tag-filter/style/_theme.scss +7 -0
  365. package/lib/components/tag-filter/style/material.scss +3 -0
  366. package/lib/components/tag-filter/tag-filter.component.d.ts +9 -0
  367. package/lib/components/tag-filter/tag-filter.module.d.ts +7 -0
  368. package/lib/components/threedselector/style/_layout.scss +32 -0
  369. package/lib/components/threedselector/style/_material-definition.scss +3 -0
  370. package/lib/components/threedselector/style/_theme.scss +7 -0
  371. package/lib/components/threedselector/style/material.scss +9 -0
  372. package/lib/components/threedselector/threedselector.component.d.ts +38 -0
  373. package/lib/components/threedselector/threedselector.module.d.ts +10 -0
  374. package/{helper → lib/core/helper}/variation-helper.d.ts +2 -2
  375. package/lib/core/shader/floor-fade.shader.d.ts +5 -0
  376. package/lib/core/textures/depth-data-texture.d.ts +5 -0
  377. package/lib/directives/directives.module.d.ts +8 -0
  378. package/{app → lib}/directives/visibility-observer-master.directive.d.ts +3 -0
  379. package/{app → lib}/directives/visibility-observer.directive.d.ts +3 -0
  380. package/lib/enum/ar-feature.enum.d.ts +12 -0
  381. package/lib/enum/configuration-key.enum.d.ts +39 -0
  382. package/lib/enum/configuration-template.enum.d.ts +4 -0
  383. package/lib/enum/device-size-type.d.ts +5 -0
  384. package/lib/enum/device-tier.enum.d.ts +5 -0
  385. package/lib/enum/icon.enum.d.ts +111 -0
  386. package/lib/enum/item-type.enum.d.ts +21 -0
  387. package/lib/enum/light.enum.d.ts +7 -0
  388. package/lib/enum/navigator-type.enum.d.ts +4 -0
  389. package/lib/enum/output-encoding.enum.d.ts +7 -0
  390. package/lib/enum/result-type.enum.d.ts +19 -0
  391. package/lib/enum/scene-event.enum.d.ts +10 -0
  392. package/lib/enum/shadow-map-type.enum.d.ts +6 -0
  393. package/lib/enum/texture-type.d.ts +7 -0
  394. package/lib/enum/tone-mapping-local.enum.d.ts +10 -0
  395. package/lib/enum/view-mode.enum.d.ts +5 -0
  396. package/lib/enum/xr-mode.enum.d.ts +4 -0
  397. package/lib/environments/environment.d.ts +4 -0
  398. package/lib/interfaces/aa-options.interface.d.ts +4 -0
  399. package/lib/interfaces/adjustable-element.interface.d.ts +5 -0
  400. package/lib/interfaces/ao-options.interface.d.ts +18 -0
  401. package/lib/interfaces/changes.interface.d.ts +9 -0
  402. package/lib/interfaces/configuration-data.interface.d.ts +40 -0
  403. package/lib/interfaces/light-preset.interface.d.ts +22 -0
  404. package/lib/interfaces/post-processing-setting.interface.d.ts +11 -0
  405. package/lib/interfaces/scene-option-button.interface.d.ts +19 -0
  406. package/lib/interfaces/screen-size-info.d.ts +10 -0
  407. package/lib/interfaces/setting.interface.d.ts +8 -0
  408. package/lib/interfaces/texture.interface.d.ts +44 -0
  409. package/lib/interfaces/vignette-options.interface.d.ts +4 -0
  410. package/lib/model/ar-position-indicator.d.ts +4 -0
  411. package/lib/model/camera-settings.d.ts +12 -0
  412. package/lib/model/configuration-result-object.d.ts +30 -0
  413. package/lib/model/configurator-error-message.d.ts +8 -0
  414. package/lib/model/configurator-settings.d.ts +62 -0
  415. package/lib/model/custom-button.d.ts +10 -0
  416. package/lib/model/factory.d.ts +5 -0
  417. package/lib/model/icon.d.ts +4 -0
  418. package/lib/model/intersected-objects.d.ts +6 -0
  419. package/lib/model/light-preset.d.ts +33 -0
  420. package/lib/model/light-properties.d.ts +25 -0
  421. package/lib/model/material.d.ts +41 -0
  422. package/lib/model/metadata.d.ts +78 -0
  423. package/lib/model/render-parameters.d.ts +12 -0
  424. package/lib/model/setting-options.d.ts +67 -0
  425. package/lib/model/settings.d.ts +10 -0
  426. package/lib/model/shadow-properties.d.ts +7 -0
  427. package/lib/model/skin.d.ts +15 -0
  428. package/lib/model/texture.d.ts +52 -0
  429. package/{model → lib/model}/variation-settings.d.ts +9 -8
  430. package/{model → lib/model}/variation.d.ts +2 -1
  431. package/lib/model/xr-reticle.d.ts +17 -0
  432. package/lib/modules/render/enum/scene-type.enum.d.ts +4 -0
  433. package/lib/modules/render/model/ar-parameters.d.ts +9 -0
  434. package/lib/modules/render/model/scene-setting.d.ts +13 -0
  435. package/lib/modules/render/model/scene-settings.d.ts +4 -0
  436. package/lib/pipes/append.pipe.d.ts +7 -0
  437. package/lib/pipes/google-translate.pipe.d.ts +11 -0
  438. package/lib/pipes/localize.pipe.d.ts +10 -0
  439. package/lib/pipes/pipes.module.d.ts +11 -0
  440. package/lib/pipes/prepend.pipe.d.ts +7 -0
  441. package/lib/pipes/strip-html.pipe.d.ts +7 -0
  442. package/lib/services/app-event.service.d.ts +32 -0
  443. package/lib/services/app-initializer.service.d.ts +14 -0
  444. package/lib/services/ar.service.d.ts +120 -0
  445. package/lib/services/build-furniture-base.service.d.ts +117 -0
  446. package/lib/services/build-furniture-without-scene.service.d.ts +14 -0
  447. package/lib/services/build-furniture.service.d.ts +14 -0
  448. package/lib/services/bundle-initialzer.service.d.ts +45 -0
  449. package/lib/services/camera.service.d.ts +44 -0
  450. package/lib/services/configuration.service.d.ts +18 -0
  451. package/lib/services/configurator-connector.service.d.ts +140 -0
  452. package/lib/services/configurator.service.d.ts +62 -0
  453. package/lib/services/configuring.service.d.ts +46 -0
  454. package/lib/services/controls.d.ts +11 -0
  455. package/lib/services/debug.service.d.ts +16 -0
  456. package/lib/services/dictionary.service.d.ts +15 -0
  457. package/lib/services/dynamic-camera.service.d.ts +21 -0
  458. package/lib/services/floor-plane.service.d.ts +47 -0
  459. package/lib/services/font.service.d.ts +10 -0
  460. package/lib/services/google-translate.service.d.ts +26 -0
  461. package/lib/services/icon-cache.service.d.ts +21 -0
  462. package/lib/services/intersection.service.d.ts +11 -0
  463. package/lib/services/item.service.d.ts +18 -0
  464. package/lib/services/json-utils.service.d.ts +7 -0
  465. package/lib/services/light-creation.service.d.ts +9 -0
  466. package/lib/services/light-presets.service.d.ts +34 -0
  467. package/lib/services/lights.service.d.ts +34 -0
  468. package/lib/services/load-furniture-base.service.d.ts +37 -0
  469. package/lib/services/load-furniture-without-scene.service.d.ts +9 -0
  470. package/lib/services/load-furniture.service.d.ts +9 -0
  471. package/lib/services/loader.service.d.ts +11 -0
  472. package/lib/services/locator.service.d.ts +7 -0
  473. package/lib/services/message-board.service.d.ts +18 -0
  474. package/lib/services/post-processing.service.d.ts +74 -0
  475. package/lib/services/product-configurator.service.d.ts +11 -0
  476. package/lib/services/progress.service.d.ts +9 -0
  477. package/lib/services/scene-event.service.d.ts +72 -0
  478. package/lib/services/scene-options.service.d.ts +11 -0
  479. package/lib/services/scene.service.d.ts +71 -0
  480. package/lib/services/screen-size-analysis.service.d.ts +32 -0
  481. package/lib/services/settings.service.d.ts +24 -0
  482. package/lib/services/switch-build-furniture.service.d.ts +21 -0
  483. package/lib/services/switch-load-furniture.service.d.ts +21 -0
  484. package/lib/services/threedselector.service.d.ts +17 -0
  485. package/lib/services/utils.service.d.ts +24 -0
  486. package/lib/services/variation-cache.service.d.ts +23 -0
  487. package/lib/services/variation.service.d.ts +26 -0
  488. package/lib/services/view-mode.service.d.ts +17 -0
  489. package/lib/services/vr.service.d.ts +42 -0
  490. package/lib/services/xr.service.d.ts +56 -0
  491. package/lib/style/_mixin.scss +9 -0
  492. package/lib/style/configurator-globals.scss +21 -0
  493. package/lib/style/template_variables.scss +37 -0
  494. package/lib/utils/color.utils.d.ts +8 -0
  495. package/lib/utils/debug.utils.d.ts +3 -0
  496. package/lib/utils/device.utils.d.ts +7 -0
  497. package/{utils → lib/utils}/file.utils.d.ts +3 -0
  498. package/{utils → lib/utils}/image.utils.d.ts +2 -3
  499. package/lib/utils/json-parser.utils.d.ts +9 -0
  500. package/lib/utils/material.utils.d.ts +34 -0
  501. package/lib/utils/object.utils.d.ts +32 -0
  502. package/lib/utils/relative-position.utils.d.ts +12 -0
  503. package/lib/utils/rotation-helper.utils.d.ts +6 -0
  504. package/lib/utils/scene-3d.utils.d.ts +8 -0
  505. package/lib/utils/text-utils.d.ts +4 -0
  506. package/{utils → lib/utils}/threed.utils.d.ts +7 -3
  507. package/{utils → lib/utils}/variation-utils.d.ts +4 -2
  508. package/package.json +17 -30
  509. package/public-api.d.ts +60 -0
  510. package/README.md +0 -28
  511. package/app/components/answers/answer/answer.component.d.ts +0 -11
  512. package/app/components/answers/answers.component.d.ts +0 -8
  513. package/app/components/answers/answers.module.d.ts +0 -2
  514. package/app/components/selections/selections.component.d.ts +0 -21
  515. package/app/components/selections/selections.module.d.ts +0 -2
  516. package/app/components/shared/loader/loader.component.d.ts +0 -2
  517. package/app/components/shared/shared.module.d.ts +0 -2
  518. package/app/services/configurator.service.d.ts +0 -19
  519. package/app/services/image-cache.service.d.ts +0 -10
  520. package/app/utils/object.utils.d.ts +0 -7
  521. package/colijnit-configurator.metadata.json +0 -1
  522. package/esm2015/app/builder.js +0 -710
  523. package/esm2015/app/components/answers/answer/answer.component.js +0 -66
  524. package/esm2015/app/components/answers/answers.component.js +0 -38
  525. package/esm2015/app/components/answers/answers.module.js +0 -27
  526. package/esm2015/app/components/selections/selections.component.js +0 -129
  527. package/esm2015/app/components/selections/selections.module.js +0 -21
  528. package/esm2015/app/components/shared/loader/loader.component.js +0 -22
  529. package/esm2015/app/components/shared/shared.module.js +0 -19
  530. package/esm2015/app/directives/visibility-observer-master.directive.js +0 -50
  531. package/esm2015/app/directives/visibility-observer.directive.js +0 -55
  532. package/esm2015/app/services/configurator.service.js +0 -79
  533. package/esm2015/app/services/image-cache.service.js +0 -63
  534. package/esm2015/app/utils/object.utils.js +0 -51
  535. package/esm2015/helper/variation-helper.js +0 -549
  536. package/esm2015/model/material.js +0 -11
  537. package/esm2015/model/variation-settings.js +0 -54
  538. package/esm2015/model/variation.js +0 -3
  539. package/esm2015/public_api.js +0 -7
  540. package/esm2015/utils/asset.utils.js +0 -124
  541. package/esm2015/utils/base-utils.js +0 -9
  542. package/esm2015/utils/file.utils.js +0 -142
  543. package/esm2015/utils/image.utils.js +0 -66
  544. package/esm2015/utils/object.utils.js +0 -49
  545. package/esm2015/utils/scene-utils.js +0 -187
  546. package/esm2015/utils/threed.utils.js +0 -226
  547. package/esm2015/utils/variation-utils.js +0 -388
  548. package/model/material.d.ts +0 -40
  549. package/public_api.d.ts +0 -6
  550. package/utils/object.utils.d.ts +0 -7
  551. /package/{utils → lib/utils}/asset.utils.d.ts +0 -0
  552. /package/{utils → lib/utils}/base-utils.d.ts +0 -0
  553. /package/{utils → lib/utils}/scene-utils.d.ts +0 -0
@@ -0,0 +1,844 @@
1
+ import { __awaiter } from "tslib";
2
+ import { Injectable } from '@angular/core';
3
+ import * as THREE from 'three';
4
+ import { Box3, DirectionalLight, DoubleSide, LightProbe, Matrix4, Mesh, MeshBasicMaterial, MeshPhongMaterial, PCFSoftShadowMap, PlaneGeometry, Raycaster, Scene, ShadowMaterial, SphereGeometry, SRGBColorSpace, Texture, Vector3 } from 'three';
5
+ import * as TWEEN from '@tweenjs/tween.js';
6
+ import { BehaviorSubject, Subject } from 'rxjs';
7
+ import { ArFeature } from '../enum/ar-feature.enum';
8
+ import { Reticle } from '../model/xr-reticle';
9
+ import { DepthDataTexture } from '../core/textures/depth-data-texture';
10
+ import { ArPositionIndicator } from '../model/ar-position-indicator';
11
+ import { ObjectUtils } from '../utils/object.utils';
12
+ import { MaterialUtils } from '../utils/material.utils';
13
+ import { DeviceUtils } from '../utils/device.utils';
14
+ import * as i0 from "@angular/core";
15
+ import * as i1 from "./camera.service";
16
+ import * as i2 from "./settings.service";
17
+ import * as i3 from "./configurator-connector.service";
18
+ export class ArService {
19
+ constructor(_cameraService, _settingsService, _iOne) {
20
+ this._cameraService = _cameraService;
21
+ this._settingsService = _settingsService;
22
+ this._iOne = _iOne;
23
+ this.updateContextMenu = new BehaviorSubject(null);
24
+ this.shouldAddObjectToScene = new Subject();
25
+ this.showConfigurator = false;
26
+ this.userInSelectionMenu = false;
27
+ this.showContextMenu = false;
28
+ this._arFeatures = [];
29
+ this._debug = false;
30
+ this._surfaceFoundOnce = false;
31
+ this._aRModelRotationStartingValue = 0;
32
+ this._vertexList = [];
33
+ this._detectedPlanes = [];
34
+ this._rawPlanes = new Set();
35
+ this._doubleTapTimeframe = 500;
36
+ this._holdingTouch = false;
37
+ this._cleanup = true;
38
+ this._animating = false;
39
+ this._pointRepresentation = new Mesh(new SphereGeometry(0.02, 12, 12), new MeshBasicMaterial({
40
+ color: 0x4ccaed,
41
+ transparent: true,
42
+ opacity: 0.2
43
+ }));
44
+ window.onbeforeunload = () => this.ngOnDestroy();
45
+ }
46
+ ngOnDestroy() {
47
+ ObjectUtils.DisposeObject(this._reticle);
48
+ ObjectUtils.DisposeObject(this._sunLight);
49
+ ObjectUtils.DisposeObject(this._pointRepresentation);
50
+ }
51
+ resetPlaneDetection() {
52
+ return __awaiter(this, void 0, void 0, function* () {
53
+ this._reticle.visible = false;
54
+ this._activeARModel.visible = false;
55
+ this._vertexList = [];
56
+ this._detectedPlanes.forEach((plane) => this.scene.remove(plane));
57
+ this._detectedPlanes = [];
58
+ this.scene.remove(this._positionIndicator);
59
+ this._rawPlanes = new Set();
60
+ this._cleanup = false;
61
+ yield this._session.end();
62
+ this._cleanup = true;
63
+ this._session = null;
64
+ this._initSession();
65
+ });
66
+ }
67
+ endSessionEvent() {
68
+ this._session.end();
69
+ }
70
+ arIOSSupported() {
71
+ return __awaiter(this, void 0, void 0, function* () {
72
+ const a = document.createElement('a');
73
+ // relList.supports('ar') exists on Safari that supports Quick Look
74
+ return !!(a.relList && a.relList.supports && a.relList.supports('ar'));
75
+ });
76
+ }
77
+ arSupported() {
78
+ return __awaiter(this, void 0, void 0, function* () {
79
+ if (navigator.xr) {
80
+ return yield navigator.xr.isSessionSupported('immersive-ar');
81
+ }
82
+ else {
83
+ return false;
84
+ }
85
+ });
86
+ }
87
+ addObjectToARScene(object) {
88
+ this._activeARModel = object;
89
+ this._activeARModel.visible = false;
90
+ this._activeARModel.castShadow = true;
91
+ this._activeARModel.receiveShadow = true;
92
+ this._positionIndicator = new ArPositionIndicator(new Box3().setFromObject(object));
93
+ this.scene.add(this._activeARModel, this._positionIndicator);
94
+ }
95
+ modelLoading() {
96
+ return !this._activeARModel;
97
+ }
98
+ modelPlaced() {
99
+ return this._activeARModel && this._activeARModel.visible && !this._holdingTouch;
100
+ }
101
+ handleFrame(xrFrame) {
102
+ if (this._session && this._activeARModel) {
103
+ // TODO FIX
104
+ // this._iOne.shouldShowLoader = false;
105
+ this._checkAvailableFeatures(xrFrame);
106
+ this._checkHitTestMethod(xrFrame);
107
+ this._checkExtraFeatures(xrFrame);
108
+ this._handleHoldMoveEvent();
109
+ this._handleMultiTouchEvent();
110
+ if (this._activeARModel.visible) {
111
+ this.updateContextMenu.next();
112
+ }
113
+ }
114
+ TWEEN.update();
115
+ this._renderer.render(this.scene, this._cameraService.camera);
116
+ }
117
+ init(renderer) {
118
+ // TODO FIX
119
+ // this._iOne.shouldShowLoader = true;
120
+ if (!this._renderer) {
121
+ this._renderer = renderer;
122
+ this._renderer.outputColorSpace = SRGBColorSpace;
123
+ this._initScene();
124
+ this._initLighting();
125
+ this._initController();
126
+ this._reticle = new Reticle();
127
+ this.scene.add(this._reticle);
128
+ }
129
+ this._initRenderer();
130
+ this._initSession();
131
+ }
132
+ savePreSelectionPosition() {
133
+ this._aRModelBackupPosition = this._activeARModel.position.clone();
134
+ }
135
+ updateChangedModel() {
136
+ if (this._aRModelBackupPosition) {
137
+ this._activeARModel.position.set(this._aRModelBackupPosition.x, this._aRModelBackupPosition.y, this._aRModelBackupPosition.z);
138
+ }
139
+ if (this._arFeatures.includes(ArFeature.CPUDepthOcclusion)) {
140
+ this._updateMeshMaterials();
141
+ }
142
+ }
143
+ arModeHasBeenActive() {
144
+ return this.scene !== undefined;
145
+ }
146
+ showMovePhoneAnimation() {
147
+ return this._activeARModel && !this._reticle.visible && !this._surfaceFoundOnce;
148
+ }
149
+ getActiveModel() {
150
+ return this._activeARModel;
151
+ }
152
+ _initSession() {
153
+ if (!this._session) {
154
+ // 'depth-sensing'
155
+ const features = {
156
+ requiredFeatures: ['local-floor', 'hit-test'],
157
+ optionalFeatures: ['light-estimation', 'plane-detection', 'anchors', 'dom-overlay'],
158
+ domOverlay: { root: document.getElementById('ar-root') },
159
+ depthSensing: {
160
+ usagePreference: ['cpu-optimized'],
161
+ dataFormatPreference: ['luminance-alpha']
162
+ }
163
+ };
164
+ navigator.xr.requestSession('immersive-ar', features).then((session) => {
165
+ this._renderer.xr.setReferenceSpaceType('local');
166
+ session.requestReferenceSpace('viewer').then((refSpace) => {
167
+ session.requestHitTestSource({ space: refSpace }).then((hitTestSource) => {
168
+ this.hitTestSource = hitTestSource;
169
+ });
170
+ });
171
+ session.requestReferenceSpace('local').then((refSpace) => {
172
+ this.refSpace = refSpace;
173
+ this._onSessionStarted(session);
174
+ });
175
+ });
176
+ }
177
+ }
178
+ _checkAvailableFeatures(xrFrame) {
179
+ if (this._settingsService.settings.arParameters.depthOcclusion && this._settingsService.settings.arParameters.depthHitTest &&
180
+ !(this._arFeatures.includes(ArFeature.CPUDepthOcclusion)) && this._session.depthUsage) {
181
+ this._arFeatures.push(ArFeature.CPUDepthOcclusion, ArFeature.CPUDepthHitTest);
182
+ this._initCPUDepthOcclusion();
183
+ }
184
+ if (this._settingsService.settings.arParameters.anchoredHitTest &&
185
+ !(this._arFeatures.includes(ArFeature.AnchoredHitTest)) && xrFrame.trackedAnchors) {
186
+ this._arFeatures.push(ArFeature.AnchoredHitTest);
187
+ this._initAnchoredHitTest();
188
+ }
189
+ if (this._settingsService.settings.arParameters.lightEstimation &&
190
+ !(this._arFeatures.includes(ArFeature.LightEstimation))) {
191
+ this._session.requestLightProbe().then((lightProbe) => {
192
+ if (lightProbe) {
193
+ this._arFeatures.push(ArFeature.LightEstimation);
194
+ this._initLightEstimation(lightProbe);
195
+ }
196
+ });
197
+ }
198
+ if (this._settingsService.settings.arParameters.reflectionEstimation &&
199
+ !(this._arFeatures.includes(ArFeature.ReflectionCubeMap)) && this._lightProbe
200
+ && this._glBinding.getReflectionCubeMap(this._lightProbe)) {
201
+ this._arFeatures.push(ArFeature.ReflectionCubeMap);
202
+ this._initReflectionCubeMap();
203
+ }
204
+ if (this._settingsService.settings.arParameters.planeDetection && this._settingsService.settings.arParameters.planeHitTest &&
205
+ !(this._arFeatures.includes(ArFeature.PlaneDetection)) && xrFrame.worldInformation) {
206
+ this._arFeatures.push(ArFeature.PlaneDetection, ArFeature.PlaneDetectionHitTest);
207
+ this._initPlaneDetection();
208
+ }
209
+ }
210
+ _initRenderer() {
211
+ this._renderer.xr.enabled = true;
212
+ this._renderer.shadowMap.type = PCFSoftShadowMap;
213
+ this._renderer.setClearColor(0x000000, 0);
214
+ this._renderer.autoClear = false;
215
+ }
216
+ _initController() {
217
+ this._tempMatrix = new Matrix4();
218
+ this._raycaster = new Raycaster();
219
+ this._controller = this._renderer.xr.getController(0);
220
+ this.scene.add(this._controller);
221
+ }
222
+ _initScene() {
223
+ this.scene = new Scene();
224
+ const planeGeometry = new PlaneGeometry(100, 100);
225
+ const material = new ShadowMaterial({ opacity: 0.2 });
226
+ this._shadowPlane = new Mesh(planeGeometry, material);
227
+ this._shadowPlane.name = 'shadowPlane';
228
+ this._shadowPlane.rotation.x -= Math.PI / 2;
229
+ this._shadowPlane.receiveShadow = true;
230
+ this._shadowPlane.visible = false;
231
+ this.scene.add(this._shadowPlane);
232
+ }
233
+ _initLightEstimation(lightProbe) {
234
+ this._threeLightProbe = new LightProbe();
235
+ this.scene.add(this._threeLightProbe);
236
+ this._lightProbe = lightProbe;
237
+ // @ts-ignore
238
+ this._glBinding = new XRWebGLBinding(this._session, this._renderer.getContext());
239
+ }
240
+ _initReflectionCubeMap() {
241
+ this._cubeMapTexture = new Texture();
242
+ this._renderer.initTexture(this._cubeMapTexture);
243
+ this.scene.environment = this._cubeMapTexture;
244
+ this._lightProbe.addEventListener('reflectionchange', () => {
245
+ const rawData = this._glBinding.getReflectionCubeMap(this._lightProbe);
246
+ const texProps = this._renderer.properties.get(this._cubeMapTexture);
247
+ // @ts-ignore
248
+ texProps.__webglTexture = rawData;
249
+ });
250
+ }
251
+ _initCPUDepthOcclusion() {
252
+ this._depthDataTexture = new DepthDataTexture();
253
+ this._updateMeshMaterials();
254
+ }
255
+ _initAnchoredHitTest() {
256
+ this._anchoredObjects = [];
257
+ }
258
+ _initPlaneDetection() {
259
+ this._createPlaneMaterial();
260
+ }
261
+ _initLighting() {
262
+ const ambientLight = new THREE.AmbientLight(0xffffff, 0.1);
263
+ ambientLight.color.setHex(0xffffff).convertSRGBToLinear();
264
+ ambientLight.name = 'ambientLight';
265
+ this._sunLight = new DirectionalLight('black', 0.3);
266
+ this._sunLight.castShadow = true;
267
+ this._sunLight.shadow.mapSize.width = 4096;
268
+ this._sunLight.shadow.mapSize.height = 4096;
269
+ this._sunLight.shadow.camera.left = -10;
270
+ this._sunLight.shadow.camera.right = 10;
271
+ this._sunLight.shadow.camera.top = 10;
272
+ this._sunLight.shadow.camera.bottom = -10;
273
+ this._sunLight.shadow.camera.near = 0.1;
274
+ this._sunLight.shadow.camera.far = 30;
275
+ this._sunLight.visible = true;
276
+ this._sunLight.target.visible = true;
277
+ this._sunLight.name = 'sunLight';
278
+ this.scene.add(/*ambientLight, */ this._sunLight.target, this._sunLight);
279
+ }
280
+ _checkHitTestMethod(xrFrame) {
281
+ if (this._arFeatures.includes(ArFeature.CPUDepthOcclusion) && this._arFeatures.includes(ArFeature.AnchoredHitTest)) {
282
+ this._executeDepthAnchorHitTest(xrFrame);
283
+ }
284
+ else if (this._arFeatures.includes(ArFeature.AnchoredHitTest)) {
285
+ this._executeAnchoredHitTest(xrFrame);
286
+ }
287
+ else if (this._arFeatures.includes(ArFeature.CPUDepthHitTest)) {
288
+ this._executeCPUDepthHitTest(xrFrame);
289
+ }
290
+ else {
291
+ this._executeDefaultHitTest(xrFrame);
292
+ }
293
+ }
294
+ _executeDepthAnchorHitTest(xrFrame) {
295
+ const xrViewerPose = xrFrame.getViewerPose(this.refSpace);
296
+ const xrCamera = this._renderer.xr.getCamera( /*this._cameraService.camera*/); // todo: due to threejs update parameter not needed anymore, check this!
297
+ this._reticle.visible = false;
298
+ if (this.hitTestSource && xrViewerPose) {
299
+ const hitTestResults = xrFrame.getHitTestResults(this.hitTestSource);
300
+ if (hitTestResults.length === 0) {
301
+ if (xrViewerPose.views.length > 0 && xrCamera) {
302
+ for (const view of xrViewerPose.views) {
303
+ if (!this._activeARModel.visible) {
304
+ const depthData = xrFrame.getDepthInformation(view);
305
+ // Place object as soon as depth data is available and distance is within reasonable values
306
+ if (depthData && depthData.getDepthInMeters(0.5, 0.5) > 0.1 && depthData.getDepthInMeters(0.5, 0.5) < 2.5) {
307
+ this._activeARModel.position.set(xrCamera.position.x, xrCamera.position.y, xrCamera.position.z);
308
+ this._activeARModel.rotation.setFromQuaternion(xrCamera.quaternion);
309
+ this._activeARModel.translateZ(-depthData.getDepthInMeters(0.5, 0.5));
310
+ this._activeARModel.position.y += 0.02;
311
+ this._activeARModel.rotation.set(0, 0, 0);
312
+ this._activeARModel.visible = true;
313
+ }
314
+ }
315
+ }
316
+ }
317
+ }
318
+ else {
319
+ // When hit test results are available we switch to the anchored hit test method and place the model accordingly
320
+ this._executeAnchoredHitTest(xrFrame);
321
+ if (this._anchoredObjects.length === 0) {
322
+ this._handleTouchEvent(false);
323
+ }
324
+ }
325
+ }
326
+ }
327
+ _executeAnchoredHitTest(xrFrame) {
328
+ this._executeDefaultHitTest(xrFrame);
329
+ for (const { anchoredObject, anchor } of this._anchoredObjects) {
330
+ if (!xrFrame.trackedAnchors.has(anchor)) {
331
+ continue;
332
+ }
333
+ const anchorPose = xrFrame.getPose(anchor.anchorSpace, this.refSpace);
334
+ if (anchorPose) {
335
+ const hitMatrix = new Matrix4().fromArray(anchorPose.transform.matrix);
336
+ anchoredObject.position.setFromMatrixPosition(hitMatrix);
337
+ }
338
+ }
339
+ }
340
+ _executeCPUDepthHitTest(xrFrame) {
341
+ const xrViewerPose = xrFrame.getViewerPose(this.refSpace);
342
+ const xrCamera = this._renderer.xr.getCamera( /*this._cameraService.camera*/); // todo: due to threejs update parameter not needed anymore, check this!
343
+ this._reticle.visible = false;
344
+ if (xrViewerPose && xrViewerPose.views.length > 0 && xrCamera) {
345
+ for (const view of xrViewerPose.views) {
346
+ if (!this._activeARModel.visible) {
347
+ this._reticle.visible = true;
348
+ this._surfaceFoundOnce = true;
349
+ }
350
+ const depthData = xrFrame.getDepthInformation(view);
351
+ if (depthData) {
352
+ this._reticle.position.set(xrCamera.position.x, xrCamera.position.y, xrCamera.position.z);
353
+ this._reticle.rotation.setFromQuaternion(xrCamera.quaternion);
354
+ this._reticle.translateZ(-depthData.getDepthInMeters(0.5, 0.5));
355
+ this._reticle.position.y += 0.02;
356
+ this._reticle.rotation.set(0, 0, 0);
357
+ }
358
+ }
359
+ }
360
+ }
361
+ _executeDefaultHitTest(xrFrame) {
362
+ const xrViewerPose = xrFrame.getViewerPose(this.refSpace);
363
+ this._reticle.visible = false;
364
+ if (this.hitTestSource && xrViewerPose) {
365
+ const hitTestResults = xrFrame.getHitTestResults(this.hitTestSource);
366
+ if (hitTestResults.length > 0) {
367
+ const pose = hitTestResults[0].getPose(this.refSpace);
368
+ if (!this._activeARModel.visible) {
369
+ this._reticle.visible = true;
370
+ this._surfaceFoundOnce = true;
371
+ }
372
+ const hitMatrix = new Matrix4().fromArray(pose.transform.matrix);
373
+ this._hitTestResult = hitMatrix;
374
+ this._reticle.position.setFromMatrixPosition(hitMatrix);
375
+ this._reticle.position.y += 0.02; // Prevents z-fighting
376
+ this._reticleHitTestResult = hitTestResults[0];
377
+ }
378
+ }
379
+ }
380
+ _checkExtraFeatures(xrFrame) {
381
+ if (this._arFeatures.includes(ArFeature.LightEstimation)) {
382
+ this._adjustLighting(xrFrame);
383
+ }
384
+ if (this._arFeatures.includes(ArFeature.CPUDepthOcclusion)) {
385
+ this._hideOccludedMeshes(xrFrame);
386
+ }
387
+ // if (this._arFeatures.includes(ArFeature.PlaneDetection)) {
388
+ // this._drawPlanes(xrFrame);
389
+ // }
390
+ }
391
+ _hideOccludedMeshes(xrFrame) {
392
+ const xrViewerPose = xrFrame.getViewerPose(this.refSpace);
393
+ if (xrViewerPose && xrViewerPose.views.length > 0) {
394
+ for (const view of xrViewerPose.views) {
395
+ const depthData = xrFrame.getDepthInformation(view);
396
+ if (depthData) {
397
+ this._depthDataTexture.updateDepth(depthData);
398
+ this._updateAugmentedMaterialUniforms(depthData.normDepthBufferFromNormView.matrix);
399
+ }
400
+ }
401
+ }
402
+ }
403
+ _createPlaneMaterial() {
404
+ return __awaiter(this, void 0, void 0, function* () {
405
+ const pm = new MeshPhongMaterial({ transparent: true, side: DoubleSide });
406
+ pm.map = yield MaterialUtils.FromUrl('assets/textures/Floor/Tiles/ar_floor_texture.png', false, 1, 2, 2);
407
+ pm.map.flipY = false;
408
+ pm.needsUpdate = true;
409
+ this._planeMaterial = pm;
410
+ });
411
+ }
412
+ _onSessionStarted(session) {
413
+ return __awaiter(this, void 0, void 0, function* () {
414
+ const domOverlay = document.getElementById('ar-root');
415
+ session.addEventListener('end', this._onSessionEnded.bind(this));
416
+ session.addEventListener('select', () => this._handleTouchEvent());
417
+ session.addEventListener('selectstart', ($event) => this._handleHoldStartEvent($event));
418
+ session.addEventListener('selectend', ($event) => this._handleHoldEndEvent($event));
419
+ domOverlay.addEventListener('beforexrselect', ($event) => this._checkingInterfaceInteraction($event));
420
+ yield this._renderer.getContext().makeXRCompatible();
421
+ this._renderer.xr.setSession(session);
422
+ this._session = session;
423
+ });
424
+ }
425
+ _onSessionEnded() {
426
+ if (this._cleanup) {
427
+ this._session = null;
428
+ this._surfaceFoundOnce = false;
429
+ this._reticle.visible = false;
430
+ this.scene.remove(this._positionIndicator);
431
+ this._activeARModel.visible = true;
432
+ this._activeARModel.position.set(0, 0, 0);
433
+ this._removeMaterialShaders();
434
+ this.shouldAddObjectToScene.next(this._activeARModel);
435
+ this._activeARModel = null;
436
+ this._holdingTouch = false;
437
+ this._arFeatures = [];
438
+ this._lightProbe = null;
439
+ this._vertexList = [];
440
+ this._detectedPlanes = [];
441
+ this._rawPlanes = new Set();
442
+ this._renderer.xr.enabled = false;
443
+ this._renderer.shadowMap.type = PCFSoftShadowMap;
444
+ this._renderer.setClearColor(0xfafafa);
445
+ this._renderer.autoClear = true;
446
+ // TODO FIX
447
+ // this._viewModeService.viewMode = ViewMode.RoomPlan3D;
448
+ }
449
+ }
450
+ _setArModelShadows() {
451
+ if (this._activeARModel) {
452
+ this._activeARModel.traverse((node) => {
453
+ if (node instanceof Mesh) {
454
+ node.castShadow = true;
455
+ node.receiveShadow = true;
456
+ }
457
+ });
458
+ }
459
+ }
460
+ _handleTouchEvent(manualTouch = true) {
461
+ this._handleDoubleTapEvent();
462
+ if (manualTouch) {
463
+ if (this._reticle.visible && !this._activeARModel.visible) {
464
+ if (this._arFeatures.includes(ArFeature.AnchoredHitTest)) {
465
+ this._activeARModel.position.copy(this._reticle.position);
466
+ this._reticleHitTestResult.createAnchor().then((anchor) => {
467
+ this._anchoredObjects.push({
468
+ anchoredObject: this._shadowPlane,
469
+ anchor: anchor
470
+ });
471
+ }).catch((e) => {
472
+ // Unable to create anchor
473
+ });
474
+ }
475
+ else {
476
+ this._activeARModel.position.copy(this._reticle.position);
477
+ this._aRModelBackupYPosition = this._reticle.position.y;
478
+ this._shadowPlane.position.copy(this._reticle.position);
479
+ this._positionIndicator.position.copy(this._reticle.position);
480
+ }
481
+ }
482
+ }
483
+ else {
484
+ if (this._arFeatures.includes(ArFeature.AnchoredHitTest)) {
485
+ this._activeARModel.position.copy(this._reticle.position);
486
+ this._reticleHitTestResult.createAnchor().then((anchor) => {
487
+ this._anchoredObjects.push({
488
+ anchoredObject: this._shadowPlane,
489
+ anchor: anchor
490
+ });
491
+ }).catch((e) => {
492
+ // Unable to create anchor
493
+ });
494
+ }
495
+ else {
496
+ this._activeARModel.position.copy(this._reticle.position);
497
+ this._aRModelBackupYPosition = this._reticle.position.y;
498
+ this._shadowPlane.position.copy(this._reticle.position);
499
+ this._positionIndicator.position.copy(this._reticle.position);
500
+ }
501
+ }
502
+ this._activeARModel.visible = true;
503
+ this._shadowPlane.visible = true;
504
+ this._positionIndicator.visible = true;
505
+ this._setArModelShadows();
506
+ this._setPlanesVisibilty(false);
507
+ }
508
+ _handleMultiTouchEvent() {
509
+ const inputSources = this._session.inputSources;
510
+ if (inputSources.length === 2 && this._activeARModel.visible && !this._holdingTouch) {
511
+ this._aRModelBackupYRotation = this._aRModelBackupYRotation === 0 ? this._activeARModel.rotation.y / 2 : this._aRModelBackupYRotation;
512
+ const dx = inputSources[1].gamepad.axes[0] - inputSources[0].gamepad.axes[0];
513
+ const dy = inputSources[1].gamepad.axes[1] - inputSources[0].gamepad.axes[1];
514
+ const angle = Math.atan2(dy, dx);
515
+ this._aRModelRotationStartingValue = this._aRModelRotationStartingValue === 0 ? angle : this._aRModelRotationStartingValue;
516
+ const difference = this._aRModelBackupYRotation - (angle - this._aRModelRotationStartingValue);
517
+ this._activeARModel.rotation.y = this._aRModelBackupYRotation + difference;
518
+ }
519
+ else {
520
+ this._aRModelBackupYRotation = 0;
521
+ this._aRModelRotationStartingValue = 0;
522
+ }
523
+ }
524
+ _handleDoubleTapEvent() {
525
+ const intersections = this._getObjectIntersections([this._activeARModel]);
526
+ if (intersections.length > 0) {
527
+ const currentTimestamp = Date.now();
528
+ this.showContextMenu = this._lastObjectTouchTimestamp && currentTimestamp - this._lastObjectTouchTimestamp < this._doubleTapTimeframe;
529
+ this._lastObjectTouchTimestamp = currentTimestamp;
530
+ }
531
+ else {
532
+ this.showContextMenu = false;
533
+ }
534
+ }
535
+ _checkIfHoldTouchEvent($event) {
536
+ return __awaiter(this, void 0, void 0, function* () {
537
+ setTimeout(() => {
538
+ if (!this.userInSelectionMenu && this._lastEventTimestamp === $event.timeStamp && this._session.inputSources.length === 1) {
539
+ this._holdingTouch = true;
540
+ this._toggleHoldTouchEvent();
541
+ }
542
+ }, 200);
543
+ });
544
+ }
545
+ _handleHoldStartEvent($event) {
546
+ this._lastEventTimestamp = $event.timeStamp;
547
+ this._checkIfHoldTouchEvent($event);
548
+ }
549
+ _handleHoldEndEvent($event) {
550
+ this._lastEventTimestamp = $event.timeStamp;
551
+ if (this._holdingTouch) {
552
+ this._holdingTouch = false;
553
+ this._toggleHoldTouchEvent();
554
+ }
555
+ }
556
+ _toggleHoldTouchEvent() {
557
+ if (this._holdingTouch) {
558
+ // this._setPlanesVisibilty(true);
559
+ this._callLiftAnimation();
560
+ }
561
+ else {
562
+ this._callDropAnimation();
563
+ this._setPlanesVisibilty(false);
564
+ this._activeARModel.position.y = this._aRModelBackupYPosition;
565
+ }
566
+ this._toggleARModelTransparency();
567
+ }
568
+ _handleHoldMoveEvent() {
569
+ if (this._holdingTouch && !this.userInSelectionMenu) {
570
+ const intersections = this._getObjectIntersections([this._shadowPlane]);
571
+ if (intersections.length > 0) {
572
+ const movePosition = !this._animating ? new Vector3(intersections[0].point.x, intersections[0].point.y + 0.2, intersections[0].point.z) :
573
+ new Vector3(intersections[0].point.x, this._activeARModel.position.y, intersections[0].point.z);
574
+ this._activeARModel.position.copy(movePosition);
575
+ this._aRModelBackupYPosition = intersections[0].point.y;
576
+ this._positionIndicator.position.copy(intersections[0].point);
577
+ this._updateShadows(intersections[0].point);
578
+ }
579
+ }
580
+ }
581
+ _updateShadows(centerPosition) {
582
+ this._shadowPlane.position.copy(centerPosition);
583
+ this.scene.traverse((node) => {
584
+ if (node instanceof DirectionalLight) {
585
+ node.target.position.copy(centerPosition);
586
+ node.shadow.camera.updateProjectionMatrix();
587
+ }
588
+ });
589
+ }
590
+ _adjustLighting(frame) {
591
+ const lightEstimate = frame.getLightEstimate(this._lightProbe);
592
+ if (lightEstimate) {
593
+ this._threeLightProbe.sh.fromArray(lightEstimate.sphericalHarmonicsCoefficients);
594
+ const intensity = Math.max(1.0, Math.max(lightEstimate.primaryLightIntensity.x, Math.max(lightEstimate.primaryLightIntensity.y, lightEstimate.primaryLightIntensity.z)));
595
+ this._sunLight.position.set(lightEstimate.primaryLightDirection.x, lightEstimate.primaryLightDirection.y, lightEstimate.primaryLightDirection.z);
596
+ this._sunLight.color.setRGB(lightEstimate.primaryLightIntensity.x / intensity, lightEstimate.primaryLightIntensity.y / intensity, lightEstimate.primaryLightIntensity.z / intensity);
597
+ this._sunLight.intensity = intensity;
598
+ }
599
+ }
600
+ _toggleARModelTransparency() {
601
+ this._activeARModel.traverse((node) => {
602
+ if (node instanceof Mesh) {
603
+ const materials = !Array.isArray(node.material) ? [node.material] : node.material;
604
+ materials.forEach(material => {
605
+ material.transparent = this._holdingTouch;
606
+ material.opacity = this._holdingTouch ? 0.5 : 1;
607
+ material.needsUpdate = true;
608
+ });
609
+ }
610
+ });
611
+ }
612
+ _setPlanesVisibilty(visible) {
613
+ this._detectedPlanes.forEach((plane) => plane.visible = visible);
614
+ }
615
+ _getObjectIntersections(objects) {
616
+ this._tempMatrix.identity().extractRotation(this._controller.matrixWorld);
617
+ this._raycaster.ray.origin.setFromMatrixPosition(this._controller.matrixWorld);
618
+ this._raycaster.ray.direction.set(0, 0, -1).applyMatrix4(this._tempMatrix);
619
+ return this._raycaster.intersectObjects(objects);
620
+ }
621
+ // TODO: Needs to be made compatible with BufferGeometry if we want to keep plane detection visualization
622
+ _drawPlane(vertices, planePose) {
623
+ // const hitMatrix = new Matrix4().fromArray(planePose.transform.matrix);
624
+ // const pointGroup = new Group();
625
+ //
626
+ // // Create vertices
627
+ // vertices.forEach((vertex) => {
628
+ // if (this._debug) {
629
+ // const point = this._pointRepresentation.clone();
630
+ // point.position.set(vertex.x, 0, vertex.z);
631
+ // pointGroup.add(point);
632
+ // }
633
+ // this._vertexList.push(new DOMPoint(vertex.x, vertex.z));
634
+ // });
635
+ //
636
+ // if (this._debug) {
637
+ // pointGroup.position.setFromMatrixPosition(hitMatrix);
638
+ // this.scene.add(pointGroup);
639
+ // }
640
+ //
641
+ // // Generate polygon from vertices
642
+ // const hull = makeHull(this._vertexList);
643
+ // const geometry = new BufferGeometry();
644
+ // const vectorTwoList = hull.map((point) => new Vector2(point.x, point.y));
645
+ // const vectorThreeList = hull.map((point) => new Vector3(point.x, this._detectedPlanes.length > 0 ? this._detectedPlanes[0].position.y : 0, point.y));
646
+ // const faceArray = ShapeUtils.triangulateShape(vectorTwoList, []);
647
+ // geometry.vertices.push(...vectorThreeList);
648
+ //
649
+ // // Generate faces
650
+ // for (let i = 0; i < faceArray.length; i++) {
651
+ // geometry.faces.push(new THREE.Face3(faceArray[i][0], faceArray[i][1], faceArray[i][2]));
652
+ // }
653
+ // geometry.computeVertexNormals();
654
+ // geometry.normalize();
655
+ //
656
+ // // Generate UV's
657
+ // geometry.computeBoundingBox();
658
+ // const max = geometry.boundingBox.max, min = geometry.boundingBox.min;
659
+ // const offset = new THREE.Vector2(0 - min.x, 0 - min.z);
660
+ // const range = new THREE.Vector2(max.x - min.x, max.z - min.z);
661
+ // const faces = geometry.faces;
662
+ // geometry.faceVertexUvs[0] = [];
663
+ //
664
+ // for (let i = 0; i < faces.length; i++) {
665
+ // const v1 = geometry.vertices[faces[i].a],
666
+ // v2 = geometry.vertices[faces[i].b],
667
+ // v3 = geometry.vertices[faces[i].c];
668
+ //
669
+ // geometry.faceVertexUvs[0].push([
670
+ // new THREE.Vector2((v1.x + offset.x) / range.x, (v1.z + offset.y) / range.y),
671
+ // new THREE.Vector2((v2.x + offset.x) / range.x, (v2.z + offset.y) / range.y),
672
+ // new THREE.Vector2((v3.x + offset.x) / range.x, (v3.z + offset.y) / range.y)
673
+ // ]);
674
+ // }
675
+ // geometry.uvsNeedUpdate = true;
676
+ //
677
+ // // Create and set plane
678
+ // const mesh = new Mesh(geometry, this._planeMaterial);
679
+ // mesh.position.setFromMatrixPosition(hitMatrix);
680
+ // this._detectedPlanes.push(mesh);
681
+ // this.scene.add(mesh);
682
+ }
683
+ _drawPlanes(xrFrame) {
684
+ if (!this._activeARModel.visible) {
685
+ const planesDetected = xrFrame.worldInformation.detectedPlanes;
686
+ if (planesDetected.size > 0) {
687
+ planesDetected.forEach(plane => {
688
+ if (!this._rawPlanes.has(plane)) {
689
+ const planePose = xrFrame.getPose(plane.planeSpace, this.refSpace);
690
+ if (planePose) {
691
+ this._rawPlanes.add(plane);
692
+ const planeVertices = plane.polygon;
693
+ this._drawPlane(planeVertices, planePose);
694
+ }
695
+ }
696
+ });
697
+ }
698
+ }
699
+ }
700
+ _callLiftAnimation() {
701
+ this._animating = true;
702
+ const position = this._activeARModel.position.clone();
703
+ const targetPosition = new Vector3(this._activeARModel.position.x, this._activeARModel.position.y + 0.2, this._activeARModel.position.z);
704
+ this._liftAnimation = new TWEEN.Tween(position)
705
+ .to(targetPosition, 500)
706
+ .easing(TWEEN.Easing.Quadratic.Out)
707
+ .onUpdate(() => this._activeARModel.position.copy(new Vector3(this._activeARModel.position.x, position.y, this._activeARModel.position.z)))
708
+ .onComplete(() => this._animating = false);
709
+ this._liftAnimation.start();
710
+ }
711
+ _callDropAnimation() {
712
+ this._animating = true;
713
+ const position = this._activeARModel.position.clone();
714
+ const targetPosition = new Vector3(this._activeARModel.position.x, this._activeARModel.position.y - 0.2, this._activeARModel.position.z);
715
+ this._dropAnimation = new TWEEN.Tween(position)
716
+ .to(targetPosition, 500)
717
+ .easing(TWEEN.Easing.Quadratic.Out)
718
+ .onUpdate(() => this._activeARModel.position.copy(new Vector3(this._activeARModel.position.x, position.y, this._activeARModel.position.z)))
719
+ .onComplete(() => this._animating = false);
720
+ this._dropAnimation.start();
721
+ }
722
+ _createAugmentedMaterial(material, depthMap) {
723
+ material.userData = {
724
+ uDepthTexture: { value: depthMap },
725
+ uWidth: { value: 1.0 },
726
+ uHeight: { value: 1.0 },
727
+ uUvTransform: { value: new Matrix4() },
728
+ uOcclusionEnabled: { value: true }
729
+ };
730
+ material.userData.isAgumentedMaterial = true;
731
+ material.onBeforeCompile = (shader) => {
732
+ // Pass uniforms from userData to the
733
+ for (const i in material.userData) {
734
+ shader.uniforms[i] = material.userData[i];
735
+ }
736
+ // Fragment variables
737
+ shader.fragmentShader = `
738
+ uniform sampler2D uDepthTexture;
739
+ uniform float uWidth;
740
+ uniform float uHeight;
741
+ uniform mat4 uUvTransform;
742
+ uniform bool uOcclusionEnabled;
743
+ varying float vDepth;
744
+ ` + shader.fragmentShader;
745
+ let fragmentEntryPoint = '#include <clipping_planes_fragment>';
746
+ if (material instanceof ShadowMaterial) {
747
+ fragmentEntryPoint = '#include <fog_fragment>';
748
+ }
749
+ // Fragment depth logic
750
+ shader.fragmentShader = shader.fragmentShader.replace('void main', `float getDepthInMillimeters(in sampler2D depthText, in vec2 uv)
751
+ {
752
+ vec2 packedDepth = texture2D(depthText, uv).ra;
753
+ return dot(packedDepth, vec2(255.0, 65280.0));
754
+ }
755
+ void main`);
756
+ shader.fragmentShader = shader.fragmentShader.replace(fragmentEntryPoint, `
757
+ ${fragmentEntryPoint}
758
+ // Normalize x, y to range [0, 1]
759
+ float x = gl_FragCoord.x / uWidth;
760
+ float y = gl_FragCoord.y / uHeight;
761
+ vec2 texCoord = (uUvTransform * vec4(x, 1.0 - y, 0.0, 1.0)).xy;
762
+ float depth = getDepthInMillimeters(uDepthTexture, texCoord) / 1000.0;
763
+ if (depth < vDepth)
764
+ {
765
+ discard;
766
+ }
767
+ `);
768
+ // Vertex variables
769
+ shader.vertexShader = `
770
+ varying float vDepth;
771
+ ` + shader.vertexShader;
772
+ // Vertex depth logic
773
+ shader.vertexShader = shader.vertexShader.replace('#include <fog_vertex>', `
774
+ #include <fog_vertex>
775
+ vDepth = gl_Position.z;
776
+ `);
777
+ };
778
+ return material;
779
+ }
780
+ _updateAugmentedMaterialUniforms(normTextureFromNormViewMatrix) {
781
+ this.scene.traverse((child) => {
782
+ if (child instanceof Mesh && child.material) {
783
+ if (child.material instanceof Array) {
784
+ for (const material of child.material) {
785
+ if (material.userData.isAgumentedMaterial) {
786
+ material.userData.uWidth.value = Math.floor(DeviceUtils.GetPixelRatio() * window.innerWidth);
787
+ material.userData.uHeight.value = Math.floor(DeviceUtils.GetPixelRatio() * window.innerHeight);
788
+ material.userData.uUvTransform.value.fromArray(normTextureFromNormViewMatrix);
789
+ material.needsUpdate = true;
790
+ }
791
+ }
792
+ }
793
+ else if (child.userData.isAgumentedMaterial) {
794
+ child.material.userData.uWidth.value = Math.floor(DeviceUtils.GetPixelRatio() * window.innerWidth);
795
+ child.material.userData.uHeight.value = Math.floor(DeviceUtils.GetPixelRatio() * window.innerHeight);
796
+ child.material.userData.uUvTransform.value.fromArray(normTextureFromNormViewMatrix);
797
+ child.material.needsUpdate = true;
798
+ }
799
+ }
800
+ });
801
+ }
802
+ _updateMeshMaterials() {
803
+ this.scene.traverse((object) => {
804
+ if (object instanceof Mesh) {
805
+ if (object.material instanceof Array) {
806
+ for (let material of object.material) {
807
+ material = this._createAugmentedMaterial(material, this._depthDataTexture);
808
+ }
809
+ }
810
+ else {
811
+ object.material = this._createAugmentedMaterial(object.material, this._depthDataTexture);
812
+ }
813
+ }
814
+ });
815
+ }
816
+ _removeMaterialShaders() {
817
+ this.scene.traverse((object) => {
818
+ if (object instanceof Mesh) {
819
+ if (object.material instanceof Array) {
820
+ for (const material of object.material) {
821
+ material.onBeforeCompile = (shader) => {
822
+ shader = null;
823
+ };
824
+ }
825
+ }
826
+ else {
827
+ object.material.onBeforeCompile = (shader) => {
828
+ shader = null;
829
+ };
830
+ }
831
+ }
832
+ });
833
+ }
834
+ _checkingInterfaceInteraction(event) {
835
+ this.userInSelectionMenu = event.path.filter((entry) => entry.localName === 'ar-gui-configurator').length > 0;
836
+ }
837
+ }
838
+ ArService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ArService, deps: [{ token: i1.CameraService }, { token: i2.SettingsService }, { token: i3.ConfiguratorConnectorService }], target: i0.ɵɵFactoryTarget.Injectable });
839
+ ArService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ArService, providedIn: 'root' });
840
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ArService, decorators: [{
841
+ type: Injectable,
842
+ args: [{ providedIn: 'root' }]
843
+ }], ctorParameters: function () { return [{ type: i1.CameraService }, { type: i2.SettingsService }, { type: i3.ConfiguratorConnectorService }]; } });
844
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbmZpZ3VyYXRvci9zcmMvbGliL3NlcnZpY2VzL2FyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBQyxVQUFVLEVBQVksTUFBTSxlQUFlLENBQUM7QUFDcEQsT0FBTyxLQUFLLEtBQUssTUFBTSxPQUFPLENBQUM7QUFDL0IsT0FBTyxFQUNMLElBQUksRUFDSixnQkFBZ0IsRUFDaEIsVUFBVSxFQUVWLFVBQVUsRUFFVixPQUFPLEVBQ1AsSUFBSSxFQUNKLGlCQUFpQixFQUNqQixpQkFBaUIsRUFFakIsZ0JBQWdCLEVBQ2hCLGFBQWEsRUFDYixTQUFTLEVBQ1QsS0FBSyxFQUNMLGNBQWMsRUFDZCxjQUFjLEVBRWQsY0FBYyxFQUNkLE9BQU8sRUFDUCxPQUFPLEVBRVIsTUFBTSxPQUFPLENBQUM7QUFDZixPQUFPLEtBQUssS0FBSyxNQUFNLG1CQUFtQixDQUFDO0FBQzNDLE9BQU8sRUFBQyxlQUFlLEVBQUUsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzlDLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQztBQUVsRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDOUMsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0scUNBQXFDLENBQUM7QUFDckUsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sZ0NBQWdDLENBQUM7QUFHbkUsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQ2xELE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQztBQUV0RCxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sdUJBQXVCLENBQUM7Ozs7O0FBUWxELE1BQU0sT0FBTyxTQUFTO0lBaUVwQixZQUNVLGNBQTZCLEVBQzdCLGdCQUFpQyxFQUNq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O0lBQ2hILENBQUM7O3VHQTE2QlUsU0FBUzsyR0FBVCxTQUFTLGNBREcsTUFBTTs0RkFDbEIsU0FBUztrQkFEckIsVUFBVTttQkFBQyxFQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0luamVjdGFibGUsIE9uRGVzdHJveX0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCAqIGFzIFRIUkVFIGZyb20gJ3RocmVlJztcclxuaW1wb3J0IHtcclxuICBCb3gzLFxyXG4gIERpcmVjdGlvbmFsTGlnaHQsXHJcbiAgRG91YmxlU2lkZSxcclxuICBJbnRlcnNlY3Rpb24sXHJcbiAgTGlnaHRQcm9iZSxcclxuICBNYXRlcmlhbCxcclxuICBNYXRyaXg0LFxyXG4gIE1lc2gsXHJcbiAgTWVzaEJhc2ljTWF0ZXJpYWwsXHJcbiAgTWVzaFBob25nTWF0ZXJpYWwsXHJcbiAgT2JqZWN0M0QsXHJcbiAgUENGU29mdFNoYWRvd01hcCxcclxuICBQbGFuZUdlb21ldHJ5LFxyXG4gIFJheWNhc3RlcixcclxuICBTY2VuZSxcclxuICBTaGFkb3dNYXRlcmlhbCxcclxuICBTcGhlcmVHZW9tZXRyeSxcclxuICBTcG90TGlnaHQsXHJcbiAgU1JHQkNvbG9yU3BhY2UsXHJcbiAgVGV4dHVyZSxcclxuICBWZWN0b3IzLFxyXG4gIFdlYkdMUmVuZGVyZXJcclxufSBmcm9tICd0aHJlZSc7XHJcbmltcG9ydCAqIGFzIFRXRUVOIGZyb20gJ0B0d2VlbmpzL3R3ZWVuLmpzJztcclxuaW1wb3J0IHtCZWhhdmlvclN1YmplY3QsIFN1YmplY3R9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQge0FyRmVhdHVyZX0gZnJvbSAnLi4vZW51bS9hci1mZWF0dXJlLmVudW0nO1xyXG5pbXBvcnQge0NhbWVyYVNlcnZpY2V9IGZyb20gJy4vY2FtZXJhLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBSZXRpY2xlIH0gZnJvbSAnLi4vbW9kZWwveHItcmV0aWNsZSc7XHJcbmltcG9ydCB7RGVwdGhEYXRhVGV4dHVyZX0gZnJvbSAnLi4vY29yZS90ZXh0dXJlcy9kZXB0aC1kYXRhLXRleHR1cmUnO1xyXG5pbXBvcnQge0FyUG9zaXRpb25JbmRpY2F0b3J9IGZyb20gJy4uL21vZGVsL2FyLXBvc2l0aW9uLWluZGljYXRvcic7XHJcbmltcG9ydCB7U2V0dGluZ3NTZXJ2aWNlfSBmcm9tICcuL3NldHRpbmdzLnNlcnZpY2UnO1xyXG5pbXBvcnQge0NvbmZpZ3VyYXRvckNvbm5lY3RvclNlcnZpY2V9IGZyb20gJy4vY29uZmlndXJhdG9yLWNvbm5lY3Rvci5zZXJ2aWNlJztcclxuaW1wb3J0IHtPYmplY3RVdGlsc30gZnJvbSAnLi4vdXRpbHMvb2JqZWN0LnV0aWxzJztcclxuaW1wb3J0IHtNYXRlcmlhbFV0aWxzfSBmcm9tICcuLi91dGlscy9tYXRlcmlhbC51dGlscyc7XHJcbmltcG9ydCB7Vmlld01vZGV9IGZyb20gJy4uL2VudW0vdmlldy1tb2RlLmVudW0nO1xyXG5pbXBvcnQge0RldmljZVV0aWxzfSBmcm9tICcuLi91dGlscy9kZXZpY2UudXRpbHMnO1xyXG5cclxuaW50ZXJmYWNlIFBvaW50IHtcclxuICB4OiBudW1iZXI7XHJcbiAgeTogbnVtYmVyO1xyXG59XHJcblxyXG5ASW5qZWN0YWJsZSh7cHJvdmlkZWRJbjogJ3Jvb3QnfSlcclxuZXhwb3J0IGNsYXNzIEFyU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XHJcblxyXG4gIHB1YmxpYyB1cGRhdGVDb250ZXh0TWVudTogQmVoYXZpb3JTdWJqZWN0PHZvaWQ+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDx2b2lkPihudWxsKTtcclxuXHJcbiAgcHVibGljIHNob3VsZEFkZE9iamVjdFRvU2NlbmU6IFN1YmplY3Q8T2JqZWN0M0Q+ID0gbmV3IFN1YmplY3Q8T2JqZWN0M0Q+KCk7XHJcbiAgcHVibGljIHNob3dDb25maWd1cmF0b3I6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgcHVibGljIHJlZlNwYWNlOiBhbnk7XHJcbiAgcHVibGljIGhpdFRlc3RTb3VyY2U6IGFueTtcclxuICBwdWJsaWMgc2NlbmU6IFNjZW5lO1xyXG4gIHB1YmxpYyB1c2VySW5TZWxlY3Rpb25NZW51OiBib29sZWFuID0gZmFsc2U7XHJcbiAgcHVibGljIHNob3dDb250ZXh0TWVudTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBwcml2YXRlIF9hckZlYXR1cmVzOiBBckZlYXR1cmVbXSA9IFtdO1xyXG4gIHByaXZhdGUgX3JlbmRlcmVyOiBXZWJHTFJlbmRlcmVyO1xyXG4gIHByaXZhdGUgX2dsQmluZGluZzogYW55O1xyXG4gIHByaXZhdGUgX3Nlc3Npb246IGFueTtcclxuICBwcml2YXRlIF9kZWJ1ZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIHByaXZhdGUgX3N1cmZhY2VGb3VuZE9uY2UgPSBmYWxzZTtcclxuXHJcbiAgcHJpdmF0ZSBfcmV0aWNsZTogUmV0aWNsZTtcclxuICBwcml2YXRlIF9oaXRUZXN0UmVzdWx0OiBNYXRyaXg0O1xyXG4gIHByaXZhdGUgX3JldGljbGVIaXRUZXN0UmVzdWx0OiBhbnk7XHJcbiAgcHJpdmF0ZSBfYW5jaG9yZWRPYmplY3RzOiB7YW5jaG9yZWRPYmplY3Q6IE9iamVjdDNELCBhbmNob3I6IGFueX1bXTtcclxuICBwcml2YXRlIF9hY3RpdmVBUk1vZGVsOiBPYmplY3QzRDtcclxuICBwcml2YXRlIF9hUk1vZGVsQmFja3VwWVBvc2l0aW9uOiBudW1iZXI7XHJcbiAgcHJpdmF0ZSBfYVJNb2RlbEJhY2t1cFBvc2l0aW9uOiBWZWN0b3IzO1xyXG4gIHByaXZhdGUgX2FSTW9kZWxCYWNrdXBZUm90YXRpb246IG51bWJlcjtcclxuICBwcml2YXRlIF9hUk1vZGVsUm90YXRpb25TdGFydGluZ1ZhbHVlOiBudW1iZXIgPSAwO1xyXG4gIHByaXZhdGUgX3ZlcnRleExpc3Q6IEFycmF5PFBvaW50PiA9IFtdO1xyXG4gIHByaXZhdGUgX2RldGVjdGVkUGxhbmVzOiBNZXNoW10gPSBbXTtcclxuICBwcml2YXRlIF9yYXdQbGFuZXM6IFNldDxhbnk+ID0gbmV3IFNldCgpO1xyXG4gIHByaXZhdGUgX3BsYW5lTWF0ZXJpYWw6IE1lc2hQaG9uZ01hdGVyaWFsO1xyXG4gIHByaXZhdGUgX3NoYWRvd1BsYW5lOiBNZXNoO1xyXG5cclxuICBwcml2YXRlIF9sYXN0RXZlbnRUaW1lc3RhbXA6IG51bWJlcjtcclxuICBwcml2YXRlIF9sYXN0T2JqZWN0VG91Y2hUaW1lc3RhbXA6IG51bWJlcjtcclxuICBwcml2YXRlIF9kb3VibGVUYXBUaW1lZnJhbWU6IG51bWJlciA9IDUwMDtcclxuICBwcml2YXRlIF9ob2xkaW5nVG91Y2g6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBwcml2YXRlIF9jb250cm9sbGVyOiBhbnk7XHJcbiAgcHJpdmF0ZSBfcmF5Y2FzdGVyOiBSYXljYXN0ZXI7XHJcbiAgcHJpdmF0ZSBfdGVtcE1hdHJpeDogTWF0cml4NDtcclxuICBwcml2YXRlIF9jbGVhbnVwOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgcHJpdmF0ZSBfYW5pbWF0aW5nOiBib29sZWFuID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBfbGlmdEFuaW1hdGlvbjogVFdFRU4uVHdlZW48YW55PjtcclxuICBwcml2YXRlIF9kcm9wQW5pbWF0aW9uOiBUV0VFTi5Ud2Vlbjxhbnk+O1xyXG5cclxuICBwcml2YXRlIF9saWdodFByb2JlOiBhbnk7XHJcbiAgcHJpdmF0ZSBfdGhyZWVMaWdodFByb2JlOiBMaWdodFByb2JlO1xyXG4gIHByaXZhdGUgX2N1YmVNYXBUZXh0dXJlOiBUZXh0dXJlO1xyXG4gIHByaXZhdGUgX2RlcHRoRGF0YVRleHR1cmU6IERlcHRoRGF0YVRleHR1cmU7XHJcbiAgcHJpdmF0ZSBfc3VuTGlnaHQ6IFNwb3RMaWdodCB8IERpcmVjdGlvbmFsTGlnaHQ7XHJcblxyXG4gIHByaXZhdGUgX3Bvc2l0aW9uSW5kaWNhdG9yOiBBclBvc2l0aW9uSW5kaWNhdG9yO1xyXG5cclxuICBwcml2YXRlIF9wb2ludFJlcHJlc2VudGF0aW9uID0gbmV3IE1lc2goXHJcbiAgICBuZXcgU3BoZXJlR2VvbWV0cnkoMC4wMiwgMTIsIDEyKSxcclxuICAgIG5ldyBNZXNoQmFzaWNNYXRlcmlhbCh7XHJcbiAgICAgIGNvbG9yOiAweDRjY2FlZCxcclxuICAgICAgdHJhbnNwYXJlbnQ6IHRydWUsXHJcbiAgICAgIG9wYWNpdHk6IDAuMlxyXG4gICAgfSlcclxuICApO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgX2NhbWVyYVNlcnZpY2U6IENhbWVyYVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIF9zZXR0aW5nc1NlcnZpY2U6IFNldHRpbmdzU2VydmljZSxcclxuICAgIHByaXZhdGUgX2lPbmU6IENvbmZpZ3VyYXRvckNvbm5lY3RvclNlcnZpY2VcclxuICApIHtcclxuICAgIHdpbmRvdy5vbmJlZm9yZXVubG9hZCA9ICgpID0+IHRoaXMubmdPbkRlc3Ryb3koKTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCkge1xyXG4gICAgT2JqZWN0VXRpbHMuRGlzcG9zZU9iamVjdCh0aGlzLl9yZXRpY2xlKTtcclxuICAgIE9iamVjdFV0aWxzLkRpc3Bvc2VPYmplY3QodGhpcy5fc3VuTGlnaHQpO1xyXG4gICAgT2JqZWN0VXRpbHMuRGlzcG9zZU9iamVjdCh0aGlzLl9wb2ludFJlcHJlc2VudGF0aW9uKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBhc3luYyByZXNldFBsYW5lRGV0ZWN0aW9uKCkge1xyXG4gICAgdGhpcy5fcmV0aWNsZS52aXNpYmxlID0gZmFsc2U7XHJcbiAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnZpc2libGUgPSBmYWxzZTtcclxuICAgIHRoaXMuX3ZlcnRleExpc3QgPSBbXTtcclxuICAgIHRoaXMuX2RldGVjdGVkUGxhbmVzLmZvckVhY2goKHBsYW5lKSA9PiB0aGlzLnNjZW5lLnJlbW92ZShwbGFuZSkpO1xyXG4gICAgdGhpcy5fZGV0ZWN0ZWRQbGFuZXMgPSBbXTtcclxuICAgIHRoaXMuc2NlbmUucmVtb3ZlKHRoaXMuX3Bvc2l0aW9uSW5kaWNhdG9yKTtcclxuICAgIHRoaXMuX3Jhd1BsYW5lcyA9IG5ldyBTZXQ8YW55PigpO1xyXG4gICAgdGhpcy5fY2xlYW51cCA9IGZhbHNlO1xyXG4gICAgYXdhaXQgdGhpcy5fc2Vzc2lvbi5lbmQoKTtcclxuICAgIHRoaXMuX2NsZWFudXAgPSB0cnVlO1xyXG4gICAgdGhpcy5fc2Vzc2lvbiA9IG51bGw7XHJcbiAgICB0aGlzLl9pbml0U2Vzc2lvbigpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGVuZFNlc3Npb25FdmVudCgpOiB2b2lkIHtcclxuICAgIHRoaXMuX3Nlc3Npb24uZW5kKCk7XHJcbiAgfVxyXG4gIHB1YmxpYyBhc3luYyBhcklPU1N1cHBvcnRlZCgpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgIGNvbnN0IGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XHJcbiAgICAvLyByZWxMaXN0LnN1cHBvcnRzKCdhcicpIGV4aXN0cyBvbiBTYWZhcmkgdGhhdCBzdXBwb3J0cyBRdWljayBMb29rXHJcbiAgICByZXR1cm4gISEoYS5yZWxMaXN0ICYmIChhLnJlbExpc3QgYXMgYW55KS5zdXBwb3J0cyAmJiBhLnJlbExpc3Quc3VwcG9ydHMoJ2FyJykpO1xyXG4gIH1cclxuICBwdWJsaWMgYXN5bmMgYXJTdXBwb3J0ZWQoKSB7XHJcbiAgICBpZiAoKG5hdmlnYXRvciBhcyBhbnkpLnhyKSB7XHJcbiAgICAgIHJldHVybiBhd2FpdCAobmF2aWdhdG9yIGFzIGFueSkueHIuaXNTZXNzaW9uU3VwcG9ydGVkKCdpbW1lcnNpdmUtYXInKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBhZGRPYmplY3RUb0FSU2NlbmUob2JqZWN0OiBPYmplY3QzRCk6IHZvaWQge1xyXG4gICAgdGhpcy5fYWN0aXZlQVJNb2RlbCA9IG9iamVjdDtcclxuICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwudmlzaWJsZSA9IGZhbHNlO1xyXG4gICAgdGhpcy5fYWN0aXZlQVJNb2RlbC5jYXN0U2hhZG93ID0gdHJ1ZTtcclxuICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucmVjZWl2ZVNoYWRvdyA9IHRydWU7XHJcbiAgICB0aGlzLl9wb3NpdGlvbkluZGljYXRvciA9IG5ldyBBclBvc2l0aW9uSW5kaWNhdG9yKG5ldyBCb3gzKCkuc2V0RnJvbU9iamVjdChvYmplY3QpKTtcclxuICAgIHRoaXMuc2NlbmUuYWRkKHRoaXMuX2FjdGl2ZUFSTW9kZWwsIHRoaXMuX3Bvc2l0aW9uSW5kaWNhdG9yKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBtb2RlbExvYWRpbmcoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gIXRoaXMuX2FjdGl2ZUFSTW9kZWw7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbW9kZWxQbGFjZWQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5fYWN0aXZlQVJNb2RlbCAmJiB0aGlzLl9hY3RpdmVBUk1vZGVsLnZpc2libGUgJiYgIXRoaXMuX2hvbGRpbmdUb3VjaDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBoYW5kbGVGcmFtZSh4ckZyYW1lKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5fc2Vzc2lvbiAmJiB0aGlzLl9hY3RpdmVBUk1vZGVsKSB7XHJcbiAgICAgIC8vIFRPRE8gRklYXHJcbiAgICAgIC8vIHRoaXMuX2lPbmUuc2hvdWxkU2hvd0xvYWRlciA9IGZhbHNlO1xyXG5cclxuICAgICAgdGhpcy5fY2hlY2tBdmFpbGFibGVGZWF0dXJlcyh4ckZyYW1lKTtcclxuICAgICAgdGhpcy5fY2hlY2tIaXRUZXN0TWV0aG9kKHhyRnJhbWUpO1xyXG4gICAgICB0aGlzLl9jaGVja0V4dHJhRmVhdHVyZXMoeHJGcmFtZSk7XHJcbiAgICAgIHRoaXMuX2hhbmRsZUhvbGRNb3ZlRXZlbnQoKTtcclxuICAgICAgdGhpcy5faGFuZGxlTXVsdGlUb3VjaEV2ZW50KCk7XHJcblxyXG4gICAgICBpZiAodGhpcy5fYWN0aXZlQVJNb2RlbC52aXNpYmxlKSB7XHJcbiAgICAgICAgdGhpcy51cGRhdGVDb250ZXh0TWVudS5uZXh0KCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIFRXRUVOLnVwZGF0ZSgpO1xyXG4gICAgdGhpcy5fcmVuZGVyZXIucmVuZGVyKHRoaXMuc2NlbmUsIHRoaXMuX2NhbWVyYVNlcnZpY2UuY2FtZXJhKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBpbml0KHJlbmRlcmVyOiBXZWJHTFJlbmRlcmVyKTogdm9pZCB7XHJcbiAgICAvLyBUT0RPIEZJWFxyXG4gICAgLy8gdGhpcy5faU9uZS5zaG91bGRTaG93TG9hZGVyID0gdHJ1ZTtcclxuICAgIGlmICghdGhpcy5fcmVuZGVyZXIpIHtcclxuICAgICAgdGhpcy5fcmVuZGVyZXIgPSByZW5kZXJlcjtcclxuICAgICAgdGhpcy5fcmVuZGVyZXIub3V0cHV0Q29sb3JTcGFjZSA9IFNSR0JDb2xvclNwYWNlO1xyXG4gICAgICB0aGlzLl9pbml0U2NlbmUoKTtcclxuICAgICAgdGhpcy5faW5pdExpZ2h0aW5nKCk7XHJcbiAgICAgIHRoaXMuX2luaXRDb250cm9sbGVyKCk7XHJcblxyXG4gICAgICB0aGlzLl9yZXRpY2xlID0gbmV3IFJldGljbGUoKTtcclxuICAgICAgdGhpcy5zY2VuZS5hZGQodGhpcy5fcmV0aWNsZSk7XHJcbiAgICB9XHJcbiAgICB0aGlzLl9pbml0UmVuZGVyZXIoKTtcclxuICAgIHRoaXMuX2luaXRTZXNzaW9uKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2F2ZVByZVNlbGVjdGlvblBvc2l0aW9uKCkge1xyXG4gICAgdGhpcy5fYVJNb2RlbEJhY2t1cFBvc2l0aW9uID0gdGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi5jbG9uZSgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHVwZGF0ZUNoYW5nZWRNb2RlbCgpIHtcclxuICAgIGlmICh0aGlzLl9hUk1vZGVsQmFja3VwUG9zaXRpb24pIHtcclxuICAgICAgdGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi5zZXQodGhpcy5fYVJNb2RlbEJhY2t1cFBvc2l0aW9uLngsIHRoaXMuX2FSTW9kZWxCYWNrdXBQb3NpdGlvbi55LCB0aGlzLl9hUk1vZGVsQmFja3VwUG9zaXRpb24ueik7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5fYXJGZWF0dXJlcy5pbmNsdWRlcyhBckZlYXR1cmUuQ1BVRGVwdGhPY2NsdXNpb24pKSB7XHJcbiAgICAgIHRoaXMuX3VwZGF0ZU1lc2hNYXRlcmlhbHMoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBhck1vZGVIYXNCZWVuQWN0aXZlKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuc2NlbmUgIT09IHVuZGVmaW5lZDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzaG93TW92ZVBob25lQW5pbWF0aW9uKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2ZUFSTW9kZWwgJiYgIXRoaXMuX3JldGljbGUudmlzaWJsZSAmJiAhdGhpcy5fc3VyZmFjZUZvdW5kT25jZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXRBY3RpdmVNb2RlbCgpOiBhbnkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2ZUFSTW9kZWw7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9pbml0U2Vzc2lvbigpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5fc2Vzc2lvbikge1xyXG4gICAgICAvLyAnZGVwdGgtc2Vuc2luZydcclxuICAgICAgY29uc3QgZmVhdHVyZXMgPSB7XHJcbiAgICAgICAgcmVxdWlyZWRGZWF0dXJlczogWydsb2NhbC1mbG9vcicsICdoaXQtdGVzdCddLFxyXG4gICAgICAgIG9wdGlvbmFsRmVhdHVyZXM6IFsnbGlnaHQtZXN0aW1hdGlvbicsICdwbGFuZS1kZXRlY3Rpb24nLCAnYW5jaG9ycycsICdkb20tb3ZlcmxheSddXHJcbiAgICAgICAgLCBkb21PdmVybGF5OiB7cm9vdDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FyLXJvb3QnKX1cclxuICAgICAgICAsIGRlcHRoU2Vuc2luZzoge1xyXG4gICAgICAgICAgdXNhZ2VQcmVmZXJlbmNlOiBbJ2NwdS1vcHRpbWl6ZWQnXSxcclxuICAgICAgICAgIGRhdGFGb3JtYXRQcmVmZXJlbmNlOiBbJ2x1bWluYW5jZS1hbHBoYSddXHJcbiAgICAgICAgfVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgKG5hdmlnYXRvciBhcyBhbnkpLnhyLnJlcXVlc3RTZXNzaW9uKCdpbW1lcnNpdmUtYXInLCBmZWF0dXJlcykudGhlbigoc2Vzc2lvbikgPT4ge1xyXG4gICAgICAgIHRoaXMuX3JlbmRlcmVyLnhyLnNldFJlZmVyZW5jZVNwYWNlVHlwZSgnbG9jYWwnKTtcclxuXHJcbiAgICAgICAgc2Vzc2lvbi5yZXF1ZXN0UmVmZXJlbmNlU3BhY2UoJ3ZpZXdlcicpLnRoZW4oKHJlZlNwYWNlKSA9PiB7XHJcbiAgICAgICAgICBzZXNzaW9uLnJlcXVlc3RIaXRUZXN0U291cmNlKHtzcGFjZTogcmVmU3BhY2V9KS50aGVuKChoaXRUZXN0U291cmNlKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuaGl0VGVzdFNvdXJjZSA9IGhpdFRlc3RTb3VyY2U7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgc2Vzc2lvbi5yZXF1ZXN0UmVmZXJlbmNlU3BhY2UoJ2xvY2FsJykudGhlbigocmVmU3BhY2UpID0+IHtcclxuICAgICAgICAgIHRoaXMucmVmU3BhY2UgPSByZWZTcGFjZTtcclxuICAgICAgICAgIHRoaXMuX29uU2Vzc2lvblN0YXJ0ZWQoc2Vzc2lvbik7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY2hlY2tBdmFpbGFibGVGZWF0dXJlcyh4ckZyYW1lOiBhbnkpIHtcclxuICAgIGlmICh0aGlzLl9zZXR0aW5nc1NlcnZpY2Uuc2V0dGluZ3MuYXJQYXJhbWV0ZXJzLmRlcHRoT2NjbHVzaW9uICYmIHRoaXMuX3NldHRpbmdzU2VydmljZS5zZXR0aW5ncy5hclBhcmFtZXRlcnMuZGVwdGhIaXRUZXN0ICYmXHJcbiAgICAgICEodGhpcy5fYXJGZWF0dXJlcy5pbmNsdWRlcyhBckZlYXR1cmUuQ1BVRGVwdGhPY2NsdXNpb24pKSAmJiB0aGlzLl9zZXNzaW9uLmRlcHRoVXNhZ2UpIHtcclxuICAgICAgdGhpcy5fYXJGZWF0dXJlcy5wdXNoKEFyRmVhdHVyZS5DUFVEZXB0aE9jY2x1c2lvbiwgQXJGZWF0dXJlLkNQVURlcHRoSGl0VGVzdCk7XHJcbiAgICAgIHRoaXMuX2luaXRDUFVEZXB0aE9jY2x1c2lvbigpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9zZXR0aW5nc1NlcnZpY2Uuc2V0dGluZ3MuYXJQYXJhbWV0ZXJzLmFuY2hvcmVkSGl0VGVzdCAmJlxyXG4gICAgICAhKHRoaXMuX2FyRmVhdHVyZXMuaW5jbHVkZXMoQXJGZWF0dXJlLkFuY2hvcmVkSGl0VGVzdCkpICYmIHhyRnJhbWUudHJhY2tlZEFuY2hvcnMpIHtcclxuICAgICAgdGhpcy5fYXJGZWF0dXJlcy5wdXNoKEFyRmVhdHVyZS5BbmNob3JlZEhpdFRlc3QpO1xyXG4gICAgICB0aGlzLl9pbml0QW5jaG9yZWRIaXRUZXN0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuX3NldHRpbmdzU2VydmljZS5zZXR0aW5ncy5hclBhcmFtZXRlcnMubGlnaHRFc3RpbWF0aW9uICYmXHJcbiAgICAgICEodGhpcy5fYXJGZWF0dXJlcy5pbmNsdWRlcyhBckZlYXR1cmUuTGlnaHRFc3RpbWF0aW9uKSkpIHtcclxuICAgICAgdGhpcy5fc2Vzc2lvbi5yZXF1ZXN0TGlnaHRQcm9iZSgpLnRoZW4oKGxpZ2h0UHJvYmU6IGFueSkgPT4ge1xyXG4gICAgICAgIGlmIChsaWdodFByb2JlKSB7XHJcbiAgICAgICAgICB0aGlzLl9hckZlYXR1cmVzLnB1c2goQXJGZWF0dXJlLkxpZ2h0RXN0aW1hdGlvbik7XHJcbiAgICAgICAgICB0aGlzLl9pbml0TGlnaHRFc3RpbWF0aW9uKGxpZ2h0UHJvYmUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuX3NldHRpbmdzU2VydmljZS5zZXR0aW5ncy5hclBhcmFtZXRlcnMucmVmbGVjdGlvbkVzdGltYXRpb24gJiZcclxuICAgICAgISh0aGlzLl9hckZlYXR1cmVzLmluY2x1ZGVzKEFyRmVhdHVyZS5SZWZsZWN0aW9uQ3ViZU1hcCkpICYmIHRoaXMuX2xpZ2h0UHJvYmVcclxuICAgICAgJiYgdGhpcy5fZ2xCaW5kaW5nLmdldFJlZmxlY3Rpb25DdWJlTWFwKHRoaXMuX2xpZ2h0UHJvYmUpKSB7XHJcbiAgICAgIHRoaXMuX2FyRmVhdHVyZXMucHVzaChBckZlYXR1cmUuUmVmbGVjdGlvbkN1YmVNYXApO1xyXG4gICAgICB0aGlzLl9pbml0UmVmbGVjdGlvbkN1YmVNYXAoKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5fc2V0dGluZ3NTZXJ2aWNlLnNldHRpbmdzLmFyUGFyYW1ldGVycy5wbGFuZURldGVjdGlvbiAmJiB0aGlzLl9zZXR0aW5nc1NlcnZpY2Uuc2V0dGluZ3MuYXJQYXJhbWV0ZXJzLnBsYW5lSGl0VGVzdCAmJlxyXG4gICAgICAhKHRoaXMuX2FyRmVhdHVyZXMuaW5jbHVkZXMoQXJGZWF0dXJlLlBsYW5lRGV0ZWN0aW9uKSkgJiYgeHJGcmFtZS53b3JsZEluZm9ybWF0aW9uKSB7XHJcbiAgICAgIHRoaXMuX2FyRmVhdHVyZXMucHVzaChBckZlYXR1cmUuUGxhbmVEZXRlY3Rpb24sIEFyRmVhdHVyZS5QbGFuZURldGVjdGlvbkhpdFRlc3QpO1xyXG4gICAgICB0aGlzLl9pbml0UGxhbmVEZXRlY3Rpb24oKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2luaXRSZW5kZXJlcigpOiB2b2lkIHtcclxuICAgIHRoaXMuX3JlbmRlcmVyLnhyLmVuYWJsZWQgPSB0cnVlO1xyXG4gICAgdGhpcy5fcmVuZGVyZXIuc2hhZG93TWFwLnR5cGUgPSBQQ0ZTb2Z0U2hhZG93TWFwO1xyXG4gICAgdGhpcy5fcmVuZGVyZXIuc2V0Q2xlYXJDb2xvcigweDAwMDAwMCwgMCk7XHJcbiAgICB0aGlzLl9yZW5kZXJlci5hdXRvQ2xlYXIgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2luaXRDb250cm9sbGVyKCk6IHZvaWQge1xyXG4gICAgdGhpcy5fdGVtcE1hdHJpeCA9IG5ldyBNYXRyaXg0KCk7XHJcbiAgICB0aGlzLl9yYXljYXN0ZXIgPSBuZXcgUmF5Y2FzdGVyKCk7XHJcbiAgICB0aGlzLl9jb250cm9sbGVyID0gdGhpcy5fcmVuZGVyZXIueHIuZ2V0Q29udHJvbGxlcigwKTtcclxuICAgIHRoaXMuc2NlbmUuYWRkKHRoaXMuX2NvbnRyb2xsZXIpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaW5pdFNjZW5lKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zY2VuZSA9IG5ldyBTY2VuZSgpO1xyXG4gICAgY29uc3QgcGxhbmVHZW9tZXRyeSA9IG5ldyBQbGFuZUdlb21ldHJ5KDEwMCwgMTAwKTtcclxuICAgIGNvbnN0IG1hdGVyaWFsID0gbmV3IFNoYWRvd01hdGVyaWFsKHtvcGFjaXR5OiAwLjJ9KTtcclxuICAgIHRoaXMuX3NoYWRvd1BsYW5lID0gbmV3IE1lc2gocGxhbmVHZW9tZXRyeSwgbWF0ZXJpYWwpO1xyXG4gICAgdGhpcy5fc2hhZG93UGxhbmUubmFtZSA9ICdzaGFkb3dQbGFuZSc7XHJcbiAgICB0aGlzLl9zaGFkb3dQbGFuZS5yb3RhdGlvbi54IC09IE1hdGguUEkgLyAyO1xyXG4gICAgdGhpcy5fc2hhZG93UGxhbmUucmVjZWl2ZVNoYWRvdyA9IHRydWU7XHJcbiAgICB0aGlzLl9zaGFkb3dQbGFuZS52aXNpYmxlID0gZmFsc2U7XHJcbiAgICB0aGlzLnNjZW5lLmFkZCh0aGlzLl9zaGFkb3dQbGFuZSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9pbml0TGlnaHRFc3RpbWF0aW9uKGxpZ2h0UHJvYmU6IGFueSkge1xyXG4gICAgdGhpcy5fdGhyZWVMaWdodFByb2JlID0gIG5ldyBMaWdodFByb2JlKCk7XHJcbiAgICB0aGlzLnNjZW5lLmFkZCh0aGlzLl90aHJlZUxpZ2h0UHJvYmUpO1xyXG4gICAgdGhpcy5fbGlnaHRQcm9iZSA9IGxpZ2h0UHJvYmU7XHJcblxyXG4gICAgLy8gQHRzLWlnbm9yZVxyXG4gICAgdGhpcy5fZ2xCaW5kaW5nID0gbmV3IFhSV2ViR0xCaW5kaW5nKHRoaXMuX3Nlc3Npb24sIHRoaXMuX3JlbmRlcmVyLmdldENvbnRleHQoKSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9pbml0UmVmbGVjdGlvbkN1YmVNYXAoKSB7XHJcbiAgICB0aGlzLl9jdWJlTWFwVGV4dHVyZSA9IG5ldyBUZXh0dXJlKCk7XHJcbiAgICB0aGlzLl9yZW5kZXJlci5pbml0VGV4dHVyZSh0aGlzLl9jdWJlTWFwVGV4dHVyZSk7XHJcbiAgICB0aGlzLnNjZW5lLmVudmlyb25tZW50ID0gdGhpcy5fY3ViZU1hcFRleHR1cmU7XHJcblxyXG4gICAgdGhpcy5fbGlnaHRQcm9iZS5hZGRFdmVudExpc3RlbmVyKCdyZWZsZWN0aW9uY2hhbmdlJywgKCkgPT4ge1xyXG4gICAgICBjb25zdCByYXdEYXRhID0gdGhpcy5fZ2xCaW5kaW5nLmdldFJlZmxlY3Rpb25DdWJlTWFwKHRoaXMuX2xpZ2h0UHJvYmUpO1xyXG4gICAgICBjb25zdCB0ZXhQcm9wcyA9IHRoaXMuX3JlbmRlcmVyLnByb3BlcnRpZXMuZ2V0KHRoaXMuX2N1YmVNYXBUZXh0dXJlKTtcclxuICAgICAgLy8gQHRzLWlnbm9yZVxyXG4gICAgICB0ZXhQcm9wcy5fX3dlYmdsVGV4dHVyZSA9IHJhd0RhdGE7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2luaXRDUFVEZXB0aE9jY2x1c2lvbigpIHtcclxuICAgIHRoaXMuX2RlcHRoRGF0YVRleHR1cmUgPSBuZXcgRGVwdGhEYXRhVGV4dHVyZSgpO1xyXG4gICAgdGhpcy5fdXBkYXRlTWVzaE1hdGVyaWFscygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaW5pdEFuY2hvcmVkSGl0VGVzdCgpIHtcclxuICAgIHRoaXMuX2FuY2hvcmVkT2JqZWN0cyA9IFtdO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaW5pdFBsYW5lRGV0ZWN0aW9uKCkge1xyXG4gICAgdGhpcy5fY3JlYXRlUGxhbmVNYXRlcmlhbCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaW5pdExpZ2h0aW5nKCkge1xyXG4gICAgY29uc3QgYW1iaWVudExpZ2h0ID0gbmV3IFRIUkVFLkFtYmllbnRMaWdodCgweGZmZmZmZiwgMC4xKTtcclxuICAgIGFtYmllbnRMaWdodC5jb2xvci5zZXRIZXgoMHhmZmZmZmYpLmNvbnZlcnRTUkdCVG9MaW5lYXIoKTtcclxuICAgIGFtYmllbnRMaWdodC5uYW1lID0gJ2FtYmllbnRMaWdodCc7XHJcblxyXG4gICAgdGhpcy5fc3VuTGlnaHQgPSBuZXcgRGlyZWN0aW9uYWxMaWdodCgnYmxhY2snLCAwLjMpO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQuY2FzdFNoYWRvdyA9IHRydWU7XHJcbiAgICB0aGlzLl9zdW5MaWdodC5zaGFkb3cubWFwU2l6ZS53aWR0aCA9IDQwOTY7XHJcbiAgICB0aGlzLl9zdW5MaWdodC5zaGFkb3cubWFwU2l6ZS5oZWlnaHQgPSA0MDk2O1xyXG4gICAgdGhpcy5fc3VuTGlnaHQuc2hhZG93LmNhbWVyYS5sZWZ0ID0gLTEwO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQuc2hhZG93LmNhbWVyYS5yaWdodCA9IDEwO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQuc2hhZG93LmNhbWVyYS50b3AgPSAxMDtcclxuICAgIHRoaXMuX3N1bkxpZ2h0LnNoYWRvdy5jYW1lcmEuYm90dG9tID0gLTEwO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQuc2hhZG93LmNhbWVyYS5uZWFyID0gMC4xO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQuc2hhZG93LmNhbWVyYS5mYXIgPSAzMDtcclxuICAgIHRoaXMuX3N1bkxpZ2h0LnZpc2libGUgPSB0cnVlO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQudGFyZ2V0LnZpc2libGUgPSB0cnVlO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQubmFtZSA9ICdzdW5MaWdodCc7XHJcbiAgICB0aGlzLnNjZW5lLmFkZCgvKmFtYmllbnRMaWdodCwgKi90aGlzLl9zdW5MaWdodC50YXJnZXQsIHRoaXMuX3N1bkxpZ2h0KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2NoZWNrSGl0VGVzdE1ldGhvZCh4ckZyYW1lOiBhbnkpIHtcclxuICAgIGlmICh0aGlzLl9hckZlYXR1cmVzLmluY2x1ZGVzKEFyRmVhdHVyZS5DUFVEZXB0aE9jY2x1c2lvbikgJiYgdGhpcy5fYXJGZWF0dXJlcy5pbmNsdWRlcyhBckZlYXR1cmUuQW5jaG9yZWRIaXRUZXN0KSkge1xyXG4gICAgICB0aGlzLl9leGVjdXRlRGVwdGhBbmNob3JIaXRUZXN0KHhyRnJhbWUpO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLl9hckZlYXR1cmVzLmluY2x1ZGVzKEFyRmVhdHVyZS5BbmNob3JlZEhpdFRlc3QpKSB7XHJcbiAgICAgIHRoaXMuX2V4ZWN1dGVBbmNob3JlZEhpdFRlc3QoeHJGcmFtZSk7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMuX2FyRmVhdHVyZXMuaW5jbHVkZXMoQXJGZWF0dXJlLkNQVURlcHRoSGl0VGVzdCkpIHtcclxuICAgICAgdGhpcy5fZXhlY3V0ZUNQVURlcHRoSGl0VGVzdCh4ckZyYW1lKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuX2V4ZWN1dGVEZWZhdWx0SGl0VGVzdCh4ckZyYW1lKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2V4ZWN1dGVEZXB0aEFuY2hvckhpdFRlc3QoeHJGcmFtZSkge1xyXG4gICAgY29uc3QgeHJWaWV3ZXJQb3NlOiBhbnkgPSB4ckZyYW1lLmdldFZpZXdlclBvc2UodGhpcy5yZWZTcGFjZSk7XHJcbiAgICBjb25zdCB4ckNhbWVyYTogYW55ID0gdGhpcy5fcmVuZGVyZXIueHIuZ2V0Q2FtZXJhKC8qdGhpcy5fY2FtZXJhU2VydmljZS5jYW1lcmEqLyk7IC8vIHRvZG86IGR1ZSB0byB0aHJlZWpzIHVwZGF0ZSBwYXJhbWV0ZXIgbm90IG5lZWRlZCBhbnltb3JlLCBjaGVjayB0aGlzIVxyXG4gICAgdGhpcy5fcmV0aWNsZS52aXNpYmxlID0gZmFsc2U7XHJcblxyXG4gICAgaWYgKHRoaXMuaGl0VGVzdFNvdXJjZSAmJiB4clZpZXdlclBvc2UpIHtcclxuICAgICAgY29uc3QgaGl0VGVzdFJlc3VsdHMgPSB4ckZyYW1lLmdldEhpdFRlc3RSZXN1bHRzKHRoaXMuaGl0VGVzdFNvdXJjZSk7XHJcbiAgICAgIGlmIChoaXRUZXN0UmVzdWx0cy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICBpZiAoeHJWaWV3ZXJQb3NlLnZpZXdzLmxlbmd0aCA+IDAgJiYgeHJDYW1lcmEpIHtcclxuICAgICAgICAgIGZvciAoY29uc3QgdmlldyBvZiB4clZpZXdlclBvc2Uudmlld3MpIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLl9hY3RpdmVBUk1vZGVsLnZpc2libGUpIHtcclxuICAgICAgICAgICAgICBjb25zdCBkZXB0aERhdGE6IGFueSA9IHhyRnJhbWUuZ2V0RGVwdGhJbmZvcm1hdGlvbih2aWV3KTtcclxuICAgICAgICAgICAgICAvLyBQbGFjZSBvYmplY3QgYXMgc29vbiBhcyBkZXB0aCBkYXRhIGlzIGF2YWlsYWJsZSBhbmQgZGlzdGFuY2UgaXMgd2l0aGluIHJlYXNvbmFibGUgdmFsdWVzXHJcbiAgICAgICAgICAgICAgaWYgKGRlcHRoRGF0YSAmJiBkZXB0aERhdGEuZ2V0RGVwdGhJbk1ldGVycygwLjUsIDAuNSkgPiAwLjEgJiYgZGVwdGhEYXRhLmdldERlcHRoSW5NZXRlcnMoMC41LCAwLjUpIDwgMi41KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLnNldCh4ckNhbWVyYS5wb3NpdGlvbi54LCB4ckNhbWVyYS5wb3NpdGlvbi55LCB4ckNhbWVyYS5wb3NpdGlvbi56KTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucm90YXRpb24uc2V0RnJvbVF1YXRlcm5pb24oeHJDYW1lcmEucXVhdGVybmlvbik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnRyYW5zbGF0ZVooLWRlcHRoRGF0YS5nZXREZXB0aEluTWV0ZXJzKDAuNSwgMC41KSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLnkgKz0gMC4wMjtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucm90YXRpb24uc2V0KDAsIDAsIDApO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlQVJNb2RlbC52aXNpYmxlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gV2hlbiBoaXQgdGVzdCByZXN1bHRzIGFyZSBhdmFpbGFibGUgd2Ugc3dpdGNoIHRvIHRoZSBhbmNob3JlZCBoaXQgdGVzdCBtZXRob2QgYW5kIHBsYWNlIHRoZSBtb2RlbCBhY2NvcmRpbmdseVxyXG4gICAgICAgIHRoaXMuX2V4ZWN1dGVBbmNob3JlZEhpdFRlc3QoeHJGcmFtZSk7XHJcbiAgICAgICAgaWYgKHRoaXMuX2FuY2hvcmVkT2JqZWN0cy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgIHRoaXMuX2hhbmRsZVRvdWNoRXZlbnQoZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfZXhlY3V0ZUFuY2hvcmVkSGl0VGVzdCh4ckZyYW1lOiBhbnkpIHtcclxuICAgIHRoaXMuX2V4ZWN1dGVEZWZhdWx0SGl0VGVzdCh4ckZyYW1lKTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IHthbmNob3JlZE9iamVjdCwgYW5jaG9yfSBvZiB0aGlzLl9hbmNob3JlZE9iamVjdHMpIHtcclxuICAgICAgaWYgKCF4ckZyYW1lLnRyYWNrZWRBbmNob3JzLmhhcyhhbmNob3IpKSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuICAgICAgY29uc3QgYW5jaG9yUG9zZSA9IHhyRnJhbWUuZ2V0UG9zZShhbmNob3IuYW5jaG9yU3BhY2UsIHRoaXMucmVmU3BhY2UpO1xyXG4gICAgICBpZiAoYW5jaG9yUG9zZSkge1xyXG4gICAgICAgIGNvbnN0IGhpdE1hdHJpeCA9IG5ldyBNYXRyaXg0KCkuZnJvbUFycmF5KGFuY2hvclBvc2UudHJhbnNmb3JtLm1hdHJpeCk7XHJcbiAgICAgICAgYW5jaG9yZWRPYmplY3QucG9zaXRpb24uc2V0RnJvbU1hdHJpeFBvc2l0aW9uKGhpdE1hdHJpeCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2V4ZWN1dGVDUFVEZXB0aEhpdFRlc3QoeHJGcmFtZTogYW55KSB7XHJcbiAgICBjb25zdCB4clZpZXdlclBvc2U6IGFueSA9IHhyRnJhbWUuZ2V0Vmlld2VyUG9zZSh0aGlzLnJlZlNwYWNlKTtcclxuICAgIGNvbnN0IHhyQ2FtZXJhOiBhbnkgPSB0aGlzLl9yZW5kZXJlci54ci5nZXRDYW1lcmEoLyp0aGlzLl9jYW1lcmFTZXJ2aWNlLmNhbWVyYSovKTsgLy8gdG9kbzogZHVlIHRvIHRocmVlanMgdXBkYXRlIHBhcmFtZXRlciBub3QgbmVlZGVkIGFueW1vcmUsIGNoZWNrIHRoaXMhXHJcbiAgICB0aGlzLl9yZXRpY2xlLnZpc2libGUgPSBmYWxzZTtcclxuXHJcbiAgICBpZiAoeHJWaWV3ZXJQb3NlICYmIHhyVmlld2VyUG9zZS52aWV3cy5sZW5ndGggPiAwICYmIHhyQ2FtZXJhKSB7XHJcbiAgICAgIGZvciAoY29uc3QgdmlldyBvZiB4clZpZXdlclBvc2Uudmlld3MpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2FjdGl2ZUFSTW9kZWwudmlzaWJsZSkge1xyXG4gICAgICAgICAgdGhpcy5fcmV0aWNsZS52aXNpYmxlID0gdHJ1ZTtcclxuICAgICAgICAgIHRoaXMuX3N1cmZhY2VGb3VuZE9uY2UgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZGVwdGhEYXRhOiBhbnkgPSB4ckZyYW1lLmdldERlcHRoSW5mb3JtYXRpb24odmlldyk7XHJcbiAgICAgICAgaWYgKGRlcHRoRGF0YSkge1xyXG4gICAgICAgICAgdGhpcy5fcmV0aWNsZS5wb3NpdGlvbi5zZXQoeHJDYW1lcmEucG9zaXRpb24ueCwgeHJDYW1lcmEucG9zaXRpb24ueSwgeHJDYW1lcmEucG9zaXRpb24ueik7XHJcbiAgICAgICAgICB0aGlzLl9yZXRpY2xlLnJvdGF0aW9uLnNldEZyb21RdWF0ZXJuaW9uKHhyQ2FtZXJhLnF1YXRlcm5pb24pO1xyXG4gICAgICAgICAgdGhpcy5fcmV0aWNsZS50cmFuc2xhdGVaKC1kZXB0aERhdGEuZ2V0RGVwdGhJbk1ldGVycygwLjUsIDAuNSkpO1xyXG4gICAgICAgICAgdGhpcy5fcmV0aWNsZS5wb3NpdGlvbi55ICs9IDAuMDI7XHJcbiAgICAgICAgICB0aGlzLl9yZXRpY2xlLnJvdGF0aW9uLnNldCgwLCAwLCAwKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2V4ZWN1dGVEZWZhdWx0SGl0VGVzdCh4ckZyYW1lOiBhbnkpIHtcclxuICAgIGNvbnN0IHhyVmlld2VyUG9zZSA9IHhyRnJhbWUuZ2V0Vmlld2VyUG9zZSh0aGlzLnJlZlNwYWNlKTtcclxuICAgIHRoaXMuX3JldGljbGUudmlzaWJsZSA9IGZhbHNlO1xyXG5cclxuICAgIGlmICh0aGlzLmhpdFRlc3RTb3VyY2UgJiYgeHJWaWV3ZXJQb3NlKSB7XHJcbiAgICAgIGNvbnN0IGhpdFRlc3RSZXN1bHRzID0geHJGcmFtZS5nZXRIaXRUZXN0UmVzdWx0cyh0aGlzLmhpdFRlc3RTb3VyY2UpO1xyXG4gICAgICBpZiAoaGl0VGVzdFJlc3VsdHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGNvbnN0IHBvc2UgPSBoaXRUZXN0UmVzdWx0c1swXS5nZXRQb3NlKHRoaXMucmVmU3BhY2UpO1xyXG4gICAgICAgIGlmICghdGhpcy5fYWN0aXZlQVJNb2RlbC52aXNpYmxlKSB7XHJcbiAgICAgICAgICB0aGlzLl9yZXRpY2xlLnZpc2libGUgPSB0cnVlO1xyXG4gICAgICAgICAgdGhpcy5fc3VyZmFjZUZvdW5kT25jZSA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGhpdE1hdHJpeCA9IG5ldyBNYXRyaXg0KCkuZnJvbUFycmF5KHBvc2UudHJhbnNmb3JtLm1hdHJpeCk7XHJcbiAgICAgICAgdGhpcy5faGl0VGVzdFJlc3VsdCA9IGhpdE1hdHJpeDtcclxuICAgICAgICB0aGlzLl9yZXRpY2xlLnBvc2l0aW9uLnNldEZyb21NYXRyaXhQb3NpdGlvbihoaXRNYXRyaXgpO1xyXG4gICAgICAgIHRoaXMuX3JldGljbGUucG9zaXRpb24ueSArPSAwLjAyOyAvLyBQcmV2ZW50cyB6LWZpZ2h0aW5nXHJcbiAgICAgICAgdGhpcy5fcmV0aWNsZUhpdFRlc3RSZXN1bHQgPSBoaXRUZXN0UmVzdWx0c1swXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY2hlY2tFeHRyYUZlYXR1cmVzKHhyRnJhbWU6IGFueSkge1xyXG4gICAgaWYgKHRoaXMuX2FyRmVhdHVyZXMuaW5jbHVkZXMoQXJGZWF0dXJlLkxpZ2h0RXN0aW1hdGlvbikpIHtcclxuICAgICAgdGhpcy5fYWRqdXN0TGlnaHRpbmcoeHJGcmFtZSk7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5fYXJGZWF0dXJlcy5pbmNsdWRlcyhBckZlYXR1cmUuQ1BVRGVwdGhPY2NsdXNpb24pKSB7XHJcbiAgICAgIHRoaXMuX2hpZGVPY2NsdWRlZE1lc2hlcyh4ckZyYW1lKTtcclxuICAgIH1cclxuICAgIC8vIGlmICh0aGlzLl9hckZlYXR1cmVzLmluY2x1ZGVzKEFyRmVhdHVyZS5QbGFuZURldGVjdGlvbikpIHtcclxuICAgIC8vICAgdGhpcy5fZHJhd1BsYW5lcyh4ckZyYW1lKTtcclxuICAgIC8vIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2hpZGVPY2NsdWRlZE1lc2hlcyh4ckZyYW1lOiBhbnkpIHtcclxuICAgIGNvbnN0IHhyVmlld2VyUG9zZTogYW55ID0geHJGcmFtZS5nZXRWaWV3ZXJQb3NlKHRoaXMucmVmU3BhY2UpO1xyXG4gICAgaWYgKHhyVmlld2VyUG9zZSAmJiB4clZpZXdlclBvc2Uudmlld3MubGVuZ3RoID4gMCkge1xyXG4gICAgICBmb3IgKGNvbnN0IHZpZXcgb2YgeHJWaWV3ZXJQb3NlLnZpZXdzKSB7XHJcbiAgICAgICAgY29uc3QgZGVwdGhEYXRhOiBhbnkgPSB4ckZyYW1lLmdldERlcHRoSW5mb3JtYXRpb24odmlldyk7XHJcbiAgICAgICAgaWYgKGRlcHRoRGF0YSkge1xyXG4gICAgICAgICAgdGhpcy5fZGVwdGhEYXRhVGV4dHVyZS51cGRhdGVEZXB0aChkZXB0aERhdGEpO1xyXG4gICAgICAgICAgdGhpcy5fdXBkYXRlQXVnbWVudGVkTWF0ZXJpYWxVbmlmb3JtcyhkZXB0aERhdGEubm9ybURlcHRoQnVmZmVyRnJvbU5vcm1WaWV3Lm1hdHJpeCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIF9jcmVhdGVQbGFuZU1hdGVyaWFsKCkge1xyXG4gICAgY29uc3QgcG0gPSBuZXcgTWVzaFBob25nTWF0ZXJpYWwoe3RyYW5zcGFyZW50OiB0cnVlLCBzaWRlOiBEb3VibGVTaWRlfSk7XHJcbiAgICBwbS5tYXAgPSBhd2FpdCBNYXRlcmlhbFV0aWxzLkZyb21VcmwoJ2Fzc2V0cy90ZXh0dXJlcy9GbG9vci9UaWxlcy9hcl9mbG9vcl90ZXh0dXJlLnBuZycsXHJcbiAgICAgIGZhbHNlLCAxLCAyLCAyKTtcclxuICAgIHBtLm1hcC5mbGlwWSA9IGZhbHNlO1xyXG4gICAgcG0ubmVlZHNVcGRhdGUgPSB0cnVlO1xyXG4gICAgdGhpcy5fcGxhbmVNYXRlcmlhbCA9IHBtO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBfb25TZXNzaW9uU3RhcnRlZChzZXNzaW9uOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGRvbU92ZXJsYXkgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXItcm9vdCcpO1xyXG4gICAgc2Vzc2lvbi5hZGRFdmVudExpc3RlbmVyKCdlbmQnLCB0aGlzLl9vblNlc3Npb25FbmRlZC5iaW5kKHRoaXMpKTtcclxuICAgIHNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcignc2VsZWN0JywgKCkgPT4gdGhpcy5faGFuZGxlVG91Y2hFdmVudCgpKTtcclxuICAgIHNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcignc2VsZWN0c3RhcnQnLCAoJGV2ZW50KSA9PiB0aGlzLl9oYW5kbGVIb2xkU3RhcnRFdmVudCgkZXZlbnQpKTtcclxuICAgIHNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcignc2VsZWN0ZW5kJywgKCRldmVudCkgPT4gdGhpcy5faGFuZGxlSG9sZEVuZEV2ZW50KCRldmVudCkpO1xyXG4gICAgZG9tT3ZlcmxheS5hZGRFdmVudExpc3RlbmVyKCdiZWZvcmV4cnNlbGVjdCcsICgkZXZlbnQpID0+IHRoaXMuX2NoZWNraW5nSW50ZXJmYWNlSW50ZXJhY3Rpb24oJGV2ZW50KSk7XHJcbiAgICBhd2FpdCAoPGFueT50aGlzLl9yZW5kZXJlci5nZXRDb250ZXh0KCkpLm1ha2VYUkNvbXBhdGlibGUoKTtcclxuICAgIHRoaXMuX3JlbmRlcmVyLnhyLnNldFNlc3Npb24oc2Vzc2lvbik7XHJcbiAgICB0aGlzLl9zZXNzaW9uID0gc2Vzc2lvbjtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX29uU2Vzc2lvbkVuZGVkKCkge1xyXG4gICAgaWYgKHRoaXMuX2NsZWFudXApIHtcclxuICAgICAgdGhpcy5fc2Vzc2lvbiA9IG51bGw7XHJcbiAgICAgIHRoaXMuX3N1cmZhY2VGb3VuZE9uY2UgPSBmYWxzZTtcclxuICAgICAgdGhpcy5fcmV0aWNsZS52aXNpYmxlID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuc2NlbmUucmVtb3ZlKHRoaXMuX3Bvc2l0aW9uSW5kaWNhdG9yKTtcclxuICAgICAgdGhpcy5fYWN0aXZlQVJNb2RlbC52aXNpYmxlID0gdHJ1ZTtcclxuICAgICAgdGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi5zZXQoMCwgMCwgMCk7XHJcbiAgICAgIHRoaXMuX3JlbW92ZU1hdGVyaWFsU2hhZGVycygpO1xyXG4gICAgICB0aGlzLnNob3VsZEFkZE9iamVjdFRvU2NlbmUubmV4dCh0aGlzLl9hY3RpdmVBUk1vZGVsKTtcclxuICAgICAgdGhpcy5fYWN0aXZlQVJNb2RlbCA9IG51bGw7XHJcbiAgICAgIHRoaXMuX2hvbGRpbmdUb3VjaCA9IGZhbHNlO1xyXG4gICAgICB0aGlzLl9hckZlYXR1cmVzID0gW107XHJcbiAgICAgIHRoaXMuX2xpZ2h0UHJvYmUgPSBudWxsO1xyXG5cclxuICAgICAgdGhpcy5fdmVydGV4TGlzdCA9IFtdO1xyXG4gICAgICB0aGlzLl9kZXRlY3RlZFBsYW5lcyA9IFtdO1xyXG4gICAgICB0aGlzLl9yYXdQbGFuZXMgPSBuZXcgU2V0PGFueT4oKTtcclxuXHJcbiAgICAgIHRoaXMuX3JlbmRlcmVyLnhyLmVuYWJsZWQgPSBmYWxzZTtcclxuICAgICAgdGhpcy5fcmVuZGVyZXIuc2hhZG93TWFwLnR5cGUgPSBQQ0ZTb2Z0U2hhZG93TWFwO1xyXG4gICAgICB0aGlzLl9yZW5kZXJlci5zZXRDbGVhckNvbG9yKDB4ZmFmYWZhKTtcclxuICAgICAgdGhpcy5fcmVuZGVyZXIuYXV0b0NsZWFyID0gdHJ1ZTtcclxuXHJcbiAgICAgIC8vIFRPRE8gRklYXHJcbiAgICAgIC8vIHRoaXMuX3ZpZXdNb2RlU2VydmljZS52aWV3TW9kZSA9IFZpZXdNb2RlLlJvb21QbGFuM0Q7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9zZXRBck1vZGVsU2hhZG93cygpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLl9hY3RpdmVBUk1vZGVsKSB7XHJcbiAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwudHJhdmVyc2UoKG5vZGUpID0+IHtcclxuICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIE1lc2gpIHtcclxuICAgICAgICAgIG5vZGUuY2FzdFNoYWRvdyA9IHRydWU7XHJcbiAgICAgICAgICBub2RlLnJlY2VpdmVTaGFkb3cgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9oYW5kbGVUb3VjaEV2ZW50KG1hbnVhbFRvdWNoOiBib29sZWFuID0gdHJ1ZSk6IHZvaWQge1xyXG4gICAgdGhpcy5faGFuZGxlRG91YmxlVGFwRXZlbnQoKTtcclxuXHJcbiAgICBpZiAobWFudWFsVG91Y2gpIHtcclxuICAgICAgaWYgKHRoaXMuX3JldGljbGUudmlzaWJsZSAmJiAhdGhpcy5fYWN0aXZlQVJNb2RlbC52aXNpYmxlKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2FyRmVhdHVyZXMuaW5jbHVkZXMoQXJGZWF0dXJlLkFuY2hvcmVkSGl0VGVzdCkpIHtcclxuICAgICAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucG9zaXRpb24uY29weSh0aGlzLl9yZXRpY2xlLnBvc2l0aW9uKTtcclxuICAgICAgICAgIHRoaXMuX3JldGljbGVIaXRUZXN0UmVzdWx0LmNyZWF0ZUFuY2hvcigpLnRoZW4oKGFuY2hvcikgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9hbmNob3JlZE9iamVjdHMucHVzaCh7XHJcbiAgICAgICAgICAgICAgYW5jaG9yZWRPYmplY3Q6IHRoaXMuX3NoYWRvd1BsYW5lLFxyXG4gICAgICAgICAgICAgIGFuY2hvcjogYW5jaG9yfSk7XHJcbiAgICAgICAgICB9KS5jYXRjaCgoZSkgPT4ge1xyXG4gICAgICAgICAgICAvLyBVbmFibGUgdG8gY3JlYXRlIGFuY2hvclxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucG9zaXRpb24uY29weSh0aGlzLl9yZXRpY2xlLnBvc2l0aW9uKTtcclxuICAgICAgICAgIHRoaXMuX2FSTW9kZWxCYWNrdXBZUG9zaXRpb24gPSB0aGlzLl9yZXRpY2xlLnBvc2l0aW9uLnk7XHJcbiAgICAgICAgICB0aGlzLl9zaGFkb3dQbGFuZS5wb3NpdGlvbi5jb3B5KHRoaXMuX3JldGljbGUucG9zaXRpb24pO1xyXG4gICAgICAgICAgdGhpcy5fcG9zaXRpb25JbmRpY2F0b3IucG9zaXRpb24uY29weSh0aGlzLl9yZXRpY2xlLnBvc2l0aW9uKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmICh0aGlzLl9hckZlYXR1cmVzLmluY2x1ZGVzKEFyRmVhdHVyZS5BbmNob3JlZEhpdFRlc3QpKSB7XHJcbiAgICAgICAgdGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi5jb3B5KHRoaXMuX3JldGljbGUucG9zaXRpb24pO1xyXG4gICAgICAgIHRoaXMuX3JldGljbGVIaXRUZXN0UmVzdWx0LmNyZWF0ZUFuY2hvcigpLnRoZW4oKGFuY2hvcikgPT4ge1xyXG4gICAgICAgICAgdGhpcy5fYW5jaG9yZWRPYmplY3RzLnB1c2goe1xyXG4gICAgICAgICAgICBhbmNob3JlZE9iamVjdDogdGhpcy5fc2hhZG93UGxhbmUsXHJcbiAgICAgICAgICAgIGFuY2hvcjogYW5jaG9yXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9KS5jYXRjaCgoZSkgPT4ge1xyXG4gICAgICAgICAgLy8gVW5hYmxlIHRvIGNyZWF0ZSBhbmNob3JcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLmNvcHkodGhpcy5fcmV0aWNsZS5wb3NpdGlvbik7XHJcbiAgICAgICAgdGhpcy5fYVJNb2RlbEJhY2t1cFlQb3NpdGlvbiA9IHRoaXMuX3JldGljbGUucG9zaXRpb24ueTtcclxuICAgICAgICB0aGlzLl9zaGFkb3dQbGFuZS5wb3NpdGlvbi5jb3B5KHRoaXMuX3JldGljbGUucG9zaXRpb24pO1xyXG4gICAgICAgIHRoaXMuX3Bvc2l0aW9uSW5kaWNhdG9yLnBvc2l0aW9uLmNvcHkodGhpcy5fcmV0aWNsZS5wb3NpdGlvbik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnZpc2libGUgPSB0cnVlO1xyXG4gICAgdGhpcy5fc2hhZG93UGxhbmUudmlzaWJsZSA9IHRydWU7XHJcbiAgICB0aGlzLl9wb3NpdGlvbkluZGljYXRvci52aXNpYmxlID0gdHJ1ZTtcclxuICAgIHRoaXMuX3NldEFyTW9kZWxTaGFkb3dzKCk7XHJcbiAgICB0aGlzLl9zZXRQbGFuZXNWaXNpYmlsdHkoZmFsc2UpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaGFuZGxlTXVsdGlUb3VjaEV2ZW50KCk6IHZvaWQge1xyXG4gICAgY29uc3QgaW5wdXRTb3VyY2VzID0gdGhpcy5fc2Vzc2lvbi5pbnB1dFNvdXJjZXM7XHJcbiAgICBpZiAoaW5wdXRTb3VyY2VzLmxlbmd0aCA9PT0gMiAmJiB0aGlzLl9hY3RpdmVBUk1vZGVsLnZpc2libGUgJiYgIXRoaXMuX2hvbGRpbmdUb3VjaCkge1xyXG4gICAgICB0aGlzLl9hUk1vZGVsQmFja3VwWVJvdGF0aW9uID0gdGhpcy5fYVJNb2RlbEJhY2t1cFlSb3RhdGlvbiA9PT0gMCA/IHRoaXMuX2FjdGl2ZUFSTW9kZWwucm90YXRpb24ueSAvIDIgOiB0aGlzLl9hUk1vZGVsQmFja3VwWVJvdGF0aW9uO1xyXG4gICAgICBjb25zdCBkeCA9IGlucHV0U291cmNlc1sxXS5nYW1lcGFkLmF4ZXNbMF0gLSBpbnB1dFNvdXJjZXNbMF0uZ2FtZXBhZC5heGVzWzBdO1xyXG4gICAgICBjb25zdCBkeSA9IGlucHV0U291cmNlc1sxXS5nYW1lcGFkLmF4ZXNbMV0gLSBpbnB1dFNvdXJjZXNbMF0uZ2FtZXBhZC5heGVzWzFdO1xyXG4gICAgICBjb25zdCBhbmdsZSA9IE1hdGguYXRhbjIoZHksIGR4KTtcclxuICAgICAgdGhpcy5fYVJNb2RlbFJvdGF0aW9uU3RhcnRpbmdWYWx1ZSA9IHRoaXMuX2FSTW9kZWxSb3RhdGlvblN0YXJ0aW5nVmFsdWUgPT09IDAgPyBhbmdsZSA6IHRoaXMuX2FSTW9kZWxSb3RhdGlvblN0YXJ0aW5nVmFsdWU7XHJcbiAgICAgIGNvbnN0IGRpZmZlcmVuY2UgPSB0aGlzLl9hUk1vZGVsQmFja3VwWVJvdGF0aW9uIC0gKGFuZ2xlIC0gdGhpcy5fYVJNb2RlbFJvdGF0aW9uU3RhcnRpbmdWYWx1ZSk7XHJcbiAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucm90YXRpb24ueSA9IHRoaXMuX2FSTW9kZWxCYWNrdXBZUm90YXRpb24gKyBkaWZmZXJlbmNlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5fYVJNb2RlbEJhY2t1cFlSb3RhdGlvbiA9IDA7XHJcbiAgICAgIHRoaXMuX2FSTW9kZWxSb3RhdGlvblN0YXJ0aW5nVmFsdWUgPSAwO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaGFuZGxlRG91YmxlVGFwRXZlbnQoKTogdm9pZCB7XHJcbiAgICBjb25zdCBpbnRlcnNlY3Rpb25zOiBJbnRlcnNlY3Rpb25bXSA9IHRoaXMuX2dldE9iamVjdEludGVyc2VjdGlvbnMoW3RoaXMuX2FjdGl2ZUFSTW9kZWxdKTtcclxuICAgIGlmIChpbnRlcnNlY3Rpb25zLmxlbmd0aCA+IDApIHtcclxuICAgICAgY29uc3QgY3VycmVudFRpbWVzdGFtcDogbnVtYmVyID0gRGF0ZS5ub3coKTtcclxuICAgICAgdGhpcy5zaG93Q29udGV4dE1lbnUgPSB0aGlzLl9sYXN0T2JqZWN0VG91Y2hUaW1lc3RhbXAgJiYgY3VycmVudFRpbWVzdGFtcCAtIHRoaXMuX2xhc3RPYmplY3RUb3VjaFRpbWVzdGFtcCA8IHRoaXMuX2RvdWJsZVRhcFRpbWVmcmFtZTtcclxuICAgICAgdGhpcy5fbGFzdE9iamVjdFRvdWNoVGltZXN0YW1wID0gY3VycmVudFRpbWVzdGFtcDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc2hvd0NvbnRleHRNZW51ID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIF9jaGVja0lmSG9sZFRvdWNoRXZlbnQoJGV2ZW50KSB7XHJcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgaWYgKCF0aGlzLnVzZXJJblNlbGVjdGlvbk1lbnUgJiYgdGhpcy5fbGFzdEV2ZW50VGltZXN0YW1wID09PSAkZXZlbnQudGltZVN0YW1wICYmIHRoaXMuX3Nlc3Npb24uaW5wdXRTb3VyY2VzLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgIHRoaXMuX2hvbGRpbmdUb3VjaCA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fdG9nZ2xlSG9sZFRvdWNoRXZlbnQoKTtcclxuICAgICAgfVxyXG4gICAgfSwgMjAwKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2hhbmRsZUhvbGRTdGFydEV2ZW50KCRldmVudDogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLl9sYXN0RXZlbnRUaW1lc3RhbXAgPSAkZXZlbnQudGltZVN0YW1wO1xyXG4gICAgdGhpcy5fY2hlY2tJZkhvbGRUb3VjaEV2ZW50KCRldmVudCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9oYW5kbGVIb2xkRW5kRXZlbnQoJGV2ZW50OiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMuX2xhc3RFdmVudFRpbWVzdGFtcCA9ICRldmVudC50aW1lU3RhbXA7XHJcbiAgICBpZiAodGhpcy5faG9sZGluZ1RvdWNoKSB7XHJcbiAgICAgIHRoaXMuX2hvbGRpbmdUb3VjaCA9IGZhbHNlO1xyXG4gICAgICB0aGlzLl90b2dnbGVIb2xkVG91Y2hFdmVudCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfdG9nZ2xlSG9sZFRvdWNoRXZlbnQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5faG9sZGluZ1RvdWNoKSB7XHJcbiAgICAgIC8vIHRoaXMuX3NldFBsYW5lc1Zpc2liaWx0eSh0cnVlKTtcclxuICAgICAgdGhpcy5fY2FsbExpZnRBbmltYXRpb24oKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuX2NhbGxEcm9wQW5pbWF0aW9uKCk7XHJcbiAgICAgIHRoaXMuX3NldFBsYW5lc1Zpc2liaWx0eShmYWxzZSk7XHJcbiAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucG9zaXRpb24ueSA9IHRoaXMuX2FSTW9kZWxCYWNrdXBZUG9zaXRpb247XHJcbiAgICB9XHJcbiAgICB0aGlzLl90b2dnbGVBUk1vZGVsVHJhbnNwYXJlbmN5KCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9oYW5kbGVIb2xkTW92ZUV2ZW50KCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuX2hvbGRpbmdUb3VjaCAmJiAhdGhpcy51c2VySW5TZWxlY3Rpb25NZW51KSB7XHJcbiAgICAgIGNvbnN0IGludGVyc2VjdGlvbnM6IEludGVyc2VjdGlvbltdID0gdGhpcy5fZ2V0T2JqZWN0SW50ZXJzZWN0aW9ucyhbdGhpcy5fc2hhZG93UGxhbmVdKTtcclxuICAgICAgaWYgKGludGVyc2VjdGlvbnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGNvbnN0IG1vdmVQb3NpdGlvbiA9ICF0aGlzLl9hbmltYXRpbmcgPyBuZXcgVmVjdG9yMyhpbnRlcnNlY3Rpb25zWzBdLnBvaW50LngsIGludGVyc2VjdGlvbnNbMF0ucG9pbnQueSArIDAuMiwgaW50ZXJzZWN0aW9uc1swXS5wb2ludC56KSA6XHJcbiAgICAgICAgICBuZXcgVmVjdG9yMyhpbnRlcnNlY3Rpb25zWzBdLnBvaW50LngsIHRoaXMuX2FjdGl2ZUFSTW9kZWwucG9zaXRpb24ueSwgaW50ZXJzZWN0aW9uc1swXS5wb2ludC56KTtcclxuICAgICAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLmNvcHkobW92ZVBvc2l0aW9uKTtcclxuICAgICAgICB0aGlzLl9hUk1vZGVsQmFja3VwWVBvc2l0aW9uID0gaW50ZXJzZWN0aW9uc1swXS5wb2ludC55O1xyXG4gICAgICAgIHRoaXMuX3Bvc2l0aW9uSW5kaWNhdG9yLnBvc2l0aW9uLmNvcHkoaW50ZXJzZWN0aW9uc1swXS5wb2ludCk7XHJcbiAgICAgICAgdGhpcy5fdXBkYXRlU2hhZG93cyhpbnRlcnNlY3Rpb25zWzBdLnBvaW50KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfdXBkYXRlU2hhZG93cyhjZW50ZXJQb3NpdGlvbjogVmVjdG9yMyk6IHZvaWQge1xyXG4gICAgdGhpcy5fc2hhZG93UGxhbmUucG9zaXRpb24uY29weShjZW50ZXJQb3NpdGlvbik7XHJcbiAgICB0aGlzLnNjZW5lLnRyYXZlcnNlKChub2RlKSA9PiB7XHJcbiAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgRGlyZWN0aW9uYWxMaWdodCkge1xyXG4gICAgICAgIG5vZGUudGFyZ2V0LnBvc2l0aW9uLmNvcHkoY2VudGVyUG9zaXRpb24pO1xyXG4gICAgICAgIG5vZGUuc2hhZG93LmNhbWVyYS51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfYWRqdXN0TGlnaHRpbmcoZnJhbWUpOiB2b2lkIHtcclxuICAgIGNvbnN0IGxpZ2h0RXN0aW1hdGUgPSBmcmFtZS5nZXRMaWdodEVzdGltYXRlKHRoaXMuX2xpZ2h0UHJvYmUpO1xyXG5cclxuICAgIGlmIChsaWdodEVzdGltYXRlKSB7XHJcbiAgICAgIHRoaXMuX3RocmVlTGlnaHRQcm9iZS5zaC5mcm9tQXJyYXkobGlnaHRFc3RpbWF0ZS5zcGhlcmljYWxIYXJtb25pY3NDb2VmZmljaWVudHMpO1xyXG5cclxuICAgICAgY29uc3QgaW50ZW5zaXR5ID0gTWF0aC5tYXgoMS4wLFxyXG4gICAgICAgIE1hdGgubWF4KGxpZ2h0RXN0aW1hdGUucHJpbWFyeUxpZ2h0SW50ZW5zaXR5LngsXHJcbiAgICAgICAgICBNYXRoLm1heChsaWdodEVzdGltYXRlLnByaW1hcnlMaWdodEludGVuc2l0eS55LFxyXG4gICAgICAgICAgICBsaWdodEVzdGltYXRlLnByaW1hcnlMaWdodEludGVuc2l0eS56KSkpO1xyXG5cclxuICAgICAgdGhpcy5fc3VuTGlnaHQucG9zaXRpb24uc2V0KGxpZ2h0RXN0aW1hdGUucHJpbWFyeUxpZ2h0RGlyZWN0aW9uLngsXHJcbiAgICAgICAgbGlnaHRFc3RpbWF0ZS5wcmltYXJ5TGlnaHREaXJlY3Rpb24ueSxcclxuICAgICAgICBsaWdodEVzdGltYXRlLnByaW1hcnlMaWdodERpcmVjdGlvbi56KTtcclxuICAgICAgdGhpcy5fc3VuTGlnaHQuY29sb3Iuc2V0UkdCKGxpZ2h0RXN0aW1hdGUucHJpbWFyeUxpZ2h0SW50ZW5zaXR5LnggLyBpbnRlbnNpdHksXHJcbiAgICAgICAgbGlnaHRFc3RpbWF0ZS5wcmltYXJ5TGlnaHRJbnRlbnNpdHkueSAvIGludGVuc2l0eSxcclxuICAgICAgICBsaWdodEVzdGltYXRlLnByaW1hcnlMaWdodEludGVuc2l0eS56IC8gaW50ZW5zaXR5KTtcclxuICAgICAgdGhpcy5fc3VuTGlnaHQuaW50ZW5zaXR5ID0gaW50ZW5zaXR5O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfdG9nZ2xlQVJNb2RlbFRyYW5zcGFyZW5jeSgpOiB2b2lkIHtcclxuICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwudHJhdmVyc2UoKG5vZGUpID0+IHtcclxuICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBNZXNoKSB7XHJcbiAgICAgICAgY29uc3QgbWF0ZXJpYWxzOiBhbnkgPSAhQXJyYXkuaXNBcnJheShub2RlLm1hdGVyaWFsKSA/IFtub2RlLm1hdGVyaWFsXSA6IG5vZGUubWF0ZXJpYWw7XHJcbiAgICAgICAgbWF0ZXJpYWxzLmZvckVhY2gobWF0ZXJpYWwgPT4ge1xyXG4gICAgICAgICAgbWF0ZXJpYWwudHJhbnNwYXJlbnQgPSB0aGlzLl9ob2xkaW5nVG91Y2g7XHJcbiAgICAgICAgICBtYXRlcmlhbC5vcGFjaXR5ID0gdGhpcy5faG9sZGluZ1RvdWNoID8gMC41IDogMTtcclxuICAgICAgICAgIG1hdGVyaWFsLm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9zZXRQbGFuZXNWaXNpYmlsdHkodmlzaWJsZTogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgdGhpcy5fZGV0ZWN0ZWRQbGFuZXMuZm9yRWFjaCgocGxhbmUpID0+IHBsYW5lLnZpc2libGUgPSB2aXNpYmxlKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2dldE9iamVjdEludGVyc2VjdGlvbnMob2JqZWN0czogT2JqZWN0M0RbXSkge1xyXG4gICAgdGhpcy5fdGVtcE1hdHJpeC5pZGVudGl0eSgpLmV4dHJhY3RSb3RhdGlvbih0aGlzLl9jb250cm9sbGVyLm1hdHJpeFdvcmxkKTtcclxuICAgIHRoaXMuX3JheWNhc3Rlci5yYXkub3JpZ2luLnNldEZyb21NYXRyaXhQb3NpdGlvbih0aGlzLl9jb250cm9sbGVyLm1hdHJpeFdvcmxkKTtcclxuICAgIHRoaXMuX3JheWNhc3Rlci5yYXkuZGlyZWN0aW9uLnNldCgwLCAwLCAtMSkuYXBwbHlNYXRyaXg0KHRoaXMuX3RlbXBNYXRyaXgpO1xyXG4gICAgcmV0dXJuIHRoaXMuX3JheWNhc3Rlci5pbnRlcnNlY3RPYmplY3RzKG9iamVjdHMpO1xyXG4gIH1cclxuXHJcbiAgLy8gVE9ETzogTmVlZHMgdG8gYmUgbWFkZSBjb21wYXRpYmxlIHdpdGggQnVmZmVyR2VvbWV0cnkgaWYgd2Ugd2FudCB0byBrZWVwIHBsYW5lIGRldGVjdGlvbiB2aXN1YWxpemF0aW9uXHJcbiAgcHJpdmF0ZSBfZHJhd1BsYW5lKHZlcnRpY2VzOiBBcnJheTxET01Qb2ludFJlYWRPbmx5PiwgcGxhbmVQb3NlKSB7XHJcbiAgICAvLyBjb25zdCBoaXRNYXRyaXggPSBuZXcgTWF0cml4NCgpLmZyb21BcnJheShwbGFuZVBvc2UudHJhbnNmb3JtLm1hdHJpeCk7XHJcbiAgICAvLyBjb25zdCBwb2ludEdyb3VwID0gbmV3IEdyb3VwKCk7XHJcbiAgICAvL1xyXG4gICAgLy8gLy8gQ3JlYXRlIHZlcnRpY2VzXHJcbiAgICAvLyB2ZXJ0aWNlcy5mb3JFYWNoKCh2ZXJ0ZXgpID0+IHtcclxuICAgIC8vICAgaWYgKHRoaXMuX2RlYnVnKSB7XHJcbiAgICAvLyAgICAgY29uc3QgcG9pbnQgPSB0aGlzLl9wb2ludFJlcHJlc2VudGF0aW9uLmNsb25lKCk7XHJcbiAgICAvLyAgICAgcG9pbnQucG9zaXRpb24uc2V0KHZlcnRleC54LCAwLCB2ZXJ0ZXgueik7XHJcbiAgICAvLyAgICAgcG9pbnRHcm91cC5hZGQocG9pbnQpO1xyXG4gICAgLy8gICB9XHJcbiAgICAvLyAgIHRoaXMuX3ZlcnRleExpc3QucHVzaChuZXcgRE9NUG9pbnQodmVydGV4LngsIHZlcnRleC56KSk7XHJcbiAgICAvLyB9KTtcclxuICAgIC8vXHJcbiAgICAvLyBpZiAodGhpcy5fZGVidWcpIHtcclxuICAgIC8vICAgcG9pbnRHcm91cC5wb3NpdGlvbi5zZXRGcm9tTWF0cml4UG9zaXRpb24oaGl0TWF0cml4KTtcclxuICAgIC8vICAgdGhpcy5zY2VuZS5hZGQocG9pbnRHcm91cCk7XHJcbiAgICAvLyB9XHJcbiAgICAvL1xyXG4gICAgLy8gLy8gR2VuZXJhdGUgcG9seWdvbiBmcm9tIHZlcnRpY2VzXHJcbiAgICAvLyBjb25zdCBodWxsID0gbWFrZUh1bGwodGhpcy5fdmVydGV4TGlzdCk7XHJcbiAgICAvLyBjb25zdCBnZW9tZXRyeSA9IG5ldyBCdWZmZXJHZW9tZXRyeSgpO1xyXG4gICAgLy8gY29uc3QgdmVjdG9yVHdvTGlzdCA9IGh1bGwubWFwKChwb2ludCkgPT4gbmV3IFZlY3RvcjIocG9pbnQueCwgcG9pbnQueSkpO1xyXG4gICAgLy8gY29uc3QgdmVjdG9yVGhyZWVMaXN0ID0gaHVsbC5tYXAoKHBvaW50KSA9PiBuZXcgVmVjdG9yMyhwb2ludC54LCB0aGlzLl9kZXRlY3RlZFBsYW5lcy5sZW5ndGggPiAwID8gdGhpcy5fZGV0ZWN0ZWRQbGFuZXNbMF0ucG9zaXRpb24ueSA6IDAsIHBvaW50LnkpKTtcclxuICAgIC8vIGNvbnN0IGZhY2VBcnJheSA9IFNoYXBlVXRpbHMudHJpYW5ndWxhdGVTaGFwZSh2ZWN0b3JUd29MaXN0LCBbXSk7XHJcbiAgICAvLyBnZW9tZXRyeS52ZXJ0aWNlcy5wdXNoKC4uLnZlY3RvclRocmVlTGlzdCk7XHJcbiAgICAvL1xyXG4gICAgLy8gLy8gR2VuZXJhdGUgZmFjZXNcclxuICAgIC8vIGZvciAobGV0IGkgPSAwOyBpIDwgZmFjZUFycmF5Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAvLyAgIGdlb21ldHJ5LmZhY2VzLnB1c2gobmV3IFRIUkVFLkZhY2UzKGZhY2VBcnJheVtpXVswXSwgZmFjZUFycmF5W2ldWzFdLCBmYWNlQXJyYXlbaV1bMl0pKTtcclxuICAgIC8vIH1cclxuICAgIC8vIGdlb21ldHJ5LmNvbXB1dGVWZXJ0ZXhOb3JtYWxzKCk7XHJcbiAgICAvLyBnZW9tZXRyeS5ub3JtYWxpemUoKTtcclxuICAgIC8vXHJcbiAgICAvLyAvLyBHZW5lcmF0ZSBVVidzXHJcbiAgICAvLyBnZW9tZXRyeS5jb21wdXRlQm91bmRpbmdCb3goKTtcclxuICAgIC8vIGNvbnN0IG1heCA9IGdlb21ldHJ5LmJvdW5kaW5nQm94Lm1heCwgbWluID0gZ2VvbWV0cnkuYm91bmRpbmdCb3gubWluO1xyXG4gICAgLy8gY29uc3Qgb2Zmc2V0ID0gbmV3IFRIUkVFLlZlY3RvcjIoMCAtIG1pbi54LCAwIC0gbWluLnopO1xyXG4gICAgLy8gY29uc3QgcmFuZ2UgPSBuZXcgVEhSRUUuVmVjdG9yMihtYXgueCAtIG1pbi54LCBtYXgueiAtIG1pbi56KTtcclxuICAgIC8vIGNvbnN0IGZhY2VzID0gZ2VvbWV0cnkuZmFjZXM7XHJcbiAgICAvLyBnZW9tZXRyeS5mYWNlVmVydGV4VXZzWzBdID0gW107XHJcbiAgICAvL1xyXG4gICAgLy8gZm9yIChsZXQgaSA9IDA7IGkgPCBmYWNlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgLy8gICBjb25zdCB2MSA9IGdlb21ldHJ5LnZlcnRpY2VzW2ZhY2VzW2ldLmFdLFxyXG4gICAgLy8gICAgIHYyID0gZ2VvbWV0cnkudmVydGljZXNbZmFjZXNbaV0uYl0sXHJcbiAgICAvLyAgICAgdjMgPSBnZW9tZXRyeS52ZXJ0aWNlc1tmYWNlc1tpXS5jXTtcclxuICAgIC8vXHJcbiAgICAvLyAgIGdlb21ldHJ5LmZhY2VWZXJ0ZXhVdnNbMF0ucHVzaChbXHJcbiAgICAvLyAgICAgbmV3IFRIUkVFLlZlY3RvcjIoKHYxLnggKyBvZmZzZXQueCkgLyByYW5nZS54LCAodjEueiArIG9mZnNldC55KSAvIHJhbmdlLnkpLFxyXG4gICAgLy8gICAgIG5ldyBUSFJFRS5WZWN0b3IyKCh2Mi54ICsgb2Zmc2V0LngpIC8gcmFuZ2UueCwgKHYyLnogKyBvZmZzZXQueSkgLyByYW5nZS55KSxcclxuICAgIC8vICAgICBuZXcgVEhSRUUuVmVjdG9yMigodjMueCArIG9mZnNldC54KSAvIHJhbmdlLngsICh2My56ICsgb2Zmc2V0LnkpIC8gcmFuZ2UueSlcclxuICAgIC8vICAgXSk7XHJcbiAgICAvLyB9XHJcbiAgICAvLyBnZW9tZXRyeS51dnNOZWVkVXBkYXRlID0gdHJ1ZTtcclxuICAgIC8vXHJcbiAgICAvLyAvLyBDcmVhdGUgYW5kIHNldCBwbGFuZVxyXG4gICAgLy8gY29uc3QgbWVzaCA9IG5ldyBNZXNoKGdlb21ldHJ5LCB0aGlzLl9wbGFuZU1hdGVyaWFsKTtcclxuICAgIC8vIG1lc2gucG9zaXRpb24uc2V0RnJvbU1hdHJpeFBvc2l0aW9uKGhpdE1hdHJpeCk7XHJcbiAgICAvLyB0aGlzLl9kZXRlY3RlZFBsYW5lcy5wdXNoKG1lc2gpO1xyXG4gICAgLy8gdGhpcy5zY2VuZS5hZGQobWVzaCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9kcmF3UGxhbmVzKHhyRnJhbWUpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5fYWN0aXZlQVJNb2RlbC52aXNpYmxlKSB7XHJcbiAgICAgIGNvbnN0IHBsYW5lc0RldGVjdGVkID0geHJGcmFtZS53b3JsZEluZm9ybWF0aW9uLmRldGVjdGVkUGxhbmVzO1xyXG4gICAgICBpZiAocGxhbmVzRGV0ZWN0ZWQuc2l6ZSA+IDApIHtcclxuICAgICAgICBwbGFuZXNEZXRlY3RlZC5mb3JFYWNoKHBsYW5lID0+IHtcclxuICAgICAgICAgIGlmICghdGhpcy5fcmF3UGxhbmVzLmhhcyhwbGFuZSkpIHtcclxuICAgICAgICAgICAgY29uc3QgcGxhbmVQb3NlID0geHJGcmFtZS5nZXRQb3NlKHBsYW5lLnBsYW5lU3BhY2UsIHRoaXMucmVmU3BhY2UpO1xyXG4gICAgICAgICAgICBpZiAocGxhbmVQb3NlKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5fcmF3UGxhbmVzLmFkZChwbGFuZSk7XHJcbiAgICAgICAgICAgICAgY29uc3QgcGxhbmVWZXJ0aWNlcyA9IHBsYW5lLnBvbHlnb247XHJcbiAgICAgICAgICAgICAgdGhpcy5fZHJhd1BsYW5lKHBsYW5lVmVydGljZXMsIHBsYW5lUG9zZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY2FsbExpZnRBbmltYXRpb24oKTogdm9pZCB7XHJcbiAgICB0aGlzLl9hbmltYXRpbmcgPSB0cnVlO1xyXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLmNsb25lKCk7XHJcbiAgICBjb25zdCB0YXJnZXRQb3NpdGlvbiA9IG5ldyBWZWN0b3IzKHRoaXMuX2FjdGl2ZUFSTW9kZWwucG9zaXRpb24ueCwgdGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi55ICsgMC4yLCB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLnopO1xyXG4gICAgdGhpcy5fbGlmdEFuaW1hdGlvbiA9IG5ldyBUV0VFTi5Ud2Vlbihwb3NpdGlvbilcclxuICAgICAgLnRvKHRhcmdldFBvc2l0aW9uLCA1MDApXHJcbiAgICAgIC5lYXNpbmcoVFdFRU4uRWFzaW5nLlF1YWRyYXRpYy5PdXQpXHJcbiAgICAgIC5vblVwZGF0ZSgoKSA9PiB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLmNvcHkobmV3IFZlY3RvcjModGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi54LCBwb3NpdGlvbi55LCB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLnopKSlcclxuICAgICAgLm9uQ29tcGxldGUoKCkgPT4gdGhpcy5fYW5pbWF0aW5nID0gZmFsc2UpO1xyXG4gICAgdGhpcy5fbGlmdEFuaW1hdGlvbi5zdGFydCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY2FsbERyb3BBbmltYXRpb24oKTogdm9pZCB7XHJcbiAgICB0aGlzLl9hbmltYXRpbmcgPSB0cnVlO1xyXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLmNsb25lKCk7XHJcbiAgICBjb25zdCB0YXJnZXRQb3NpdGlvbiA9IG5ldyBWZWN0b3IzKHRoaXMuX2FjdGl2ZUFSTW9kZWwucG9zaXRpb24ueCwgdGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi55IC0gMC4yLCB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLnopO1xyXG4gICAgdGhpcy5fZHJvcEFuaW1hdGlvbiA9IG5ldyBUV0VFTi5Ud2Vlbihwb3NpdGlvbilcclxuICAgICAgLnRvKHRhcmdldFBvc2l0aW9uLCA1MDApXHJcbiAgICAgIC5lYXNpbmcoVFdFRU4uRWFzaW5nLlF1YWRyYXRpYy5PdXQpXHJcbiAgICAgIC5vblVwZGF0ZSgoKSA9PiB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLmNvcHkobmV3IFZlY3RvcjModGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi54LCBwb3NpdGlvbi55LCB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLnopKSlcclxuICAgICAgLm9uQ29tcGxldGUoKCkgPT4gdGhpcy5fYW5pbWF0aW5nID0gZmFsc2UpO1xyXG4gICAgdGhpcy5fZHJvcEFuaW1hdGlvbi5zdGFydCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY3JlYXRlQXVnbWVudGVkTWF0ZXJpYWwobWF0ZXJpYWw6IE1hdGVyaWFsIHwgU2hhZG93TWF0ZXJpYWwsIGRlcHRoTWFwKSB7XHJcbiAgICBtYXRlcmlhbC51c2VyRGF0YSA9IHtcclxuICAgICAgdURlcHRoVGV4dHVyZToge3ZhbHVlOiBkZXB0aE1hcH0sXHJcbiAgICAgIHVXaWR0aDoge3ZhbHVlOiAxLjB9LFxyXG4gICAgICB1SGVpZ2h0OiB7dmFsdWU6IDEuMH0sXHJcbiAgICAgIHVVdlRyYW5zZm9ybToge3ZhbHVlOiBuZXcgTWF0cml4NCgpfSxcclxuICAgICAgdU9jY2x1c2lvbkVuYWJsZWQ6IHt2YWx1ZTogdHJ1ZX1cclxuICAgIH07XHJcblxyXG4gICAgbWF0ZXJpYWwudXNlckRhdGEuaXNBZ3VtZW50ZWRNYXRlcmlhbCA9IHRydWU7XHJcblxyXG4gICAgbWF0ZXJpYWwub25CZWZvcmVDb21waWxlID0gKHNoYWRlcikgPT4ge1xyXG4gICAgICAvLyBQYXNzIHVuaWZvcm1zIGZyb20gdXNlckRhdGEgdG8gdGhlXHJcbiAgICAgIGZvciAoY29uc3QgaSBpbiBtYXRlcmlhbC51c2VyRGF0YSkge1xyXG4gICAgICAgIHNoYWRlci51bmlmb3Jtc1tpXSA9IG1hdGVyaWFsLnVzZXJEYXRhW2ldO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBGcmFnbWVudCB2YXJpYWJsZXNcclxuICAgICAgc2hhZGVyLmZyYWdtZW50U2hhZGVyID0gYFxyXG5cdFx0XHR1bmlmb3JtIHNhbXBsZXIyRCB1RGVwdGhUZXh0dXJlO1xyXG5cdFx0XHR1bmlmb3JtIGZsb2F0IHVXaWR0aDtcclxuXHRcdFx0dW5pZm9ybSBmbG9hdCB1SGVpZ2h0O1xyXG5cdFx0XHR1bmlmb3JtIG1hdDQgdVV2VHJhbnNmb3JtO1xyXG5cdFx0XHR1bmlmb3JtIGJvb2wgdU9jY2x1c2lvbkVuYWJsZWQ7XHJcblx0XHRcdHZhcnlpbmcgZmxvYXQgdkRlcHRoO1xyXG5cdFx0XHRgICsgc2hhZGVyLmZyYWdtZW50U2hhZGVyO1xyXG5cclxuXHJcbiAgICAgIGxldCBmcmFnbWVudEVudHJ5UG9pbnQgPSAnI2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc19mcmFnbWVudD4nO1xyXG4gICAgICBpZiAobWF0ZXJpYWwgaW5zdGFuY2VvZiBTaGFkb3dNYXRlcmlhbCkge1xyXG4gICAgICAgIGZyYWdtZW50RW50cnlQb2ludCA9ICcjaW5jbHVkZSA8Zm9nX2ZyYWdtZW50Pic7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIEZyYWdtZW50IGRlcHRoIGxvZ2ljXHJcbiAgICAgIHNoYWRlci5mcmFnbWVudFNoYWRlciA9IHNoYWRlci5mcmFnbWVudFNoYWRlci5yZXBsYWNlKCd2b2lkIG1haW4nLFxyXG4gICAgICAgIGBmbG9hdCBnZXREZXB0aEluTWlsbGltZXRlcnMoaW4gc2FtcGxlcjJEIGRlcHRoVGV4dCwgaW4gdmVjMiB1dilcclxuXHRcdFx0e1xyXG5cdFx0XHRcdHZlYzIgcGFja2VkRGVwdGggPSB0ZXh0dXJlMkQoZGVwdGhUZXh0LCB1dikucmE7XHJcblx0XHRcdFx0cmV0dXJuIGRvdChwYWNrZWREZXB0aCwgdmVjMigyNTUuMCwgNjUyODAuMCkpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHZvaWQgbWFpbmApO1xyXG5cclxuXHJcbiAgICAgIHNoYWRlci5mcmFnbWVudFNoYWRlciA9IHNoYWRlci5mcmFnbWVudFNoYWRlci5yZXBsYWNlKGZyYWdtZW50RW50cnlQb2ludCwgYFxyXG5cdFx0XHQke2ZyYWdtZW50RW50cnlQb2ludH1cclxuXHRcdFx0XHQvLyBOb3JtYWxpemUgeCwgeSB0byByYW5nZSBbMCwgMV1cclxuXHRcdFx0XHRmbG9hdCB4ID0gZ2xfRnJhZ0Nvb3JkLnggLyB1V2lkdGg7XHJcblx0XHRcdFx0ZmxvYXQgeSA9IGdsX0ZyYWdDb29yZC55IC8gdUhlaWdodDtcclxuXHRcdFx0XHR2ZWMyIHRleENvb3JkID0gKHVVdlRyYW5zZm9ybSAqIHZlYzQoeCwgMS4wIC0geSwgMC4wLCAxLjApKS54eTtcclxuXHRcdFx0XHRmbG9hdCBkZXB0aCA9IGdldERlcHRoSW5NaWxsaW1ldGVycyh1RGVwdGhUZXh0dXJlLCB0ZXhDb29yZCkgLyAxMDAwLjA7XHJcblx0XHRcdFx0aWYgKGRlcHRoIDwgdkRlcHRoKVxyXG5cdFx0XHRcdHtcclxuXHRcdFx0XHRcdGRpc2NhcmQ7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRgKTtcclxuXHJcbiAgICAgIC8vIFZlcnRleCB2YXJpYWJsZXNcclxuICAgICAgc2hhZGVyLnZlcnRleFNoYWRlciA9IGBcclxuXHRcdFx0dmFyeWluZyBmbG9hdCB2RGVwdGg7XHJcblx0XHRcdGAgKyBzaGFkZXIudmVydGV4U2hhZGVyO1xyXG5cclxuICAgICAgLy8gVmVydGV4IGRlcHRoIGxvZ2ljXHJcbiAgICAgIHNoYWRlci52ZXJ0ZXhTaGFkZXIgPSBzaGFkZXIudmVydGV4U2hhZGVyLnJlcGxhY2UoJyNpbmNsdWRlIDxmb2dfdmVydGV4PicsIGBcclxuXHRcdFx0I2luY2x1ZGUgPGZvZ192ZXJ0ZXg+XHJcblx0XHRcdHZEZXB0aCA9IGdsX1Bvc2l0aW9uLno7XHJcblx0XHRcdGApO1xyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gbWF0ZXJpYWw7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF91cGRhdGVBdWdtZW50ZWRNYXRlcmlhbFVuaWZvcm1zKG5vcm1UZXh0dXJlRnJvbU5vcm1WaWV3TWF0cml4KSB7XHJcbiAgICB0aGlzLnNjZW5lLnRyYXZlcnNlKChjaGlsZCkgPT4ge1xyXG4gICAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiBNZXNoICYmIGNoaWxkLm1hdGVyaWFsKSB7XHJcbiAgICAgICAgaWYgKGNoaWxkLm1hdGVyaWFsIGluc3RhbmNlb2YgQXJyYXkpIHtcclxuICAgICAgICAgIGZvciAoY29uc3QgbWF0ZXJpYWwgb2YgY2hpbGQubWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgaWYgKG1hdGVyaWFsLnVzZXJEYXRhLmlzQWd1bWVudGVkTWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgICBtYXRlcmlhbC51c2VyRGF0YS51V2lkdGgudmFsdWUgPSBNYXRoLmZsb29yKERldmljZVV0aWxzLkdldFBpeGVsUmF0aW8oKSAqIHdpbmRvdy5pbm5lcldpZHRoKTtcclxuICAgICAgICAgICAgICBtYXRlcmlhbC51c2VyRGF0YS51SGVpZ2h0LnZhbHVlID0gTWF0aC5mbG9vcihEZXZpY2VVdGlscy5HZXRQaXhlbFJhdGlvKCkgKiB3aW5kb3cuaW5uZXJIZWlnaHQpO1xyXG4gICAgICAgICAgICAgIG1hdGVyaWFsLnVzZXJEYXRhLnVVdlRyYW5zZm9ybS52YWx1ZS5mcm9tQXJyYXkobm9ybVRleHR1cmVGcm9tTm9ybVZpZXdNYXRyaXgpO1xyXG4gICAgICAgICAgICAgIG1hdGVyaWFsLm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAoY2hpbGQudXNlckRhdGEuaXNBZ3VtZW50ZWRNYXRlcmlhbCkge1xyXG4gICAgICAgICAgY2hpbGQubWF0ZXJpYWwudXNlckRhdGEudVdpZHRoLnZhbHVlID0gTWF0aC5mbG9vcihEZXZpY2VVdGlscy5HZXRQaXhlbFJhdGlvKCkgKiB3aW5kb3cuaW5uZXJXaWR0aCk7XHJcbiAgICAgICAgICBjaGlsZC5tYXRlcmlhbC51c2VyRGF0YS51SGVpZ2h0LnZhbHVlID0gTWF0aC5mbG9vcihEZXZpY2VVdGlscy5HZXRQaXhlbFJhdGlvKCkgKiB3aW5kb3cuaW5uZXJIZWlnaHQpO1xyXG4gICAgICAgICAgY2hpbGQubWF0ZXJpYWwudXNlckRhdGEudVV2VHJhbnNmb3JtLnZhbHVlLmZyb21BcnJheShub3JtVGV4dHVyZUZyb21Ob3JtVmlld01hdHJpeCk7XHJcbiAgICAgICAgICBjaGlsZC5tYXRlcmlhbC5uZWVkc1VwZGF0ZSA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3VwZGF0ZU1lc2hNYXRlcmlhbHMoKTogdm9pZCB7XHJcbiAgICB0aGlzLnNjZW5lLnRyYXZlcnNlKChvYmplY3QpID0+IHtcclxuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIE1lc2gpIHtcclxuICAgICAgICBpZiAob2JqZWN0Lm1hdGVyaWFsIGluc3RhbmNlb2YgQXJyYXkpIHtcclxuICAgICAgICAgIGZvciAobGV0IG1hdGVyaWFsIG9mIG9iamVjdC5tYXRlcmlhbCkge1xyXG4gICAgICAgICAgICBtYXRlcmlhbCA9IHRoaXMuX2NyZWF0ZUF1Z21lbnRlZE1hdGVyaWFsKG1hdGVyaWFsLCB0aGlzLl9kZXB0aERhdGFUZXh0dXJlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgb2JqZWN0Lm1hdGVyaWFsID0gdGhpcy5fY3JlYXRlQXVnbWVudGVkTWF0ZXJpYWwob2JqZWN0Lm1hdGVyaWFsLCB0aGlzLl9kZXB0aERhdGFUZXh0dXJlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfcmVtb3ZlTWF0ZXJpYWxTaGFkZXJzKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zY2VuZS50cmF2ZXJzZSgob2JqZWN0KSA9PiB7XHJcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBNZXNoKSB7XHJcbiAgICAgICAgaWYgKG9iamVjdC5tYXRlcmlhbCBpbnN0YW5jZW9mIEFycmF5KSB7XHJcbiAgICAgICAgICBmb3IgKGNvbnN0IG1hdGVyaWFsIG9mIG9iamVjdC5tYXRlcmlhbCkge1xyXG4gICAgICAgICAgICBtYXRlcmlhbC5vbkJlZm9yZUNvbXBpbGUgPSAoc2hhZGVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgc2hhZGVyID0gbnVsbDtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgb2JqZWN0Lm1hdGVyaWFsLm9uQmVmb3JlQ29tcGlsZSA9IChzaGFkZXIpID0+IHtcclxuICAgICAgICAgICAgc2hhZGVyID0gbnVsbDtcclxuICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2NoZWNraW5nSW50ZXJmYWNlSW50ZXJhY3Rpb24oZXZlbnQ6IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy51c2VySW5TZWxlY3Rpb25NZW51ID0gZXZlbnQucGF0aC5maWx0ZXIoKGVudHJ5KSA9PiBlbnRyeS5sb2NhbE5hbWUgPT09ICdhci1ndWktY29uZmlndXJhdG9yJykubGVuZ3RoID4gMDtcclxuICB9XHJcbn1cclxuIl19