@colijnit/homedecorator 255.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 (986) hide show
  1. package/_variables.scss +1 -0
  2. package/app/app.component.scss +30 -0
  3. package/app/app.version.d.ts +5 -0
  4. package/app/bundle/threedselector-bundle/threedselector-bundle.component.scss +24 -0
  5. package/app/bundle/threedselector-bundle/threedselector-selections-bundle.component.scss +4 -0
  6. package/app/core/components/debug/debug.component.d.ts +17 -0
  7. package/app/core/components/debug/debug.component.scss +27 -0
  8. package/app/core/components/error/error-message.component.d.ts +14 -0
  9. package/app/core/components/error/error-message.component.scss +18 -0
  10. package/app/core/components/tooltip/tooltip.component.d.ts +17 -0
  11. package/app/core/components/tooltip/tooltip.component.scss +34 -0
  12. package/app/core/const/dimensioning.d.ts +24 -0
  13. package/app/core/core.module.d.ts +27 -0
  14. package/app/core/directive/autofocus.directive.d.ts +11 -0
  15. package/app/core/directive/tooltip.directive.d.ts +21 -0
  16. package/app/core/directive/visibility-observer-master.directive.d.ts +12 -0
  17. package/app/core/directive/visibility-observer.directive.d.ts +16 -0
  18. package/app/core/enum/configuration-key.enum.d.ts +35 -0
  19. package/app/core/enum/export-type.enum.d.ts +5 -0
  20. package/app/core/enum/google-tag-manager-event.enum.d.ts +12 -0
  21. package/app/core/enum/icon-name.enum.d.ts +15 -0
  22. package/app/core/enum/icon.enum.d.ts +33 -0
  23. package/app/core/enum/light.enum.d.ts +7 -0
  24. package/app/core/enum/message-type.enum.d.ts +69 -0
  25. package/app/core/enum/model-type.enum.d.ts +6 -0
  26. package/app/core/enum/output-encoding.enum.d.ts +4 -0
  27. package/app/core/enum/shadow-map-type.enum.d.ts +6 -0
  28. package/app/core/enum/user-role-type.enum.d.ts +18 -0
  29. package/app/core/enum/view-mode.enum.d.ts +9 -0
  30. package/app/core/enum/xr-mode.enum.d.ts +4 -0
  31. package/app/core/interface/adjustable-element.interface.d.ts +5 -0
  32. package/app/core/interface/category.interface.d.ts +9 -0
  33. package/app/core/interface/changes.interface.d.ts +9 -0
  34. package/app/core/interface/child-params.interface.d.ts +3 -0
  35. package/app/core/interface/configuration-data.interface.d.ts +36 -0
  36. package/app/core/interface/external-settings.interface.d.ts +6 -0
  37. package/app/core/interface/info-dialog-data.interface.d.ts +4 -0
  38. package/app/core/interface/light-preset.interface.d.ts +18 -0
  39. package/app/core/interface/loading-overlay-data.interface.d.ts +4 -0
  40. package/app/core/interface/media-resource.interface.d.ts +6 -0
  41. package/app/core/interface/message-with-payload.interface.d.ts +81 -0
  42. package/app/core/interface/message-without-payload.interface.d.ts +35 -0
  43. package/app/core/interface/preset.interface.d.ts +8 -0
  44. package/app/core/interface/selected-floor-event.interface.d.ts +5 -0
  45. package/app/core/interface/selected-wall-event.interface.d.ts +6 -0
  46. package/app/core/interface/texture.interface.d.ts +37 -0
  47. package/app/core/interface/toolbar-icon.interface.d.ts +8 -0
  48. package/app/core/model/ar-position-indicator.d.ts +4 -0
  49. package/app/core/model/camera-settings.d.ts +12 -0
  50. package/app/core/model/category.d.ts +12 -0
  51. package/app/core/model/custom-button.d.ts +10 -0
  52. package/app/core/model/error-message.d.ts +8 -0
  53. package/app/core/model/export-object.d.ts +5 -0
  54. package/app/core/model/from-intersection-observer.d.ts +7 -0
  55. package/app/core/model/homedecorator-settings-options.d.ts +46 -0
  56. package/app/core/model/homedecorator-settings.d.ts +54 -0
  57. package/app/core/model/icon.d.ts +4 -0
  58. package/app/core/model/light-preset.d.ts +27 -0
  59. package/app/core/model/light-properties.d.ts +25 -0
  60. package/app/core/model/media-resource.d.ts +7 -0
  61. package/app/core/model/preset.d.ts +10 -0
  62. package/app/core/model/ral-color.d.ts +19 -0
  63. package/app/core/model/shadow-properties.d.ts +7 -0
  64. package/app/core/model/texture-type.d.ts +6 -0
  65. package/app/core/model/texture.d.ts +43 -0
  66. package/app/core/model/three-object.d.ts +1 -0
  67. package/app/core/model/toast-type.d.ts +5 -0
  68. package/app/core/model/toast.d.ts +5 -0
  69. package/app/core/model/xr-reticle.d.ts +17 -0
  70. package/app/core/pipe/append.pipe.d.ts +7 -0
  71. package/app/core/pipe/cm-to-measure.pipe.d.ts +10 -0
  72. package/app/core/pipe/filter.pipe.d.ts +7 -0
  73. package/app/core/pipe/keys.pipe.d.ts +7 -0
  74. package/app/core/pipe/localize.pipe.d.ts +10 -0
  75. package/app/core/pipe/m-to-measure.pipe.d.ts +10 -0
  76. package/app/core/pipe/prepend.pipe.d.ts +7 -0
  77. package/app/core/pipe/scm-to-measure.pipe.d.ts +10 -0
  78. package/app/core/pipe/sm-to-measure.pipe.d.ts +10 -0
  79. package/app/core/pipe/strip-html.pipe.d.ts +7 -0
  80. package/app/core/service/3dm-api.d.ts +65 -0
  81. package/app/core/service/app-state.service.d.ts +49 -0
  82. package/app/core/service/configuration.service.d.ts +15 -0
  83. package/app/core/service/debug.service.d.ts +16 -0
  84. package/app/core/service/dimensioning.service.d.ts +14 -0
  85. package/app/core/service/dynamic-camera.service.d.ts +23 -0
  86. package/app/core/service/environment.service.d.ts +8 -0
  87. package/app/core/service/error.service.d.ts +11 -0
  88. package/app/core/service/export.service.d.ts +18 -0
  89. package/app/core/service/file.service.d.ts +9 -0
  90. package/app/core/service/homedecorator-app-event.service.d.ts +23 -0
  91. package/app/core/service/homedecorator-app.service.d.ts +58 -0
  92. package/app/core/service/homedecorator-connector-adapter.service.d.ts +90 -0
  93. package/app/core/service/homedecorator-connector.service.d.ts +127 -0
  94. package/app/core/service/homedecorator-dictionary.service.d.ts +15 -0
  95. package/app/core/service/homedecorator-icon-cache.service.d.ts +21 -0
  96. package/app/core/service/homedecorator-settings.service.d.ts +23 -0
  97. package/app/core/service/homedecorator.service.d.ts +14 -0
  98. package/app/core/service/integration.service.d.ts +16 -0
  99. package/app/core/service/item-serialization.service.d.ts +78 -0
  100. package/app/core/service/json-utils.service.d.ts +7 -0
  101. package/app/core/service/message-bus.service.d.ts +21 -0
  102. package/app/core/service/permanent-store.service.d.ts +37 -0
  103. package/app/core/service/presets.service.d.ts +50 -0
  104. package/app/core/service/progress.service.d.ts +17 -0
  105. package/app/core/service/ral.service.d.ts +17 -0
  106. package/app/core/service/skip-button-info.service.d.ts +19 -0
  107. package/app/core/service/toast.service.d.ts +12 -0
  108. package/app/core/service/utils.service.d.ts +68 -0
  109. package/app/core/service/view-mode.service.d.ts +27 -0
  110. package/app/core/service/web-worker.service.d.ts +18 -0
  111. package/app/core/utils/clone-utils.d.ts +5 -0
  112. package/app/core/utils/color.utils.d.ts +7 -0
  113. package/app/core/utils/file.utils.d.ts +36 -0
  114. package/app/core/utils/function/is-empty.function.d.ts +1 -0
  115. package/app/core/utils/function/is-nill.function.d.ts +1 -0
  116. package/app/core/utils/material.utils.d.ts +33 -0
  117. package/app/core/utils/object.utils.d.ts +14 -0
  118. package/app/core/utils/relative-position.utils.d.ts +12 -0
  119. package/app/core/utils/variation-utils.d.ts +12 -0
  120. package/app/core/workers/enum/web-worker-message.enum.d.ts +4 -0
  121. package/app/core/workers/enum/web-worker-type.enum.d.ts +3 -0
  122. package/app/development/components/selected-child-material-texture.component.d.ts +58 -0
  123. package/app/development/components/selected-child-material-texture.component.scss +122 -0
  124. package/app/development/components/selected-child-material.component.d.ts +73 -0
  125. package/app/development/components/selected-child-material.component.scss +45 -0
  126. package/app/development/components/selected-child.component.d.ts +8 -0
  127. package/app/development/components/selected-child.component.scss +40 -0
  128. package/app/development/components/selected-object-base.d.ts +32 -0
  129. package/app/development/components/selected-object.component.d.ts +20 -0
  130. package/app/development/components/selected-object.component.scss +13 -0
  131. package/app/development/development.module.d.ts +19 -0
  132. package/app/development/directive/development.directive.d.ts +19 -0
  133. package/app/development/service/development.service.d.ts +49 -0
  134. package/app/homedecorator.component.d.ts +42 -0
  135. package/app/homedecorator.component.scss +34 -0
  136. package/app/homedecorator.module.d.ts +18 -0
  137. package/app/plugins/core3d/collision-manager/collision-manager.service.d.ts +23 -0
  138. package/app/plugins/core3d/collision-manager/floorplan-collision-detection.d.ts +9 -0
  139. package/app/plugins/core3d/collision-manager/snapping-collision.service.d.ts +47 -0
  140. package/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-buttons/ar-gui-buttons.component.d.ts +17 -0
  141. package/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-buttons/ar-gui-buttons.component.scss +30 -0
  142. package/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-configurator/ar-gui-configurator.component.d.ts +25 -0
  143. package/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-configurator/ar-gui-configurator.component.scss +13 -0
  144. package/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-context-menu/ar-gui-context-menu.component.d.ts +21 -0
  145. package/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-context-menu/ar-gui-context-menu.component.scss +6 -0
  146. package/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-notifications/ar-gui-notifications.component.d.ts +11 -0
  147. package/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-notifications/ar-gui-notifications.component.scss +19 -0
  148. package/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-root.component.d.ts +16 -0
  149. package/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-root.component.scss +23 -0
  150. package/app/plugins/core3d/components/lightplan/edit-light/edit-light.component.d.ts +46 -0
  151. package/app/plugins/core3d/components/lightplan/edit-light/edit-light.component.scss +93 -0
  152. package/app/plugins/core3d/components/lightplan/edit-lightplan/edit-lightplan.component.d.ts +24 -0
  153. package/app/plugins/core3d/components/lightplan/edit-lightplan/edit-lightplan.component.scss +93 -0
  154. package/app/plugins/core3d/components/lightplan/lightplan.component.d.ts +60 -0
  155. package/app/plugins/core3d/components/lightplan/lightplan.component.scss +102 -0
  156. package/app/plugins/core3d/components/scene-options/scene-options.component.d.ts +17 -0
  157. package/app/plugins/core3d/components/scene-options/scene-options.component.scss +54 -0
  158. package/app/plugins/core3d/core/angles.d.ts +8 -0
  159. package/app/plugins/core3d/core/corner-utils.d.ts +8 -0
  160. package/app/plugins/core3d/core/dimensioning.d.ts +19 -0
  161. package/app/plugins/core3d/core/utils.d.ts +147 -0
  162. package/app/plugins/core3d/core3d/components/scenecontrol/scene-control.component.d.ts +49 -0
  163. package/app/plugins/core3d/core3d/components/scenecontrol/scene-control.component.scss +3 -0
  164. package/app/plugins/core3d/core3d/core3d.component.d.ts +76 -0
  165. package/app/plugins/core3d/core3d/core3d.component.scss +27 -0
  166. package/app/plugins/core3d/core3d.module.d.ts +38 -0
  167. package/app/plugins/core3d/directive/scene.directive.d.ts +26 -0
  168. package/app/plugins/core3d/enum/ar-feature.enum.d.ts +12 -0
  169. package/app/plugins/core3d/enum/direction.enum.d.ts +8 -0
  170. package/app/plugins/core3d/enum/result-type.enum.d.ts +19 -0
  171. package/app/plugins/core3d/hud/bounding-measurement-box/bounding-box-measurement.d.ts +28 -0
  172. package/app/plugins/core3d/hud/bounding-measurement-box/box-measurement.d.ts +17 -0
  173. package/app/plugins/core3d/hud/bounding-measurement-box/door-or-window-box-measurement.d.ts +29 -0
  174. package/app/plugins/core3d/hud/bounding-measurement-box/measurable.d.ts +8 -0
  175. package/app/plugins/core3d/hud/bounding-measurement-box/measurement-utils.d.ts +9 -0
  176. package/app/plugins/core3d/hud/custom-shape-name-label.d.ts +15 -0
  177. package/app/plugins/core3d/hud/floor-indicator.d.ts +20 -0
  178. package/app/plugins/core3d/hud/furniture-measurements.d.ts +12 -0
  179. package/app/plugins/core3d/hud/indicator-factory.d.ts +7 -0
  180. package/app/plugins/core3d/hud/measurements.d.ts +46 -0
  181. package/app/plugins/core3d/hud/on-wall-measurements.d.ts +18 -0
  182. package/app/plugins/core3d/hud/opening-symbol.d.ts +11 -0
  183. package/app/plugins/core3d/hud/rotation-helper.d.ts +44 -0
  184. package/app/plugins/core3d/hud/utils.d.ts +3 -0
  185. package/app/plugins/core3d/interface/dragged-data.interface.d.ts +10 -0
  186. package/app/plugins/core3d/interface/edge-visibility-changes.d.ts +5 -0
  187. package/app/plugins/core3d/interface/model.interface.d.ts +42 -0
  188. package/app/plugins/core3d/interface/opening.interface.d.ts +6 -0
  189. package/app/plugins/core3d/interface/scene-option-button.interface.d.ts +17 -0
  190. package/app/plugins/core3d/interface/scene-update.interface.d.ts +5 -0
  191. package/app/plugins/core3d/items/base-item.d.ts +97 -0
  192. package/app/plugins/core3d/items/custom-cylinder-floor-item.d.ts +12 -0
  193. package/app/plugins/core3d/items/custom-cylinder-wall-item.d.ts +13 -0
  194. package/app/plugins/core3d/items/custom-floor-item.d.ts +9 -0
  195. package/app/plugins/core3d/items/custom-objects.d.ts +55 -0
  196. package/app/plugins/core3d/items/custom-shape-floor-item.d.ts +9 -0
  197. package/app/plugins/core3d/items/custom-shape-wall-item.d.ts +10 -0
  198. package/app/plugins/core3d/items/custom-wall-floor-item.d.ts +19 -0
  199. package/app/plugins/core3d/items/custom-wall-item.d.ts +9 -0
  200. package/app/plugins/core3d/items/factory.d.ts +24 -0
  201. package/app/plugins/core3d/items/floor-item.d.ts +13 -0
  202. package/app/plugins/core3d/items/floor-pin.d.ts +11 -0
  203. package/app/plugins/core3d/items/floor-plane-item.d.ts +30 -0
  204. package/app/plugins/core3d/items/furniture.d.ts +3 -0
  205. package/app/plugins/core3d/items/in-wall-floor-item.d.ts +9 -0
  206. package/app/plugins/core3d/items/item-group.d.ts +51 -0
  207. package/app/plugins/core3d/items/item-type.d.ts +21 -0
  208. package/app/plugins/core3d/items/item.d.ts +84 -0
  209. package/app/plugins/core3d/items/metadata.d.ts +74 -0
  210. package/app/plugins/core3d/items/on-floor-item.d.ts +8 -0
  211. package/app/plugins/core3d/items/pin.d.ts +5 -0
  212. package/app/plugins/core3d/items/three-mesh.d.ts +8 -0
  213. package/app/plugins/core3d/items/wall-floor-item.d.ts +8 -0
  214. package/app/plugins/core3d/items/wall-objects.d.ts +512 -0
  215. package/app/plugins/core3d/items/wall-pin.d.ts +8 -0
  216. package/app/plugins/core3d/model/ar-parameters.d.ts +9 -0
  217. package/app/plugins/core3d/model/box-skin-default.d.ts +5 -0
  218. package/app/plugins/core3d/model/collision-info.d.ts +6 -0
  219. package/app/plugins/core3d/model/custom-floor-group-result.d.ts +18 -0
  220. package/app/plugins/core3d/model/cylinder-skin-default.d.ts +4 -0
  221. package/app/plugins/core3d/model/dragged-status.d.ts +18 -0
  222. package/app/plugins/core3d/model/face.d.ts +11 -0
  223. package/app/plugins/core3d/model/geometry.d.ts +11 -0
  224. package/app/plugins/core3d/model/scene-event.enum.d.ts +10 -0
  225. package/app/plugins/core3d/model/skin.d.ts +15 -0
  226. package/app/plugins/core3d/model/threed-model.d.ts +47 -0
  227. package/app/plugins/core3d/service/ar.service.d.ts +121 -0
  228. package/app/plugins/core3d/service/camera.service.d.ts +70 -0
  229. package/app/plugins/core3d/service/ceiling.service.d.ts +25 -0
  230. package/app/plugins/core3d/service/controls.d.ts +11 -0
  231. package/app/plugins/core3d/service/drag-and-drop.service.d.ts +73 -0
  232. package/app/plugins/core3d/service/error-glow.service.d.ts +18 -0
  233. package/app/plugins/core3d/service/floor.service.d.ts +43 -0
  234. package/app/plugins/core3d/service/font.service.d.ts +10 -0
  235. package/app/plugins/core3d/service/hud.service.d.ts +79 -0
  236. package/app/plugins/core3d/service/intersection.service.d.ts +10 -0
  237. package/app/plugins/core3d/service/item-group.service.d.ts +33 -0
  238. package/app/plugins/core3d/service/item.service.d.ts +37 -0
  239. package/app/plugins/core3d/service/light-presets.service.d.ts +46 -0
  240. package/app/plugins/core3d/service/lights.service.d.ts +38 -0
  241. package/app/plugins/core3d/service/message-board.service.d.ts +18 -0
  242. package/app/plugins/core3d/service/models.service.d.ts +37 -0
  243. package/app/plugins/core3d/service/outline.service.d.ts +40 -0
  244. package/app/plugins/core3d/service/rotation.service.d.ts +57 -0
  245. package/app/plugins/core3d/service/scene-event.service.d.ts +131 -0
  246. package/app/plugins/core3d/service/scene-options.service.d.ts +11 -0
  247. package/app/plugins/core3d/service/scene.service.d.ts +74 -0
  248. package/app/plugins/core3d/service/vr.service.d.ts +44 -0
  249. package/app/plugins/core3d/service/wall-measurements.service.d.ts +23 -0
  250. package/app/plugins/core3d/service/xr.service.d.ts +56 -0
  251. package/app/plugins/core3d/textures/DepthDataTexture.d.ts +5 -0
  252. package/app/plugins/core3d/walkthrough-camera-controls/walkthrough-camera-controls.component.d.ts +19 -0
  253. package/app/plugins/core3d/walkthrough-camera-controls/walkthrough-camera-controls.component.scss +7 -0
  254. package/app/plugins/furniture-manager/furniture-library/furniture-library.component.d.ts +27 -0
  255. package/app/plugins/furniture-manager/furniture-library/furniture-library.component.scss +20 -0
  256. package/app/plugins/furniture-manager/furniture-manager/furniture-manager.component.d.ts +91 -0
  257. package/app/plugins/furniture-manager/furniture-manager/furniture-manager.component.scss +57 -0
  258. package/app/plugins/furniture-manager/furniture-manager.module.d.ts +23 -0
  259. package/app/plugins/help/help/help.component.d.ts +21 -0
  260. package/app/plugins/help/help/help.component.scss +0 -0
  261. package/app/plugins/help/help-dialog/help-dialog.component.d.ts +20 -0
  262. package/app/plugins/help/help-dialog/help-dialog.component.scss +28 -0
  263. package/app/plugins/help/help.module.d.ts +12 -0
  264. package/app/plugins/lite-selector/lite-selector/component/animation/animation.component.d.ts +19 -0
  265. package/app/plugins/lite-selector/lite-selector/component/animation/animation.component.scss +0 -0
  266. package/app/plugins/lite-selector/lite-selector/component/answer-card/answer-card.component.d.ts +41 -0
  267. package/app/plugins/lite-selector/lite-selector/component/answer-card/answer-card.component.scss +25 -0
  268. package/app/plugins/lite-selector/lite-selector/component/answers-slideout/answers-slideout.component.d.ts +72 -0
  269. package/app/plugins/lite-selector/lite-selector/component/answers-slideout/answers-slideout.component.scss +146 -0
  270. package/app/plugins/lite-selector/lite-selector/component/color-filter/color-filter.component.d.ts +19 -0
  271. package/app/plugins/lite-selector/lite-selector/component/color-filter/color-filter.component.scss +37 -0
  272. package/app/plugins/lite-selector/lite-selector/component/customizer/customizer.component.d.ts +28 -0
  273. package/app/plugins/lite-selector/lite-selector/component/customizer/customizer.component.scss +127 -0
  274. package/app/plugins/lite-selector/lite-selector/component/image-zoom/image-zoom.component.d.ts +9 -0
  275. package/app/plugins/lite-selector/lite-selector/component/image-zoom/image-zoom.component.scss +47 -0
  276. package/app/plugins/lite-selector/lite-selector/component/selections-summary/selections-summary-line.component.d.ts +31 -0
  277. package/app/plugins/lite-selector/lite-selector/component/selections-summary/selections-summary-line.component.scss +11 -0
  278. package/app/plugins/lite-selector/lite-selector/component/selections-summary/selections-summary.component.d.ts +38 -0
  279. package/app/plugins/lite-selector/lite-selector/component/selections-summary/selections-summary.component.scss +80 -0
  280. package/app/plugins/lite-selector/lite-selector/component/tag-filter/tag-filter.component.d.ts +8 -0
  281. package/app/plugins/lite-selector/lite-selector/component/tag-filter/tag-filter.component.scss +10 -0
  282. package/app/plugins/lite-selector/lite-selector/lite-selector.component.d.ts +40 -0
  283. package/app/plugins/lite-selector/lite-selector/lite-selector.component.scss +10 -0
  284. package/app/plugins/lite-selector/lite-selector/service/customizer.service.d.ts +44 -0
  285. package/app/plugins/lite-selector/lite-selector.module.d.ts +22 -0
  286. package/app/plugins/model-uploader/model-previewer/model-preview.component.d.ts +57 -0
  287. package/app/plugins/model-uploader/model-previewer/model-preview.component.scss +75 -0
  288. package/app/plugins/model-uploader/model-uploader/model-upload.component.scss +34 -0
  289. package/app/plugins/model-uploader/model-uploader/model-uploader.component.d.ts +23 -0
  290. package/app/plugins/model-uploader/model-uploader.module.d.ts +16 -0
  291. package/app/plugins/plugin-interface.d.ts +5 -0
  292. package/app/plugins/plugins.module.d.ts +15 -0
  293. package/app/plugins/presets/presets/presets.component.d.ts +22 -0
  294. package/app/plugins/presets/presets/presets.component.scss +0 -0
  295. package/app/plugins/presets/presets.module.d.ts +10 -0
  296. package/app/plugins/product-catalog/own-collection-catalog/product-own-collection.component.d.ts +19 -0
  297. package/app/plugins/product-catalog/own-collection-catalog/product-own-collection.component.scss +4 -0
  298. package/app/plugins/product-catalog/own-collection-catalog/product-own-collection.module.d.ts +10 -0
  299. package/app/plugins/product-catalog/product-catalog/product-catalog.component.d.ts +70 -0
  300. package/app/plugins/product-catalog/product-catalog/product-catalog.component.scss +128 -0
  301. package/app/plugins/product-catalog/product-catalog.module.d.ts +16 -0
  302. package/app/plugins/render/enum/connection-status.d.ts +6 -0
  303. package/app/plugins/render/enum/render-modes.d.ts +5 -0
  304. package/app/plugins/render/enum/render-status.d.ts +7 -0
  305. package/app/plugins/render/model/camera-position.d.ts +7 -0
  306. package/app/plugins/render/model/image-size.d.ts +6 -0
  307. package/app/plugins/render/model/lightning.d.ts +5 -0
  308. package/app/plugins/render/model/render-data.d.ts +15 -0
  309. package/app/plugins/render/model/render-environment.d.ts +6 -0
  310. package/app/plugins/render/model/render-parameters.d.ts +15 -0
  311. package/app/plugins/render/model/render-queue-item.d.ts +14 -0
  312. package/app/plugins/render/model/render-settings.d.ts +9 -0
  313. package/app/plugins/render/model/render.d.ts +14 -0
  314. package/app/plugins/render/render-controls/render-controls.component.d.ts +27 -0
  315. package/app/plugins/render/render-controls/render-controls.component.scss +51 -0
  316. package/app/plugins/render/render-dialog/render-dialog.component.d.ts +59 -0
  317. package/app/plugins/render/render-dialog/render-dialog.component.scss +320 -0
  318. package/app/plugins/render/render.module.d.ts +20 -0
  319. package/app/plugins/render/service/new-render.service.d.ts +65 -0
  320. package/app/plugins/render/service/render.service.d.ts +104 -0
  321. package/app/plugins/room-planner/components/appearance-section/appearance-section.component.d.ts +43 -0
  322. package/app/plugins/room-planner/components/appearance-section/appearance-section.component.scss +14 -0
  323. package/app/plugins/room-planner/components/color-picker/color-picker.component.d.ts +11 -0
  324. package/app/plugins/room-planner/components/color-picker/color-picker.component.scss +0 -0
  325. package/app/plugins/room-planner/components/custom-cylinder-creator/custom-cylinder-creator.component.d.ts +49 -0
  326. package/app/plugins/room-planner/components/custom-cylinder-creator/custom-cylinder-creator.component.scss +19 -0
  327. package/app/plugins/room-planner/components/custome-shape-creator/custom-shape-creator.component.d.ts +49 -0
  328. package/app/plugins/room-planner/components/custome-shape-creator/custom-shape-creator.component.scss +24 -0
  329. package/app/plugins/room-planner/components/dimension-input/dimension-input.component.d.ts +22 -0
  330. package/app/plugins/room-planner/components/dimension-input/dimension-input.component.scss +14 -0
  331. package/app/plugins/room-planner/components/edit-apply/edit-apply.component.d.ts +19 -0
  332. package/app/plugins/room-planner/components/edit-apply/edit-apply.component.scss +0 -0
  333. package/app/plugins/room-planner/components/edit-parameter/edit-parameter.component.d.ts +28 -0
  334. package/app/plugins/room-planner/components/edit-parameter/edit-parameter.component.scss +23 -0
  335. package/app/plugins/room-planner/components/file-drop/file-drop.component.d.ts +21 -0
  336. package/app/plugins/room-planner/components/file-drop/file-drop.component.scss +31 -0
  337. package/app/plugins/room-planner/components/floorplanner/const/defaults.d.ts +48 -0
  338. package/app/plugins/room-planner/components/floorplanner/floorplanner-mode.d.ts +9 -0
  339. package/app/plugins/room-planner/components/floorplanner/floorplanner.component.d.ts +172 -0
  340. package/app/plugins/room-planner/components/floorplanner/floorplanner.component.scss +48 -0
  341. package/app/plugins/room-planner/components/floorplanner/service/floorplan.service.d.ts +103 -0
  342. package/app/plugins/room-planner/components/floorplanner/service/room.service.d.ts +75 -0
  343. package/app/plugins/room-planner/components/floorplanner/snap-indicator-mode.d.ts +5 -0
  344. package/app/plugins/room-planner/components/floorplanner/utils/context.utils.d.ts +5 -0
  345. package/app/plugins/room-planner/components/object-library/object-library.component.d.ts +23 -0
  346. package/app/plugins/room-planner/components/object-library/object-library.component.scss +43 -0
  347. package/app/plugins/room-planner/components/ral-color-picker/ral-color-picker.component.d.ts +22 -0
  348. package/app/plugins/room-planner/components/ral-color-picker/ral-color-picker.component.scss +55 -0
  349. package/app/plugins/room-planner/components/rgb-color-picker/rgb-color-picker.component.d.ts +11 -0
  350. package/app/plugins/room-planner/components/rgb-color-picker/rgb-color-picker.component.scss +10 -0
  351. package/app/plugins/room-planner/components/selected-floor/selected-floor.component.d.ts +16 -0
  352. package/app/plugins/room-planner/components/selected-floor/selected-floor.component.scss +16 -0
  353. package/app/plugins/room-planner/components/selected-object/selected-object.component.d.ts +44 -0
  354. package/app/plugins/room-planner/components/selected-object/selected-object.component.scss +21 -0
  355. package/app/plugins/room-planner/components/selected-threed-object/selected-threed-object.component.d.ts +57 -0
  356. package/app/plugins/room-planner/components/selected-threed-object/selected-threed-object.component.scss +35 -0
  357. package/app/plugins/room-planner/components/selected-wall/selected-wall.component.d.ts +45 -0
  358. package/app/plugins/room-planner/components/selected-wall/selected-wall.component.scss +31 -0
  359. package/app/plugins/room-planner/components/settings/settings-options.component.d.ts +18 -0
  360. package/app/plugins/room-planner/components/settings/settings-options.component.scss +46 -0
  361. package/app/plugins/room-planner/components/settings/settings.component.d.ts +63 -0
  362. package/app/plugins/room-planner/components/settings/settings.component.scss +42 -0
  363. package/app/plugins/room-planner/components/texture-editor/texture-editor.component.d.ts +125 -0
  364. package/app/plugins/room-planner/components/texture-editor/texture-editor.component.scss +38 -0
  365. package/app/plugins/room-planner/components/texture-picker/texture-picker.component.d.ts +25 -0
  366. package/app/plugins/room-planner/components/texture-picker/texture-picker.component.scss +49 -0
  367. package/app/plugins/room-planner/components/wall-length-input/wall-length-input.component.d.ts +16 -0
  368. package/app/plugins/room-planner/components/wall-length-input/wall-length-input.component.scss +5 -0
  369. package/app/plugins/room-planner/const/key.d.ts +10 -0
  370. package/app/plugins/room-planner/room-planner/room-planner.component.d.ts +236 -0
  371. package/app/plugins/room-planner/room-planner/room-planner.component.scss +167 -0
  372. package/app/plugins/room-planner/room-planner.module.d.ts +59 -0
  373. package/app/plugins/threed-in-photo/components/threed-in-photo-scene/threed-in-photo-scene.component.d.ts +18 -0
  374. package/app/plugins/threed-in-photo/components/threed-in-photo-scene/threed-in-photo-scene.component.scss +7 -0
  375. package/app/plugins/threed-in-photo/components/upload-image/upload-image.component.d.ts +18 -0
  376. package/app/plugins/threed-in-photo/components/upload-image/upload-image.component.scss +7 -0
  377. package/app/plugins/threed-in-photo/components/view-control/view-control.component.d.ts +30 -0
  378. package/app/plugins/threed-in-photo/components/view-control/view-control.component.scss +40 -0
  379. package/app/plugins/threed-in-photo/models/model-output.d.ts +14 -0
  380. package/app/plugins/threed-in-photo/services/threed-in-photo-build.service.d.ts +37 -0
  381. package/app/plugins/threed-in-photo/services/threed-in-photo-connection.service.d.ts +8 -0
  382. package/app/plugins/threed-in-photo/services/threed-in-photo-control.service.d.ts +14 -0
  383. package/app/plugins/threed-in-photo/services/threed-in-photo-event-listeners.service.d.ts +15 -0
  384. package/app/plugins/threed-in-photo/services/threed-in-photo-event.service.d.ts +9 -0
  385. package/app/plugins/threed-in-photo/services/threed-in-photo-initializer.service.d.ts +27 -0
  386. package/app/plugins/threed-in-photo/services/threed-in-photo-render.service.d.ts +20 -0
  387. package/app/plugins/threed-in-photo/services/threed-in-photo-scene.service.d.ts +12 -0
  388. package/app/plugins/threed-in-photo/services/threed-in-photo-view.service.d.ts +8 -0
  389. package/app/plugins/threed-in-photo/threed-in-photo.module.d.ts +17 -0
  390. package/app/plugins/threed-in-photo/utils/utils.d.ts +6 -0
  391. package/app/plugins/threedselector/element-buttons/element-buttons.component.d.ts +31 -0
  392. package/app/plugins/threedselector/element-buttons/element-buttons.component.scss +61 -0
  393. package/app/plugins/threedselector/element-slider/element-slider.component.d.ts +14 -0
  394. package/app/plugins/threedselector/element-slider/element-slider.component.scss +47 -0
  395. package/app/plugins/threedselector/element-toolbar/element-toolbar.component.d.ts +26 -0
  396. package/app/plugins/threedselector/element-toolbar/element-toolbar.component.scss +142 -0
  397. package/app/plugins/threedselector/threedselector/model/furniture-connected-part-integration.d.ts +7 -0
  398. package/app/plugins/threedselector/threedselector/model/furniture-integration.d.ts +12 -0
  399. package/app/plugins/threedselector/threedselector/model/furniture-part-integration.d.ts +14 -0
  400. package/app/plugins/threedselector/threedselector/model/furniture-part-variation.d.ts +7 -0
  401. package/app/plugins/threedselector/threedselector/model/material.d.ts +41 -0
  402. package/app/plugins/threedselector/threedselector/model/variation-settings.d.ts +53 -0
  403. package/app/plugins/threedselector/threedselector/model/variation.d.ts +11 -0
  404. package/app/plugins/threedselector/threedselector/service/animation.service.d.ts +22 -0
  405. package/app/plugins/threedselector/threedselector/service/build-furniture.service.d.ts +186 -0
  406. package/app/plugins/threedselector/threedselector/service/dimensions.service.d.ts +33 -0
  407. package/app/plugins/threedselector/threedselector/service/element.service.d.ts +45 -0
  408. package/app/plugins/threedselector/threedselector/service/light-creation.service.d.ts +9 -0
  409. package/app/plugins/threedselector/threedselector/service/load-furniture.service.d.ts +74 -0
  410. package/app/plugins/threedselector/threedselector/service/resize.service.d.ts +13 -0
  411. package/app/plugins/threedselector/threedselector/service/third-party-model.service.d.ts +66 -0
  412. package/app/plugins/threedselector/threedselector/service/threedselector.service.d.ts +22 -0
  413. package/app/plugins/threedselector/threedselector/service/variation-cache.service.d.ts +23 -0
  414. package/app/plugins/threedselector/threedselector/service/variation.service.d.ts +23 -0
  415. package/app/plugins/threedselector/threedselector/threedselector.component.d.ts +188 -0
  416. package/app/plugins/threedselector/threedselector/threedselector.component.scss +82 -0
  417. package/app/plugins/threedselector/threedselector/utils/asset.utils.d.ts +19 -0
  418. package/app/plugins/threedselector/threedselector/utils/image.utils.d.ts +6 -0
  419. package/app/plugins/threedselector/threedselector/utils/json-parser.utils.d.ts +9 -0
  420. package/app/plugins/threedselector/threedselector/utils/scene-3d.utils.d.ts +10 -0
  421. package/app/plugins/threedselector/threedselector.module.d.ts +31 -0
  422. package/app/plugins/toolbar/download-dialog/download-dialog.component.d.ts +14 -0
  423. package/app/plugins/toolbar/download-dialog/download-dialog.component.scss +22 -0
  424. package/app/plugins/toolbar/draw-dialog/draw-dialog.component.d.ts +66 -0
  425. package/app/plugins/toolbar/draw-dialog/draw-dialog.component.scss +97 -0
  426. package/app/plugins/toolbar/edit-preset-dialog/edit-preset-dialog.component.d.ts +8 -0
  427. package/app/plugins/toolbar/edit-preset-dialog/edit-preset-dialog.component.scss +0 -0
  428. package/app/plugins/toolbar/landing-screen-modal/landing-screen-modal.component.d.ts +36 -0
  429. package/app/plugins/toolbar/landing-screen-modal/landing-screen-modal.component.scss +71 -0
  430. package/app/plugins/toolbar/load-from-cloud-dialog/load-from-cloud-dialog.component.d.ts +36 -0
  431. package/app/plugins/toolbar/load-from-cloud-dialog/load-from-cloud-dialog.component.scss +3 -0
  432. package/app/plugins/toolbar/open-dialog/open-dialog.component.d.ts +23 -0
  433. package/app/plugins/toolbar/open-dialog/open-dialog.component.scss +0 -0
  434. package/app/plugins/toolbar/pdf-crop-dialog/pdf-crop-dialog.component.d.ts +34 -0
  435. package/app/plugins/toolbar/pdf-crop-dialog/pdf-crop-dialog.component.scss +17 -0
  436. package/app/plugins/toolbar/save-dialog/save-dialog.component.d.ts +38 -0
  437. package/app/plugins/toolbar/save-dialog/save-dialog.component.scss +33 -0
  438. package/app/plugins/toolbar/saved-dialog/saved-dialog.component.d.ts +24 -0
  439. package/app/plugins/toolbar/saved-dialog/saved-dialog.component.scss +7 -0
  440. package/app/plugins/toolbar/toolbar/limited-mode-message-component/limited-mode-message.component.d.ts +9 -0
  441. package/app/plugins/toolbar/toolbar/limited-mode-message-component/limited-mode-message.component.scss +10 -0
  442. package/app/plugins/toolbar/toolbar/toolbar.component.d.ts +101 -0
  443. package/app/plugins/toolbar/toolbar/toolbar.component.scss +251 -0
  444. package/app/plugins/toolbar/toolbar.module.d.ts +44 -0
  445. package/app/root/root.component.scss +0 -0
  446. package/app/service/dynamic-script.service.d.ts +8 -0
  447. package/app/service/google-tag-manager.service.d.ts +19 -0
  448. package/app/service/local-storage.service.d.ts +18 -0
  449. package/app/service/service-locator.service.d.ts +4 -0
  450. package/app/shared/base64-images.d.ts +4 -0
  451. package/app/shared/button-elevation/button-elevation.component.d.ts +40 -0
  452. package/app/shared/button-elevation/button-elevation.component.scss +109 -0
  453. package/app/shared/button-elevation/button-elevation.module.d.ts +16 -0
  454. package/app/shared/camera-settings-dialog/camera-settings-dialog.component.d.ts +24 -0
  455. package/app/shared/camera-settings-dialog/camera-settings-dialog.component.scss +30 -0
  456. package/app/shared/camera-settings-dialog/camera-settings-dialog.module.d.ts +16 -0
  457. package/app/shared/category-library/category-library.component.d.ts +10 -0
  458. package/app/shared/category-library/category-library.component.scss +16 -0
  459. package/app/shared/category-library/category-library.module.d.ts +11 -0
  460. package/app/shared/context-menu/context-menu.component.d.ts +12 -0
  461. package/app/shared/context-menu/context-menu.component.scss +25 -0
  462. package/app/shared/context-menu/context-menu.module.d.ts +14 -0
  463. package/app/shared/context-menu/item-context-menu/item-context-menu.component.d.ts +30 -0
  464. package/app/shared/context-menu/item-context-menu/item-context-menu.component.scss +32 -0
  465. package/app/shared/dialog/dialog.component.d.ts +26 -0
  466. package/app/shared/dialog/dialog.component.scss +25 -0
  467. package/app/shared/dialog/dialog.module.d.ts +12 -0
  468. package/app/shared/dialog/enum/dialog-type.enum.d.ts +6 -0
  469. package/app/shared/dialog/interface/dialog-config.interface.d.ts +7 -0
  470. package/app/shared/dialog/service/dialog.service.d.ts +11 -0
  471. package/app/shared/error-dialog/error-dialog.component.d.ts +11 -0
  472. package/app/shared/error-dialog/error-dialog.component.scss +0 -0
  473. package/app/shared/error-dialog/error-dialog.module.d.ts +10 -0
  474. package/app/shared/export-dialog/export-dialog.component.d.ts +11 -0
  475. package/app/shared/export-dialog/export-dialog.component.scss +19 -0
  476. package/app/shared/export-dialog/export-dialog.module.d.ts +11 -0
  477. package/app/shared/info-dialog/info-dialog.component.d.ts +9 -0
  478. package/app/shared/info-dialog/info-dialog.component.scss +15 -0
  479. package/app/shared/info-dialog/info-dialog.module.d.ts +12 -0
  480. package/app/shared/loader/hd-loader.component.d.ts +6 -0
  481. package/app/shared/loader/hd-loader.component.scss +44 -0
  482. package/app/shared/loader/hd-loader.module.d.ts +9 -0
  483. package/app/shared/loader/loader.component.scss +42 -0
  484. package/app/shared/loading-overlay/dialog/loading-overlay-dialog.component.d.ts +8 -0
  485. package/app/shared/loading-overlay/dialog/loading-overlay-dialog.component.scss +3 -0
  486. package/app/shared/loading-overlay/loading-overlay.component.d.ts +19 -0
  487. package/app/shared/loading-overlay/loading-overlay.component.scss +9 -0
  488. package/app/shared/loading-overlay/loading-overlay.module.d.ts +11 -0
  489. package/app/shared/model-dialog/model-dialog-furniture-list.component.d.ts +35 -0
  490. package/app/shared/model-dialog/model-dialog-furniture-list.component.scss +221 -0
  491. package/app/shared/model-dialog/model-dialog.component.d.ts +31 -0
  492. package/app/shared/model-dialog/model-dialog.component.scss +22 -0
  493. package/app/shared/model-dialog/model-dialog.module.d.ts +16 -0
  494. package/app/shared/progress-bar/progress-bar.component.d.ts +9 -0
  495. package/app/shared/progress-bar/progress-bar.component.scss +11 -0
  496. package/app/shared/progress-bar/progress-bar.module.d.ts +9 -0
  497. package/app/shared/register-dialog/register-dialog.component.d.ts +26 -0
  498. package/app/shared/register-dialog/register-dialog.component.scss +21 -0
  499. package/app/shared/screen-size-analysis/device-size-type.d.ts +5 -0
  500. package/app/shared/screen-size-analysis/navigator-type.enum.d.ts +4 -0
  501. package/app/shared/screen-size-analysis/screen-size-analysis.service.d.ts +27 -0
  502. package/app/shared/screen-size-analysis/screen-size-config.d.ts +5 -0
  503. package/app/shared/screen-size-analysis/screen-size-info.d.ts +10 -0
  504. package/app/shared/slider-input/slider-input.component.d.ts +13 -0
  505. package/app/shared/slider-input/slider-input.component.scss +12 -0
  506. package/app/shared/slider-input/slider-input.module.d.ts +13 -0
  507. package/app/shared/toolbar-icon/toolbar-icon.component.d.ts +12 -0
  508. package/app/shared/toolbar-icon/toolbar-icon.component.scss +8 -0
  509. package/app/shared/toolbar-icon/toolbar-icon.module.d.ts +11 -0
  510. package/app/shared/zoom-controls/zoom-controls.component.d.ts +16 -0
  511. package/app/shared/zoom-controls/zoom-controls.component.scss +0 -0
  512. package/app/shared/zoom-controls/zoom-controls.module.d.ts +10 -0
  513. package/assets/.gitkeep +0 -0
  514. package/assets/3d-models/pin.mtl +12 -0
  515. package/assets/3d-models/pin.obj +1083 -0
  516. package/assets/colors/ral.json +2345 -0
  517. package/assets/cursors/pencil.png +0 -0
  518. package/assets/cursors/pencil.svg +1 -0
  519. package/assets/fonts/helvetiker_regular.ttf +0 -0
  520. package/assets/fonts/helvetiker_regular.typeface.json +1 -0
  521. package/assets/fonts/helvetiker_regular.woff +0 -0
  522. package/assets/fonts/optimer_regular.typeface.json +1 -0
  523. package/assets/hdri/TSStudio3Point.hdr +135 -0
  524. package/assets/hdri/ground_MASK.jpg +0 -0
  525. package/assets/hdri/std_env_v2_A.hdr +0 -0
  526. package/assets/hdri/std_env_v2_B.hdr +0 -0
  527. package/assets/hdri/std_env_v2_C.hdr +0 -0
  528. package/assets/hdri/std_env_v2_D.hdr +0 -0
  529. package/assets/hdri/std_env_v2_E.hdr +46 -0
  530. package/assets/icons/add-button.svg +10 -0
  531. package/assets/icons/ar_circle.svg +7 -0
  532. package/assets/icons/arrow_point_down.svg +6 -0
  533. package/assets/icons/brush.svg +1 -0
  534. package/assets/icons/cart-shopping-regular.svg +1 -0
  535. package/assets/icons/check.svg +6 -0
  536. package/assets/icons/cit_powered_white.svg +92 -0
  537. package/assets/icons/conf_frame.svg +1 -0
  538. package/assets/icons/conf_plane.svg +1 -0
  539. package/assets/icons/cross.svg +1 -0
  540. package/assets/icons/cube-outline.svg +1 -0
  541. package/assets/icons/cube-unfolded.svg +1 -0
  542. package/assets/icons/delete-button.svg +16 -0
  543. package/assets/icons/download.svg +4 -0
  544. package/assets/icons/edit-button.svg +18 -0
  545. package/assets/icons/google-cardboard-orange.svg +1 -0
  546. package/assets/icons/google-cardboard.svg +1 -0
  547. package/assets/icons/hand-pointer.svg +1 -0
  548. package/assets/icons/height_adjust.svg +1 -0
  549. package/assets/icons/magic-wand.svg +57 -0
  550. package/assets/icons/magnifier.svg +12 -0
  551. package/assets/icons/measurements.svg +1 -0
  552. package/assets/icons/move-phone-ar.svg +4 -0
  553. package/assets/icons/qrcode.svg +1 -0
  554. package/assets/icons/street-view-orange.svg +5 -0
  555. package/assets/icons/street-view.svg +6 -0
  556. package/assets/icons/swap-button.svg +12 -0
  557. package/assets/icons/tilt-phone.svg +29 -0
  558. package/assets/icons/triangle_down.svg +1 -0
  559. package/assets/icons/triangle_up.svg +1 -0
  560. package/assets/images/colijn-logo.webp +0 -0
  561. package/assets/images/favicon.ico +0 -0
  562. package/assets/images/favicon.png +0 -0
  563. package/assets/images/ione360-logo.webp +0 -0
  564. package/assets/images/logo.svg +35 -0
  565. package/assets/workers/indexedDB-web-worker.js +74 -0
  566. package/bundle-styles.scss +267 -0
  567. package/bundles/colijnit-homedecorator.umd.js +47374 -0
  568. package/bundles/colijnit-homedecorator.umd.js.map +1 -0
  569. package/colijnit-homedecorator.d.ts +5 -0
  570. package/environments/environment.d.ts +11 -0
  571. package/esm2015/app/app.version.js +9 -0
  572. package/esm2015/app/core/components/debug/debug.component.js +57 -0
  573. package/esm2015/app/core/components/error/error-message.component.js +55 -0
  574. package/esm2015/app/core/components/tooltip/tooltip.component.js +73 -0
  575. package/esm2015/app/core/const/dimensioning.js +28 -0
  576. package/esm2015/app/core/core.module.js +159 -0
  577. package/esm2015/app/core/directive/autofocus.directive.js +26 -0
  578. package/esm2015/app/core/directive/tooltip.directive.js +64 -0
  579. package/esm2015/app/core/directive/visibility-observer-master.directive.js +53 -0
  580. package/esm2015/app/core/directive/visibility-observer.directive.js +54 -0
  581. package/esm2015/app/core/enum/configuration-key.enum.js +37 -0
  582. package/esm2015/app/core/enum/export-type.enum.js +7 -0
  583. package/esm2015/app/core/enum/google-tag-manager-event.enum.js +14 -0
  584. package/esm2015/app/core/enum/icon-name.enum.js +17 -0
  585. package/esm2015/app/core/enum/icon.enum.js +35 -0
  586. package/esm2015/app/core/enum/light.enum.js +9 -0
  587. package/esm2015/app/core/enum/message-type.enum.js +71 -0
  588. package/esm2015/app/core/enum/model-type.enum.js +8 -0
  589. package/esm2015/app/core/enum/output-encoding.enum.js +6 -0
  590. package/esm2015/app/core/enum/shadow-map-type.enum.js +8 -0
  591. package/esm2015/app/core/enum/user-role-type.enum.js +22 -0
  592. package/esm2015/app/core/enum/view-mode.enum.js +11 -0
  593. package/esm2015/app/core/enum/xr-mode.enum.js +6 -0
  594. package/esm2015/app/core/interface/adjustable-element.interface.js +2 -0
  595. package/esm2015/app/core/interface/category.interface.js +2 -0
  596. package/esm2015/app/core/interface/changes.interface.js +2 -0
  597. package/esm2015/app/core/interface/child-params.interface.js +2 -0
  598. package/esm2015/app/core/interface/configuration-data.interface.js +2 -0
  599. package/esm2015/app/core/interface/external-settings.interface.js +2 -0
  600. package/esm2015/app/core/interface/info-dialog-data.interface.js +2 -0
  601. package/esm2015/app/core/interface/light-preset.interface.js +2 -0
  602. package/esm2015/app/core/interface/loading-overlay-data.interface.js +2 -0
  603. package/esm2015/app/core/interface/media-resource.interface.js +2 -0
  604. package/esm2015/app/core/interface/message-with-payload.interface.js +2 -0
  605. package/esm2015/app/core/interface/message-without-payload.interface.js +2 -0
  606. package/esm2015/app/core/interface/preset.interface.js +2 -0
  607. package/esm2015/app/core/interface/selected-floor-event.interface.js +2 -0
  608. package/esm2015/app/core/interface/selected-wall-event.interface.js +2 -0
  609. package/esm2015/app/core/interface/texture.interface.js +2 -0
  610. package/esm2015/app/core/interface/toolbar-icon.interface.js +2 -0
  611. package/esm2015/app/core/model/ar-position-indicator.js +21 -0
  612. package/esm2015/app/core/model/camera-settings.js +14 -0
  613. package/esm2015/app/core/model/category.js +15 -0
  614. package/esm2015/app/core/model/custom-button.js +16 -0
  615. package/esm2015/app/core/model/error-message.js +9 -0
  616. package/esm2015/app/core/model/export-object.js +3 -0
  617. package/esm2015/app/core/model/from-intersection-observer.js +64 -0
  618. package/esm2015/app/core/model/homedecorator-settings-options.js +49 -0
  619. package/esm2015/app/core/model/homedecorator-settings.js +22 -0
  620. package/esm2015/app/core/model/icon.js +34 -0
  621. package/esm2015/app/core/model/light-preset.js +59 -0
  622. package/esm2015/app/core/model/light-properties.js +45 -0
  623. package/esm2015/app/core/model/media-resource.js +10 -0
  624. package/esm2015/app/core/model/preset.js +15 -0
  625. package/esm2015/app/core/model/ral-color.js +2 -0
  626. package/esm2015/app/core/model/shadow-properties.js +10 -0
  627. package/esm2015/app/core/model/texture-type.js +8 -0
  628. package/esm2015/app/core/model/texture.js +58 -0
  629. package/esm2015/app/core/model/three-object.js +2 -0
  630. package/esm2015/app/core/model/toast-type.js +7 -0
  631. package/esm2015/app/core/model/toast.js +7 -0
  632. package/esm2015/app/core/model/xr-reticle.js +87 -0
  633. package/esm2015/app/core/pipe/append.pipe.js +21 -0
  634. package/esm2015/app/core/pipe/cm-to-measure.pipe.js +20 -0
  635. package/esm2015/app/core/pipe/filter.pipe.js +20 -0
  636. package/esm2015/app/core/pipe/keys.pipe.js +22 -0
  637. package/esm2015/app/core/pipe/localize.pipe.js +28 -0
  638. package/esm2015/app/core/pipe/m-to-measure.pipe.js +20 -0
  639. package/esm2015/app/core/pipe/prepend.pipe.js +21 -0
  640. package/esm2015/app/core/pipe/scm-to-measure.pipe.js +20 -0
  641. package/esm2015/app/core/pipe/sm-to-measure.pipe.js +20 -0
  642. package/esm2015/app/core/pipe/strip-html.pipe.js +17 -0
  643. package/esm2015/app/core/service/3dm-api.js +246 -0
  644. package/esm2015/app/core/service/app-state.service.js +128 -0
  645. package/esm2015/app/core/service/configuration.service.js +72 -0
  646. package/esm2015/app/core/service/debug.service.js +45 -0
  647. package/esm2015/app/core/service/dimensioning.service.js +45 -0
  648. package/esm2015/app/core/service/dynamic-camera.service.js +107 -0
  649. package/esm2015/app/core/service/environment.service.js +17 -0
  650. package/esm2015/app/core/service/error.service.js +30 -0
  651. package/esm2015/app/core/service/export.service.js +97 -0
  652. package/esm2015/app/core/service/file.service.js +44 -0
  653. package/esm2015/app/core/service/homedecorator-app-event.service.js +27 -0
  654. package/esm2015/app/core/service/homedecorator-app.service.js +201 -0
  655. package/esm2015/app/core/service/homedecorator-connector-adapter.service.js +455 -0
  656. package/esm2015/app/core/service/homedecorator-connector.service.js +604 -0
  657. package/esm2015/app/core/service/homedecorator-dictionary.service.js +73 -0
  658. package/esm2015/app/core/service/homedecorator-icon-cache.service.js +43 -0
  659. package/esm2015/app/core/service/homedecorator-settings.service.js +146 -0
  660. package/esm2015/app/core/service/homedecorator.service.js +37 -0
  661. package/esm2015/app/core/service/integration.service.js +56 -0
  662. package/esm2015/app/core/service/item-serialization.service.js +188 -0
  663. package/esm2015/app/core/service/json-utils.service.js +56 -0
  664. package/esm2015/app/core/service/message-bus.service.js +28 -0
  665. package/esm2015/app/core/service/permanent-store.service.js +135 -0
  666. package/esm2015/app/core/service/presets.service.js +297 -0
  667. package/esm2015/app/core/service/progress.service.js +74 -0
  668. package/esm2015/app/core/service/ral.service.js +98 -0
  669. package/esm2015/app/core/service/skip-button-info.service.js +60 -0
  670. package/esm2015/app/core/service/toast.service.js +23 -0
  671. package/esm2015/app/core/service/utils.service.js +566 -0
  672. package/esm2015/app/core/service/view-mode.service.js +61 -0
  673. package/esm2015/app/core/service/web-worker.service.js +44 -0
  674. package/esm2015/app/core/utils/clone-utils.js +41 -0
  675. package/esm2015/app/core/utils/color.utils.js +20 -0
  676. package/esm2015/app/core/utils/file.utils.js +234 -0
  677. package/esm2015/app/core/utils/function/is-empty.function.js +5 -0
  678. package/esm2015/app/core/utils/function/is-nill.function.js +5 -0
  679. package/esm2015/app/core/utils/material.utils.js +407 -0
  680. package/esm2015/app/core/utils/object.utils.js +191 -0
  681. package/esm2015/app/core/utils/relative-position.utils.js +74 -0
  682. package/esm2015/app/core/utils/variation-utils.js +314 -0
  683. package/esm2015/app/core/workers/enum/web-worker-message.enum.js +6 -0
  684. package/esm2015/app/core/workers/enum/web-worker-type.enum.js +5 -0
  685. package/esm2015/app/development/components/selected-child-material-texture.component.js +467 -0
  686. package/esm2015/app/development/components/selected-child-material.component.js +863 -0
  687. package/esm2015/app/development/components/selected-child.component.js +64 -0
  688. package/esm2015/app/development/components/selected-object-base.js +127 -0
  689. package/esm2015/app/development/components/selected-object.component.js +98 -0
  690. package/esm2015/app/development/development.module.js +74 -0
  691. package/esm2015/app/development/directive/development.directive.js +92 -0
  692. package/esm2015/app/development/service/development.service.js +212 -0
  693. package/esm2015/app/homedecorator.component.js +285 -0
  694. package/esm2015/app/homedecorator.module.js +60 -0
  695. package/esm2015/app/plugins/core3d/collision-manager/collision-manager.service.js +119 -0
  696. package/esm2015/app/plugins/core3d/collision-manager/floorplan-collision-detection.js +158 -0
  697. package/esm2015/app/plugins/core3d/collision-manager/snapping-collision.service.js +234 -0
  698. package/esm2015/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-buttons/ar-gui-buttons.component.js +36 -0
  699. package/esm2015/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-configurator/ar-gui-configurator.component.js +49 -0
  700. package/esm2015/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-context-menu/ar-gui-context-menu.component.js +77 -0
  701. package/esm2015/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-elements/ar-gui-notifications/ar-gui-notifications.component.js +26 -0
  702. package/esm2015/app/plugins/core3d/components/ar-gui/ar-gui-root/ar-gui-root.component.js +46 -0
  703. package/esm2015/app/plugins/core3d/components/lightplan/edit-light/edit-light.component.js +197 -0
  704. package/esm2015/app/plugins/core3d/components/lightplan/edit-lightplan/edit-lightplan.component.js +197 -0
  705. package/esm2015/app/plugins/core3d/components/lightplan/lightplan.component.js +512 -0
  706. package/esm2015/app/plugins/core3d/components/scene-options/scene-options.component.js +88 -0
  707. package/esm2015/app/plugins/core3d/core/angles.js +19 -0
  708. package/esm2015/app/plugins/core3d/core/corner-utils.js +9 -0
  709. package/esm2015/app/plugins/core3d/core/dimensioning.js +79 -0
  710. package/esm2015/app/plugins/core3d/core/utils.js +606 -0
  711. package/esm2015/app/plugins/core3d/core3d/components/scenecontrol/scene-control.component.js +289 -0
  712. package/esm2015/app/plugins/core3d/core3d/core3d.component.js +243 -0
  713. package/esm2015/app/plugins/core3d/core3d.module.js +201 -0
  714. package/esm2015/app/plugins/core3d/directive/scene.directive.js +41 -0
  715. package/esm2015/app/plugins/core3d/enum/ar-feature.enum.js +14 -0
  716. package/esm2015/app/plugins/core3d/enum/direction.enum.js +10 -0
  717. package/esm2015/app/plugins/core3d/enum/result-type.enum.js +21 -0
  718. package/esm2015/app/plugins/core3d/hud/bounding-measurement-box/bounding-box-measurement.js +99 -0
  719. package/esm2015/app/plugins/core3d/hud/bounding-measurement-box/box-measurement.js +35 -0
  720. package/esm2015/app/plugins/core3d/hud/bounding-measurement-box/door-or-window-box-measurement.js +95 -0
  721. package/esm2015/app/plugins/core3d/hud/bounding-measurement-box/measurable.js +2 -0
  722. package/esm2015/app/plugins/core3d/hud/bounding-measurement-box/measurement-utils.js +22 -0
  723. package/esm2015/app/plugins/core3d/hud/custom-shape-name-label.js +31 -0
  724. package/esm2015/app/plugins/core3d/hud/floor-indicator.js +80 -0
  725. package/esm2015/app/plugins/core3d/hud/furniture-measurements.js +44 -0
  726. package/esm2015/app/plugins/core3d/hud/indicator-factory.js +49 -0
  727. package/esm2015/app/plugins/core3d/hud/measurements.js +165 -0
  728. package/esm2015/app/plugins/core3d/hud/on-wall-measurements.js +80 -0
  729. package/esm2015/app/plugins/core3d/hud/opening-symbol.js +74 -0
  730. package/esm2015/app/plugins/core3d/hud/rotation-helper.js +263 -0
  731. package/esm2015/app/plugins/core3d/hud/utils.js +30 -0
  732. package/esm2015/app/plugins/core3d/interface/dragged-data.interface.js +2 -0
  733. package/esm2015/app/plugins/core3d/interface/edge-visibility-changes.js +2 -0
  734. package/esm2015/app/plugins/core3d/interface/model.interface.js +2 -0
  735. package/esm2015/app/plugins/core3d/interface/opening.interface.js +2 -0
  736. package/esm2015/app/plugins/core3d/interface/scene-option-button.interface.js +6 -0
  737. package/esm2015/app/plugins/core3d/interface/scene-update.interface.js +2 -0
  738. package/esm2015/app/plugins/core3d/items/base-item.js +233 -0
  739. package/esm2015/app/plugins/core3d/items/custom-cylinder-floor-item.js +41 -0
  740. package/esm2015/app/plugins/core3d/items/custom-cylinder-wall-item.js +45 -0
  741. package/esm2015/app/plugins/core3d/items/custom-floor-item.js +11 -0
  742. package/esm2015/app/plugins/core3d/items/custom-objects.js +295 -0
  743. package/esm2015/app/plugins/core3d/items/custom-shape-floor-item.js +45 -0
  744. package/esm2015/app/plugins/core3d/items/custom-shape-wall-item.js +37 -0
  745. package/esm2015/app/plugins/core3d/items/custom-wall-floor-item.js +84 -0
  746. package/esm2015/app/plugins/core3d/items/custom-wall-item.js +11 -0
  747. package/esm2015/app/plugins/core3d/items/factory.js +130 -0
  748. package/esm2015/app/plugins/core3d/items/floor-item.js +29 -0
  749. package/esm2015/app/plugins/core3d/items/floor-pin.js +31 -0
  750. package/esm2015/app/plugins/core3d/items/floor-plane-item.js +95 -0
  751. package/esm2015/app/plugins/core3d/items/furniture.js +2 -0
  752. package/esm2015/app/plugins/core3d/items/in-wall-floor-item.js +14 -0
  753. package/esm2015/app/plugins/core3d/items/item-group.js +160 -0
  754. package/esm2015/app/plugins/core3d/items/item-type.js +23 -0
  755. package/esm2015/app/plugins/core3d/items/item.js +388 -0
  756. package/esm2015/app/plugins/core3d/items/metadata.js +2 -0
  757. package/esm2015/app/plugins/core3d/items/on-floor-item.js +10 -0
  758. package/esm2015/app/plugins/core3d/items/pin.js +2 -0
  759. package/esm2015/app/plugins/core3d/items/three-mesh.js +17 -0
  760. package/esm2015/app/plugins/core3d/items/wall-floor-item.js +9 -0
  761. package/esm2015/app/plugins/core3d/items/wall-objects.js +2381 -0
  762. package/esm2015/app/plugins/core3d/items/wall-pin.js +25 -0
  763. package/esm2015/app/plugins/core3d/model/ar-parameters.js +12 -0
  764. package/esm2015/app/plugins/core3d/model/box-skin-default.js +17 -0
  765. package/esm2015/app/plugins/core3d/model/collision-info.js +2 -0
  766. package/esm2015/app/plugins/core3d/model/custom-floor-group-result.js +13 -0
  767. package/esm2015/app/plugins/core3d/model/cylinder-skin-default.js +14 -0
  768. package/esm2015/app/plugins/core3d/model/dragged-status.js +51 -0
  769. package/esm2015/app/plugins/core3d/model/face.js +18 -0
  770. package/esm2015/app/plugins/core3d/model/geometry.js +52 -0
  771. package/esm2015/app/plugins/core3d/model/scene-event.enum.js +12 -0
  772. package/esm2015/app/plugins/core3d/model/skin.js +2 -0
  773. package/esm2015/app/plugins/core3d/model/threed-model.js +49 -0
  774. package/esm2015/app/plugins/core3d/service/ar.service.js +844 -0
  775. package/esm2015/app/plugins/core3d/service/camera.service.js +340 -0
  776. package/esm2015/app/plugins/core3d/service/ceiling.service.js +104 -0
  777. package/esm2015/app/plugins/core3d/service/controls.js +763 -0
  778. package/esm2015/app/plugins/core3d/service/drag-and-drop.service.js +369 -0
  779. package/esm2015/app/plugins/core3d/service/error-glow.service.js +131 -0
  780. package/esm2015/app/plugins/core3d/service/floor.service.js +229 -0
  781. package/esm2015/app/plugins/core3d/service/font.service.js +27 -0
  782. package/esm2015/app/plugins/core3d/service/hud.service.js +404 -0
  783. package/esm2015/app/plugins/core3d/service/intersection.service.js +55 -0
  784. package/esm2015/app/plugins/core3d/service/item-group.service.js +117 -0
  785. package/esm2015/app/plugins/core3d/service/item.service.js +205 -0
  786. package/esm2015/app/plugins/core3d/service/light-presets.service.js +296 -0
  787. package/esm2015/app/plugins/core3d/service/lights.service.js +190 -0
  788. package/esm2015/app/plugins/core3d/service/message-board.service.js +60 -0
  789. package/esm2015/app/plugins/core3d/service/models.service.js +146 -0
  790. package/esm2015/app/plugins/core3d/service/outline.service.js +150 -0
  791. package/esm2015/app/plugins/core3d/service/rotation.service.js +183 -0
  792. package/esm2015/app/plugins/core3d/service/scene-event.service.js +1000 -0
  793. package/esm2015/app/plugins/core3d/service/scene-options.service.js +24 -0
  794. package/esm2015/app/plugins/core3d/service/scene.service.js +351 -0
  795. package/esm2015/app/plugins/core3d/service/vr.service.js +198 -0
  796. package/esm2015/app/plugins/core3d/service/wall-measurements.service.js +79 -0
  797. package/esm2015/app/plugins/core3d/service/xr.service.js +397 -0
  798. package/esm2015/app/plugins/core3d/textures/DepthDataTexture.js +17 -0
  799. package/esm2015/app/plugins/core3d/walkthrough-camera-controls/walkthrough-camera-controls.component.js +54 -0
  800. package/esm2015/app/plugins/furniture-manager/furniture-library/furniture-library.component.js +92 -0
  801. package/esm2015/app/plugins/furniture-manager/furniture-manager/furniture-manager.component.js +458 -0
  802. package/esm2015/app/plugins/furniture-manager/furniture-manager.module.js +100 -0
  803. package/esm2015/app/plugins/help/help/help.component.js +71 -0
  804. package/esm2015/app/plugins/help/help-dialog/help-dialog.component.js +83 -0
  805. package/esm2015/app/plugins/help/help.module.js +35 -0
  806. package/esm2015/app/plugins/lite-selector/lite-selector/component/animation/animation.component.js +36 -0
  807. package/esm2015/app/plugins/lite-selector/lite-selector/component/answer-card/answer-card.component.js +187 -0
  808. package/esm2015/app/plugins/lite-selector/lite-selector/component/answers-slideout/answers-slideout.component.js +417 -0
  809. package/esm2015/app/plugins/lite-selector/lite-selector/component/color-filter/color-filter.component.js +44 -0
  810. package/esm2015/app/plugins/lite-selector/lite-selector/component/customizer/customizer.component.js +82 -0
  811. package/esm2015/app/plugins/lite-selector/lite-selector/component/image-zoom/image-zoom.component.js +27 -0
  812. package/esm2015/app/plugins/lite-selector/lite-selector/component/selections-summary/selections-summary-line.component.js +148 -0
  813. package/esm2015/app/plugins/lite-selector/lite-selector/component/selections-summary/selections-summary.component.js +167 -0
  814. package/esm2015/app/plugins/lite-selector/lite-selector/component/tag-filter/tag-filter.component.js +25 -0
  815. package/esm2015/app/plugins/lite-selector/lite-selector/lite-selector.component.js +150 -0
  816. package/esm2015/app/plugins/lite-selector/lite-selector/service/customizer.service.js +222 -0
  817. package/esm2015/app/plugins/lite-selector/lite-selector.module.js +108 -0
  818. package/esm2015/app/plugins/model-uploader/model-previewer/model-preview.component.js +470 -0
  819. package/esm2015/app/plugins/model-uploader/model-uploader/model-uploader.component.js +132 -0
  820. package/esm2015/app/plugins/model-uploader/model-uploader.module.js +60 -0
  821. package/esm2015/app/plugins/plugin-interface.js +2 -0
  822. package/esm2015/app/plugins/plugins.module.js +80 -0
  823. package/esm2015/app/plugins/presets/presets/presets.component.js +72 -0
  824. package/esm2015/app/plugins/presets/presets.module.js +33 -0
  825. package/esm2015/app/plugins/product-catalog/own-collection-catalog/product-own-collection.component.js +57 -0
  826. package/esm2015/app/plugins/product-catalog/own-collection-catalog/product-own-collection.module.js +34 -0
  827. package/esm2015/app/plugins/product-catalog/product-catalog/product-catalog.component.js +428 -0
  828. package/esm2015/app/plugins/product-catalog/product-catalog.module.js +61 -0
  829. package/esm2015/app/plugins/render/enum/connection-status.js +8 -0
  830. package/esm2015/app/plugins/render/enum/render-modes.js +7 -0
  831. package/esm2015/app/plugins/render/enum/render-status.js +9 -0
  832. package/esm2015/app/plugins/render/model/camera-position.js +6 -0
  833. package/esm2015/app/plugins/render/model/image-size.js +3 -0
  834. package/esm2015/app/plugins/render/model/lightning.js +3 -0
  835. package/esm2015/app/plugins/render/model/render-data.js +6 -0
  836. package/esm2015/app/plugins/render/model/render-environment.js +3 -0
  837. package/esm2015/app/plugins/render/model/render-parameters.js +15 -0
  838. package/esm2015/app/plugins/render/model/render-queue-item.js +11 -0
  839. package/esm2015/app/plugins/render/model/render-settings.js +12 -0
  840. package/esm2015/app/plugins/render/model/render.js +10 -0
  841. package/esm2015/app/plugins/render/render-controls/render-controls.component.js +89 -0
  842. package/esm2015/app/plugins/render/render-dialog/render-dialog.component.js +318 -0
  843. package/esm2015/app/plugins/render/render.module.js +85 -0
  844. package/esm2015/app/plugins/render/service/new-render.service.js +302 -0
  845. package/esm2015/app/plugins/render/service/render.service.js +650 -0
  846. package/esm2015/app/plugins/room-planner/components/appearance-section/appearance-section.component.js +190 -0
  847. package/esm2015/app/plugins/room-planner/components/color-picker/color-picker.component.js +32 -0
  848. package/esm2015/app/plugins/room-planner/components/custom-cylinder-creator/custom-cylinder-creator.component.js +219 -0
  849. package/esm2015/app/plugins/room-planner/components/custome-shape-creator/custom-shape-creator.component.js +257 -0
  850. package/esm2015/app/plugins/room-planner/components/dimension-input/dimension-input.component.js +66 -0
  851. package/esm2015/app/plugins/room-planner/components/edit-apply/edit-apply.component.js +57 -0
  852. package/esm2015/app/plugins/room-planner/components/edit-parameter/edit-parameter.component.js +79 -0
  853. package/esm2015/app/plugins/room-planner/components/file-drop/file-drop.component.js +107 -0
  854. package/esm2015/app/plugins/room-planner/components/floorplanner/const/defaults.js +57 -0
  855. package/esm2015/app/plugins/room-planner/components/floorplanner/floorplanner-mode.js +11 -0
  856. package/esm2015/app/plugins/room-planner/components/floorplanner/floorplanner.component.js +1303 -0
  857. package/esm2015/app/plugins/room-planner/components/floorplanner/service/floorplan.service.js +536 -0
  858. package/esm2015/app/plugins/room-planner/components/floorplanner/service/room.service.js +330 -0
  859. package/esm2015/app/plugins/room-planner/components/floorplanner/snap-indicator-mode.js +7 -0
  860. package/esm2015/app/plugins/room-planner/components/floorplanner/utils/context.utils.js +53 -0
  861. package/esm2015/app/plugins/room-planner/components/object-library/object-library.component.js +63 -0
  862. package/esm2015/app/plugins/room-planner/components/ral-color-picker/ral-color-picker.component.js +128 -0
  863. package/esm2015/app/plugins/room-planner/components/rgb-color-picker/rgb-color-picker.component.js +37 -0
  864. package/esm2015/app/plugins/room-planner/components/selected-floor/selected-floor.component.js +36 -0
  865. package/esm2015/app/plugins/room-planner/components/selected-object/selected-object.component.js +203 -0
  866. package/esm2015/app/plugins/room-planner/components/selected-threed-object/selected-threed-object.component.js +139 -0
  867. package/esm2015/app/plugins/room-planner/components/selected-wall/selected-wall.component.js +102 -0
  868. package/esm2015/app/plugins/room-planner/components/settings/settings-options.component.js +152 -0
  869. package/esm2015/app/plugins/room-planner/components/settings/settings.component.js +188 -0
  870. package/esm2015/app/plugins/room-planner/components/texture-editor/texture-editor.component.js +617 -0
  871. package/esm2015/app/plugins/room-planner/components/texture-picker/texture-picker.component.js +74 -0
  872. package/esm2015/app/plugins/room-planner/components/wall-length-input/wall-length-input.component.js +48 -0
  873. package/esm2015/app/plugins/room-planner/const/key.js +12 -0
  874. package/esm2015/app/plugins/room-planner/room-planner/room-planner.component.js +1681 -0
  875. package/esm2015/app/plugins/room-planner/room-planner.module.js +233 -0
  876. package/esm2015/app/plugins/threed-in-photo/components/threed-in-photo-scene/threed-in-photo-scene.component.js +43 -0
  877. package/esm2015/app/plugins/threed-in-photo/components/upload-image/upload-image.component.js +61 -0
  878. package/esm2015/app/plugins/threed-in-photo/components/view-control/view-control.component.js +164 -0
  879. package/esm2015/app/plugins/threed-in-photo/models/model-output.js +18 -0
  880. package/esm2015/app/plugins/threed-in-photo/services/threed-in-photo-build.service.js +243 -0
  881. package/esm2015/app/plugins/threed-in-photo/services/threed-in-photo-connection.service.js +50 -0
  882. package/esm2015/app/plugins/threed-in-photo/services/threed-in-photo-control.service.js +33 -0
  883. package/esm2015/app/plugins/threed-in-photo/services/threed-in-photo-event-listeners.service.js +36 -0
  884. package/esm2015/app/plugins/threed-in-photo/services/threed-in-photo-event.service.js +19 -0
  885. package/esm2015/app/plugins/threed-in-photo/services/threed-in-photo-initializer.service.js +53 -0
  886. package/esm2015/app/plugins/threed-in-photo/services/threed-in-photo-render.service.js +61 -0
  887. package/esm2015/app/plugins/threed-in-photo/services/threed-in-photo-scene.service.js +37 -0
  888. package/esm2015/app/plugins/threed-in-photo/services/threed-in-photo-view.service.js +21 -0
  889. package/esm2015/app/plugins/threed-in-photo/threed-in-photo.module.js +67 -0
  890. package/esm2015/app/plugins/threed-in-photo/utils/utils.js +21 -0
  891. package/esm2015/app/plugins/threedselector/element-buttons/element-buttons.component.js +95 -0
  892. package/esm2015/app/plugins/threedselector/element-slider/element-slider.component.js +28 -0
  893. package/esm2015/app/plugins/threedselector/element-toolbar/element-toolbar.component.js +80 -0
  894. package/esm2015/app/plugins/threedselector/threedselector/model/furniture-connected-part-integration.js +3 -0
  895. package/esm2015/app/plugins/threedselector/threedselector/model/furniture-integration.js +13 -0
  896. package/esm2015/app/plugins/threedselector/threedselector/model/furniture-part-integration.js +6 -0
  897. package/esm2015/app/plugins/threedselector/threedselector/model/furniture-part-variation.js +3 -0
  898. package/esm2015/app/plugins/threedselector/threedselector/model/material.js +11 -0
  899. package/esm2015/app/plugins/threedselector/threedselector/model/variation-settings.js +11 -0
  900. package/esm2015/app/plugins/threedselector/threedselector/model/variation.js +3 -0
  901. package/esm2015/app/plugins/threedselector/threedselector/service/animation.service.js +65 -0
  902. package/esm2015/app/plugins/threedselector/threedselector/service/build-furniture.service.js +1343 -0
  903. package/esm2015/app/plugins/threedselector/threedselector/service/dimensions.service.js +183 -0
  904. package/esm2015/app/plugins/threedselector/threedselector/service/element.service.js +373 -0
  905. package/esm2015/app/plugins/threedselector/threedselector/service/light-creation.service.js +35 -0
  906. package/esm2015/app/plugins/threedselector/threedselector/service/load-furniture.service.js +291 -0
  907. package/esm2015/app/plugins/threedselector/threedselector/service/resize.service.js +70 -0
  908. package/esm2015/app/plugins/threedselector/threedselector/service/third-party-model.service.js +156 -0
  909. package/esm2015/app/plugins/threedselector/threedselector/service/threedselector.service.js +101 -0
  910. package/esm2015/app/plugins/threedselector/threedselector/service/variation-cache.service.js +133 -0
  911. package/esm2015/app/plugins/threedselector/threedselector/service/variation.service.js +436 -0
  912. package/esm2015/app/plugins/threedselector/threedselector/threedselector.component.js +1116 -0
  913. package/esm2015/app/plugins/threedselector/threedselector/utils/asset.utils.js +128 -0
  914. package/esm2015/app/plugins/threedselector/threedselector/utils/image.utils.js +33 -0
  915. package/esm2015/app/plugins/threedselector/threedselector/utils/json-parser.utils.js +188 -0
  916. package/esm2015/app/plugins/threedselector/threedselector/utils/scene-3d.utils.js +159 -0
  917. package/esm2015/app/plugins/threedselector/threedselector.module.js +129 -0
  918. package/esm2015/app/plugins/toolbar/download-dialog/download-dialog.component.js +33 -0
  919. package/esm2015/app/plugins/toolbar/draw-dialog/draw-dialog.component.js +279 -0
  920. package/esm2015/app/plugins/toolbar/edit-preset-dialog/edit-preset-dialog.component.js +22 -0
  921. package/esm2015/app/plugins/toolbar/landing-screen-modal/landing-screen-modal.component.js +123 -0
  922. package/esm2015/app/plugins/toolbar/load-from-cloud-dialog/load-from-cloud-dialog.component.js +140 -0
  923. package/esm2015/app/plugins/toolbar/open-dialog/open-dialog.component.js +83 -0
  924. package/esm2015/app/plugins/toolbar/pdf-crop-dialog/pdf-crop-dialog.component.js +92 -0
  925. package/esm2015/app/plugins/toolbar/save-dialog/save-dialog.component.js +146 -0
  926. package/esm2015/app/plugins/toolbar/saved-dialog/saved-dialog.component.js +66 -0
  927. package/esm2015/app/plugins/toolbar/toolbar/limited-mode-message-component/limited-mode-message.component.js +26 -0
  928. package/esm2015/app/plugins/toolbar/toolbar/toolbar.component.js +676 -0
  929. package/esm2015/app/plugins/toolbar/toolbar.module.js +177 -0
  930. package/esm2015/app/service/dynamic-script.service.js +56 -0
  931. package/esm2015/app/service/google-tag-manager.service.js +89 -0
  932. package/esm2015/app/service/local-storage.service.js +93 -0
  933. package/esm2015/app/service/service-locator.service.js +4 -0
  934. package/esm2015/app/shared/base64-images.js +6 -0
  935. package/esm2015/app/shared/button-elevation/button-elevation.component.js +279 -0
  936. package/esm2015/app/shared/button-elevation/button-elevation.module.js +60 -0
  937. package/esm2015/app/shared/camera-settings-dialog/camera-settings-dialog.component.js +197 -0
  938. package/esm2015/app/shared/camera-settings-dialog/camera-settings-dialog.module.js +58 -0
  939. package/esm2015/app/shared/category-library/category-library.component.js +27 -0
  940. package/esm2015/app/shared/category-library/category-library.module.js +39 -0
  941. package/esm2015/app/shared/context-menu/context-menu.component.js +35 -0
  942. package/esm2015/app/shared/context-menu/context-menu.module.js +49 -0
  943. package/esm2015/app/shared/context-menu/item-context-menu/item-context-menu.component.js +93 -0
  944. package/esm2015/app/shared/dialog/dialog.component.js +119 -0
  945. package/esm2015/app/shared/dialog/dialog.module.js +45 -0
  946. package/esm2015/app/shared/dialog/enum/dialog-type.enum.js +8 -0
  947. package/esm2015/app/shared/dialog/interface/dialog-config.interface.js +2 -0
  948. package/esm2015/app/shared/dialog/service/dialog.service.js +21 -0
  949. package/esm2015/app/shared/error-dialog/error-dialog.component.js +24 -0
  950. package/esm2015/app/shared/error-dialog/error-dialog.module.js +30 -0
  951. package/esm2015/app/shared/export-dialog/export-dialog.component.js +68 -0
  952. package/esm2015/app/shared/export-dialog/export-dialog.module.js +35 -0
  953. package/esm2015/app/shared/info-dialog/info-dialog.component.js +54 -0
  954. package/esm2015/app/shared/info-dialog/info-dialog.module.js +37 -0
  955. package/esm2015/app/shared/loader/hd-loader.component.js +24 -0
  956. package/esm2015/app/shared/loader/hd-loader.module.js +33 -0
  957. package/esm2015/app/shared/loading-overlay/dialog/loading-overlay-dialog.component.js +26 -0
  958. package/esm2015/app/shared/loading-overlay/loading-overlay.component.js +55 -0
  959. package/esm2015/app/shared/loading-overlay/loading-overlay.module.js +42 -0
  960. package/esm2015/app/shared/model-dialog/model-dialog-furniture-list.component.js +325 -0
  961. package/esm2015/app/shared/model-dialog/model-dialog.component.js +104 -0
  962. package/esm2015/app/shared/model-dialog/model-dialog.module.js +64 -0
  963. package/esm2015/app/shared/progress-bar/progress-bar.component.js +39 -0
  964. package/esm2015/app/shared/progress-bar/progress-bar.module.js +33 -0
  965. package/esm2015/app/shared/register-dialog/register-dialog.component.js +112 -0
  966. package/esm2015/app/shared/screen-size-analysis/device-size-type.js +7 -0
  967. package/esm2015/app/shared/screen-size-analysis/navigator-type.enum.js +6 -0
  968. package/esm2015/app/shared/screen-size-analysis/screen-size-analysis.service.js +93 -0
  969. package/esm2015/app/shared/screen-size-analysis/screen-size-config.js +7 -0
  970. package/esm2015/app/shared/screen-size-analysis/screen-size-info.js +2 -0
  971. package/esm2015/app/shared/slider-input/slider-input.component.js +35 -0
  972. package/esm2015/app/shared/slider-input/slider-input.module.js +46 -0
  973. package/esm2015/app/shared/toolbar-icon/toolbar-icon.component.js +95 -0
  974. package/esm2015/app/shared/toolbar-icon/toolbar-icon.module.js +38 -0
  975. package/esm2015/app/shared/zoom-controls/zoom-controls.component.js +47 -0
  976. package/esm2015/app/shared/zoom-controls/zoom-controls.module.js +34 -0
  977. package/esm2015/colijnit-homedecorator.js +5 -0
  978. package/esm2015/environments/environment.js +17 -0
  979. package/esm2015/public_api.js +4 -0
  980. package/fesm2015/colijnit-homedecorator.js +45086 -0
  981. package/fesm2015/colijnit-homedecorator.js.map +1 -0
  982. package/homedecorator-globals.scss +361 -0
  983. package/package.json +48 -0
  984. package/palette.scss +32 -0
  985. package/public_api.d.ts +3 -0
  986. package/styles.scss +377 -0
@@ -0,0 +1,2381 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { BoxGeometry, BufferAttribute, BufferGeometry, Color, DoubleSide, Matrix4, Mesh, MeshBasicMaterial, MeshPhysicalMaterial, Path, Quaternion, Shape, ShapeGeometry, SRGBColorSpace, Vector2, Vector3 } from 'three';
11
+ import * as THREE from 'three';
12
+ import { sameTextures } from '../../../core/model/texture';
13
+ import { Item } from './item';
14
+ import { Utils } from '../core/utils';
15
+ import { defaultEdgeColor, defaultWallColor } from '../../room-planner/components/floorplanner/const/defaults';
16
+ import { ThreeMesh } from './three-mesh';
17
+ import { isNill } from '../../../core/utils/function/is-nill.function';
18
+ import { TextureType } from '../../../core/model/texture-type';
19
+ import { MaterialUtils } from '../../../core/utils/material.utils';
20
+ import { ItemType } from './item-type';
21
+ import * as Geometry from '../model/geometry';
22
+ import { ItemGroup } from './item-group';
23
+ /**
24
+ * A Wall is the basic element to create Rooms.
25
+ *
26
+ * Walls consists of two half edges.
27
+ */
28
+ export class Wall {
29
+ /**
30
+ * Constructs a new wall.
31
+ * @param start Start corner.
32
+ * @param end End corner.
33
+ */
34
+ constructor(start, end) {
35
+ this.start = start;
36
+ this.end = end;
37
+ /** Front is the plane from start to end. */
38
+ this.frontEdge = null;
39
+ /** Back is the plane from end to start. */
40
+ this.backEdge = null;
41
+ /** */
42
+ this.orphan = false;
43
+ /** Items attached to this wall */
44
+ this.items = [];
45
+ this.itemsChanged = false;
46
+ /** */
47
+ this.onItems = [];
48
+ /** The front-side color. */
49
+ this.frontColor = defaultWallColor;
50
+ /** The back-side color. */
51
+ this.backColor = defaultWallColor;
52
+ this.id = this.getUuid();
53
+ this.start.attachStart(this);
54
+ this.end.attachEnd(this);
55
+ }
56
+ set height(value) {
57
+ this._height = value;
58
+ if (this.frontEdge) {
59
+ this.frontEdge.height = this._height;
60
+ }
61
+ if (this.backEdge) {
62
+ this.backEdge.height = this._height;
63
+ }
64
+ this.items.forEach((item) => item.reposition());
65
+ this.onItems.forEach((item) => item.reposition());
66
+ }
67
+ get height() {
68
+ return this._height;
69
+ }
70
+ getUuid() {
71
+ return [this.start.id, this.end.id].join();
72
+ }
73
+ showHideWall(show) {
74
+ if (this.frontEdge) {
75
+ this.frontEdge.showHideEdge(show);
76
+ }
77
+ if (this.backEdge) {
78
+ this.backEdge.showHideEdge(show);
79
+ }
80
+ }
81
+ resetFrontBack() {
82
+ if (this.frontEdge) {
83
+ this.frontEdge.disposePlane();
84
+ }
85
+ if (this.backEdge) {
86
+ this.backEdge.disposePlane();
87
+ }
88
+ this.frontEdge = null;
89
+ this.backEdge = null;
90
+ this.orphan = false;
91
+ }
92
+ move(x, y) {
93
+ if (!this.amountWallMoved) {
94
+ this.amountWallMoved = new Vector2();
95
+ }
96
+ const diffX = this.end.x - this.start.x;
97
+ const diffY = this.end.y - this.start.y;
98
+ const prevStartX = this.start.x;
99
+ const prevStartY = this.start.y;
100
+ this.start.move(x, y);
101
+ this.end.move(x + diffX, y + diffY);
102
+ this.amountWallMoved.add(new Vector2(this.start.x - prevStartX, this.start.y - prevStartY));
103
+ }
104
+ relativeMove(dx, dy) {
105
+ this.start.relativeMove(dx, dy);
106
+ this.end.relativeMove(dx, dy);
107
+ }
108
+ fireRedraw() {
109
+ if (this.frontEdge) {
110
+ this.frontEdge.redraw();
111
+ }
112
+ if (this.backEdge) {
113
+ this.backEdge.redraw();
114
+ }
115
+ }
116
+ getStart() {
117
+ return this.start;
118
+ }
119
+ getEnd() {
120
+ return this.end;
121
+ }
122
+ getStartX() {
123
+ return this.start.getX();
124
+ }
125
+ getEndX() {
126
+ return this.end.getX();
127
+ }
128
+ getStartY() {
129
+ return this.start.getY();
130
+ }
131
+ getEndY() {
132
+ return this.end.getY();
133
+ }
134
+ remove() {
135
+ this.start.detachWall(this);
136
+ this.end.detachWall(this);
137
+ this.frontTexture = undefined;
138
+ this.backTexture = undefined;
139
+ }
140
+ setStart(corner) {
141
+ this.start.detachWall(this);
142
+ corner.attachStart(this);
143
+ this.start = corner;
144
+ }
145
+ setEnd(corner) {
146
+ this.end.detachWall(this);
147
+ corner.attachEnd(this);
148
+ this.end = corner;
149
+ }
150
+ distanceFrom(x, y) {
151
+ return Utils.pointDistanceFromLine(x, y, this.getStartX(), this.getStartY(), this.getEndX(), this.getEndY());
152
+ }
153
+ closestPointTo(x, y) {
154
+ return Utils.closestPointOnLine(x, y, this.getStartX(), this.getStartY(), this.getEndX(), this.getEndY());
155
+ }
156
+ isToOrFrom(x, y) {
157
+ return (this.getStartX() === x && this.getStartY() === y) ||
158
+ (this.getEndX() === x && this.getEndY() === y);
159
+ }
160
+ /** Return the corner opposite of the one provided.
161
+ * @param corner The given corner.
162
+ * @returns The opposite corner.
163
+ */
164
+ _oppositeCorner(corner) {
165
+ if (this.start === corner) {
166
+ return this.end;
167
+ }
168
+ else if (this.end === corner) {
169
+ return this.start;
170
+ }
171
+ else {
172
+ console.log('Wall does not connect to corner');
173
+ }
174
+ }
175
+ get length() {
176
+ return Utils.distance(this.getStartX(), this.getStartY(), this.getEndX(), this.getEndY());
177
+ }
178
+ get edgesLengths() {
179
+ const lengths = [];
180
+ if (this.frontEdge) {
181
+ lengths.push(this.frontEdge.interiorDistance());
182
+ }
183
+ if (this.backEdge) {
184
+ lengths.push(this.backEdge.interiorDistance());
185
+ }
186
+ return lengths;
187
+ }
188
+ updateInWallItems() {
189
+ this.items.filter(item => item instanceof InWallItem).forEach((item) => item.onWallUpdated(this));
190
+ }
191
+ updateWallItems() {
192
+ this.items.filter(item => item instanceof WallItem).forEach((item) => item.onWallMoved(this));
193
+ this.onItems.filter(item => item instanceof WallItem || item instanceof WallItemGroup).forEach((item) => item.onWallMoved(this));
194
+ this.amountWallMoved = undefined;
195
+ }
196
+ getItems() {
197
+ return this.items;
198
+ }
199
+ getWallItems() {
200
+ return this.items.filter(item => item instanceof WallItem);
201
+ }
202
+ get side() {
203
+ if (this.frontEdge && this.backEdge) {
204
+ return THREE.DoubleSide;
205
+ }
206
+ else if (this.frontEdge) {
207
+ return THREE.FrontSide;
208
+ }
209
+ else if (this.backEdge) {
210
+ return THREE.BackSide;
211
+ }
212
+ }
213
+ addItem(item) {
214
+ this.items.push(item);
215
+ this.itemsChanged = true;
216
+ }
217
+ removeItem(item) {
218
+ this.items = this.items.filter(i => i !== item);
219
+ this.itemsChanged = true;
220
+ }
221
+ addOnItem(item) {
222
+ this.onItems.push(item);
223
+ this.itemsChanged = true;
224
+ }
225
+ removeOnItem(item) {
226
+ this.onItems = this.onItems.filter(i => i !== item);
227
+ this.itemsChanged = true;
228
+ }
229
+ }
230
+ /**
231
+ * Corners are used to define Walls.
232
+ */
233
+ export class Corner {
234
+ /** Constructs a corner.
235
+ * @param x X coordinate.
236
+ * @param y Y coordinate.
237
+ * @param id An optional unique id. If not set, created internally.
238
+ */
239
+ constructor(x, y, id) {
240
+ this.x = x;
241
+ this.y = y;
242
+ this.id = id;
243
+ /** Array of start walls. */
244
+ this.wallStarts = [];
245
+ /** Array of end walls. */
246
+ this.wallEnds = [];
247
+ this.id = id || Utils.guid();
248
+ }
249
+ absorbWallsFrom(corner) {
250
+ for (let i = corner.wallStarts.length - 1; i >= 0; i--) {
251
+ corner.wallStarts[i].setStart(this);
252
+ }
253
+ for (let i = corner.wallEnds.length - 1; i >= 0; i--) {
254
+ corner.wallEnds[i].setEnd(this);
255
+ }
256
+ }
257
+ /**
258
+ * @returns
259
+ * @deprecated
260
+ */
261
+ getX() {
262
+ return this.x;
263
+ }
264
+ /**
265
+ * @returns
266
+ * @deprecated
267
+ */
268
+ getY() {
269
+ return this.y;
270
+ }
271
+ /** Moves corner relatively to new position.
272
+ * @param dx The delta x.
273
+ * @param dy The delta y.
274
+ */
275
+ relativeMove(dx, dy) {
276
+ this.move(this.x + dx, this.y + dy);
277
+ }
278
+ /** Removes all walls. */
279
+ removeAll() {
280
+ for (let i = 0; i < this.wallStarts.length; i++) {
281
+ this.wallStarts[i].remove();
282
+ }
283
+ for (let i = 0; i < this.wallEnds.length; i++) {
284
+ this.wallEnds[i].remove();
285
+ }
286
+ }
287
+ /** Moves corner to new position.
288
+ * @param newX The new x position.
289
+ * @param newY The new y position.
290
+ */
291
+ move(newX, newY) {
292
+ this.x = newX;
293
+ this.y = newY;
294
+ }
295
+ /** Gets the adjacent corners.
296
+ * @returns Array of corners.
297
+ */
298
+ adjacentCorners() {
299
+ const retArray = [];
300
+ for (let i = 0; i < this.wallStarts.length; i++) {
301
+ retArray.push(this.wallStarts[i].getEnd());
302
+ }
303
+ for (let i = 0; i < this.wallEnds.length; i++) {
304
+ retArray.push(this.wallEnds[i].getStart());
305
+ }
306
+ return retArray;
307
+ }
308
+ /** Checks if a wall is connected.
309
+ * @param wall A wall.
310
+ * @returns True in case of connection.
311
+ */
312
+ isWallConnected(wall) {
313
+ for (let i = 0; i < this.wallStarts.length; i++) {
314
+ if (this.wallStarts[i] === wall) {
315
+ return true;
316
+ }
317
+ }
318
+ for (let i = 0; i < this.wallEnds.length; i++) {
319
+ if (this.wallEnds[i] === wall) {
320
+ return true;
321
+ }
322
+ }
323
+ return false;
324
+ }
325
+ /**
326
+ *
327
+ */
328
+ distanceFrom(x, y) {
329
+ const distance = Utils.distance(x, y, this.x, this.y);
330
+ return distance;
331
+ }
332
+ /** Gets the distance from a wall.
333
+ * @param wall A wall.
334
+ * @returns The distance.
335
+ */
336
+ distanceFromWall(wall) {
337
+ return wall.distanceFrom(this.x, this.y);
338
+ }
339
+ /** Gets the distance from a corner.
340
+ * @param corner A corner.
341
+ * @returns The distance.
342
+ */
343
+ distanceFromCorner(corner) {
344
+ return this.distanceFrom(corner.x, corner.y);
345
+ }
346
+ /** Detaches a wall.
347
+ * @param wall A wall.
348
+ */
349
+ detachWall(wall) {
350
+ Utils.removeValue(this.wallStarts, wall);
351
+ Utils.removeValue(this.wallEnds, wall);
352
+ }
353
+ /** Attaches a start wall.
354
+ * @param wall A wall.
355
+ */
356
+ attachStart(wall) {
357
+ this.wallStarts.push(wall);
358
+ }
359
+ /** Attaches an end wall.
360
+ * @param wall A wall.
361
+ */
362
+ attachEnd(wall) {
363
+ this.wallEnds.push(wall);
364
+ }
365
+ /** Get wall to corner.
366
+ * @param corner A corner.
367
+ * @return The associated wall or null.
368
+ */
369
+ wallTo(corner) {
370
+ for (let i = 0; i < this.wallStarts.length; i++) {
371
+ if (this.wallStarts[i].getEnd() === corner) {
372
+ return this.wallStarts[i];
373
+ }
374
+ }
375
+ return null;
376
+ }
377
+ /** Get wall from corner.
378
+ * @param corner A corner.
379
+ * @return The associated wall or null.
380
+ */
381
+ wallFrom(corner) {
382
+ for (let i = 0; i < this.wallEnds.length; i++) {
383
+ if (this.wallEnds[i].getStart() === corner) {
384
+ return this.wallEnds[i];
385
+ }
386
+ }
387
+ return null;
388
+ }
389
+ /** Get wall to or from corner.
390
+ * @param corner A corner.
391
+ * @return The associated wall or null.
392
+ */
393
+ wallToOrFrom(corner) {
394
+ return this.wallTo(corner) || this.wallFrom(corner);
395
+ }
396
+ get startWalls() {
397
+ return this.wallStarts;
398
+ }
399
+ get endWalls() {
400
+ return this.wallEnds;
401
+ }
402
+ /** Ensure we do not have duplicate walls (i.e. same start and end points) */
403
+ removeDuplicateWalls() {
404
+ // delete the wall between these corners, if it exists
405
+ const wallEndpoints = {};
406
+ const wallStartpoints = {};
407
+ for (let i = this.wallStarts.length - 1; i >= 0; i--) {
408
+ if (this.wallStarts[i].getEnd() === this) {
409
+ // remove zero length wall
410
+ this.wallStarts[i].remove();
411
+ }
412
+ else if (this.wallStarts[i].getEnd().id in wallEndpoints) {
413
+ // remove duplicated wall
414
+ this.wallStarts[i].remove();
415
+ }
416
+ else {
417
+ wallEndpoints[this.wallStarts[i].getEnd().id] = true;
418
+ }
419
+ }
420
+ for (let i = this.wallEnds.length - 1; i >= 0; i--) {
421
+ if (this.wallEnds[i].getStart() === this) {
422
+ // removed zero length wall
423
+ this.wallEnds[i].remove();
424
+ }
425
+ else if (this.wallEnds[i].getStart().id in wallStartpoints) {
426
+ // removed duplicated wall
427
+ this.wallEnds[i].remove();
428
+ }
429
+ else {
430
+ wallStartpoints[this.wallEnds[i].getStart().id] = true;
431
+ }
432
+ }
433
+ // find and remove cycle ~ more than a single wall between 2 corners
434
+ for (const outWall of this.wallStarts) {
435
+ for (const inWall of this.wallEnds) {
436
+ if (outWall.getEnd() === inWall.getStart()) {
437
+ outWall.remove();
438
+ }
439
+ }
440
+ }
441
+ }
442
+ }
443
+ /**
444
+ * Half Edges are created by Room.
445
+ *
446
+ * Once rooms have been identified, Half Edges are created for each interior wall.
447
+ *
448
+ * A wall can have two half edges if it is visible from both sides.
449
+ */
450
+ export class HalfEdge {
451
+ /**
452
+ * Constructs a half edge.
453
+ * @param room The associated room.
454
+ * @param wall The corresponding wall.
455
+ * @param front True if front side.
456
+ */
457
+ constructor(room, wall, front) {
458
+ this.room = room;
459
+ this.wall = wall;
460
+ this.front = front;
461
+ /** used for intersection testing... not convinced this belongs here */
462
+ this.plane = null;
463
+ /** transform from world coords to wall planes (z=0) */
464
+ this.interiorTransform = new Matrix4();
465
+ /** transform from world coords to wall planes (z=0) */
466
+ this.invInteriorTransform = new Matrix4();
467
+ /** transform from world coords to wall planes (z=0) */
468
+ this.exteriorTransform = new Matrix4();
469
+ /** transform from world coords to wall planes (z=0) */
470
+ this.invExteriorTransform = new Matrix4();
471
+ /** */
472
+ this.edges = [];
473
+ this.front = front || false;
474
+ this.offset = wall.thickness / 2.0;
475
+ this.height = wall.height;
476
+ if (this.front) {
477
+ this.wall.frontEdge = this;
478
+ }
479
+ else {
480
+ this.wall.backEdge = this;
481
+ }
482
+ this.wall.updateInWallItems();
483
+ }
484
+ /** When height of walls are modified, plane should be recreated */
485
+ set height(value) {
486
+ this._height = value;
487
+ this.disposePlane();
488
+ this.generatePlane();
489
+ }
490
+ get height() {
491
+ return this._height;
492
+ }
493
+ showHideEdge(show) {
494
+ this.edges.forEach(e => e.showHideEdge(show));
495
+ }
496
+ updateVisibility(cameraPosition) {
497
+ let visibilityChanged = null;
498
+ this.edges.forEach(e => {
499
+ const edgeVisibilityChanged = e.updateVisibility(cameraPosition);
500
+ if (edgeVisibilityChanged !== null) {
501
+ visibilityChanged = edgeVisibilityChanged;
502
+ }
503
+ });
504
+ return visibilityChanged;
505
+ }
506
+ updateVisiblity(visibility) {
507
+ this.edges.forEach(e => {
508
+ e.visible = visibility;
509
+ e.updateObjectVisibility();
510
+ e.setAllPlanesVisible();
511
+ });
512
+ }
513
+ redraw() {
514
+ return __awaiter(this, void 0, void 0, function* () {
515
+ // this.edges.forEach(e => e.redraw());
516
+ for (let i = 0; i < this.edges.length; i++) {
517
+ yield this.edges[i].redraw();
518
+ }
519
+ });
520
+ }
521
+ /**
522
+ *
523
+ */
524
+ getTexture() {
525
+ if (this.front) {
526
+ return this.wall.frontTexture;
527
+ }
528
+ else {
529
+ return this.wall.backTexture;
530
+ }
531
+ }
532
+ getColor() {
533
+ if (this.front) {
534
+ return this.wall.frontColor;
535
+ }
536
+ else {
537
+ return this.wall.backColor;
538
+ }
539
+ }
540
+ /**
541
+ *
542
+ */
543
+ setTexture(texture) {
544
+ return __awaiter(this, void 0, void 0, function* () {
545
+ if (texture) {
546
+ texture.roughness = !isNill(texture.roughness) ? texture.roughness : 0.8;
547
+ }
548
+ if (this.front) {
549
+ this.wall.frontTexture = texture;
550
+ this.wall.frontColor = defaultWallColor;
551
+ }
552
+ else {
553
+ this.wall.backTexture = texture;
554
+ this.wall.backColor = defaultWallColor;
555
+ }
556
+ // this.redrawCallbacks.fire();
557
+ yield this.redraw();
558
+ });
559
+ }
560
+ setColor(value) {
561
+ if (this.front) {
562
+ this.wall.frontTexture = null;
563
+ this.wall.frontColor = value;
564
+ }
565
+ else {
566
+ this.wall.backTexture = null;
567
+ this.wall.backColor = value;
568
+ }
569
+ // this.redrawCallbacks.fire();
570
+ this.redraw();
571
+ }
572
+ /**
573
+ * this feels hacky, but need wall items
574
+ */
575
+ generatePlane() {
576
+ function transformCorner(corner) {
577
+ return new Vector3(corner.x, 0, corner.y);
578
+ }
579
+ this.offset = this.wall.thickness / 2.0;
580
+ this._height = this.wall.height;
581
+ const v1 = transformCorner(this.interiorStart());
582
+ const v2 = transformCorner(this.interiorEnd());
583
+ const v3 = v2.clone();
584
+ v3.y = this.wall.height;
585
+ const v4 = v1.clone();
586
+ v4.y = this.wall.height;
587
+ const geometry = new BufferGeometry().setFromPoints([v1, v2, v3, v4]);
588
+ const faceVertexIndexArray = new Uint16Array([0, 1, 2, 0, 2, 3]);
589
+ const faceBufferAttribute = new BufferAttribute(faceVertexIndexArray, 1);
590
+ geometry.setIndex(faceBufferAttribute);
591
+ geometry.computeVertexNormals();
592
+ geometry.computeBoundingBox();
593
+ this.plane = new ThreeMesh(geometry, new MeshPhysicalMaterial(null));
594
+ this.plane.name = `half-edge-plane-${this.front ? 'front' : 'back'}`;
595
+ this.plane.castShadow = true;
596
+ Utils.setPlaneVisibility(this.plane, true);
597
+ this.plane.userData.edge = this;
598
+ this.computeTransforms(this.interiorTransform, this.invInteriorTransform, this.interiorStart(), this.interiorEnd());
599
+ this.computeTransforms(this.exteriorTransform, this.invExteriorTransform, this.exteriorStart(), this.exteriorEnd());
600
+ }
601
+ disposePlane() {
602
+ if (this.plane) {
603
+ Utils.DisposeObject(this.plane);
604
+ this.plane = null;
605
+ }
606
+ }
607
+ interiorDistance() {
608
+ const start = this.interiorStart();
609
+ const end = this.interiorEnd();
610
+ return Utils.distance(start.x, start.y, end.x, end.y);
611
+ }
612
+ computeTransforms(transform, invTransform, start, end) {
613
+ const v1 = start;
614
+ const v2 = end;
615
+ const angle = Utils.angle(1, 0, v2.x - v1.x, v2.y - v1.y);
616
+ const tt = new Matrix4();
617
+ tt.makeTranslation(-v1.x, 0, -v1.y);
618
+ const tr = new Matrix4();
619
+ tr.makeRotationY(-angle);
620
+ transform.multiplyMatrices(tr, tt);
621
+ invTransform.copy(transform).invert();
622
+ }
623
+ /** Gets the distance from specified point.
624
+ * @param x X coordinate of the point.
625
+ * @param y Y coordinate of the point.
626
+ * @returns The distance.
627
+ */
628
+ distanceTo(x, y) {
629
+ // x, y, x1, y1, x2, y2
630
+ return Utils.pointDistanceFromLine(x, y, this.interiorStart().x, this.interiorStart().y, this.interiorEnd().x, this.interiorEnd().y);
631
+ }
632
+ getStart() {
633
+ if (this.front) {
634
+ return this.wall.getStart();
635
+ }
636
+ else {
637
+ return this.wall.getEnd();
638
+ }
639
+ }
640
+ getEnd() {
641
+ if (this.front) {
642
+ return this.wall.getEnd();
643
+ }
644
+ else {
645
+ return this.wall.getStart();
646
+ }
647
+ }
648
+ getOppositeEdge() {
649
+ if (this.front) {
650
+ return this.wall.backEdge;
651
+ }
652
+ else {
653
+ return this.wall.frontEdge;
654
+ }
655
+ }
656
+ // these return an object with attributes x, y
657
+ interiorEnd() {
658
+ const vec = this.halfAngleVector(this, this.next);
659
+ return new Vector2(this.getEnd().x + vec.x, this.getEnd().y + vec.y);
660
+ }
661
+ interiorStart() {
662
+ const vec = this.halfAngleVector(this.prev, this);
663
+ return new Vector2(this.getStart().x + vec.x, this.getStart().y + vec.y);
664
+ }
665
+ interiorCenter() {
666
+ return new Vector2((this.interiorStart().x + this.interiorEnd().x) / 2.0, (this.interiorStart().y + this.interiorEnd().y) / 2.0);
667
+ }
668
+ exteriorEnd() {
669
+ const vec = this.halfAngleVector(this, this.next);
670
+ return new Vector2(this.getEnd().x - vec.x, this.getEnd().y - vec.y);
671
+ }
672
+ exteriorStart() {
673
+ const vec = this.halfAngleVector(this.prev, this);
674
+ return new Vector2(this.getStart().x - vec.x, this.getStart().y - vec.y);
675
+ }
676
+ /** Get the corners of the half edge.
677
+ * @returns An array of x,y pairs.
678
+ */
679
+ corners() {
680
+ return [this.interiorStart(), this.interiorEnd(),
681
+ this.exteriorEnd(), this.exteriorStart()];
682
+ }
683
+ /**
684
+ * Gets CCW angle from v1 to v2
685
+ */
686
+ halfAngleVector(v1, v2) {
687
+ // make the best of things if we dont have prev or next
688
+ let v1startX;
689
+ let v1startY;
690
+ let v1endX;
691
+ let v1endY;
692
+ let v2startX;
693
+ let v2startY;
694
+ let v2endX;
695
+ let v2endY;
696
+ if (!v1) {
697
+ v1startX = v2.getStart().x - (v2.getEnd().x - v2.getStart().x);
698
+ v1startY = v2.getStart().y - (v2.getEnd().y - v2.getStart().y);
699
+ v1endX = v2.getStart().x;
700
+ v1endY = v2.getStart().y;
701
+ }
702
+ else {
703
+ v1startX = v1.getStart().x;
704
+ v1startY = v1.getStart().y;
705
+ v1endX = v1.getEnd().x;
706
+ v1endY = v1.getEnd().y;
707
+ }
708
+ if (!v2) {
709
+ v2startX = v1.getEnd().x;
710
+ v2startY = v1.getEnd().y;
711
+ v2endX = v1.getEnd().x + (v1.getEnd().x - v1.getStart().x);
712
+ v2endY = v1.getEnd().y + (v1.getEnd().y - v1.getStart().y);
713
+ }
714
+ else {
715
+ v2startX = v2.getStart().x;
716
+ v2startY = v2.getStart().y;
717
+ v2endX = v2.getEnd().x;
718
+ v2endY = v2.getEnd().y;
719
+ }
720
+ // CCW angle between edges
721
+ const theta = Utils.angle2pi(v1startX - v1endX, v1startY - v1endY, v2endX - v1endX, v2endY - v1endY);
722
+ // cosine and sine of half angle
723
+ const cs = Math.cos(theta / 2.0);
724
+ const sn = Math.sin(theta / 2.0);
725
+ // rotate v2
726
+ const v2dx = v2endX - v2startX;
727
+ const v2dy = v2endY - v2startY;
728
+ const vx = v2dx * cs - v2dy * sn;
729
+ const vy = v2dx * sn + v2dy * cs;
730
+ // normalize
731
+ const mag = Utils.distance(0, 0, vx, vy);
732
+ const desiredMag = (this.offset) / sn;
733
+ const scalar = desiredMag / mag;
734
+ return new Vector2(vx * scalar, vy * scalar);
735
+ }
736
+ get invExteriorQuaternion() {
737
+ const quaternion = new Quaternion();
738
+ quaternion.setFromRotationMatrix(this.invExteriorTransform);
739
+ return quaternion;
740
+ }
741
+ }
742
+ export class Edge {
743
+ constructor(_halfEdge) {
744
+ this._halfEdge = _halfEdge;
745
+ this._fillerColor = new Color(0xdddddd);
746
+ this._planes = {
747
+ exterior: null,
748
+ interior: null,
749
+ sides: null,
750
+ bottom: null,
751
+ top: null
752
+ };
753
+ this._last = {
754
+ color: null,
755
+ texture: null,
756
+ fillerMaterial: null,
757
+ wallMaterial: null,
758
+ height: null
759
+ };
760
+ if (_halfEdge) {
761
+ this._wall = _halfEdge.wall;
762
+ this._front = _halfEdge.front;
763
+ // this.updatePlanes();
764
+ }
765
+ }
766
+ showHideEdge(show) {
767
+ this._planeList().forEach(p => p.visible = show);
768
+ }
769
+ _planeList() {
770
+ return (this._planes.sides || []).concat([
771
+ this._planes.top,
772
+ this._planes.bottom,
773
+ this._planes.interior,
774
+ this._planes.exterior
775
+ ]).filter(x => x);
776
+ }
777
+ getPlanes() {
778
+ return this._planeList();
779
+ }
780
+ getTopSideFillers() {
781
+ return this._planes.sides.concat([this._planes.top]);
782
+ }
783
+ init() {
784
+ return __awaiter(this, void 0, void 0, function* () {
785
+ // this.halfEdge.redrawCallbacks.add(this.redraw);
786
+ // halfEdge.itemAddedCallbacks.add(updateObjectVisibility);
787
+ // controls.cameraMovedCallbacks.add(updateVisibility);
788
+ yield this.updatePlanes();
789
+ // addToScene();
790
+ });
791
+ }
792
+ redraw() {
793
+ return __awaiter(this, void 0, void 0, function* () {
794
+ yield this.updatePlanes();
795
+ });
796
+ }
797
+ // private removeFromScene() {
798
+ // this.planeList().forEach((plane) => {
799
+ // scene.remove(plane);
800
+ // Utils.disposeObject(plane);
801
+ // });
802
+ // Object.keys(planes).forEach((key: string) => planes[key] = null);
803
+ // Object.keys(last).forEach((key: string) => last[key] = null);
804
+ // }
805
+ // private addToScene() {
806
+ // planeList().forEach((plane) => {
807
+ // scene.add(plane);
808
+ // });
809
+ // updateVisibility();
810
+ // }
811
+ updateVisibility(cameraPosition) {
812
+ // finds the normal from the specified halfEdge
813
+ const start = this._halfEdge.interiorStart();
814
+ const end = this._halfEdge.interiorEnd();
815
+ const x = end.x - start.x;
816
+ const y = end.y - start.y;
817
+ // rotate 90 degrees CCW
818
+ const normal = new Vector3(-y, 0, x);
819
+ normal.normalize();
820
+ // setup camera
821
+ const position = cameraPosition.clone();
822
+ const focus = new Vector3((start.x + end.x) / 2.0, 0, (start.y + end.y) / 2.0);
823
+ const direction = position.sub(focus).normalize();
824
+ // find dot
825
+ const dot = normal.dot(direction);
826
+ // update visible
827
+ const newVisible = (dot >= 0);
828
+ // show or hide plans
829
+ this._planeList().forEach((plane) => Utils.setPlaneVisibility(plane, newVisible));
830
+ if (newVisible !== this.visible) {
831
+ this.visible = newVisible;
832
+ this.updateObjectVisibility();
833
+ return newVisible;
834
+ }
835
+ else {
836
+ return null;
837
+ }
838
+ }
839
+ updateObjectVisibility() {
840
+ this._wall.items.forEach((item) => {
841
+ item.updateEdgeVisibility(this);
842
+ });
843
+ this._wall.onItems.forEach((item) => {
844
+ item.updateEdgeVisibility(this);
845
+ });
846
+ }
847
+ setAllPlanesVisible() {
848
+ this._planeList().forEach((plane) => Utils.setPlaneVisibility(plane, true));
849
+ }
850
+ _addMaterialMap(material, texture) {
851
+ return __awaiter(this, void 0, void 0, function* () {
852
+ const dimensions = new THREE.Vector2(this._halfEdge.interiorDistance(), this._wall.height - this._wall.thickness);
853
+ texture.dimensions = dimensions.multiplyScalar(100);
854
+ switch (texture.type) {
855
+ case TextureType.Image:
856
+ material.map = yield MaterialUtils.FromImage(texture);
857
+ material.map.colorSpace = SRGBColorSpace;
858
+ material.needsUpdate = true;
859
+ break;
860
+ case TextureType.CustomPattern:
861
+ material.map = yield MaterialUtils.CustomTileMapTexture(texture, dimensions);
862
+ material.map.colorSpace = SRGBColorSpace;
863
+ material.needsUpdate = true;
864
+ break;
865
+ case TextureType.Basic:
866
+ material.map = yield MaterialUtils.FromUrl(texture.url, texture.stretch, texture.tileSize, null, null, texture.dimensions, texture.tileRotation);
867
+ material.map.colorSpace = SRGBColorSpace;
868
+ material.needsUpdate = true;
869
+ break;
870
+ case TextureType.PBR:
871
+ material = material;
872
+ if (texture.materializeUrl) {
873
+ yield MaterialUtils.loadMaterializeMaps(material, texture);
874
+ }
875
+ else {
876
+ material.map = yield MaterialUtils.FromUrl(texture.url, texture.stretch, texture.tileSize, texture.repeatX, texture.repeatY, texture.dimensions, texture.tileRotation);
877
+ material.map.colorSpace = SRGBColorSpace;
878
+ material.roughnessMap = texture.roughnessMap ? yield MaterialUtils.FromUrl(texture.roughnessMap, texture.stretch, texture.tileSize, texture.repeatX, texture.repeatY, texture.dimensions, texture.tileRotation) : null;
879
+ material.bumpMap = texture.bumpMap ? yield MaterialUtils.FromUrl(texture.bumpMap, texture.stretch, texture.tileSize, texture.repeatX, texture.repeatY, texture.dimensions, texture.tileRotation) : null;
880
+ material.normalMap = texture.normalMap ? yield MaterialUtils.FromUrl(texture.normalMap, texture.stretch, texture.tileSize, texture.repeatX, texture.repeatY, texture.dimensions, texture.tileRotation) : null;
881
+ material.metalnessMap = texture.metalnessMap ? yield MaterialUtils.FromUrl(texture.metalnessMap, texture.stretch, texture.tileSize, texture.repeatX, texture.repeatY, texture.dimensions, texture.tileRotation) : null;
882
+ material.aoMap = texture.aoMap ? yield MaterialUtils.FromUrl(texture.aoMap, texture.stretch, texture.tileSize, texture.repeatX, texture.repeatY, texture.dimensions, texture.tileRotation) : null;
883
+ material.needsUpdate = true;
884
+ }
885
+ }
886
+ });
887
+ }
888
+ _isValid(startEnd) {
889
+ return !startEnd.find(e => !isFinite(e.x) || !isFinite(e.y));
890
+ }
891
+ _updateFillerMaterial() {
892
+ if (this._fillerMaterial) {
893
+ return this._fillerMaterial;
894
+ }
895
+ const material = new MeshBasicMaterial({
896
+ color: this._fillerColor,
897
+ side: DoubleSide
898
+ });
899
+ return material;
900
+ }
901
+ _updateWallMaterial(texture, color = defaultEdgeColor) {
902
+ return __awaiter(this, void 0, void 0, function* () {
903
+ const isSameColor = color && this._last.color && color === this._last.color;
904
+ const isSameTexture = sameTextures(texture, this._last.texture);
905
+ if (isSameColor && isSameTexture) {
906
+ return this._wallMaterial;
907
+ }
908
+ if (!isSameColor) {
909
+ this._last.color = color;
910
+ }
911
+ if (!isSameTexture) {
912
+ this._last.texture = Object.assign({}, texture);
913
+ }
914
+ let material;
915
+ material = new THREE.MeshPhongMaterial({
916
+ color: color,
917
+ side: THREE.FrontSide
918
+ });
919
+ if (texture) {
920
+ material = new THREE.MeshStandardMaterial({
921
+ color: color,
922
+ side: THREE.FrontSide,
923
+ roughness: !isNill(texture.roughness) ? texture.roughness : 0.8,
924
+ metalness: !isNill(texture.metalness) ? texture.metalness : 0,
925
+ bumpScale: !isNill(texture.bumpScale) ? texture.bumpScale : 1
926
+ });
927
+ yield this._addMaterialMap(material, texture);
928
+ }
929
+ return material;
930
+ });
931
+ }
932
+ _equalLastVec2(plane, paramSuffix) {
933
+ const paramName = `${plane}${paramSuffix}`;
934
+ const getter = this._halfEdge[paramName]();
935
+ return this._last[paramName] &&
936
+ this._halfEdge[paramName] &&
937
+ this._last[paramName].x === getter.x &&
938
+ this._last[paramName].y === getter.y;
939
+ }
940
+ _copyLast(plane, params) {
941
+ params.forEach((param) => {
942
+ const paramName = param === 'InvTransform' ?
943
+ this._invTransformParam(plane) :
944
+ `${plane}${param}`;
945
+ const current = 'function' === typeof this._halfEdge[paramName] ?
946
+ this._halfEdge[paramName]() : this._halfEdge[paramName];
947
+ this._last[paramName] = current;
948
+ });
949
+ }
950
+ _transformParam(plane) {
951
+ return `${plane}Transform`;
952
+ }
953
+ _invTransformParam(plane) {
954
+ return `inv${plane.charAt(0).toUpperCase()}${plane.substr(1)}Transform`;
955
+ }
956
+ _updateMainPlane(plane, material) {
957
+ let updatePlane = this._planes[plane];
958
+ const geo = this._createGeometry(this._halfEdge[`${plane}Start`](), this._halfEdge[`${plane}End`](), this._halfEdge[this._transformParam(plane)], this._halfEdge[this._invTransformParam(plane)]);
959
+ if (!updatePlane) {
960
+ updatePlane = new ThreeMesh(geo, material);
961
+ updatePlane.name = 'edge';
962
+ updatePlane.userData.wall = this._wall;
963
+ updatePlane.castShadow = true;
964
+ updatePlane.receiveShadow = true;
965
+ }
966
+ else {
967
+ updatePlane.geometry = geo;
968
+ updatePlane.material = material;
969
+ updatePlane.material.needsUpdate = true;
970
+ } /* else {
971
+ updatePlane = this.makeWall(
972
+ this.halfEdge[`${plane}Start`](),
973
+ this.halfEdge[`${plane}End`](),
974
+ this.halfEdge[this.transformParam(plane)],
975
+ this.halfEdge[this.invTransformParam(plane)],
976
+ material
977
+ );
978
+ }*/
979
+ return updatePlane;
980
+ // const oldPlane = this.planes[plane];
981
+ // const newPlane = this.makeWall(
982
+ // this.halfEdge[`${plane}Start`](),
983
+ // this.halfEdge[`${plane}End`](),
984
+ // this.halfEdge[this.transformParam(plane)],
985
+ // this.halfEdge[this.invTransformParam(plane)],
986
+ // material
987
+ // );
988
+ // if (oldPlane) {
989
+ // // scene.remove(oldPlane);
990
+ // Utils.disposeObject(oldPlane);
991
+ // }
992
+ // // scene.add(newPlane);
993
+ // return newPlane;
994
+ }
995
+ _updateBottomPlane() {
996
+ const oldPlane = this._planes.bottom;
997
+ if (oldPlane &&
998
+ this._equalLastVec2('interior', 'Start') &&
999
+ this._equalLastVec2('interior', 'End') &&
1000
+ this._equalLastVec2('exterior', 'Start') &&
1001
+ this._equalLastVec2('exterior', 'End')) {
1002
+ return oldPlane;
1003
+ }
1004
+ const newPlane = this._buildFiller(0, this._fillerMaterial);
1005
+ if (oldPlane) {
1006
+ // Dispose function does not actually remove the object from the scene
1007
+ Utils.DisposeObject(oldPlane);
1008
+ oldPlane.visible = false;
1009
+ }
1010
+ // scene.add(newPlane);
1011
+ return newPlane;
1012
+ }
1013
+ _updateTopPlane() {
1014
+ const oldPlane = this._planes.top;
1015
+ if (oldPlane &&
1016
+ this._last.height === this._wall.height &&
1017
+ this._equalLastVec2('interior', 'Start') &&
1018
+ this._equalLastVec2('interior', 'End') &&
1019
+ this._equalLastVec2('exterior', 'Start') &&
1020
+ this._equalLastVec2('exterior', 'End')) {
1021
+ return oldPlane;
1022
+ }
1023
+ if (oldPlane) {
1024
+ // Dispose function does not actually remove the object from the scene
1025
+ Utils.DisposeObject(oldPlane);
1026
+ oldPlane.visible = false;
1027
+ }
1028
+ const newPlane = this._buildFiller(this._wall.height, this._fillerMaterial);
1029
+ // scene.add(newPlane);
1030
+ return newPlane;
1031
+ }
1032
+ _updateSidePlanes() {
1033
+ const oldPlanes = this._planes.sides;
1034
+ if (oldPlanes &&
1035
+ this._last.height === this._wall.height &&
1036
+ this._equalLastVec2('interior', 'Start') &&
1037
+ this._equalLastVec2('interior', 'End') &&
1038
+ this._equalLastVec2('exterior', 'Start') &&
1039
+ this._equalLastVec2('exterior', 'End')) {
1040
+ return oldPlanes;
1041
+ }
1042
+ const newPlanes = [
1043
+ this._buildSideFiller(this._halfEdge.interiorStart(), this._halfEdge.exteriorStart(), this._wall.height, this._fillerMaterial),
1044
+ this._buildSideFiller(this._halfEdge.interiorEnd(), this._halfEdge.exteriorEnd(), this._wall.height, this._fillerMaterial)
1045
+ ];
1046
+ if (oldPlanes) {
1047
+ oldPlanes.forEach(p => {
1048
+ // Dispose function does not actually remove the object from the scene
1049
+ Utils.DisposeObject(p);
1050
+ p.visible = false;
1051
+ });
1052
+ }
1053
+ // newPlanes.forEach(p => scene.add(p));
1054
+ return newPlanes;
1055
+ }
1056
+ updatePlanes() {
1057
+ return __awaiter(this, void 0, void 0, function* () {
1058
+ this._fillerMaterial = this._updateFillerMaterial();
1059
+ if (this._isValid([this._halfEdge.exteriorStart(), this._halfEdge.exteriorEnd()])) {
1060
+ this._planes.exterior = this._updateMainPlane('exterior', this._fillerMaterial);
1061
+ if (this._halfEdge.getTexture() && this._halfEdge.getTexture().type !== TextureType.Image) {
1062
+ this._updateUvs(this._planes.exterior);
1063
+ }
1064
+ }
1065
+ const oldWallMaterial = this._wallMaterial;
1066
+ this._wallMaterial = yield this._updateWallMaterial(this._halfEdge.getTexture(), this._halfEdge.getColor());
1067
+ if (this._isValid([this._halfEdge.interiorStart(), this._halfEdge.interiorEnd()])) {
1068
+ // this.planes.interior = (!oldWallMaterial || oldWallMaterial === this.wallMaterial)
1069
+ // ? this.updateMainPlane('interior', this.wallMaterial)
1070
+ // : this.updateMainPlaneMaterial('interior', this.wallMaterial);
1071
+ this._planes.interior = this._updateMainPlane('interior', this._wallMaterial);
1072
+ if (this._halfEdge.getTexture() && this._halfEdge.getTexture().type !== TextureType.Image) {
1073
+ this._updateUvs(this._planes.interior);
1074
+ }
1075
+ }
1076
+ this._planes.bottom = this._updateBottomPlane();
1077
+ this._planes.top = this._updateTopPlane();
1078
+ this._planes.sides = this._updateSidePlanes();
1079
+ this._last.fillerMaterial = this._fillerMaterial;
1080
+ this._last.wallMaterial = this._wallMaterial;
1081
+ this._last.height = this._wall.height;
1082
+ this._copyLast('exterior', ['Start', 'End', 'Transform', 'InvTransform']);
1083
+ this._copyLast('interior', ['Start', 'End', 'Transform', 'InvTransform']);
1084
+ });
1085
+ }
1086
+ _updateUvs(mesh) {
1087
+ const dimensions = new THREE.Vector2(this._halfEdge.interiorDistance(), this._wall.height - this._wall.thickness).multiplyScalar(100);
1088
+ const ratio = dimensions.x / dimensions.y;
1089
+ let uvY;
1090
+ const tempVector = new Vector2();
1091
+ const uvArray = mesh.geometry.attributes.uv;
1092
+ if (uvArray) {
1093
+ for (let i = 0; i < uvArray.count; i++) {
1094
+ tempVector.fromBufferAttribute(uvArray, i);
1095
+ uvY = tempVector.y;
1096
+ uvY -= 0.5;
1097
+ uvY /= ratio;
1098
+ uvY += 0.5;
1099
+ uvArray.setY(i, uvY);
1100
+ }
1101
+ uvArray.needsUpdate = true;
1102
+ }
1103
+ }
1104
+ // start, end have x and y attributes (i.e. corners)
1105
+ _createGeometry(start, end, transform, invTransform) {
1106
+ const v1 = this._toVec3(start);
1107
+ const v2 = this._toVec3(end);
1108
+ const v3 = v2.clone();
1109
+ v3.y = this._wall.height;
1110
+ const v4 = v1.clone();
1111
+ v4.y = this._wall.height;
1112
+ const points = [v1.clone(), v2.clone(), v3.clone(), v4.clone()];
1113
+ points.forEach((p) => {
1114
+ p.applyMatrix4(transform);
1115
+ });
1116
+ const shape = new Shape([
1117
+ new Vector2(points[0].x, points[0].y),
1118
+ new Vector2(points[1].x, points[1].y),
1119
+ new Vector2(points[2].x, points[2].y),
1120
+ new Vector2(points[3].x, points[3].y)
1121
+ ]);
1122
+ // add holes for each wall item
1123
+ const itemHoles = this._wall.items
1124
+ .filter((item) => !isNaN(item.position.x))
1125
+ .map((item) => {
1126
+ const pos = item.position.clone();
1127
+ pos.applyMatrix4(transform);
1128
+ const halfSize = item.halfSize;
1129
+ const min = halfSize.clone().multiplyScalar(-1);
1130
+ const max = halfSize.clone();
1131
+ min.add(pos);
1132
+ max.add(pos);
1133
+ const holePoints = [
1134
+ new Vector2(min.x, min.y),
1135
+ new Vector2(max.x, min.y),
1136
+ new Vector2(max.x, max.y),
1137
+ new Vector2(min.x, max.y)
1138
+ ];
1139
+ return holePoints;
1140
+ });
1141
+ const polygons = Utils.polygonsUnion(itemHoles);
1142
+ polygons.forEach(holePolygon => shape.holes.push(new Path(holePolygon)));
1143
+ const geometry = new ShapeGeometry(shape);
1144
+ const positionAttribute = geometry.getAttribute('position');
1145
+ const uvAttribute = geometry.getAttribute('uv');
1146
+ Utils.ApplyBufferAttributeMatrixTransform(positionAttribute, invTransform);
1147
+ // make UVs
1148
+ const totalDistance = Utils.distance(v1.x, v1.z, v2.x, v2.z);
1149
+ const height = this._wall.height;
1150
+ function vertexToUv(vertex) {
1151
+ const x = Utils.distance(v1.x, v1.z, vertex.x, vertex.z) / totalDistance;
1152
+ const y = vertex.y / height;
1153
+ return new THREE.Vector2(x, y);
1154
+ }
1155
+ const tempUVArray = [];
1156
+ const positionDataAsVector3Array = Utils.GetVector3ArrayFromBufferAttribute(positionAttribute.clone());
1157
+ positionDataAsVector3Array.forEach((vertex) => {
1158
+ tempUVArray.push(vertexToUv(vertex));
1159
+ });
1160
+ tempUVArray.forEach((uvVector, index) => {
1161
+ uvAttribute.setXY(index, uvVector.x, uvVector.y);
1162
+ });
1163
+ uvAttribute.needsUpdate = true;
1164
+ geometry.computeVertexNormals();
1165
+ return geometry;
1166
+ }
1167
+ _buildSideFiller(p1, p2, height, material) {
1168
+ const points = [
1169
+ this._toVec3(p1),
1170
+ this._toVec3(p2),
1171
+ this._toVec3(p2, height),
1172
+ this._toVec3(p1, height)
1173
+ ];
1174
+ const geometry = new BufferGeometry().setFromPoints(points);
1175
+ const filler = new Mesh(geometry, material);
1176
+ filler.castShadow = true;
1177
+ filler.receiveShadow = true;
1178
+ filler.name = 'edge-side-filler';
1179
+ return filler;
1180
+ }
1181
+ _buildFiller(height, material) {
1182
+ const points = [
1183
+ this._toVec2(this._halfEdge.exteriorStart()),
1184
+ this._toVec2(this._halfEdge.exteriorEnd()),
1185
+ this._toVec2(this._halfEdge.interiorEnd()),
1186
+ this._toVec2(this._halfEdge.interiorStart())
1187
+ ];
1188
+ const shape = new Shape(points);
1189
+ const geometry = new ShapeGeometry(shape);
1190
+ const filler = new Mesh(geometry, material);
1191
+ filler.name = 'edge-filler';
1192
+ filler.castShadow = true;
1193
+ filler.receiveShadow = true;
1194
+ filler.rotation.set(Math.PI / 2, 0, 0);
1195
+ filler.position.y = height;
1196
+ return filler;
1197
+ }
1198
+ _toVec2(pos) {
1199
+ return new Vector2(pos.x, pos.y);
1200
+ }
1201
+ _toVec3(pos, height = 0) {
1202
+ return new Vector3(pos.x, height, pos.y);
1203
+ }
1204
+ }
1205
+ export class Room {
1206
+ // private floorChangeCallbacks = $.Callbacks();
1207
+ constructor(corners, defaultTexture) {
1208
+ this.corners = corners;
1209
+ this.interiorCorners = [];
1210
+ this.edgePointer = null;
1211
+ this.edgeHeights = [];
1212
+ this.floorPlane = null;
1213
+ this.floorColor = 0xcccccc;
1214
+ this.ceilingPlane = null;
1215
+ if (defaultTexture) {
1216
+ this.floorTexture = defaultTexture;
1217
+ }
1218
+ this._setEdgePointer();
1219
+ this._updateInteriorCorners();
1220
+ }
1221
+ dispose() {
1222
+ Utils.DisposeObject(this.floorPlane);
1223
+ Utils.DisposeObject(this.ceilingPlane);
1224
+ }
1225
+ getInteriorCorners() {
1226
+ return this.interiorCorners.map((c) => new Vector2(c.x, c.y));
1227
+ }
1228
+ getUuid() {
1229
+ const cornerUuids = Utils.map(this.corners, function (c) {
1230
+ return c.id;
1231
+ });
1232
+ cornerUuids.sort();
1233
+ return cornerUuids.join();
1234
+ }
1235
+ getTexture() {
1236
+ // const uuid = this.getUuid();
1237
+ // return this.floorplan.getFloorTexture(uuid);
1238
+ return this.floorTexture;
1239
+ }
1240
+ getColor() {
1241
+ // const uuid = this.getUuid();
1242
+ // return this.floorplan.getFloorColor(uuid) || defaultFloorColor;
1243
+ return this.floorColor;
1244
+ }
1245
+ useTexture() {
1246
+ // return defaultFloorColor === this.getColor();
1247
+ }
1248
+ /**
1249
+ * textureStretch always true, just an argument for consistency with walls
1250
+ */
1251
+ // public setTexture(texture: Texture) {
1252
+ // // const uuid = this.getUuid();
1253
+ // // this.floorplan.setFloorTexture(uuid, texture);
1254
+ // // this.floorplan.deleteFloorColor(uuid);
1255
+ // // this.floorChangeCallbacks.fire();
1256
+ // }
1257
+ // public setColor(color: number) {
1258
+ // // const uuid = this.getUuid();
1259
+ // // this.floorplan.deleteFloorTexture(uuid);
1260
+ // // this.floorplan.setFloorColor(uuid, color);
1261
+ // // this.floorChangeCallbacks.fire();
1262
+ // }
1263
+ updateWallHeights() {
1264
+ let edge = this.edgePointer;
1265
+ this.edgeHeights.length = 0;
1266
+ while (true) {
1267
+ this.edgeHeights.push(edge.wall.height);
1268
+ if (edge.next === this.edgePointer) {
1269
+ break;
1270
+ }
1271
+ else {
1272
+ edge = edge.next;
1273
+ }
1274
+ }
1275
+ }
1276
+ setDefaultFloorTexture() {
1277
+ // if (!this._defaultFloorTexture) {
1278
+ // return;
1279
+ // }
1280
+ // const uuid = this.getUuid();
1281
+ // if (!this.floorplan.getFloorTexture(uuid) && !this.floorplan.getFloorColor(uuid)) {
1282
+ // this.setTexture(this._defaultFloorTexture);
1283
+ // }
1284
+ }
1285
+ _updateInteriorCorners() {
1286
+ let edge = this.edgePointer;
1287
+ this.edgeHeights.length = 0;
1288
+ while (true) {
1289
+ this.interiorCorners.push(edge.interiorStart());
1290
+ edge.generatePlane();
1291
+ this.edgeHeights.push(edge.height);
1292
+ if (edge.next === this.edgePointer) {
1293
+ break;
1294
+ }
1295
+ else {
1296
+ edge = edge.next;
1297
+ }
1298
+ }
1299
+ }
1300
+ _setEdgePointer() {
1301
+ let prevEdge = null;
1302
+ let firstEdge = null;
1303
+ for (let i = 0; i < this.corners.length; i++) {
1304
+ const firstCorner = this.corners[i];
1305
+ const secondCorner = this.corners[(i + 1) % this.corners.length];
1306
+ // find if wall is heading in that direction
1307
+ const wallTo = firstCorner.wallTo(secondCorner);
1308
+ const wallFrom = firstCorner.wallFrom(secondCorner);
1309
+ let edge;
1310
+ if (wallTo) {
1311
+ edge = new HalfEdge(this, wallTo, true);
1312
+ }
1313
+ else if (wallFrom) {
1314
+ edge = new HalfEdge(this, wallFrom, false);
1315
+ }
1316
+ else {
1317
+ // something horrible has happened
1318
+ console.log('corners arent connected by a wall, uh oh');
1319
+ }
1320
+ if (i === 0) {
1321
+ firstEdge = edge;
1322
+ }
1323
+ else {
1324
+ edge.prev = prevEdge;
1325
+ prevEdge.next = edge;
1326
+ if (i + 1 === this.corners.length) {
1327
+ firstEdge.prev = edge;
1328
+ edge.next = firstEdge;
1329
+ }
1330
+ }
1331
+ prevEdge = edge;
1332
+ }
1333
+ // hold on to an edge reference
1334
+ this.edgePointer = firstEdge;
1335
+ }
1336
+ get area() {
1337
+ const polygon = this._polygonFromCorners(this.interiorCorners);
1338
+ return Utils.polygonArea(polygon);
1339
+ }
1340
+ get center() {
1341
+ const polygon = this._polygonFromCorners(this.corners);
1342
+ return Utils.polygonCenter(polygon);
1343
+ }
1344
+ _polygonFromCorners(corners) {
1345
+ return corners.map(c => new Vector2(c.x, c.y));
1346
+ }
1347
+ }
1348
+ /**
1349
+ * A Wall Item is an entity to be placed related to a wall.
1350
+ */
1351
+ export class WallItem extends Item {
1352
+ constructor(metadata, object, texture, handlers) {
1353
+ super(metadata, object, texture, handlers);
1354
+ /** The currently applied wall */
1355
+ this.currentWall = null;
1356
+ /** The currently applied wall edge. */
1357
+ this.currentWallEdge = null;
1358
+ /** Used for finding rotations */
1359
+ this._refVec = new THREE.Vector2(0, 1.0);
1360
+ this._positionYTolerance = 0.005;
1361
+ /** */
1362
+ this._wallOffsetScalar = 0;
1363
+ /** */
1364
+ this._sizeX = 0;
1365
+ /** */
1366
+ this._sizeY = 0;
1367
+ this._flipped = false;
1368
+ /** */
1369
+ this.addToWall = false;
1370
+ /** */
1371
+ this.boundToFloor = false;
1372
+ /** */
1373
+ this.frontVisible = false;
1374
+ this.backVisible = false;
1375
+ this._hasFrontEdge = false;
1376
+ this._hasBackEdge = false;
1377
+ this.allowRotate = false;
1378
+ if (texture) {
1379
+ this.setTexture(texture);
1380
+ }
1381
+ }
1382
+ /** */
1383
+ removed() {
1384
+ if (!isNill(this.currentWallEdge) && this.addToWall) {
1385
+ this.currentWallEdge.wall.removeItem(this);
1386
+ this.redrawWall();
1387
+ }
1388
+ }
1389
+ removeFromWall() {
1390
+ if (this.currentWall) {
1391
+ this.currentWall.removeOnItem(this);
1392
+ this.currentWall = undefined;
1393
+ this.currentWallEdge = undefined;
1394
+ }
1395
+ }
1396
+ /**
1397
+ * Only hides item when entire wall is hidden
1398
+ * This prevents items being set hidden for inner walls
1399
+ * */
1400
+ updateEdgeVisibility(edge) {
1401
+ if (this.currentWall) {
1402
+ let shouldShow = false;
1403
+ if (this.currentWall.backEdge) {
1404
+ this.currentWall.backEdge.edges.forEach((e) => {
1405
+ if (e.visible) {
1406
+ shouldShow = true;
1407
+ }
1408
+ });
1409
+ }
1410
+ if (this.currentWall.frontEdge) {
1411
+ this.currentWall.frontEdge.edges.forEach(e => {
1412
+ if (e.visible) {
1413
+ shouldShow = true;
1414
+ }
1415
+ });
1416
+ }
1417
+ this.visible = shouldShow;
1418
+ }
1419
+ }
1420
+ /** */
1421
+ updateSize() {
1422
+ this._wallOffsetScalar = this.getDepth() / 2;
1423
+ this._sizeX = this.getWidth();
1424
+ this._sizeY = this.getHeight();
1425
+ }
1426
+ /** */
1427
+ resized() {
1428
+ if (this.boundToFloor) {
1429
+ this.position.y = this._boundToFloorY();
1430
+ }
1431
+ this.updateSize();
1432
+ this.redrawWall();
1433
+ }
1434
+ /** */
1435
+ placeOnEdge(edge) {
1436
+ if (!edge) {
1437
+ return;
1438
+ }
1439
+ this._onFrontSide = edge.wall.frontEdge === edge;
1440
+ this._changeWallEdge(edge);
1441
+ this.updateSize();
1442
+ // position not set
1443
+ const center = edge.interiorCenter();
1444
+ const newPos = this.positionSet ?
1445
+ (edge.wall.amountWallMoved ? this.position.add(new Vector3(edge.wall.amountWallMoved.x, 0, 0)) : this.position.clone()) :
1446
+ new THREE.Vector3(center.x, edge.wall.height / 2.0, center.y);
1447
+ this._boundMove(newPos);
1448
+ this.position.copy(newPos);
1449
+ this.redrawWall();
1450
+ }
1451
+ reposition() {
1452
+ const newPos = this.position.clone();
1453
+ this._boundMove(newPos);
1454
+ this.position.copy(newPos);
1455
+ }
1456
+ getFloorY() {
1457
+ if (this.halfSize && this.currentWallEdge) {
1458
+ return this._moveToYPosition(this.halfSize.y + this.elevation);
1459
+ }
1460
+ else {
1461
+ return this.position.y;
1462
+ }
1463
+ }
1464
+ isValidPosition(position, rotation, options) {
1465
+ return { valid: !!this.currentWallEdge };
1466
+ }
1467
+ /** */
1468
+ moveToPosition(vec3, intersection) {
1469
+ if (intersection && this.currentWallEdge) {
1470
+ if (intersection.object.userData.edge && intersection.object.userData.edge.wall !== this.currentWallEdge.wall) {
1471
+ this._changeWallEdge(intersection.object.userData.edge);
1472
+ }
1473
+ this._boundMove(vec3);
1474
+ this.position.copy(vec3);
1475
+ this.redrawWall();
1476
+ }
1477
+ }
1478
+ /** */
1479
+ moveTo2dPosition(x, y, edge) {
1480
+ const vec3 = new Vector3(x, this.position.y, y);
1481
+ this._changeWallEdge(edge);
1482
+ this._boundMove(vec3);
1483
+ this.position.copy(vec3);
1484
+ this.redrawWall();
1485
+ }
1486
+ /** */
1487
+ getWallOffset() {
1488
+ return this._wallOffsetScalar;
1489
+ }
1490
+ getStartX() {
1491
+ return this.position.x - this.getSizeX() / 2 * Math.cos(this.rotation.y);
1492
+ }
1493
+ getStartY() {
1494
+ return this.position.z + this.getSizeX() / 2 * Math.sin(this.rotation.y);
1495
+ }
1496
+ getEndX() {
1497
+ return this.position.x + this.getSizeX() / 2 * Math.cos(this.rotation.y);
1498
+ }
1499
+ getEndY() {
1500
+ return this.position.z - this.getSizeX() / 2 * Math.sin(this.rotation.y);
1501
+ }
1502
+ /**
1503
+ @returns x axis size of item's bounding box
1504
+ */
1505
+ getSizeX() {
1506
+ return this._sizeX;
1507
+ }
1508
+ /**
1509
+ @returns y axis size of item's bounding box
1510
+ */
1511
+ getSizeY() {
1512
+ return this._sizeY;
1513
+ }
1514
+ heightUpdated(amount) {
1515
+ if (!isNill(amount)) {
1516
+ this.position.y = this._moveToYPosition(this.position.y + amount);
1517
+ this.redrawWall();
1518
+ }
1519
+ else {
1520
+ super.heightUpdated();
1521
+ }
1522
+ }
1523
+ updateGeometry(width, height) {
1524
+ const geometry = Geometry.wallBox(width, height, this.getItemThickness());
1525
+ this.object.geometry.dispose();
1526
+ const rotation = this.rotation.y;
1527
+ this.rotation.y = 0;
1528
+ // this.initializeGeometry(geometry);
1529
+ this.rotation.y = rotation;
1530
+ this.resized();
1531
+ this.redrawWall();
1532
+ }
1533
+ setTexture(texture) {
1534
+ return __awaiter(this, void 0, void 0, function* () {
1535
+ this.texture = texture && Object.assign({}, texture);
1536
+ return yield this.createMaterial(this.currentWallEdge ? this.currentWallEdge.wall.side : undefined);
1537
+ });
1538
+ }
1539
+ onWallMoved(wall) {
1540
+ if (wall.frontEdge) {
1541
+ this.placeOnEdge(wall.frontEdge);
1542
+ }
1543
+ if (wall.backEdge) {
1544
+ this.placeOnEdge(wall.backEdge);
1545
+ }
1546
+ }
1547
+ updateMaterialVisibility(side = THREE.DoubleSide) {
1548
+ if (!this.texture) {
1549
+ return;
1550
+ }
1551
+ if (this.currentWallEdge) {
1552
+ return;
1553
+ }
1554
+ const isSame = this._isWallSame();
1555
+ if (!isSame) {
1556
+ this.createMaterial(side, isSame);
1557
+ return;
1558
+ }
1559
+ const textureMaterialFront = this.object.material[4];
1560
+ const textureMaterialBack = this.object.material[5];
1561
+ switch (side) {
1562
+ case THREE.DoubleSide:
1563
+ textureMaterialFront.visible = true;
1564
+ textureMaterialBack.visible = true;
1565
+ break;
1566
+ case THREE.FrontSide:
1567
+ textureMaterialFront.visible = this.frontVisible;
1568
+ textureMaterialBack.visible = !this.frontVisible;
1569
+ break;
1570
+ case THREE.BackSide:
1571
+ textureMaterialFront.visible = !this.frontVisible;
1572
+ textureMaterialBack.visible = this.frontVisible;
1573
+ break;
1574
+ }
1575
+ }
1576
+ createTextureMaterial(options) {
1577
+ return __awaiter(this, void 0, void 0, function* () {
1578
+ const { side = THREE.DoubleSide, flip = false } = options || {};
1579
+ const texture = this.getTexture();
1580
+ const material = new THREE.MeshPhongMaterial({ side });
1581
+ material.transparent = true;
1582
+ if (texture) {
1583
+ yield this.addMaterialMap(material, texture, flip);
1584
+ }
1585
+ return material;
1586
+ });
1587
+ }
1588
+ getTexture() {
1589
+ return this.texture;
1590
+ }
1591
+ createMaterial(side = THREE.DoubleSide, isSame = true) {
1592
+ return __awaiter(this, void 0, void 0, function* () {
1593
+ let textureMaterialFront;
1594
+ let textureMaterialBack;
1595
+ switch (side) {
1596
+ case THREE.DoubleSide:
1597
+ this._flipped = !isSame;
1598
+ textureMaterialFront = yield this.createTextureMaterial({ side: THREE.FrontSide, flip: this._flipped });
1599
+ textureMaterialBack = yield this.createTextureMaterial({ side: THREE.FrontSide, flip: !this._flipped });
1600
+ break;
1601
+ case THREE.FrontSide:
1602
+ this._flipped = !isSame;
1603
+ if (this.frontVisible) {
1604
+ textureMaterialFront = yield this.createTextureMaterial({ side: THREE.FrontSide, flip: this._flipped });
1605
+ }
1606
+ else {
1607
+ textureMaterialBack = yield this.createTextureMaterial({ side: THREE.BackSide, flip: !this._flipped });
1608
+ }
1609
+ break;
1610
+ case THREE.BackSide: {
1611
+ this._flipped = !isSame;
1612
+ if (!this.frontVisible) {
1613
+ textureMaterialFront = yield this.createTextureMaterial({ side: THREE.FrontSide, flip: this._flipped });
1614
+ }
1615
+ else {
1616
+ textureMaterialBack = yield this.createTextureMaterial({
1617
+ side: THREE.BackSide, flip: !this._flipped
1618
+ });
1619
+ }
1620
+ break;
1621
+ }
1622
+ }
1623
+ this.object.material = this.getMaterials(textureMaterialFront, textureMaterialBack);
1624
+ });
1625
+ }
1626
+ setYPositionBasedOnElevation() {
1627
+ this.position.y = this.elevation + this.halfSize.y;
1628
+ }
1629
+ addMaterialMap(material, texture, flip) {
1630
+ return __awaiter(this, void 0, void 0, function* () {
1631
+ const dimensions = this.getMaterialMapDimensions();
1632
+ texture.dimensions = dimensions.multiplyScalar(100);
1633
+ switch (texture.type) {
1634
+ case TextureType.Image:
1635
+ if (flip) {
1636
+ material.map = yield MaterialUtils.FromFlippedImage(texture, dimensions);
1637
+ }
1638
+ else {
1639
+ material.map = yield MaterialUtils.FromImage(texture);
1640
+ }
1641
+ break;
1642
+ case TextureType.CustomPattern:
1643
+ material.map = yield MaterialUtils.CustomTileMapTexture(texture, dimensions);
1644
+ break;
1645
+ case TextureType.Basic:
1646
+ material.map = yield MaterialUtils.FromUrl(texture.url, texture.stretch, texture.tileSize, null, null, texture.dimensions, texture.tileRotation);
1647
+ break;
1648
+ }
1649
+ // this.scene.needsUpdate = true;
1650
+ // this.scene.textureLoadedCallbacks.fire();
1651
+ });
1652
+ }
1653
+ getMaterialMapDimensions() {
1654
+ return new THREE.Vector2(this.getWidth(), this.getHeight());
1655
+ }
1656
+ getMaterials(textureMaterialFront, textureMaterialBack) {
1657
+ return [
1658
+ MaterialUtils.defaultWindow.clone(),
1659
+ MaterialUtils.defaultWindow.clone(),
1660
+ MaterialUtils.defaultWindow.clone(),
1661
+ MaterialUtils.defaultWindow.clone(),
1662
+ textureMaterialFront || MaterialUtils.defaultWindow.clone(),
1663
+ textureMaterialBack || MaterialUtils.defaultWindow.clone() // Back side
1664
+ ];
1665
+ }
1666
+ getItemThickness() {
1667
+ return this.currentWall.thickness - 0.01;
1668
+ }
1669
+ /** */
1670
+ redrawWall() {
1671
+ if (this.currentWallEdge && this.currentWallEdge.wall) {
1672
+ this.currentWallEdge.wall.fireRedraw();
1673
+ }
1674
+ // this.updateEdgeVisibility(true, this._onFrontSide);
1675
+ }
1676
+ /** */
1677
+ _changeWallEdge(wallEdge) {
1678
+ if (this.currentWallEdge === wallEdge) {
1679
+ if (!this.currentWall) {
1680
+ this.currentWall = wallEdge.wall;
1681
+ }
1682
+ return;
1683
+ }
1684
+ if (!isNill(this.currentWallEdge)) {
1685
+ if (this.addToWall) {
1686
+ this.currentWallEdge.wall.removeItem(this);
1687
+ this.redrawWall();
1688
+ }
1689
+ else {
1690
+ this.currentWallEdge.wall.removeOnItem(this);
1691
+ }
1692
+ }
1693
+ if (!wallEdge) {
1694
+ return;
1695
+ }
1696
+ // find angle between wall normals
1697
+ const normal2 = new THREE.Vector2();
1698
+ const normal3 = Utils.GetFaceNormalFromBufferGeometry(wallEdge.plane.geometry, 0, 0);
1699
+ normal2.x = normal3.x;
1700
+ normal2.y = normal3.z;
1701
+ const angle = Utils.angle(this._refVec.x, this._refVec.y, normal2.x, normal2.y);
1702
+ this.rotation.y = (this.default180 ? Math.PI : 0) + angle;
1703
+ this.traverse(c => c.matrixWorldNeedsUpdate = true);
1704
+ // update currentWall
1705
+ this.currentWall = wallEdge.wall;
1706
+ this.currentWallEdge = wallEdge;
1707
+ if (this.addToWall) {
1708
+ wallEdge.wall.addItem(this);
1709
+ if (this.metadata.texture) {
1710
+ this.updateMaterialVisibility(wallEdge.wall.side);
1711
+ }
1712
+ this.redrawWall();
1713
+ }
1714
+ else {
1715
+ wallEdge.wall.addOnItem(this);
1716
+ }
1717
+ }
1718
+ _boundToFloorY() {
1719
+ return 0.5 * this.getHeight() * this.scale.y + 0.01;
1720
+ }
1721
+ /** takes the move vec3, and makes sure object stays bounded on plane */
1722
+ _boundMove(vec3) {
1723
+ const edge = this.currentWallEdge;
1724
+ vec3.applyMatrix4(edge.interiorTransform);
1725
+ edge.wall.itemsChanged = true;
1726
+ if (vec3.x < this._sizeX / 2.0 + this._positionYTolerance) {
1727
+ vec3.x = this._sizeX / 2.0 + this._positionYTolerance;
1728
+ }
1729
+ else if (vec3.x > (edge.interiorDistance() - this._sizeX / 2.0 - this._positionYTolerance)) {
1730
+ vec3.x = edge.interiorDistance() - this._sizeX / 2.0 - this._positionYTolerance;
1731
+ }
1732
+ if (this.boundToFloor) {
1733
+ vec3.y = this._boundToFloorY();
1734
+ }
1735
+ else {
1736
+ if (this.elevationFixed || !this.elevationAdjustable) {
1737
+ // if elevation is higher than the wall, use maxY
1738
+ vec3.y = Math.min(this._getMaxY(edge), this.halfSize.y + this.elevation);
1739
+ }
1740
+ else {
1741
+ const maxY = this._getMaxY(edge);
1742
+ const minY = this._getMinT();
1743
+ if (vec3.y < minY) {
1744
+ vec3.y = minY;
1745
+ }
1746
+ else if (vec3.y > maxY) {
1747
+ vec3.y = maxY;
1748
+ }
1749
+ this.elevation = vec3.y - this.halfSize.y;
1750
+ }
1751
+ }
1752
+ vec3.z = this.getWallOffset();
1753
+ vec3.applyMatrix4(edge.invInteriorTransform);
1754
+ }
1755
+ _isWallSame() {
1756
+ let isSame = false;
1757
+ if (this.currentWallEdge) {
1758
+ const onFrontSide = this.currentWallEdge === this.currentWallEdge.wall.frontEdge;
1759
+ if (this._onFrontSide === undefined) {
1760
+ this._onFrontSide = onFrontSide;
1761
+ }
1762
+ isSame = onFrontSide === this._onFrontSide;
1763
+ }
1764
+ return isSame;
1765
+ }
1766
+ _getMaxY(edge) {
1767
+ return edge.height - this._sizeY / 2.0 - this._positionYTolerance;
1768
+ }
1769
+ _getMinT() {
1770
+ return this._sizeY / 2.0 + this._positionYTolerance;
1771
+ }
1772
+ _moveToYPosition(position) {
1773
+ const maxY = this._getMaxY(this.currentWallEdge);
1774
+ const minY = this._getMinT();
1775
+ if (position > maxY) {
1776
+ this.elevation = maxY - this.halfSize.y;
1777
+ return maxY;
1778
+ }
1779
+ if (position < minY) {
1780
+ this.elevation = minY - this.halfSize.y;
1781
+ return minY;
1782
+ }
1783
+ return position;
1784
+ }
1785
+ }
1786
+ export class InWallItem extends WallItem {
1787
+ constructor(metadata, object, texture) {
1788
+ super(metadata, object, texture);
1789
+ this._frameWidth = 0.07;
1790
+ this._frameDepth = 0.1;
1791
+ this._defaultFrameColor = 9070146; // RAL-1011
1792
+ this._defaultDoorColor = 16777215; // RAL-9010
1793
+ this.opening = {
1794
+ show: false,
1795
+ double: false,
1796
+ invertDirection: false,
1797
+ invertSide: true
1798
+ };
1799
+ this.frameColor = this._defaultFrameColor;
1800
+ this.doorColor = this._defaultDoorColor;
1801
+ this.windowColor = new THREE.Color(0.0431, 0.0588, 0.0902);
1802
+ this.isGlass = false;
1803
+ this._isWindow = false;
1804
+ this._doorpost = false;
1805
+ this._setDefault();
1806
+ this.frameTitle = 'Frame';
1807
+ this.customMeshTitle = this._isWindow ? 'Window' : 'Door';
1808
+ this.canChangeCustomMeshColor = !this._isWindow;
1809
+ this.receiveShadow = true;
1810
+ this.addToWall = true;
1811
+ this._glassMaterialCheck();
1812
+ }
1813
+ get doorpost() {
1814
+ return this._doorpost;
1815
+ }
1816
+ dispose() {
1817
+ super.dispose();
1818
+ Utils.DisposeObject(this.topFrame);
1819
+ Utils.DisposeObject(this.leftFrame);
1820
+ Utils.DisposeObject(this.rightFrame);
1821
+ Utils.DisposeObject(this.bottomFrame);
1822
+ Utils.DisposeObject(this.customMesh);
1823
+ Utils.DisposeMaterial(this.frameMaterial);
1824
+ Utils.DisposeMaterial(this.doorMaterialFront);
1825
+ Utils.DisposeMaterial(this.windowMaterial);
1826
+ }
1827
+ placeOnEdge(edge) {
1828
+ if (this.isCustom) {
1829
+ const checkMaterial = this._isWindow ? this.windowMaterial : this.doorMaterialFront;
1830
+ if (!checkMaterial) {
1831
+ this._createMaterials(THREE.DoubleSide);
1832
+ }
1833
+ this.createCustomMesh(this.getWidth(), this.getHeight());
1834
+ }
1835
+ super.placeOnEdge(edge);
1836
+ }
1837
+ /** */
1838
+ getWallOffset() {
1839
+ return -this.currentWallEdge.offset;
1840
+ }
1841
+ distanceFrom2d(x, y) {
1842
+ return Utils.pointDistanceFromLine(x, y, this.getStartX(), this.getStartY(), this.getEndX(), this.getEndY());
1843
+ }
1844
+ onWallUpdated(wall) {
1845
+ if (this.metadata.texture) {
1846
+ this.updateMaterialVisibility(wall.side);
1847
+ }
1848
+ }
1849
+ updateFrameColor(color) {
1850
+ this.frameColor = color;
1851
+ this.frameMaterial.color.setHex(color);
1852
+ this.frameMaterial.needsUpdate = true;
1853
+ // this.scene.needsUpdate = true;
1854
+ }
1855
+ updateDoorColor(color) {
1856
+ this.doorColor = color;
1857
+ this.doorMaterialFront.color.setHex(color);
1858
+ this.doorMaterialFront.transparent = false;
1859
+ this.doorMaterialFront.opacity = 1;
1860
+ this.doorMaterialFront.map = undefined;
1861
+ this.doorMaterialFront.needsUpdate = true;
1862
+ // this.scene.needsUpdate = true;
1863
+ }
1864
+ updateGlassMaterial() {
1865
+ if (!this.isGlass) {
1866
+ this.doorMaterialFront.color.setHex(0xdff0f2);
1867
+ this.doorMaterialFront.transparent = true;
1868
+ this.doorMaterialFront.alphaTest = 0;
1869
+ this.doorMaterialFront.opacity = 0.2;
1870
+ this.doorMaterialFront.map = undefined;
1871
+ this.doorMaterialFront.needsUpdate = true;
1872
+ this.doorMaterialFront.side = THREE.FrontSide;
1873
+ this.isGlass = true;
1874
+ this.customMesh.castShadow = false;
1875
+ }
1876
+ else {
1877
+ this.doorMaterialFront.transparent = false;
1878
+ this.doorMaterialFront.opacity = 1;
1879
+ this.isGlass = false;
1880
+ this.customMesh.castShadow = true;
1881
+ }
1882
+ }
1883
+ updateGeometry(width, height) {
1884
+ if (this.isCustom) {
1885
+ this.createCustomMesh(width, height);
1886
+ // this.calculateHalfSize();
1887
+ this.redrawWall();
1888
+ }
1889
+ else {
1890
+ super.updateGeometry(width, height);
1891
+ }
1892
+ }
1893
+ adjustWallBox(geometry) {
1894
+ geometry.getAttribute('position').needsUpdate = true;
1895
+ geometry.computeBoundingBox();
1896
+ geometry.applyMatrix4(new Matrix4().makeTranslation(-0.5 * (geometry.boundingBox.max.x + geometry.boundingBox.min.x), -0.5 * (geometry.boundingBox.max.y + geometry.boundingBox.min.y), -0.5 * (geometry.boundingBox.max.z + geometry.boundingBox.min.z)));
1897
+ geometry.computeBoundingBox();
1898
+ this.object.geometry = geometry;
1899
+ this.calculateHalfSize();
1900
+ }
1901
+ getVisibleMeshes() {
1902
+ if (this.isCustom && this.visible) {
1903
+ const meshes = [
1904
+ this.leftFrame,
1905
+ this.topFrame,
1906
+ this.rightFrame,
1907
+ this.customMesh
1908
+ ];
1909
+ if (this._isWindow /*|| this._doorpost*/) {
1910
+ meshes.push(this.bottomFrame);
1911
+ }
1912
+ return meshes;
1913
+ }
1914
+ else {
1915
+ return super.getVisibleMeshes();
1916
+ }
1917
+ }
1918
+ createTextureMaterial(options) {
1919
+ const _super = Object.create(null, {
1920
+ createTextureMaterial: { get: () => super.createTextureMaterial }
1921
+ });
1922
+ return __awaiter(this, void 0, void 0, function* () {
1923
+ if (this.isCustom) {
1924
+ const { side = THREE.DoubleSide, flip = false } = options || {};
1925
+ const checkMaterial = this._isWindow ? this.windowMaterial : this.doorMaterialFront;
1926
+ if (!checkMaterial) {
1927
+ this._createMaterials(side);
1928
+ }
1929
+ const texture = this.getTexture();
1930
+ if (!texture) {
1931
+ // reset to default texture
1932
+ this._createMaterials(side);
1933
+ this.createCustomMesh(this.getWidth(), this.getHeight());
1934
+ return this._isWindow ? this.windowMaterial : this.doorMaterialFront;
1935
+ }
1936
+ const material = this._isWindow ? this.windowMaterial : this.doorMaterialFront;
1937
+ const defaultMaterial = new THREE.MeshPhongMaterial();
1938
+ material.transparent = false;
1939
+ material.color = defaultMaterial.color.clone();
1940
+ material.opacity = defaultMaterial.opacity;
1941
+ material.refractionRatio = defaultMaterial.refractionRatio;
1942
+ material.shininess = defaultMaterial.shininess;
1943
+ material.specular = defaultMaterial.specular.clone();
1944
+ // Allows for transparency in png's
1945
+ material.alphaTest = 0.5;
1946
+ // Makes sure the image in only projected once on the mesh
1947
+ material.side = THREE.FrontSide;
1948
+ // Removes white edges surrounding the image
1949
+ material.transparent = true;
1950
+ // material.color = new THREE.Color(1, 1, 1);
1951
+ yield this.addMaterialMap(material, texture, flip);
1952
+ material.needsUpdate = true;
1953
+ return material;
1954
+ }
1955
+ else {
1956
+ return yield _super.createTextureMaterial.call(this, options);
1957
+ }
1958
+ });
1959
+ }
1960
+ createCustomMesh(width, height) {
1961
+ const halfWidth = width / 2;
1962
+ const halfFrame = (this._frameWidth / 2);
1963
+ this.leftFrame = this._createFrameSide(this._frameWidth, this._getHeightFrame(height), this._frameDepth);
1964
+ this.leftFrame.rotation.set(this._isWindow ? 180 * (Math.PI / 180) : 0, 0, 0);
1965
+ this.leftFrame.position.x = -halfWidth + halfFrame;
1966
+ this.leftFrame.name = 'leftFrame';
1967
+ if (!this._isWindow) {
1968
+ this.leftFrame.position.y = -(this._frameWidth / 2) + 0.02;
1969
+ }
1970
+ this.topFrame = this._createFrameSide(this._frameWidth, width, this._frameDepth);
1971
+ this.topFrame.rotation.set(0, this._isWindow ? 180 * (Math.PI / 180) : 0, -90 * (Math.PI / 180));
1972
+ this.topFrame.position.y = (height / 2) - (this._frameWidth / 2);
1973
+ this.topFrame.name = 'topFrame';
1974
+ this.rightFrame = this._createFrameSide(this._frameWidth, this._getHeightFrame(height), this._frameDepth);
1975
+ this.rightFrame.rotation.set(this._isWindow ? 180 * (Math.PI / 180) : 0, 0, -180 * (Math.PI / 180));
1976
+ this.rightFrame.position.x = (width / 2) - (this._frameWidth / 2);
1977
+ this.rightFrame.name = 'rightFrame';
1978
+ if (!this._isWindow) {
1979
+ this.rightFrame.position.y = -(this._frameWidth / 2) + 0.02;
1980
+ }
1981
+ if (this._isWindow /*|| this._doorpost*/) {
1982
+ this.bottomFrame = this._createFrameSide(this._frameWidth, width, this._frameDepth);
1983
+ this.bottomFrame.rotation.set(0, 180 * (Math.PI / 180), 90 * (Math.PI / 180));
1984
+ this.bottomFrame.position.y = -(height / 2) + (this._frameWidth / 2);
1985
+ this.bottomFrame.name = 'bottomFrame';
1986
+ }
1987
+ let customGeo;
1988
+ if (this._isWindow) {
1989
+ customGeo = new THREE.BoxGeometry(width - (2 * this._frameWidth) + 0.04, height - (2 * this._frameWidth) + 0.04, 0.024);
1990
+ }
1991
+ else {
1992
+ customGeo = new THREE.BoxGeometry(width - 0.02 * (this._frameWidth - 0.02), height - (this._frameWidth - 0.02), 0.04);
1993
+ }
1994
+ this.customMesh = new THREE.Mesh(customGeo, this._isWindow ? this.windowMaterial : this.doorMaterialFront);
1995
+ this.customMesh.castShadow = this._isWindow ? false : !this.isGlass;
1996
+ this.customMesh.renderOrder = -1;
1997
+ this.customMesh.name = 'customMesh';
1998
+ if (this._isWindow) {
1999
+ this.customMesh.name += 'Window';
2000
+ }
2001
+ if (this.isGlass) {
2002
+ this.customMesh.name += 'Glass';
2003
+ }
2004
+ if (this._isWindow) {
2005
+ this.customMesh.position.z = -0.012;
2006
+ }
2007
+ else {
2008
+ this.customMesh.position.y = -(this._frameWidth / 2) + 0.01;
2009
+ this.customMesh.position.z = 0.02;
2010
+ }
2011
+ this._getAdditionalTexture().then((frontAdditionalObj) => {
2012
+ if (frontAdditionalObj) {
2013
+ const backAdditionalObj = frontAdditionalObj.clone(true);
2014
+ backAdditionalObj.rotation.x = 180 * (Math.PI / 180);
2015
+ if (this.additionalTexture.data) {
2016
+ frontAdditionalObj.position.set(-(width / 2) + this.additionalTexture.data.x, -(height / 2) + this.additionalTexture.data.y, 0.02);
2017
+ backAdditionalObj.position.set(-(width / 2) + this.additionalTexture.data.x, -(height / 2) + this.additionalTexture.data.y, -0.02);
2018
+ }
2019
+ this.customMesh.add(frontAdditionalObj);
2020
+ this.customMesh.add(backAdditionalObj);
2021
+ }
2022
+ });
2023
+ this.children.length = 0;
2024
+ this.add(this.leftFrame, this.rightFrame, this.topFrame, this.customMesh);
2025
+ if (this._isWindow /*|| this._doorpost*/) {
2026
+ this.add(this.bottomFrame);
2027
+ }
2028
+ this.calculateHalfSize();
2029
+ // this.scene.needsUpdate = true;
2030
+ }
2031
+ cloneItem() {
2032
+ const clone = this.createClass();
2033
+ this.cloneProperties(clone);
2034
+ clone.name = 'test clone';
2035
+ return clone;
2036
+ }
2037
+ createMaterial(side = THREE.DoubleSide, isSame = true) {
2038
+ const _super = Object.create(null, {
2039
+ createTextureMaterial: { get: () => super.createTextureMaterial }
2040
+ });
2041
+ return __awaiter(this, void 0, void 0, function* () {
2042
+ if (this.isCustom) {
2043
+ yield this.createTextureMaterial({ side: THREE.FrontSide, flip: false });
2044
+ }
2045
+ else {
2046
+ yield _super.createTextureMaterial.call(this, { side, isSame });
2047
+ }
2048
+ });
2049
+ }
2050
+ createClass() {
2051
+ // create new object for proper dimensions
2052
+ const mesh = new Mesh(new BoxGeometry(this.halfSize.x * 2, this.halfSize.y * 2, this.halfSize.z * 2));
2053
+ return new InWallItem(this.metadata, mesh);
2054
+ }
2055
+ cloneProperties(clone) {
2056
+ clone.userData = this.userData;
2057
+ clone.doorMaterialFront = this.doorMaterialFront ? this.doorMaterialFront.clone() : undefined;
2058
+ if (clone.doorMaterialFront) {
2059
+ clone.doorMaterialFront.emissive = new THREE.Color(0x000000);
2060
+ clone.doorMaterialFront.needsUpdate = true;
2061
+ }
2062
+ clone.windowMaterial = this.windowMaterial ? this.windowMaterial.clone() : undefined;
2063
+ if (clone.windowMaterial) {
2064
+ clone.windowMaterial.emissive = new THREE.Color(0x000000);
2065
+ clone.windowMaterial.needsUpdate = true;
2066
+ }
2067
+ clone.frameMaterial = this.frameMaterial ? this.frameMaterial.clone() : undefined;
2068
+ if (clone.frameMaterial) {
2069
+ clone.frameMaterial.emissive = new THREE.Color(0x000000);
2070
+ clone.frameMaterial.needsUpdate = true;
2071
+ }
2072
+ clone.frameColor = this.frameColor;
2073
+ clone.doorColor = this.doorColor;
2074
+ clone.object.material = [clone.frameMaterial, clone._isWindow ? clone.windowMaterial : clone.doorMaterialFront];
2075
+ clone.texture = this.texture;
2076
+ clone.additionalTexture = this.additionalTexture;
2077
+ clone.isGlass = this.isGlass;
2078
+ }
2079
+ getMaterials(textureMaterialFront, textureMaterialBack) {
2080
+ if (this.isCustom) {
2081
+ return this.object.material;
2082
+ }
2083
+ else {
2084
+ return super.getMaterials(textureMaterialFront, textureMaterialBack);
2085
+ }
2086
+ }
2087
+ getMaterialMapDimensions() {
2088
+ if (this.isCustom) {
2089
+ return new THREE.Vector2(this.getWidth() - 0.14, this.getHeight() - 0.07);
2090
+ }
2091
+ else {
2092
+ return super.getMaterialMapDimensions();
2093
+ }
2094
+ }
2095
+ initiateItemObject(data) {
2096
+ if (this.isCustom && data && data.geometry) {
2097
+ data.geometry.verticesNeedUpdate = true;
2098
+ data.geometry.computeBoundingBox();
2099
+ data.geometry.applyMatrix4(new Matrix4().makeTranslation(-0.5 * (data.geometry.boundingBox.max.x + data.geometry.boundingBox.min.x), -0.5 * (data.geometry.boundingBox.max.y + data.geometry.boundingBox.min.y), -0.5 * (data.geometry.boundingBox.max.z + data.geometry.boundingBox.min.z)));
2100
+ data.geometry.computeBoundingBox();
2101
+ const max = data.geometry.boundingBox.max.clone();
2102
+ const min = data.geometry.boundingBox.min.clone();
2103
+ this.halfSize = max.sub(min).divideScalar(2);
2104
+ }
2105
+ }
2106
+ _setDefault() {
2107
+ // workaround because properties are not available yet when creating window/door from loading from cloud/local
2108
+ this.frameColor = this.metadata.frameColor ? this.metadata.frameColor : this._defaultFrameColor; // RAL-1011
2109
+ this.doorColor = this.metadata.doorColor ? this.metadata.doorColor : this._defaultDoorColor; // RAL-9010
2110
+ this.windowColor = this.metadata.windowColor ? this.metadata.windowColor : new THREE.Color(0xdff0f2);
2111
+ this._isWindow = this.metadata.itemType === ItemType.InWall;
2112
+ this._doorpost = this.metadata.doorpost;
2113
+ this.isGlass = this.metadata.isGlass ? this.metadata.isGlass : false;
2114
+ }
2115
+ _createMaterials(side) {
2116
+ this._setDefault();
2117
+ this.frameMaterial = new THREE.MeshPhongMaterial({ side: side, name: 'frameMaterial' });
2118
+ this.frameMaterial.color = new THREE.Color(this.frameColor);
2119
+ if (this._isWindow) {
2120
+ this.windowMaterial = new THREE.MeshPhongMaterial({ side: side, color: this.windowColor, name: 'windowMaterial' });
2121
+ this.windowMaterial.transparent = true;
2122
+ this.windowMaterial.alphaTest = 0;
2123
+ this.windowMaterial.opacity = 0.2;
2124
+ this.windowMaterial.map = undefined;
2125
+ this.windowMaterial.needsUpdate = true;
2126
+ this.windowMaterial.side = THREE.FrontSide;
2127
+ this.object.material = [this.frameMaterial, this.windowMaterial];
2128
+ }
2129
+ else {
2130
+ this.doorMaterialFront = new THREE.MeshPhongMaterial({ side: side, name: 'doorMaterialFront' });
2131
+ this.doorMaterialFront.color = new THREE.Color(this.doorColor);
2132
+ if (this._doorpost) {
2133
+ this.doorMaterialFront.transparent = true;
2134
+ this.doorMaterialFront.opacity = 0;
2135
+ }
2136
+ this.object.material = [this.frameMaterial, this.doorMaterialFront];
2137
+ }
2138
+ }
2139
+ _getHeightFrame(height) {
2140
+ return height - (this._isWindow ? 2 * (this._frameWidth - 0.02) : this._frameWidth - 0.02);
2141
+ }
2142
+ _createFrameSide(width, height, depth) {
2143
+ const outerFrameWidth = width - 0.02;
2144
+ const outerFrameGeo = new THREE.BoxGeometry(outerFrameWidth, height, depth);
2145
+ const outerFrame = new THREE.Mesh(outerFrameGeo, this.frameMaterial);
2146
+ outerFrame.castShadow = true;
2147
+ outerFrame.receiveShadow = true;
2148
+ const innerFrameGeo = new THREE.BoxGeometry(0.02, height, depth / 2);
2149
+ const innerFrame = new THREE.Mesh(innerFrameGeo, this.frameMaterial);
2150
+ innerFrame.castShadow = true;
2151
+ innerFrame.receiveShadow = true;
2152
+ innerFrame.position.x = (outerFrameWidth / 2) + 0.01;
2153
+ innerFrame.position.z = -depth / 4;
2154
+ const frameSide = new THREE.Object3D();
2155
+ frameSide.add(outerFrame, innerFrame);
2156
+ const boundingBox = new THREE.Box3().setFromObject(frameSide);
2157
+ const bbCenterPivot = new THREE.Vector3();
2158
+ boundingBox.getCenter(bbCenterPivot);
2159
+ const delta = new THREE.Vector3().sub(bbCenterPivot).setY(0);
2160
+ frameSide.children.forEach((child) => {
2161
+ child.position.add(delta);
2162
+ });
2163
+ const frameSideMesh = new Mesh();
2164
+ frameSideMesh.add(outerFrame, innerFrame);
2165
+ return frameSideMesh;
2166
+ }
2167
+ _getAdditionalTexture() {
2168
+ return new Promise((resolve, reject) => {
2169
+ // if (this.additionalTexture) {
2170
+ // LoaderUtils.LoadObjModel(this.additionalTexture.url).then((obj: THREE.Mesh) => {
2171
+ // const additionalObj: THREE.Mesh = <Mesh>obj.clone(true);
2172
+ // additionalObj.children.map(c => c.position.set(0, 0, 0));
2173
+ // if (this.additionalTexture.scale) {
2174
+ // additionalObj.scale.multiplyScalar(this.additionalTexture.scale);
2175
+ // }
2176
+ // resolve(additionalObj);
2177
+ // });
2178
+ // } else {
2179
+ resolve(null);
2180
+ // }
2181
+ });
2182
+ }
2183
+ _glassMaterialCheck() {
2184
+ let meshesFound = 0;
2185
+ this.traverse((child) => {
2186
+ if (child instanceof Mesh && child.material) {
2187
+ meshesFound++;
2188
+ child.castShadow = true;
2189
+ const materials = !Array.isArray(child.material) ? [child.material] : child.material;
2190
+ materials.forEach(material => {
2191
+ if (material.name && (material.name === 'Fixed_Glass' || material.name === 'Default_Glass')) {
2192
+ child.castShadow = false;
2193
+ material.transparent = true;
2194
+ material.opacity = 0.2;
2195
+ material.format = THREE.RGBAFormat;
2196
+ material.needsUpdate = true;
2197
+ }
2198
+ });
2199
+ }
2200
+ });
2201
+ // Remove to ignore old door models
2202
+ if (meshesFound === 1) {
2203
+ this.traverse((child) => {
2204
+ if (child instanceof Mesh) {
2205
+ child.castShadow = true;
2206
+ const materials = !Array.isArray(child.material) ? [child.material] : child.material;
2207
+ materials.forEach(m => {
2208
+ m.visible = m.name && (m.name === 'Fixed_Glass' || m.name === 'Default_Glass') ? m.visible = false : m.visible = true;
2209
+ });
2210
+ }
2211
+ });
2212
+ }
2213
+ }
2214
+ }
2215
+ export class WallItemGroup extends ItemGroup {
2216
+ constructor() {
2217
+ super();
2218
+ this.elevationAdjustable = true;
2219
+ this._positionYTolerance = 0.005;
2220
+ this._wallOffsetScalar = 0;
2221
+ this._sizeX = 0;
2222
+ this._sizeY = 0;
2223
+ this._refVec = new THREE.Vector2(0, 1.0);
2224
+ this.metadata = {
2225
+ itemType: 22
2226
+ };
2227
+ this.userData.itemType = this.metadata.itemType;
2228
+ }
2229
+ redrawWall() {
2230
+ if (this.currentWallEdge && this.currentWallEdge.wall) {
2231
+ this.currentWallEdge.wall.fireRedraw();
2232
+ }
2233
+ }
2234
+ isValidPosition(position, rotation, options) {
2235
+ return { valid: true };
2236
+ }
2237
+ moveToPosition(vec3, intersection) {
2238
+ if (intersection) {
2239
+ if (!this.currentWallEdge && this.items[0].currentWallEdge) {
2240
+ this.currentWallEdge = this.items[0].currentWallEdge;
2241
+ }
2242
+ if (this.currentWallEdge) {
2243
+ this._boundMove(vec3);
2244
+ this.position.copy(vec3);
2245
+ this.redrawWall();
2246
+ }
2247
+ }
2248
+ }
2249
+ createBoundaryBox() {
2250
+ this.boundaryBox.setFromObject(this);
2251
+ const max = this.boundaryBox.max.clone();
2252
+ const min = this.boundaryBox.min.clone();
2253
+ this.halfSize = max.sub(min).divideScalar(2);
2254
+ this.updateSize();
2255
+ }
2256
+ centerPivot() {
2257
+ const boundaryBoxCenter = this.boundaryBoxCenter;
2258
+ this.position.copy(boundaryBoxCenter);
2259
+ this.items.forEach(i => {
2260
+ const originalPosition = i.position.clone();
2261
+ const newPosition = originalPosition.sub(boundaryBoxCenter);
2262
+ i.position.copy(newPosition);
2263
+ });
2264
+ }
2265
+ updateSize() {
2266
+ this._wallOffsetScalar = this.halfSize.z;
2267
+ this._sizeX = this.halfSize.x * 2;
2268
+ this._sizeY = this.halfSize.y * 2;
2269
+ }
2270
+ onWallMoved(wall) {
2271
+ if (wall.frontEdge) {
2272
+ this.placeOnEdge(wall.frontEdge);
2273
+ }
2274
+ if (wall.backEdge) {
2275
+ this.placeOnEdge(wall.backEdge);
2276
+ }
2277
+ }
2278
+ placeOnEdge(edge) {
2279
+ this._originalRotation = this.rotation.clone();
2280
+ if (!edge) {
2281
+ return;
2282
+ }
2283
+ this._onFrontSide = edge.wall.frontEdge === edge;
2284
+ this._changeWallEdge(edge);
2285
+ const newPos = edge.wall.amountWallMoved ? this.position.add(new Vector3(edge.wall.amountWallMoved.x, 0, 0)) : this.position.clone();
2286
+ this._boundMove(newPos);
2287
+ this.position.copy(newPos);
2288
+ this.redrawWall();
2289
+ this.allowRotate = false;
2290
+ }
2291
+ handleGroupCreation() {
2292
+ this.items.forEach((i) => {
2293
+ if (!this.currentWallEdge) {
2294
+ this.currentWallEdge = i.currentWallEdge;
2295
+ this.currentWall = this.currentWallEdge.wall;
2296
+ }
2297
+ this.currentWall.removeOnItem(i);
2298
+ });
2299
+ this.placeOnEdge(this.currentWallEdge);
2300
+ }
2301
+ _changeWallEdge(wallEdge) {
2302
+ // find angle between wall normals
2303
+ const normal2 = new THREE.Vector2();
2304
+ const normal3 = Utils.GetFaceNormalFromBufferGeometry(wallEdge.plane.geometry, 0, 0);
2305
+ normal2.x = normal3.x;
2306
+ normal2.y = normal3.z;
2307
+ const wallRotation = Utils.angle(this._refVec.x, this._refVec.y, normal2.x, normal2.y);
2308
+ // transfer rotation from child to parent and reset boundary box
2309
+ if (this.items[0].rotation.y !== 0) {
2310
+ this.items.forEach((i) => {
2311
+ const itemWorldPosition = i.getWorldPosition(new Vector3());
2312
+ this.remove(i);
2313
+ this.rotation.y = wallRotation;
2314
+ i.position.copy(itemWorldPosition);
2315
+ this.attach(i);
2316
+ this.rotation.y = 0;
2317
+ });
2318
+ this.createBoundaryBox();
2319
+ }
2320
+ this.rotation.y = wallRotation;
2321
+ this.traverse(c => c.matrixWorldNeedsUpdate = true);
2322
+ // update currentWall
2323
+ this.currentWall = wallEdge.wall;
2324
+ this.currentWallEdge = wallEdge;
2325
+ wallEdge.wall.addOnItem(this);
2326
+ }
2327
+ updateEdgeVisibility(edge) {
2328
+ if (this.currentWall) {
2329
+ let shouldShow = false;
2330
+ if (this.currentWall.backEdge) {
2331
+ this.currentWall.backEdge.edges.forEach((e) => {
2332
+ if (e.visible) {
2333
+ shouldShow = true;
2334
+ }
2335
+ });
2336
+ }
2337
+ if (this.currentWall.frontEdge) {
2338
+ this.currentWall.frontEdge.edges.forEach(e => {
2339
+ if (e.visible) {
2340
+ shouldShow = true;
2341
+ }
2342
+ });
2343
+ }
2344
+ this.visible = shouldShow;
2345
+ }
2346
+ }
2347
+ _boundMove(vec3) {
2348
+ const edge = this.currentWallEdge;
2349
+ vec3.applyMatrix4(edge.interiorTransform);
2350
+ edge.wall.itemsChanged = true;
2351
+ if (vec3.x < this._sizeX / 2.0 + this._positionYTolerance) {
2352
+ vec3.x = this._sizeX / 2.0 + this._positionYTolerance;
2353
+ }
2354
+ else if (vec3.x > (edge.interiorDistance() - this._sizeX / 2.0 - this._positionYTolerance)) {
2355
+ vec3.x = edge.interiorDistance() - this._sizeX / 2.0 - this._positionYTolerance;
2356
+ }
2357
+ if (this.elevationFixed || !this.elevationAdjustable) {
2358
+ vec3.y = this.position.y;
2359
+ }
2360
+ else {
2361
+ const maxY = this._getMaxY(edge);
2362
+ const minY = this._getMinY();
2363
+ if (vec3.y < minY) {
2364
+ vec3.y = minY;
2365
+ }
2366
+ else if (vec3.y > maxY) {
2367
+ vec3.y = maxY;
2368
+ }
2369
+ this.elevation = vec3.y - this.halfSize.y;
2370
+ }
2371
+ vec3.z = this._wallOffsetScalar;
2372
+ vec3.applyMatrix4(edge.invInteriorTransform);
2373
+ }
2374
+ _getMaxY(edge) {
2375
+ return edge.height - this.halfSize.y - this._positionYTolerance;
2376
+ }
2377
+ _getMinY() {
2378
+ return this.halfSize.y + this._positionYTolerance;
2379
+ }
2380
+ }
2381
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbC1vYmplY3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2NsaWVudC9hcHAvcGx1Z2lucy9jb3JlM2QvaXRlbXMvd2FsbC1vYmplY3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBLE9BQU8sRUFDSCxXQUFXLEVBQ1gsZUFBZSxFQUNmLGNBQWMsRUFDZCxLQUFLLEVBQUUsVUFBVSxFQUNqQixPQUFPLEVBQ1AsSUFBSSxFQUNKLGlCQUFpQixFQUNqQixvQkFBb0IsRUFBa0MsSUFBSSxFQUMxRCxVQUFVLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQ2hELE9BQU8sRUFDUCxPQUFPLEVBQ1YsTUFBTSxPQUFPLENBQUM7QUFDZixPQUFPLEtBQUssS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUMvQixPQUFPLEVBQUMsWUFBWSxFQUFVLE1BQU0sNkJBQTZCLENBQUM7QUFDbEUsT0FBTyxFQUFDLElBQUksRUFBQyxNQUFNLFFBQVEsQ0FBQztBQUM1QixPQUFPLEVBQUMsS0FBSyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3BDLE9BQU8sRUFBQyxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLDJEQUEyRCxDQUFDO0FBQzdHLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLCtDQUErQyxDQUFDO0FBQ3JFLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxrQ0FBa0MsQ0FBQztBQUM3RCxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sb0NBQW9DLENBQUM7QUFFakUsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGFBQWEsQ0FBQztBQUVyQyxPQUFPLEtBQUssUUFBUSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFJdkM7Ozs7R0FJRztBQUNILE1B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LENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUN6RyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5RSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1FBQ25ELElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLFdBQVcsQ0FBQztRQUNsQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNqQixJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO1NBQzlEO1FBRUQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2pGLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2pHLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFX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bUJBQW1CLENBQUM7SUFDcEUsQ0FBQztJQUVPLFFBQVE7UUFDWixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztJQUN0RCxDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gICAgQm94R2VvbWV0cnksXHJcbiAgICBCdWZmZXJBdHRyaWJ1dGUsXHJcbiAgICBCdWZmZXJHZW9tZXRyeSxcclxuICAgIENvbG9yLCBEb3VibGVTaWRlLCBFdWxlciwgSW50ZXJzZWN0aW9uLCBNYXRlcmlhbCxcclxuICAgIE1hdHJpeDQsXHJcbiAgICBNZXNoLFxyXG4gICAgTWVzaEJhc2ljTWF0ZXJpYWwsIE1lc2hQaG9uZ01hdGVyaWFsLFxyXG4gICAgTWVzaFBoeXNpY2FsTWF0ZXJpYWwsIE1lc2hTdGFuZGFyZE1hdGVyaWFsLCBPYmplY3QzRCwgUGF0aCxcclxuICAgIFF1YXRlcm5pb24sIFNoYXBlLCBTaGFwZUdlb21ldHJ5LCBTUkdCQ29sb3JTcGFjZSxcclxuICAgIFZlY3RvcjIsXHJcbiAgICBWZWN0b3IzXHJcbn0gZnJvbSAndGhyZWUnO1xyXG5pbXBvcnQgKiBhcyBUSFJFRSBmcm9tICd0aHJlZSc7XHJcbmltcG9ydCB7c2FtZVRleHR1cmVzLCBUZXh0dXJlfSBmcm9tICcuLi8uLi8uLi9jb3JlL21vZGVsL3RleHR1cmUnO1xyXG5pbXBvcnQge0l0ZW19IGZyb20gJy4vaXRlbSc7XHJcbmltcG9ydCB7VXRpbHN9IGZyb20gJy4uL2NvcmUvdXRpbHMnO1xyXG5pbXBvcnQge2RlZmF1bHRFZGdlQ29sb3IsIGRlZmF1bHRXYWxsQ29sb3J9IGZyb20gJy4uLy4uL3Jvb20tcGxhbm5lci9jb21wb25lbnRzL2Zsb29ycGxhbm5lci9jb25zdC9kZWZhdWx0cyc7XHJcbmltcG9ydCB7VGhyZWVNZXNofSBmcm9tICcuL3RocmVlLW1lc2gnO1xyXG5pbXBvcnQge2lzTmlsbH0gZnJvbSAnLi4vLi4vLi4vY29yZS91dGlscy9mdW5jdGlvbi9pcy1uaWxsLmZ1bmN0aW9uJztcclxuaW1wb3J0IHtUZXh0dXJlVHlwZX0gZnJvbSAnLi4vLi4vLi4vY29yZS9tb2RlbC90ZXh0dXJlLXR5cGUnO1xyXG5pbXBvcnQge01hdGVyaWFsVXRpbHN9IGZyb20gJy4uLy4uLy4uL2NvcmUvdXRpbHMvbWF0ZXJpYWwudXRpbHMnO1xyXG5pbXBvcnQge01ldGFkYXRhfSBmcm9tICcuL21ldGFkYXRhJztcclxuaW1wb3J0IHtJdGVtVHlwZX0gZnJvbSAnLi9pdGVtLXR5cGUnO1xyXG5pbXBvcnQge0NvbGxpc2lvbkluZm99IGZyb20gJy4uL21vZGVsL2NvbGxpc2lvbi1pbmZvJztcclxuaW1wb3J0ICogYXMgR2VvbWV0cnkgZnJvbSAnLi4vbW9kZWwvZ2VvbWV0cnknO1xyXG5pbXBvcnQge0l0ZW1Hcm91cH0gZnJvbSAnLi9pdGVtLWdyb3VwJztcclxuaW1wb3J0IHtPdXRwdXRFbmNvZGluZ30gZnJvbSAnLi4vLi4vLi4vY29yZS9lbnVtL291dHB1dC1lbmNvZGluZy5lbnVtJztcclxuaW1wb3J0IHtGbG9vclBsYW5lSXRlbX0gZnJvbSAnLi9mbG9vci1wbGFuZS1pdGVtJztcclxuXHJcbi8qKlxyXG4gKiBBIFdhbGwgaXMgdGhlIGJhc2ljIGVsZW1lbnQgdG8gY3JlYXRlIFJvb21zLlxyXG4gKlxyXG4gKiBXYWxscyBjb25zaXN0cyBvZiB0d28gaGFsZiBlZGdlcy5cclxuICovXHJcbmV4cG9ydCBjbGFzcyBXYWxsIHtcclxuXHJcbiAgICAvKiogVGhlIHVuaXF1ZSBpZCBvZiBlYWNoIHdhbGwuICovXHJcbiAgICBwcml2YXRlIGlkOiBzdHJpbmc7XHJcblxyXG4gICAgLyoqIEZyb250IGlzIHRoZSBwbGFuZSBmcm9tIHN0YXJ0IHRvIGVuZC4gKi9cclxuICAgIHB1YmxpYyBmcm9udEVkZ2U6IEhhbGZFZGdlID0gbnVsbDtcclxuXHJcbiAgICAvKiogQmFjayBpcyB0aGUgcGxhbmUgZnJvbSBlbmQgdG8gc3RhcnQuICovXHJcbiAgICBwdWJsaWMgYmFja0VkZ2U6IEhhbGZFZGdlID0gbnVsbDtcclxuXHJcbiAgICAvKiogKi9cclxuICAgIHB1YmxpYyBvcnBoYW4gPSBmYWxzZTtcclxuXHJcbiAgICAvKiogSXRlbXMgYXR0YWNoZWQgdG8gdGhpcyB3YWxsICovXHJcbiAgICBwdWJsaWMgaXRlbXM6IEl0ZW1bXSA9IFtdO1xyXG4gICAgcHVibGljIGl0ZW1zQ2hhbmdlZCA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIG9uSXRlbXM6IEl0ZW1bXSA9IFtdO1xyXG5cclxuICAgIC8qKiBUaGUgZnJvbnQtc2lkZSB0ZXh0dXJlLiAqL1xyXG4gICAgcHVibGljIGZyb250VGV4dHVyZTogVGV4dHVyZTtcclxuXHJcbiAgICAvKiogVGhlIGJhY2stc2lkZSB0ZXh0dXJlLiAqL1xyXG4gICAgcHVibGljIGJhY2tUZXh0dXJlOiBUZXh0dXJlO1xyXG5cclxuICAgIC8qKiBUaGUgZnJvbnQtc2lkZSBjb2xvci4gKi9cclxuICAgIHB1YmxpYyBmcm9udENvbG9yID0gZGVmYXVsdFdhbGxDb2xvcjtcclxuXHJcbiAgICAvKiogVGhlIGJhY2stc2lkZSBjb2xvci4gKi9cclxuICAgIHB1YmxpYyBiYWNrQ29sb3IgPSBkZWZhdWx0V2FsbENvbG9yO1xyXG5cclxuICAgIHB1YmxpYyB0aGlja25lc3M7XHJcblxyXG4gICAgcHVibGljIHNldCBoZWlnaHQodmFsdWU6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMuX2hlaWdodCA9IHZhbHVlO1xyXG4gICAgICAgIGlmICh0aGlzLmZyb250RWRnZSkge1xyXG4gICAgICAgICAgICB0aGlzLmZyb250RWRnZS5oZWlnaHQgPSB0aGlzLl9oZWlnaHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmJhY2tFZGdlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYmFja0VkZ2UuaGVpZ2h0ID0gdGhpcy5faGVpZ2h0O1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLml0ZW1zLmZvckVhY2goKGl0ZW06IFdhbGxJdGVtKSA9PiBpdGVtLnJlcG9zaXRpb24oKSk7XHJcbiAgICAgICAgdGhpcy5vbkl0ZW1zLmZvckVhY2goKGl0ZW06IFdhbGxJdGVtKSA9PiBpdGVtLnJlcG9zaXRpb24oKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldCBoZWlnaHQoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5faGVpZ2h0O1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhbW91bnRXYWxsTW92ZWQ6IFZlY3RvcjI7XHJcblxyXG4gICAgcHJpdmF0ZSBfaGVpZ2h0OiBudW1iZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IHdhbGwuXHJcbiAgICAgKiBAcGFyYW0gc3RhcnQgU3RhcnQgY29ybmVyLlxyXG4gICAgICogQHBhcmFtIGVuZCBFbmQgY29ybmVyLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHN0YXJ0OiBDb3JuZXIsIHByaXZhdGUgZW5kOiBDb3JuZXIpIHtcclxuICAgICAgICB0aGlzLmlkID0gdGhpcy5nZXRVdWlkKCk7XHJcblxyXG4gICAgICAgIHRoaXMuc3RhcnQuYXR0YWNoU3RhcnQodGhpcyk7XHJcbiAgICAgICAgdGhpcy5lbmQuYXR0YWNoRW5kKHRoaXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0VXVpZCgpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiBbdGhpcy5zdGFydC5pZCwgdGhpcy5lbmQuaWRdLmpvaW4oKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc2hvd0hpZGVXYWxsKHNob3c6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgICAgICBpZiAodGhpcy5mcm9udEVkZ2UpIHsgdGhpcy5mcm9udEVkZ2Uuc2hvd0hpZGVFZGdlKHNob3cpOyB9XHJcbiAgICAgICAgaWYgKHRoaXMuYmFja0VkZ2UpIHsgdGhpcy5iYWNrRWRnZS5zaG93SGlkZUVkZ2Uoc2hvdyk7IH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcmVzZXRGcm9udEJhY2soKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZnJvbnRFZGdlKSB7IHRoaXMuZnJvbnRFZGdlLmRpc3Bvc2VQbGFuZSgpOyB9XHJcbiAgICAgICAgaWYgKHRoaXMuYmFja0VkZ2UpIHsgdGhpcy5iYWNrRWRnZS5kaXNwb3NlUGxhbmUoKTsgfVxyXG4gICAgICAgIHRoaXMuZnJvbnRFZGdlID0gbnVsbDtcclxuICAgICAgICB0aGlzLmJhY2tFZGdlID0gbnVsbDtcclxuICAgICAgICB0aGlzLm9ycGhhbiA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgbW92ZSh4OiBudW1iZXIsIHk6IG51bWJlcikge1xyXG4gICAgICAgIGlmICghdGhpcy5hbW91bnRXYWxsTW92ZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5hbW91bnRXYWxsTW92ZWQgPSBuZXcgVmVjdG9yMigpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBkaWZmWCA9IHRoaXMuZW5kLnggLSB0aGlzLnN0YXJ0Lng7XHJcbiAgICAgICAgY29uc3QgZGlmZlkgPSB0aGlzLmVuZC55IC0gdGhpcy5zdGFydC55O1xyXG4gICAgICAgIGNvbnN0IHByZXZTdGFydFg6IG51bWJlciA9IHRoaXMuc3RhcnQueDtcclxuICAgICAgICBjb25zdCBwcmV2U3RhcnRZOiBudW1iZXIgPSB0aGlzLnN0YXJ0Lnk7XHJcbiAgICAgICAgdGhpcy5zdGFydC5tb3ZlKHgsIHkpO1xyXG4gICAgICAgIHRoaXMuZW5kLm1vdmUoeCArIGRpZmZYLCB5ICsgZGlmZlkpO1xyXG4gICAgICAgIHRoaXMuYW1vdW50V2FsbE1vdmVkLmFkZChuZXcgVmVjdG9yMih0aGlzLnN0YXJ0LnggLSBwcmV2U3RhcnRYLCB0aGlzLnN0YXJ0LnkgLSBwcmV2U3RhcnRZKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZWxhdGl2ZU1vdmUoZHg6IG51bWJlciwgZHk6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMuc3RhcnQucmVsYXRpdmVNb3ZlKGR4LCBkeSk7XHJcbiAgICAgICAgdGhpcy5lbmQucmVsYXRpdmVNb3ZlKGR4LCBkeSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGZpcmVSZWRyYXcoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZnJvbnRFZGdlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZnJvbnRFZGdlLnJlZHJhdygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5iYWNrRWRnZSkge1xyXG4gICAgICAgICAgICB0aGlzLmJhY2tFZGdlLnJlZHJhdygpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0U3RhcnQoKTogQ29ybmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zdGFydDtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0RW5kKCk6IENvcm5lciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5kO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRTdGFydFgoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5nZXRYKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldEVuZFgoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5lbmQuZ2V0WCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRTdGFydFkoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5nZXRZKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldEVuZFkoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5lbmQuZ2V0WSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyByZW1vdmUoKSB7XHJcbiAgICAgICAgdGhpcy5zdGFydC5kZXRhY2hXYWxsKHRoaXMpO1xyXG4gICAgICAgIHRoaXMuZW5kLmRldGFjaFdhbGwodGhpcyk7XHJcbiAgICAgICAgdGhpcy5mcm9udFRleHR1cmUgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgdGhpcy5iYWNrVGV4dHVyZSA9IHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc2V0U3RhcnQoY29ybmVyOiBDb3JuZXIpIHtcclxuICAgICAgICB0aGlzLnN0YXJ0LmRldGFjaFdhbGwodGhpcyk7XHJcbiAgICAgICAgY29ybmVyLmF0dGFjaFN0YXJ0KHRoaXMpO1xyXG4gICAgICAgIHRoaXMuc3RhcnQgPSBjb3JuZXI7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHNldEVuZChjb3JuZXI6IENvcm5lcikge1xyXG4gICAgICAgIHRoaXMuZW5kLmRldGFjaFdhbGwodGhpcyk7XHJcbiAgICAgICAgY29ybmVyLmF0dGFjaEVuZCh0aGlzKTtcclxuICAgICAgICB0aGlzLmVuZCA9IGNvcm5lcjtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZGlzdGFuY2VGcm9tKHg6IG51bWJlciwgeTogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gVXRpbHMucG9pbnREaXN0YW5jZUZyb21MaW5lKHgsIHksXHJcbiAgICAgICAgICAgIHRoaXMuZ2V0U3RhcnRYKCksIHRoaXMuZ2V0U3RhcnRZKCksXHJcbiAgICAgICAgICAgIHRoaXMuZ2V0RW5kWCgpLCB0aGlzLmdldEVuZFkoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGNsb3Nlc3RQb2ludFRvKHg6IG51bWJlciwgeTogbnVtYmVyKTogeyB4OiBudW1iZXIsIHk6IG51bWJlciB9IHtcclxuICAgICAgICByZXR1cm4gVXRpbHMuY2xvc2VzdFBvaW50T25MaW5lKHgsIHksXHJcbiAgICAgICAgICAgIHRoaXMuZ2V0U3RhcnRYKCksIHRoaXMuZ2V0U3RhcnRZKCksXHJcbiAgICAgICAgICAgIHRoaXMuZ2V0RW5kWCgpLCB0aGlzLmdldEVuZFkoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGlzVG9PckZyb20oeDogbnVtYmVyLCB5OiBudW1iZXIpIHtcclxuICAgICAgICByZXR1cm4gKHRoaXMuZ2V0U3RhcnRYKCkgPT09IHggJiYgdGhpcy5nZXRTdGFydFkoKSA9PT0geSkgfHxcclxuICAgICAgICAgICAgKCB0aGlzLmdldEVuZFgoKSA9PT0geCAmJiB0aGlzLmdldEVuZFkoKSA9PT0geSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIFJldHVybiB0aGUgY29ybmVyIG9wcG9zaXRlIG9mIHRoZSBvbmUgcHJvdmlkZWQuXHJcbiAgICAgKiBAcGFyYW0gY29ybmVyIFRoZSBnaXZlbiBjb3JuZXIuXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgb3Bwb3NpdGUgY29ybmVyLlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIF9vcHBvc2l0ZUNvcm5lcihjb3JuZXI6IENvcm5lcik6IENvcm5lciB7XHJcbiAgICAgICAgaWYgKHRoaXMuc3RhcnQgPT09IGNvcm5lcikge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbmQ7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmVuZCA9PT0gY29ybmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0YXJ0O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdXYWxsIGRvZXMgbm90IGNvbm5lY3QgdG8gY29ybmVyJyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIFV0aWxzLmRpc3RhbmNlKHRoaXMuZ2V0U3RhcnRYKCksIHRoaXMuZ2V0U3RhcnRZKCksIHRoaXMuZ2V0RW5kWCgpLCB0aGlzLmdldEVuZFkoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldCBlZGdlc0xlbmd0aHMoKTogbnVtYmVyW10ge1xyXG4gICAgICAgIGNvbnN0IGxlbmd0aHM6IG51bWJlcltdID0gW107XHJcbiAgICAgICAgaWYgKHRoaXMuZnJvbnRFZGdlKSB7XHJcbiAgICAgICAgICAgIGxlbmd0aHMucHVzaCh0aGlzLmZyb250RWRnZS5pbnRlcmlvckRpc3RhbmNlKCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5iYWNrRWRnZSkge1xyXG4gICAgICAgICAgICBsZW5ndGhzLnB1c2godGhpcy5iYWNrRWRnZS5pbnRlcmlvckRpc3RhbmNlKCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbGVuZ3RocztcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgdXBkYXRlSW5XYWxsSXRlbXMoKSB7XHJcbiAgICAgICAgdGhpcy5pdGVtcy5maWx0ZXIoaXRlbSA9PiBpdGVtIGluc3RhbmNlb2YgSW5XYWxsSXRlbSkuZm9yRWFjaCgoaXRlbTogSW5XYWxsSXRlbSkgPT4gaXRlbS5vbldhbGxVcGRhdGVkKHRoaXMpKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgdXBkYXRlV2FsbEl0ZW1zKCkge1xyXG4gICAgICAgIHRoaXMuaXRlbXMuZmlsdGVyKGl0ZW0gPT4gaXRlbSBpbnN0YW5jZW9mIFdhbGxJdGVtKS5mb3JFYWNoKChpdGVtOiBXYWxsSXRlbSkgPT4gaXRlbS5vbldhbGxNb3ZlZCh0aGlzKSk7XHJcbiAgICAgICAgdGhpcy5vbkl0ZW1zLmZpbHRlcihpdGVtID0+IGl0ZW0gaW5zdGFuY2VvZiBXYWxsSXRlbSB8fCBpdGVtIGluc3RhbmNlb2YgV2FsbEl0ZW1Hcm91cCkuZm9yRWFjaCgoaXRlbTogV2FsbEl0ZW0pID0+IGl0ZW0ub25XYWxsTW92ZWQodGhpcykpO1xyXG4gICAgICAgIHRoaXMuYW1vdW50V2FsbE1vdmVkID0gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRJdGVtcygpOiBJdGVtW10ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLml0ZW1zO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRXYWxsSXRlbXMoKTogV2FsbEl0ZW1bXSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaXRlbXMuZmlsdGVyKGl0ZW0gPT4gaXRlbSBpbnN0YW5jZW9mIFdhbGxJdGVtKSBhcyBXYWxsSXRlbVtdO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgc2lkZSgpIHtcclxuICAgICAgICBpZiAodGhpcy5mcm9udEVkZ2UgJiYgdGhpcy5iYWNrRWRnZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gVEhSRUUuRG91YmxlU2lkZTtcclxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZnJvbnRFZGdlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBUSFJFRS5Gcm9udFNpZGU7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmJhY2tFZGdlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBUSFJFRS5CYWNrU2lkZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFkZEl0ZW0oaXRlbTogSXRlbSkge1xyXG4gICAgICAgIHRoaXMuaXRlbXMucHVzaChpdGVtKTtcclxuICAgICAgICB0aGlzLml0ZW1zQ2hhbmdlZCA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJlbW92ZUl0ZW0oaXRlbTogSXRlbSkge1xyXG4gICAgICAgIHRoaXMuaXRlbXMgPSB0aGlzLml0ZW1zLmZpbHRlcihpID0+IGkgIT09IGl0ZW0pO1xyXG4gICAgICAgIHRoaXMuaXRlbXNDaGFuZ2VkID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYWRkT25JdGVtKGl0ZW06IEl0ZW0pIHtcclxuICAgICAgICB0aGlzLm9uSXRlbXMucHVzaChpdGVtKTtcclxuICAgICAgICB0aGlzLml0ZW1zQ2hhbmdlZCA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJlbW92ZU9uSXRlbShpdGVtOiBJdGVtKSB7XHJcbiAgICAgICAgdGhpcy5vbkl0ZW1zID0gdGhpcy5vbkl0ZW1zLmZpbHRlcihpID0+IGkgIT09IGl0ZW0pO1xyXG4gICAgICAgIHRoaXMuaXRlbXNDaGFuZ2VkID0gdHJ1ZTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIENvcm5lcnMgYXJlIHVzZWQgdG8gZGVmaW5lIFdhbGxzLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIENvcm5lciB7XHJcblxyXG4gICAgLyoqIEFycmF5IG9mIHN0YXJ0IHdhbGxzLiAqL1xyXG4gICAgcHVibGljIHdhbGxTdGFydHM6IFdhbGxbXSA9IFtdO1xyXG5cclxuICAgIC8qKiBBcnJheSBvZiBlbmQgd2FsbHMuICovXHJcbiAgICBwdWJsaWMgd2FsbEVuZHM6IFdhbGxbXSA9IFtdO1xyXG5cclxuICAgIC8qKiBDb25zdHJ1Y3RzIGEgY29ybmVyLlxyXG4gICAgICogQHBhcmFtIHggWCBjb29yZGluYXRlLlxyXG4gICAgICogQHBhcmFtIHkgWSBjb29yZGluYXRlLlxyXG4gICAgICogQHBhcmFtIGlkIEFuIG9wdGlvbmFsIHVuaXF1ZSBpZC4gSWYgbm90IHNldCwgY3JlYXRlZCBpbnRlcm5hbGx5LlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgeDogbnVtYmVyLCBwdWJsaWMgeTogbnVtYmVyLCBwdWJsaWMgaWQ/OiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLmlkID0gaWQgfHwgVXRpbHMuZ3VpZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhYnNvcmJXYWxsc0Zyb20oY29ybmVyOiBDb3JuZXIpIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gY29ybmVyLndhbGxTdGFydHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICAgICAgY29ybmVyLndhbGxTdGFydHNbaV0uc2V0U3RhcnQodGhpcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAobGV0IGkgPSBjb3JuZXIud2FsbEVuZHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICAgICAgY29ybmVyLndhbGxFbmRzW2ldLnNldEVuZCh0aGlzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcmV0dXJuc1xyXG4gICAgICogQGRlcHJlY2F0ZWRcclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldFgoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy54O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHJldHVybnNcclxuICAgICAqIEBkZXByZWNhdGVkXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRZKCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMueTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogTW92ZXMgY29ybmVyIHJlbGF0aXZlbHkgdG8gbmV3IHBvc2l0aW9uLlxyXG4gICAgICogQHBhcmFtIGR4IFRoZSBkZWx0YSB4LlxyXG4gICAgICogQHBhcmFtIGR5IFRoZSBkZWx0YSB5LlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgcmVsYXRpdmVNb3ZlKGR4OiBudW1iZXIsIGR5OiBudW1iZXIpIHtcclxuICAgICAgICB0aGlzLm1vdmUodGhpcy54ICsgZHgsIHRoaXMueSArIGR5KTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogUmVtb3ZlcyBhbGwgd2FsbHMuICovXHJcbiAgICBwdWJsaWMgcmVtb3ZlQWxsKCkge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy53YWxsU3RhcnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHRoaXMud2FsbFN0YXJ0c1tpXS5yZW1vdmUoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLndhbGxFbmRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHRoaXMud2FsbEVuZHNbaV0ucmVtb3ZlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKiBNb3ZlcyBjb3JuZXIgdG8gbmV3IHBvc2l0aW9uLlxyXG4gICAgICogQHBhcmFtIG5ld1ggVGhlIG5ldyB4IHBvc2l0aW9uLlxyXG4gICAgICogQHBhcmFtIG5ld1kgVGhlIG5ldyB5IHBvc2l0aW9uLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbW92ZShuZXdYOiBudW1iZXIsIG5ld1k6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMueCA9IG5ld1g7XHJcbiAgICAgICAgdGhpcy55ID0gbmV3WTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogR2V0cyB0aGUgYWRqYWNlbnQgY29ybmVycy5cclxuICAgICAqIEByZXR1cm5zIEFycmF5IG9mIGNvcm5lcnMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhZGphY2VudENvcm5lcnMoKTogQ29ybmVyW10ge1xyXG4gICAgICAgIGNvbnN0IHJldEFycmF5ID0gW107XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLndhbGxTdGFydHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgcmV0QXJyYXkucHVzaCh0aGlzLndhbGxTdGFydHNbaV0uZ2V0RW5kKCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMud2FsbEVuZHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgcmV0QXJyYXkucHVzaCh0aGlzLndhbGxFbmRzW2ldLmdldFN0YXJ0KCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmV0QXJyYXk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIENoZWNrcyBpZiBhIHdhbGwgaXMgY29ubmVjdGVkLlxyXG4gICAgICogQHBhcmFtIHdhbGwgQSB3YWxsLlxyXG4gICAgICogQHJldHVybnMgVHJ1ZSBpbiBjYXNlIG9mIGNvbm5lY3Rpb24uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBpc1dhbGxDb25uZWN0ZWQod2FsbDogV2FsbCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy53YWxsU3RhcnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLndhbGxTdGFydHNbaV0gPT09IHdhbGwpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy53YWxsRW5kcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAodGhpcy53YWxsRW5kc1tpXSA9PT0gd2FsbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICpcclxuICAgICAqL1xyXG4gICAgcHVibGljIGRpc3RhbmNlRnJvbSh4OiBudW1iZXIsIHk6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICAgICAgY29uc3QgZGlzdGFuY2UgPSBVdGlscy5kaXN0YW5jZSh4LCB5LCB0aGlzLngsIHRoaXMueSk7XHJcbiAgICAgICAgcmV0dXJuIGRpc3RhbmNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBHZXRzIHRoZSBkaXN0YW5jZSBmcm9tIGEgd2FsbC5cclxuICAgICAqIEBwYXJhbSB3YWxsIEEgd2FsbC5cclxuICAgICAqIEByZXR1cm5zIFRoZSBkaXN0YW5jZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGRpc3RhbmNlRnJvbVdhbGwod2FsbDogV2FsbCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIHdhbGwuZGlzdGFuY2VGcm9tKHRoaXMueCwgdGhpcy55KTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogR2V0cyB0aGUgZGlzdGFuY2UgZnJvbSBhIGNvcm5lci5cclxuICAgICAqIEBwYXJhbSBjb3JuZXIgQSBjb3JuZXIuXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgZGlzdGFuY2UuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkaXN0YW5jZUZyb21Db3JuZXIoY29ybmVyOiBDb3JuZXIpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRpc3RhbmNlRnJvbShjb3JuZXIueCwgY29ybmVyLnkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBEZXRhY2hlcyBhIHdhbGwuXHJcbiAgICAgKiBAcGFyYW0gd2FsbCBBIHdhbGwuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkZXRhY2hXYWxsKHdhbGw6IFdhbGwpIHtcclxuICAgICAgICBVdGlscy5yZW1vdmVWYWx1ZSh0aGlzLndhbGxTdGFydHMsIHdhbGwpO1xyXG4gICAgICAgIFV0aWxzLnJlbW92ZVZhbHVlKHRoaXMud2FsbEVuZHMsIHdhbGwpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBBdHRhY2hlcyBhIHN0YXJ0IHdhbGwuXHJcbiAgICAgKiBAcGFyYW0gd2FsbCBBIHdhbGwuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhdHRhY2hTdGFydCh3YWxsOiBXYWxsKSB7XHJcbiAgICAgICAgdGhpcy53YWxsU3RhcnRzLnB1c2god2FsbCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEF0dGFjaGVzIGFuIGVuZCB3YWxsLlxyXG4gICAgICogQHBhcmFtIHdhbGwgQSB3YWxsLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgYXR0YWNoRW5kKHdhbGw6IFdhbGwpIHtcclxuICAgICAgICB0aGlzLndhbGxFbmRzLnB1c2god2FsbCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEdldCB3YWxsIHRvIGNvcm5lci5cclxuICAgICAqIEBwYXJhbSBjb3JuZXIgQSBjb3JuZXIuXHJcbiAgICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGVkIHdhbGwgb3IgbnVsbC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHdhbGxUbyhjb3JuZXI6IENvcm5lcik6IFdhbGwge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy53YWxsU3RhcnRzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLndhbGxTdGFydHNbaV0uZ2V0RW5kKCkgPT09IGNvcm5lcikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMud2FsbFN0YXJ0c1tpXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKiogR2V0IHdhbGwgZnJvbSBjb3JuZXIuXHJcbiAgICAgKiBAcGFyYW0gY29ybmVyIEEgY29ybmVyLlxyXG4gICAgICogQHJldHVybiBUaGUgYXNzb2NpYXRlZCB3YWxsIG9yIG51bGwuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB3YWxsRnJvbShjb3JuZXI6IENvcm5lcik6IFdhbGwge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy53YWxsRW5kcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAodGhpcy53YWxsRW5kc1tpXS5nZXRTdGFydCgpID09PSBjb3JuZXIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLndhbGxFbmRzW2ldO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiBHZXQgd2FsbCB0byBvciBmcm9tIGNvcm5lci5cclxuICAgICAqIEBwYXJhbSBjb3JuZXIgQSBjb3JuZXIuXHJcbiAgICAgKiBAcmV0dXJuIFRoZSBhc3NvY2lhdGVkIHdhbGwgb3IgbnVsbC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHdhbGxUb09yRnJvbShjb3JuZXI6IENvcm5lcik6IFdhbGwge1xyXG4gICAgICAgIHJldHVybiB0aGlzLndhbGxUbyhjb3JuZXIpIHx8IHRoaXMud2FsbEZyb20oY29ybmVyKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0IHN0YXJ0V2FsbHMoKTogV2FsbFtdIHtcclxuICAgICAgICByZXR1cm4gdGhpcy53YWxsU3RhcnRzO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgZW5kV2FsbHMoKTogV2FsbFtdIHtcclxuICAgICAgICByZXR1cm4gdGhpcy53YWxsRW5kcztcclxuICAgIH1cclxuXHJcbiAgICAvKiogRW5zdXJlIHdlIGRvIG5vdCBoYXZlIGR1cGxpY2F0ZSB3YWxscyAoaS5lLiBzYW1lIHN0YXJ0IGFuZCBlbmQgcG9pbnRzKSAqL1xyXG4gICAgcHVibGljIHJlbW92ZUR1cGxpY2F0ZVdhbGxzKCkge1xyXG4gICAgICAgIC8vIGRlbGV0ZSB0aGUgd2FsbCBiZXR3ZWVuIHRoZXNlIGNvcm5lcnMsIGlmIGl0IGV4aXN0c1xyXG4gICAgICAgIGNvbnN0IHdhbGxFbmRwb2ludHMgPSB7fTtcclxuICAgICAgICBjb25zdCB3YWxsU3RhcnRwb2ludHMgPSB7fTtcclxuICAgICAgICBmb3IgKGxldCBpID0gdGhpcy53YWxsU3RhcnRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLndhbGxTdGFydHNbaV0uZ2V0RW5kKCkgPT09IHRoaXMpIHtcclxuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB6ZXJvIGxlbmd0aCB3YWxsXHJcbiAgICAgICAgICAgICAgICB0aGlzLndhbGxTdGFydHNbaV0ucmVtb3ZlKCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy53YWxsU3RhcnRzW2ldLmdldEVuZCgpLmlkIGluIHdhbGxFbmRwb2ludHMpIHtcclxuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBkdXBsaWNhdGVkIHdhbGxcclxuICAgICAgICAgICAgICAgIHRoaXMud2FsbFN0YXJ0c1tpXS5yZW1vdmUoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHdhbGxFbmRwb2ludHNbdGhpcy53YWxsU3RhcnRzW2ldLmdldEVuZCgpLmlkXSA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMud2FsbEVuZHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMud2FsbEVuZHNbaV0uZ2V0U3RhcnQoKSA9PT0gdGhpcykge1xyXG4gICAgICAgICAgICAgICAgLy8gcmVtb3ZlZCB6ZXJvIGxlbmd0aCB3YWxsXHJcbiAgICAgICAgICAgICAgICB0aGlzLndhbGxFbmRzW2ldLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMud2FsbEVuZHNbaV0uZ2V0U3RhcnQoKS5pZCBpbiB3YWxsU3RhcnRwb2ludHMpIHtcclxuICAgICAgICAgICAgICAgIC8vIHJlbW92ZWQgZHVwbGljYXRlZCB3YWxsXHJcbiAgICAgICAgICAgICAgICB0aGlzLndhbGxFbmRzW2ldLnJlbW92ZSgpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgd2FsbFN0YXJ0cG9pbnRzW3RoaXMud2FsbEVuZHNbaV0uZ2V0U3RhcnQoKS5pZF0gPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBmaW5kIGFuZCByZW1vdmUgY3ljbGUgfiBtb3JlIHRoYW4gYSBzaW5nbGUgd2FsbCBiZXR3ZWVuIDIgY29ybmVyc1xyXG4gICAgICAgIGZvciAoY29uc3Qgb3V0V2FsbCBvZiB0aGlzLndhbGxTdGFydHMpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBpbldhbGwgb2YgdGhpcy53YWxsRW5kcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKG91dFdhbGwuZ2V0RW5kKCkgPT09IGluV2FsbC5nZXRTdGFydCgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb3V0V2FsbC5yZW1vdmUoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEhhbGYgRWRnZXMgYXJlIGNyZWF0ZWQgYnkgUm9vbS5cclxuICpcclxuICogT25jZSByb29tcyBoYXZlIGJlZW4gaWRlbnRpZmllZCwgSGFsZiBFZGdlcyBhcmUgY3JlYXRlZCBmb3IgZWFjaCBpbnRlcmlvciB3YWxsLlxyXG4gKlxyXG4gKiBBIHdhbGwgY2FuIGhhdmUgdHdvIGhhbGYgZWRnZXMgaWYgaXQgaXMgdmlzaWJsZSBmcm9tIGJvdGggc2lkZXMuXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgSGFsZkVkZ2Uge1xyXG5cclxuICAgIC8qKiBUaGUgc3VjY2Vzc29yIGVkZ2UgaW4gQ0NXID8/PyBkaXJlY3Rpb24uICovXHJcbiAgICBwdWJsaWMgbmV4dDogSGFsZkVkZ2U7XHJcblxyXG4gICAgLyoqIFRoZSBwcmVkZWNlc3NvciBlZGdlIGluIENDVyA/Pz8gZGlyZWN0aW9uLiAqL1xyXG4gICAgcHVibGljIHByZXY6IEhhbGZFZGdlO1xyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIG9mZnNldDogbnVtYmVyO1xyXG5cclxuICAgIC8qKiBXaGVuIGhlaWdodCBvZiB3YWxscyBhcmUgbW9kaWZpZWQsIHBsYW5lIHNob3VsZCBiZSByZWNyZWF0ZWQgKi9cclxuICAgIHB1YmxpYyBzZXQgaGVpZ2h0KHZhbHVlOiBudW1iZXIpIHtcclxuICAgICAgICB0aGlzLl9oZWlnaHQgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLmRpc3Bvc2VQbGFuZSgpO1xyXG4gICAgICAgIHRoaXMuZ2VuZXJhdGVQbGFuZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgaGVpZ2h0KCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hlaWdodDtcclxuICAgIH1cclxuXHJcbiAgICAvKiogdXNlZCBmb3IgaW50ZXJzZWN0aW9uIHRlc3RpbmcuLi4gbm90IGNvbnZpbmNlZCB0aGlzIGJlbG9uZ3MgaGVyZSAqL1xyXG4gICAgcHVibGljIHBsYW5lOiBUaHJlZU1lc2ggPSBudWxsO1xyXG5cclxuICAgIC8qKiB0cmFuc2Zvcm0gZnJvbSB3b3JsZCBjb29yZHMgdG8gd2FsbCBwbGFuZXMgKHo9MCkgKi9cclxuICAgIHB1YmxpYyBpbnRlcmlvclRyYW5zZm9ybSA9IG5ldyBNYXRyaXg0KCk7XHJcblxyXG4gICAgLyoqIHRyYW5zZm9ybSBmcm9tIHdvcmxkIGNvb3JkcyB0byB3YWxsIHBsYW5lcyAoej0wKSAqL1xyXG4gICAgcHVibGljIGludkludGVyaW9yVHJhbnNmb3JtID0gbmV3IE1hdHJpeDQoKTtcclxuXHJcbiAgICAvKiogdHJhbnNmb3JtIGZyb20gd29ybGQgY29vcmRzIHRvIHdhbGwgcGxhbmVzICh6PTApICovXHJcbiAgICBwcml2YXRlIGV4dGVyaW9yVHJhbnNmb3JtID0gbmV3IE1hdHJpeDQoKTtcclxuXHJcbiAgICAvKiogdHJhbnNmb3JtIGZyb20gd29ybGQgY29vcmRzIHRvIHdhbGwgcGxhbmVzICh6PTApICovXHJcbiAgICBwcml2YXRlIGludkV4dGVyaW9yVHJhbnNmb3JtID0gbmV3IE1hdHJpeDQoKTtcclxuXHJcbiAgICBwcml2YXRlIF9oZWlnaHQ6IG51bWJlcjtcclxuXHJcbiAgICAvKiogKi9cclxuXHJcbiAgICBwdWJsaWMgZWRnZXM6IEVkZ2VbXSA9IFtdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29uc3RydWN0cyBhIGhhbGYgZWRnZS5cclxuICAgICAqIEBwYXJhbSByb29tIFRoZSBhc3NvY2lhdGVkIHJvb20uXHJcbiAgICAgKiBAcGFyYW0gd2FsbCBUaGUgY29ycmVzcG9uZGluZyB3YWxsLlxyXG4gICAgICogQHBhcmFtIGZyb250IFRydWUgaWYgZnJvbnQgc2lkZS5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSByb29tOiBSb29tLCBwdWJsaWMgd2FsbDogV2FsbCwgcHVibGljIGZyb250OiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5mcm9udCA9IGZyb250IHx8IGZhbHNlO1xyXG5cclxuICAgICAgICB0aGlzLm9mZnNldCA9IHdhbGwudGhpY2tuZXNzIC8gMi4wO1xyXG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gd2FsbC5oZWlnaHQ7XHJcbiAgICAgICAgaWYgKHRoaXMuZnJvbnQpIHtcclxuICAgICAgICAgICAgdGhpcy53YWxsLmZyb250RWRnZSA9IHRoaXM7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy53YWxsLmJhY2tFZGdlID0gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy53YWxsLnVwZGF0ZUluV2FsbEl0ZW1zKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHNob3dIaWRlRWRnZShzaG93OiBib29sZWFuKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5lZGdlcy5mb3JFYWNoKGUgPT4gZS5zaG93SGlkZUVkZ2Uoc2hvdykpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyB1cGRhdGVWaXNpYmlsaXR5KGNhbWVyYVBvc2l0aW9uOiBWZWN0b3IzKTogYm9vbGVhbiB7XHJcbiAgICAgICAgbGV0IHZpc2liaWxpdHlDaGFuZ2VkOiBib29sZWFuID0gbnVsbDtcclxuICAgICAgICB0aGlzLmVkZ2VzLmZvckVhY2goZSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGVkZ2VWaXNpYmlsaXR5Q2hhbmdlZCA9IGUudXBkYXRlVmlzaWJpbGl0eShjYW1lcmFQb3NpdGlvbik7XHJcbiAgICAgICAgICAgIGlmIChlZGdlVmlzaWJpbGl0eUNoYW5nZWQgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHZpc2liaWxpdHlDaGFuZ2VkID0gZWRnZVZpc2liaWxpdHlDaGFuZ2VkO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHZpc2liaWxpdHlDaGFuZ2VkO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyB1cGRhdGVWaXNpYmxpdHkodmlzaWJpbGl0eTogYm9vbGVhbikge1xyXG4gICAgICAgIHRoaXMuZWRnZXMuZm9yRWFjaChlID0+IHtcclxuICAgICAgICAgICAgZS52aXNpYmxlID0gdmlzaWJpbGl0eTtcclxuICAgICAgICAgICAgZS51cGRhdGVPYmplY3RWaXNpYmlsaXR5KCk7XHJcbiAgICAgICAgICAgIGUuc2V0QWxsUGxhbmVzVmlzaWJsZSgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyByZWRyYXcoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgLy8gdGhpcy5lZGdlcy5mb3JFYWNoKGUgPT4gZS5yZWRyYXcoKSk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmVkZ2VzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZWRnZXNbaV0ucmVkcmF3KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICpcclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldFRleHR1cmUoKTogVGV4dHVyZSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZnJvbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2FsbC5mcm9udFRleHR1cmU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2FsbC5iYWNrVGV4dHVyZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldENvbG9yKCk6IG51bWJlciB7XHJcbiAgICAgICAgaWYgKHRoaXMuZnJvbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2FsbC5mcm9udENvbG9yO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLndhbGwuYmFja0NvbG9yO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBhc3luYyBzZXRUZXh0dXJlKHRleHR1cmU6IFRleHR1cmUpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAodGV4dHVyZSkge1xyXG4gICAgICAgICAgICB0ZXh0dXJlLnJvdWdobmVzcyA9ICFpc05pbGwodGV4dHVyZS5yb3VnaG5lc3MpID8gdGV4dHVyZS5yb3VnaG5lc3MgOiAwLjg7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5mcm9udCkge1xyXG4gICAgICAgICAgICB0aGlzLndhbGwuZnJvbnRUZXh0dXJlID0gdGV4dHVyZTtcclxuICAgICAgICAgICAgdGhpcy53YWxsLmZyb250Q29sb3IgPSBkZWZhdWx0V2FsbENvbG9yO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMud2FsbC5iYWNrVGV4dHVyZSA9IHRleHR1cmU7XHJcbiAgICAgICAgICAgIHRoaXMud2FsbC5iYWNrQ29sb3IgPSBkZWZhdWx0V2FsbENvbG9yO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyB0aGlzLnJlZHJhd0NhbGxiYWNrcy5maXJlKCk7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5yZWRyYXcoKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc2V0Q29sb3IodmFsdWU6IG51bWJlcikge1xyXG4gICAgICAgIGlmICh0aGlzLmZyb250KSB7XHJcbiAgICAgICAgICAgIHRoaXMud2FsbC5mcm9udFRleHR1cmUgPSBudWxsO1xyXG4gICAgICAgICAgICB0aGlzLndhbGwuZnJvbnRDb2xvciA9IHZhbHVlO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMud2FsbC5iYWNrVGV4dHVyZSA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMud2FsbC5iYWNrQ29sb3IgPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gdGhpcy5yZWRyYXdDYWxsYmFja3MuZmlyZSgpO1xyXG4gICAgICAgIHRoaXMucmVkcmF3KCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiB0aGlzIGZlZWxzIGhhY2t5LCBidXQgbmVlZCB3YWxsIGl0ZW1zXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZW5lcmF0ZVBsYW5lKCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIHRyYW5zZm9ybUNvcm5lcihjb3JuZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBWZWN0b3IzKGNvcm5lci54LCAwLCBjb3JuZXIueSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLm9mZnNldCA9IHRoaXMud2FsbC50aGlja25lc3MgLyAyLjA7XHJcbiAgICAgICAgdGhpcy5faGVpZ2h0ID0gdGhpcy53YWxsLmhlaWdodDtcclxuXHJcbiAgICAgICAgY29uc3QgdjEgPSB0cmFuc2Zvcm1Db3JuZXIodGhpcy5pbnRlcmlvclN0YXJ0KCkpO1xyXG4gICAgICAgIGNvbnN0IHYyID0gdHJhbnNmb3JtQ29ybmVyKHRoaXMuaW50ZXJpb3JFbmQoKSk7XHJcbiAgICAgICAgY29uc3QgdjMgPSB2Mi5jbG9uZSgpO1xyXG4gICAgICAgIHYzLnkgPSB0aGlzLndhbGwuaGVpZ2h0O1xyXG4gICAgICAgIGNvbnN0IHY0ID0gdjEuY2xvbmUoKTtcclxuICAgICAgICB2NC55ID0gdGhpcy53YWxsLmhlaWdodDtcclxuXHJcbiAgICAgICAgY29uc3QgZ2VvbWV0cnkgPSBuZXcgQnVmZmVyR2VvbWV0cnkoKS5zZXRGcm9tUG9pbnRzKFt2MSwgdjIsIHYzLCB2NF0pO1xyXG4gICAgICAgIGNvbnN0IGZhY2VWZXJ0ZXhJbmRleEFycmF5OiBVaW50MTZBcnJheSA9IG5ldyBVaW50MTZBcnJheShbMCwgMSwgMiwgMCwgMiwgM10pO1xyXG4gICAgICAgIGNvbnN0IGZhY2VCdWZmZXJBdHRyaWJ1dGU6IEJ1ZmZlckF0dHJpYnV0ZSA9IG5ldyBCdWZmZXJBdHRyaWJ1dGUoZmFjZVZlcnRleEluZGV4QXJyYXksIDEpO1xyXG4gICAgICAgIGdlb21ldHJ5LnNldEluZGV4KGZhY2VCdWZmZXJBdHRyaWJ1dGUpO1xyXG4gICAgICAgIGdlb21ldHJ5LmNvbXB1dGVWZXJ0ZXhOb3JtYWxzKCk7XHJcbiAgICAgICAgZ2VvbWV0cnkuY29tcHV0ZUJvdW5kaW5nQm94KCk7XHJcblxyXG4gICAgICAgIHRoaXMucGxhbmUgPSBuZXcgVGhyZWVNZXNoKGdlb21ldHJ5LCBuZXcgTWVzaFBoeXNpY2FsTWF0ZXJpYWwobnVsbCkpO1xyXG4gICAgICAgIHRoaXMucGxhbmUubmFtZSA9IGBoYWxmLWVkZ2UtcGxhbmUtJHt0aGlzLmZyb250ID8gJ2Zyb250JyA6ICdiYWNrJ31gO1xyXG4gICAgICAgIHRoaXMucGxhbmUuY2FzdFNoYWRvdyA9IHRydWU7XHJcbiAgICAgICAgVXRpbHMuc2V0UGxhbmVWaXNpYmlsaXR5KHRoaXMucGxhbmUsIHRydWUpO1xyXG4gICAgICAgIHRoaXMucGxhbmUudXNlckRhdGEuZWRnZSA9IHRoaXM7XHJcblxyXG4gICAgICAgIHRoaXMuY29tcHV0ZVRyYW5zZm9ybXMoXHJcbiAgICAgICAgICAgIHRoaXMuaW50ZXJpb3JUcmFuc2Zvcm0sIHRoaXMuaW52SW50ZXJpb3JUcmFuc2Zvcm0sXHJcbiAgICAgICAgICAgIHRoaXMuaW50ZXJpb3JTdGFydCgpLCB0aGlzLmludGVyaW9yRW5kKCkpO1xyXG4gICAgICAgIHRoaXMuY29tcHV0ZVRyYW5zZm9ybXMoXHJcbiAgICAgICAgICAgIHRoaXMuZXh0ZXJpb3JUcmFuc2Zvcm0sIHRoaXMuaW52RXh0ZXJpb3JUcmFuc2Zvcm0sXHJcbiAgICAgICAgICAgIHRoaXMuZXh0ZXJpb3JTdGFydCgpLCB0aGlzLmV4dGVyaW9yRW5kKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBkaXNwb3NlUGxhbmUoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMucGxhbmUpIHtcclxuICAgICAgICAgICAgVXRpbHMuRGlzcG9zZU9iamVjdCh0aGlzLnBsYW5lKTtcclxuICAgICAgICAgICAgdGhpcy5wbGFuZSA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBpbnRlcmlvckRpc3RhbmNlKCk6IG51bWJlciB7XHJcbiAgICAgICAgY29uc3Qgc3RhcnQgPSB0aGlzLmludGVyaW9yU3RhcnQoKTtcclxuICAgICAgICBjb25zdCBlbmQgPSB0aGlzLmludGVyaW9yRW5kKCk7XHJcbiAgICAgICAgcmV0dXJuIFV0aWxzLmRpc3RhbmNlKHN0YXJ0LngsIHN0YXJ0LnksIGVuZC54LCBlbmQueSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBjb21wdXRlVHJhbnNmb3Jtcyh0cmFuc2Zvcm0sIGludlRyYW5zZm9ybSwgc3RhcnQsIGVuZCkge1xyXG5cclxuICAgICAgICBjb25zdCB2MSA9IHN0YXJ0O1xyXG4gICAgICAgIGNvbnN0IHYyID0gZW5kO1xyXG5cclxuICAgICAgICBjb25zdCBhbmdsZSA9IFV0aWxzLmFuZ2xlKDEsIDAsIHYyLnggLSB2MS54LCB2Mi55IC0gdjEueSk7XHJcblxyXG4gICAgICAgIGNvbnN0IHR0ID0gbmV3IE1hdHJpeDQoKTtcclxuICAgICAgICB0dC5tYWtlVHJhbnNsYXRpb24oLXYxLngsIDAsIC12MS55KTtcclxuICAgICAgICBjb25zdCB0ciA9IG5ldyBNYXRyaXg0KCk7XHJcbiAgICAgICAgdHIubWFrZVJvdGF0aW9uWSgtYW5nbGUpO1xyXG4gICAgICAgIHRyYW5zZm9ybS5tdWx0aXBseU1hdHJpY2VzKHRyLCB0dCk7XHJcbiAgICAgICAgaW52VHJhbnNmb3JtLmNvcHkodHJhbnNmb3JtKS5pbnZlcnQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogR2V0cyB0aGUgZGlzdGFuY2UgZnJvbSBzcGVjaWZpZWQgcG9pbnQuXHJcbiAgICAgKiBAcGFyYW0geCBYIGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50LlxyXG4gICAgICogQHBhcmFtIHkgWSBjb29yZGluYXRlIG9mIHRoZSBwb2ludC5cclxuICAgICAqIEByZXR1cm5zIFRoZSBkaXN0YW5jZS5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGRpc3RhbmNlVG8oeDogbnVtYmVyLCB5OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIC8vIHgsIHksIHgxLCB5MSwgeDIsIHkyXHJcbiAgICAgICAgcmV0dXJuIFV0aWxzLnBvaW50RGlzdGFuY2VGcm9tTGluZSh4LCB5LFxyXG4gICAgICAgICAgICB0aGlzLmludGVyaW9yU3RhcnQoKS54LFxyXG4gICAgICAgICAgICB0aGlzLmludGVyaW9yU3RhcnQoKS55LFxyXG4gICAgICAgICAgICB0aGlzLmludGVyaW9yRW5kKCkueCxcclxuICAgICAgICAgICAgdGhpcy5pbnRlcmlvckVuZCgpLnkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRTdGFydCgpIHtcclxuICAgICAgICBpZiAodGhpcy5mcm9udCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy53YWxsLmdldFN0YXJ0KCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2FsbC5nZXRFbmQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldEVuZCgpIHtcclxuICAgICAgICBpZiAodGhpcy5mcm9udCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy53YWxsLmdldEVuZCgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLndhbGwuZ2V0U3RhcnQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRPcHBvc2l0ZUVkZ2UoKTogSGFsZkVkZ2Uge1xyXG4gICAgICAgIGlmICh0aGlzLmZyb250KSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLndhbGwuYmFja0VkZ2U7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMud2FsbC5mcm9udEVkZ2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIHRoZXNlIHJldHVybiBhbiBvYmplY3Qgd2l0aCBhdHRyaWJ1dGVzIHgsIHlcclxuICAgIHB1YmxpYyBpbnRlcmlvckVuZCgpOiBWZWN0b3IyIHtcclxuICAgICAgICBjb25zdCB2ZWMgPSB0aGlzLmhhbGZBbmdsZVZlY3Rvcih0aGlzLCB0aGlzLm5leHQpO1xyXG4gICAgICAgIHJldHVybiBuZXcgVmVjdG9yMih0aGlzLmdldEVuZCgpLnggKyB2ZWMueCwgdGhpcy5nZXRFbmQoKS55ICsgdmVjLnkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBpbnRlcmlvclN0YXJ0KCk6IFZlY3RvcjIge1xyXG4gICAgICAgIGNvbnN0IHZlYyA9IHRoaXMuaGFsZkFuZ2xlVmVjdG9yKHRoaXMucHJldiwgdGhpcyk7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBWZWN0b3IyKHRoaXMuZ2V0U3RhcnQoKS54ICsgdmVjLngsIHRoaXMuZ2V0U3RhcnQoKS55ICsgdmVjLnkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBpbnRlcmlvckNlbnRlcigpOiBWZWN0b3IyIHtcclxuICAgICAgICByZXR1cm4gbmV3IFZlY3RvcjIoKHRoaXMuaW50ZXJpb3JTdGFydCgpLnggKyB0aGlzLmludGVyaW9yRW5kKCkueCkgLyAyLjAsICh0aGlzLmludGVyaW9yU3RhcnQoKS55ICsgdGhpcy5pbnRlcmlvckVuZCgpLnkpIC8gMi4wKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZXh0ZXJpb3JFbmQoKTogVmVjdG9yMiB7XHJcbiAgICAgICAgY29uc3QgdmVjID0gdGhpcy5oYWxmQW5nbGVWZWN0b3IodGhpcywgdGhpcy5uZXh0KTtcclxuICAgICAgICByZXR1cm4gbmV3IFZlY3RvcjIodGhpcy5nZXRFbmQoKS54IC0gdmVjLngsIHRoaXMuZ2V0RW5kKCkueSAtIHZlYy55KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZXh0ZXJpb3JTdGFydCgpOiBWZWN0b3IyIHtcclxuICAgICAgICBjb25zdCB2ZWMgPSB0aGlzLmhhbGZBbmdsZVZlY3Rvcih0aGlzLnByZXYsIHRoaXMpO1xyXG4gICAgICAgIHJldHVybiBuZXcgVmVjdG9yMih0aGlzLmdldFN0YXJ0KCkueCAtIHZlYy54LCB0aGlzLmdldFN0YXJ0KCkueSAtIHZlYy55KTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogR2V0IHRoZSBjb3JuZXJzIG9mIHRoZSBoYWxmIGVkZ2UuXHJcbiAgICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiB4LHkgcGFpcnMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjb3JuZXJzKCk6IHsgeDogbnVtYmVyLCB5OiBudW1iZXIgfVtdIHtcclxuICAgICAgICByZXR1cm4gW3RoaXMuaW50ZXJpb3JTdGFydCgpLCB0aGlzLmludGVyaW9yRW5kKCksXHJcbiAgICAgICAgICAgIHRoaXMuZXh0ZXJpb3JFbmQoKSwgdGhpcy5leHRlcmlvclN0YXJ0KCldO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBDQ1cgYW5nbGUgZnJvbSB2MSB0byB2MlxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGhhbGZBbmdsZVZlY3Rvcih2MTogSGFsZkVkZ2UsIHYyOiBIYWxmRWRnZSk6IFZlY3RvcjIge1xyXG4gICAgICAgIC8vIG1ha2UgdGhlIGJlc3Qgb2YgdGhpbmdzIGlmIHdlIGRvbnQgaGF2ZSBwcmV2IG9yIG5leHRcclxuICAgICAgICBsZXQgdjFzdGFydFg7XHJcbiAgICAgICAgbGV0IHYxc3RhcnRZO1xyXG4gICAgICAgIGxldCB2MWVuZFg7XHJcbiAgICAgICAgbGV0IHYxZW5kWTtcclxuICAgICAgICBsZXQgdjJzdGFydFg7XHJcbiAgICAgICAgbGV0IHYyc3RhcnRZO1xyXG4gICAgICAgIGxldCB2MmVuZFg7XHJcbiAgICAgICAgbGV0IHYyZW5kWTtcclxuXHJcbiAgICAgICAgaWYgKCF2MSkge1xyXG4gICAgICAgICAgICB2MXN0YXJ0WCA9IHYyLmdldFN0YXJ0KCkueCAtICh2Mi5nZXRFbmQoKS54IC0gdjIuZ2V0U3RhcnQoKS54KTtcclxuICAgICAgICAgICAgdjFzdGFydFkgPSB2Mi5nZXRTdGFydCgpLnkgLSAodjIuZ2V0RW5kKCkueSAtIHYyLmdldFN0YXJ0KCkueSk7XHJcbiAgICAgICAgICAgIHYxZW5kWCA9IHYyLmdldFN0YXJ0KCkueDtcclxuICAgICAgICAgICAgdjFlbmRZID0gdjIuZ2V0U3RhcnQoKS55O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHYxc3RhcnRYID0gPG51bWJlcj52MS5nZXRTdGFydCgpLng7XHJcbiAgICAgICAgICAgIHYxc3RhcnRZID0gPG51bWJlcj52MS5nZXRTdGFydCgpLnk7XHJcbiAgICAgICAgICAgIHYxZW5kWCA9IHYxLmdldEVuZCgpLng7XHJcbiAgICAgICAgICAgIHYxZW5kWSA9IHYxLmdldEVuZCgpLnk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXYyKSB7XHJcbiAgICAgICAgICAgIHYyc3RhcnRYID0gdjEuZ2V0RW5kKCkueDtcclxuICAgICAgICAgICAgdjJzdGFydFkgPSB2MS5nZXRFbmQoKS55O1xyXG4gICAgICAgICAgICB2MmVuZFggPSB2MS5nZXRFbmQoKS54ICsgKHYxLmdldEVuZCgpLnggLSB2MS5nZXRTdGFydCgpLngpO1xyXG4gICAgICAgICAgICB2MmVuZFkgPSB2MS5nZXRFbmQoKS55ICsgKHYxLmdldEVuZCgpLnkgLSB2MS5nZXRTdGFydCgpLnkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHYyc3RhcnRYID0gdjIuZ2V0U3RhcnQoKS54O1xyXG4gICAgICAgICAgICB2MnN0YXJ0WSA9IHYyLmdldFN0YXJ0KCkueTtcclxuICAgICAgICAgICAgdjJlbmRYID0gdjIuZ2V0RW5kKCkueDtcclxuICAgICAgICAgICAgdjJlbmRZID0gdjIuZ2V0RW5kKCkueTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIENDVyBhbmdsZSBiZXR3ZWVuIGVkZ2VzXHJcbiAgICAgICAgY29uc3QgdGhldGEgPSBVdGlscy5hbmdsZTJwaShcclxuICAgICAgICAgICAgdjFzdGFydFggLSB2MWVuZFgsXHJcbiAgICAgICAgICAgIHYxc3RhcnRZIC0gdjFlbmRZLFxyXG4gICAgICAgICAgICB2MmVuZFggLSB2MWVuZFgsXHJcbiAgICAgICAgICAgIHYyZW5kWSAtIHYxZW5kWSk7XHJcblxyXG4gICAgICAgIC8vIGNvc2luZSBhbmQgc2luZSBvZiBoYWxmIGFuZ2xlXHJcbiAgICAgICAgY29uc3QgY3MgPSBNYXRoLmNvcyh0aGV0YSAvIDIuMCk7XHJcbiAgICAgICAgY29uc3Qgc24gPSBNYXRoLnNpbih0aGV0YSAvIDIuMCk7XHJcblxyXG4gICAgICAgIC8vIHJvdGF0ZSB2MlxyXG4gICAgICAgIGNvbnN0IHYyZHggPSB2MmVuZFggLSB2MnN0YXJ0WDtcclxuICAgICAgICBjb25zdCB2MmR5ID0gdjJlbmRZIC0gdjJzdGFydFk7XHJcblxyXG4gICAgICAgIGNvbnN0IHZ4ID0gdjJkeCAqIGNzIC0gdjJkeSAqIHNuO1xyXG4gICAgICAgIGNvbnN0IHZ5ID0gdjJkeCAqIHNuICsgdjJkeSAqIGNzO1xyXG5cclxuICAgICAgICAvLyBub3JtYWxpemVcclxuICAgICAgICBjb25zdCBtYWcgPSBVdGlscy5kaXN0YW5jZSgwLCAwLCB2eCwgdnkpO1xyXG4gICAgICAgIGNvbnN0IGRlc2lyZWRNYWcgPSAodGhpcy5vZmZzZXQpIC8gc247XHJcbiAgICAgICAgY29uc3Qgc2NhbGFyID0gZGVzaXJlZE1hZyAvIG1hZztcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBWZWN0b3IyKHZ4ICogc2NhbGFyLCB2eSAqIHNjYWxhcik7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldCBpbnZFeHRlcmlvclF1YXRlcm5pb24oKTogUXVhdGVybmlvbiB7XHJcbiAgICAgICAgY29uc3QgcXVhdGVybmlvbiA9IG5ldyBRdWF0ZXJuaW9uKCk7XHJcbiAgICAgICAgcXVhdGVybmlvbi5zZXRGcm9tUm90YXRpb25NYXRyaXgodGhpcy5pbnZFeHRlcmlvclRyYW5zZm9ybSk7XHJcbiAgICAgICAgcmV0dXJuIHF1YXRlcm5pb247XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBFZGdlIHtcclxuICAgIHByaXZhdGUgX2ZpbGxlckNvbG9yID0gbmV3IENvbG9yKDB4ZGRkZGRkKTtcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgX3dhbGw6IFdhbGw7XHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9mcm9udDogYm9vbGVhbjtcclxuXHJcbiAgICBwcml2YXRlIF9maWxsZXJNYXRlcmlhbDogVEhSRUUuTWVzaEJhc2ljTWF0ZXJpYWw7XHJcbiAgICBwcml2YXRlIF93YWxsTWF0ZXJpYWw6IFRIUkVFLk1lc2hQaG9uZ01hdGVyaWFsO1xyXG4gICAgcHJpdmF0ZSBfcGxhbmVzOiB7XHJcbiAgICAgICAgZXh0ZXJpb3I6IE1lc2gsXHJcbiAgICAgICAgaW50ZXJpb3I6IE1lc2gsXHJcbiAgICAgICAgc2lkZXM6IE1lc2hbXSxcclxuICAgICAgICBib3R0b206IE1lc2gsXHJcbiAgICAgICAgdG9wOiBNZXNoXHJcbiAgICB9ID0ge1xyXG4gICAgICAgIGV4dGVyaW9yOiBudWxsLFxyXG4gICAgICAgIGludGVyaW9yOiBudWxsLFxyXG4gICAgICAgIHNpZGVzOiBudWxsLFxyXG4gICAgICAgIGJvdHRvbTogbnVsbCxcclxuICAgICAgICB0b3A6IG51bGxcclxuICAgIH07XHJcblxyXG4gICAgcHJpdmF0ZSBfbGFzdDoge1xyXG4gICAgICAgIGNvbG9yOiBudW1iZXIsXHJcbiAgICAgICAgdGV4dHVyZTogVGV4dHVyZSxcclxuICAgICAgICBmaWxsZXJNYXRlcmlhbDogTWVzaEJhc2ljTWF0ZXJpYWwsXHJcbiAgICAgICAgd2FsbE1hdGVyaWFsOiBNZXNoUGhvbmdNYXRlcmlhbCxcclxuICAgICAgICBoZWlnaHQ6IG51bWJlclxyXG4gICAgfSA9IHtcclxuICAgICAgICBjb2xvcjogbnVsbCxcclxuICAgICAgICB0ZXh0dXJlOiBudWxsLFxyXG4gICAgICAgIGZpbGxlck1hdGVyaWFsOiBudWxsLFxyXG4gICAgICAgIHdhbGxNYXRlcmlhbDogbnVsbCxcclxuICAgICAgICBoZWlnaHQ6IG51bGxcclxuICAgIH07XHJcblxyXG4gICAgcHVibGljIHZpc2libGU7XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBfaGFsZkVkZ2U6IEhhbGZFZGdlKSB7XHJcbiAgICAgICAgaWYgKF9oYWxmRWRnZSkge1xyXG4gICAgICAgICAgICB0aGlzLl93YWxsID0gX2hhbGZFZGdlLndhbGw7XHJcbiAgICAgICAgICAgIHRoaXMuX2Zyb250ID0gX2hhbGZFZGdlLmZyb250O1xyXG4gICAgICAgICAgICAvLyB0aGlzLnVwZGF0ZVBsYW5lcygpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc2hvd0hpZGVFZGdlKHNob3c6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9wbGFuZUxpc3QoKS5mb3JFYWNoKHAgPT4gcC52aXNpYmxlID0gc2hvdyk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfcGxhbmVMaXN0KCk6IE1lc2hbXSB7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLl9wbGFuZXMuc2lkZXMgfHwgW10pLmNvbmNhdChbXHJcbiAgICAgICAgICAgIHRoaXMuX3BsYW5lcy50b3AsXHJcbiAgICAgICAgICAgIHRoaXMuX3BsYW5lcy5ib3R0b20sXHJcbiAgICAgICAgICAgIHRoaXMuX3BsYW5lcy5pbnRlcmlvcixcclxuICAgICAgICAgICAgdGhpcy5fcGxhbmVzLmV4dGVyaW9yXHJcbiAgICAgICAgXSkuZmlsdGVyKHggPT4geCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldFBsYW5lcygpOiBNZXNoW10ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wbGFuZUxpc3QoKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0VG9wU2lkZUZpbGxlcnMoKTogTWVzaFtdIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcGxhbmVzLnNpZGVzLmNvbmNhdChbdGhpcy5fcGxhbmVzLnRvcF0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyBpbml0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIC8vIHRoaXMuaGFsZkVkZ2UucmVkcmF3Q2FsbGJhY2tzLmFkZCh0aGlzLnJlZHJhdyk7XHJcbiAgICAgICAgLy8gaGFsZkVkZ2UuaXRlbUFkZGVkQ2FsbGJhY2tzLmFkZCh1cGRhdGVPYmplY3RWaXNpYmlsaXR5KTtcclxuICAgICAgICAvLyBjb250cm9scy5jYW1lcmFNb3ZlZENhbGxiYWNrcy5hZGQodXBkYXRlVmlzaWJpbGl0eSk7XHJcbiAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVQbGFuZXMoKTtcclxuICAgICAgICAvLyBhZGRUb1NjZW5lKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIHJlZHJhdygpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZVBsYW5lcygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHByaXZhdGUgcmVtb3ZlRnJvbVNjZW5lKCkge1xyXG4gICAgLy8gICB0aGlzLnBsYW5lTGlzdCgpLmZvckVhY2goKHBsYW5lKSA9PiB7XHJcbiAgICAvLyAgICAgc2NlbmUucmVtb3ZlKHBsYW5lKTtcclxuICAgIC8vICAgICBVdGlscy5kaXNwb3NlT2JqZWN0KHBsYW5lKTtcclxuICAgIC8vICAgfSk7XHJcbiAgICAvLyAgIE9iamVjdC5rZXlzKHBsYW5lcykuZm9yRWFjaCgoa2V5OiBzdHJpbmcpID0+IHBsYW5lc1trZXldID0gbnVsbCk7XHJcbiAgICAvLyAgIE9iamVjdC5rZXlzKGxhc3QpLmZvckVhY2goKGtleTogc3RyaW5nKSA9PiBsYXN0W2tleV0gPSBudWxsKTtcclxuICAgIC8vIH1cclxuXHJcbiAgICAvLyBwcml2YXRlIGFkZFRvU2NlbmUoKSB7XHJcbiAgICAvLyAgIHBsYW5lTGlzdCgpLmZvckVhY2goKHBsYW5lKSA9PiB7XHJcbiAgICAvLyAgICAgc2NlbmUuYWRkKHBsYW5lKTtcclxuICAgIC8vICAgfSk7XHJcbiAgICAvLyAgIHVwZGF0ZVZpc2liaWxpdHkoKTtcclxuICAgIC8vIH1cclxuXHJcbiAgICBwdWJsaWMgdXBkYXRlVmlzaWJpbGl0eShjYW1lcmFQb3NpdGlvbjogVmVjdG9yMyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIC8vIGZpbmRzIHRoZSBub3JtYWwgZnJvbSB0aGUgc3BlY2lmaWVkIGhhbGZFZGdlXHJcbiAgICAgICAgY29uc3Qgc3RhcnQgPSB0aGlzLl9oYWxmRWRnZS5pbnRlcmlvclN0YXJ0KCk7XHJcbiAgICAgICAgY29uc3QgZW5kID0gdGhpcy5faGFsZkVkZ2UuaW50ZXJpb3JFbmQoKTtcclxuICAgICAgICBjb25zdCB4ID0gZW5kLnggLSBzdGFydC54O1xyXG4gICAgICAgIGNvbnN0IHkgPSBlbmQueSAtIHN0YXJ0Lnk7XHJcbiAgICAgICAgLy8gcm90YXRlIDkwIGRlZ3JlZXMgQ0NXXHJcbiAgICAgICAgY29uc3Qgbm9ybWFsID0gbmV3IFZlY3RvcjMoLXksIDAsIHgpO1xyXG4gICAgICAgIG5vcm1hbC5ub3JtYWxpemUoKTtcclxuXHJcbiAgICAgICAgLy8gc2V0dXAgY2FtZXJhXHJcbiAgICAgICAgY29uc3QgcG9zaXRpb24gPSBjYW1lcmFQb3NpdGlvbi5jbG9uZSgpO1xyXG4gICAgICAgIGNvbnN0IGZvY3VzID0gbmV3IFZlY3RvcjMoXHJcbiAgICAgICAgICAgIChzdGFydC54ICsgZW5kLngpIC8gMi4wLFxyXG4gICAgICAgICAgICAwLFxyXG4gICAgICAgICAgICAoc3RhcnQueSArIGVuZC55KSAvIDIuMCk7XHJcbiAgICAgICAgY29uc3QgZGlyZWN0aW9uID0gcG9zaXRpb24uc3ViKGZvY3VzKS5ub3JtYWxpemUoKTtcclxuXHJcbiAgICAgICAgLy8gZmluZCBkb3RcclxuICAgICAgICBjb25zdCBkb3QgPSBub3JtYWwuZG90KGRpcmVjdGlvbik7XHJcblxyXG4gICAgICAgIC8vIHVwZGF0ZSB2aXNpYmxlXHJcbiAgICAgICAgY29uc3QgbmV3VmlzaWJsZSA9IChkb3QgPj0gMCk7XHJcblxyXG4gICAgICAgIC8vIHNob3cgb3IgaGlkZSBwbGFuc1xyXG4gICAgICAgIHRoaXMuX3BsYW5lTGlzdCgpLmZvckVhY2goKHBsYW5lOiBUSFJFRS5NZXNoKSA9PlxyXG4gICAgICAgICAgICBVdGlscy5zZXRQbGFuZVZpc2liaWxpdHkocGxhbmUsIG5ld1Zpc2libGUpXHJcbiAgICAgICAgKTtcclxuICAgICAgICBpZiAobmV3VmlzaWJsZSAhPT0gdGhpcy52aXNpYmxlKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlzaWJsZSA9IG5ld1Zpc2libGU7XHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlT2JqZWN0VmlzaWJpbGl0eSgpO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3VmlzaWJsZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHVwZGF0ZU9iamVjdFZpc2liaWxpdHkoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fd2FsbC5pdGVtcy5mb3JFYWNoKChpdGVtOiBXYWxsSXRlbSkgPT4ge1xyXG4gICAgICAgICAgICBpdGVtLnVwZGF0ZUVkZ2VWaXNpYmlsaXR5KHRoaXMpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuX3dhbGwub25JdGVtcy5mb3JFYWNoKChpdGVtOiBXYWxsSXRlbSkgPT4ge1xyXG4gICAgICAgICAgICBpdGVtLnVwZGF0ZUVkZ2VWaXNpYmlsaXR5KHRoaXMpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzZXRBbGxQbGFuZXNWaXNpYmxlKCkge1xyXG4gICAgICAgIHRoaXMuX3BsYW5lTGlzdCgpLmZvckVhY2goKHBsYW5lOiBUSFJFRS5NZXNoKSA9PlxyXG4gICAgICAgICAgICBVdGlscy5zZXRQbGFuZVZpc2liaWxpdHkocGxhbmUsIHRydWUpXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFzeW5jIF9hZGRNYXRlcmlhbE1hcChtYXRlcmlhbDogVEhSRUUuTWVzaFBob25nTWF0ZXJpYWwgfCBUSFJFRS5NZXNoU3RhbmRhcmRNYXRlcmlhbCwgdGV4dHVyZTogVGV4dHVyZSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGNvbnN0IGRpbWVuc2lvbnMgPSBuZXcgVEhSRUUuVmVjdG9yMihcclxuICAgICAgICAgICAgdGhpcy5faGFsZkVkZ2UuaW50ZXJpb3JEaXN0YW5jZSgpLFxyXG4gICAgICAgICAgICB0aGlzLl93YWxsLmhlaWdodCAtIHRoaXMuX3dhbGwudGhpY2tuZXNzXHJcbiAgICAgICAgKTtcclxuICAgICAgICB0ZXh0dXJlLmRpbWVuc2lvbnMgPSBkaW1lbnNpb25zLm11bHRpcGx5U2NhbGFyKDEwMCk7XHJcbiAgICAgICAgc3dpdGNoICh0ZXh0dXJlLnR5cGUpIHtcclxuICAgICAgICAgICAgY2FzZSBUZXh0dXJlVHlwZS5JbWFnZTpcclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsLm1hcCA9IGF3YWl0IE1hdGVyaWFsVXRpbHMuRnJvbUltYWdlKHRleHR1cmUpO1xyXG4gICAgICAgICAgICAgICAgbWF0ZXJpYWwubWFwLmNvbG9yU3BhY2UgPSBTUkdCQ29sb3JTcGFjZTtcclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsLm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIFRleHR1cmVUeXBlLkN1c3RvbVBhdHRlcm46XHJcbiAgICAgICAgICAgICAgICBtYXRlcmlhbC5tYXAgPSBhd2FpdCBNYXRlcmlhbFV0aWxzLkN1c3RvbVRpbGVNYXBUZXh0dXJlKHRleHR1cmUsIGRpbWVuc2lvbnMpO1xyXG4gICAgICAgICAgICAgICAgbWF0ZXJpYWwubWFwLmNvbG9yU3BhY2UgPSBTUkdCQ29sb3JTcGFjZTtcclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsLm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIFRleHR1cmVUeXBlLkJhc2ljOlxyXG4gICAgICAgICAgICAgICAgbWF0ZXJpYWwubWFwID0gYXdhaXQgTWF0ZXJpYWxVdGlscy5Gcm9tVXJsKHRleHR1cmUudXJsLCB0ZXh0dXJlLnN0cmV0Y2gsIHRleHR1cmUudGlsZVNpemUsIG51bGwsIG51bGwsIHRleHR1cmUuZGltZW5zaW9ucywgdGV4dHVyZS50aWxlUm90YXRpb24pO1xyXG4gICAgICAgICAgICAgICAgbWF0ZXJpYWwubWFwLmNvbG9yU3BhY2UgPSBTUkdCQ29sb3JTcGFjZTtcclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsLm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIFRleHR1cmVUeXBlLlBCUjpcclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsID0gbWF0ZXJpYWwgYXMgTWVzaFN0YW5kYXJkTWF0ZXJpYWw7XHJcbiAgICAgICAgICAgICAgICBpZiAodGV4dHVyZS5tYXRlcmlhbGl6ZVVybCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IE1hdGVyaWFsVXRpbHMubG9hZE1hdGVyaWFsaXplTWFwcyhtYXRlcmlhbCwgdGV4dHVyZSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIG1hdGVyaWFsLm1hcCA9IGF3YWl0IE1hdGVyaWFsVXRpbHMuRnJvbVVybCh0ZXh0dXJlLnVybCwgdGV4dHVyZS5zdHJldGNoLCB0ZXh0dXJlLnRpbGVTaXplLCB0ZXh0dXJlLnJlcGVhdFgsIHRleHR1cmUucmVwZWF0WSwgdGV4dHVyZS5kaW1lbnNpb25zLCB0ZXh0dXJlLnRpbGVSb3RhdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgbWF0ZXJpYWwubWFwLmNvbG9yU3BhY2UgPSBTUkdCQ29sb3JTcGFjZTtcclxuICAgICAgICAgICAgICAgICAgICBtYXRlcmlhbC5yb3VnaG5lc3NNYXAgPSB0ZXh0dXJlLnJvdWdobmVzc01hcCA/IGF3YWl0IE1hdGVyaWFsVXRpbHMuRnJvbVVybCh0ZXh0dXJlLnJvdWdobmVzc01hcCwgdGV4dHVyZS5zdHJldGNoLCB0ZXh0dXJlLnRpbGVTaXplLCB0ZXh0dXJlLnJlcGVhdFgsIHRleHR1cmUucmVwZWF0WSwgdGV4dHVyZS5kaW1lbnNpb25zLCB0ZXh0dXJlLnRpbGVSb3RhdGlvbikgOiBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIG1hdGVyaWFsLmJ1bXBNYXAgPSB0ZXh0dXJlLmJ1bXBNYXAgPyBhd2FpdCBNYXRlcmlhbFV0aWxzLkZyb21VcmwodGV4dHVyZS5idW1wTWFwLCB0ZXh0dXJlLnN0cmV0Y2gsIHRleHR1cmUudGlsZVNpemUsIHRleHR1cmUucmVwZWF0WCwgdGV4dHVyZS5yZXBlYXRZLCB0ZXh0dXJlLmRpbWVuc2lvbnMsIHRleHR1cmUudGlsZVJvdGF0aW9uKSA6IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgbWF0ZXJpYWwubm9ybWFsTWFwID0gdGV4dHVyZS5ub3JtYWxNYXAgPyBhd2FpdCBNYXRlcmlhbFV0aWxzLkZyb21VcmwodGV4dHVyZS5ub3JtYWxNYXAsIHRleHR1cmUuc3RyZXRjaCwgdGV4dHVyZS50aWxlU2l6ZSwgdGV4dHVyZS5yZXBlYXRYLCB0ZXh0dXJlLnJlcGVhdFksIHRleHR1cmUuZGltZW5zaW9ucywgdGV4dHVyZS50aWxlUm90YXRpb24pIDogbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICBtYXRlcmlhbC5tZXRhbG5lc3NNYXAgPSB0ZXh0dXJlLm1ldGFsbmVzc01hcCA/IGF3YWl0IE1hdGVyaWFsVXRpbHMuRnJvbVVybCh0ZXh0dXJlLm1ldGFsbmVzc01hcCwgdGV4dHVyZS5zdHJldGNoLCB0ZXh0dXJlLnRpbGVTaXplLCB0ZXh0dXJlLnJlcGVhdFgsIHRleHR1cmUucmVwZWF0WSwgdGV4dHVyZS5kaW1lbnNpb25zLCB0ZXh0dXJlLnRpbGVSb3RhdGlvbikgOiBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIG1hdGVyaWFsLmFvTWFwID0gdGV4dHVyZS5hb01hcCA/IGF3YWl0IE1hdGVyaWFsVXRpbHMuRnJvbVVybCh0ZXh0dXJlLmFvTWFwLCB0ZXh0dXJlLnN0cmV0Y2gsIHRleHR1cmUudGlsZVNpemUsIHRleHR1cmUucmVwZWF0WCwgdGV4dHVyZS5yZXBlYXRZLCB0ZXh0dXJlLmRpbWVuc2lvbnMsIHRleHR1cmUudGlsZVJvdGF0aW9uKSA6IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgbWF0ZXJpYWwubmVlZHNVcGRhdGUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9pc1ZhbGlkKHN0YXJ0RW5kKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuICFzdGFydEVuZC5maW5kKGUgPT4gIWlzRmluaXRlKGUueCkgfHwgIWlzRmluaXRlKGUueSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3VwZGF0ZUZpbGxlck1hdGVyaWFsKCk6IE1lc2hCYXNpY01hdGVyaWFsIHtcclxuICAgICAgICBpZiAodGhpcy5fZmlsbGVyTWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZpbGxlck1hdGVyaWFsO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBtYXRlcmlhbDogTWVzaEJhc2ljTWF0ZXJpYWwgPSBuZXcgTWVzaEJhc2ljTWF0ZXJpYWwoe1xyXG4gICAgICAgICAgICBjb2xvcjogdGhpcy5fZmlsbGVyQ29sb3IsXHJcbiAgICAgICAgICAgIHNpZGU6IERvdWJsZVNpZGVcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gbWF0ZXJpYWw7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhc3luYyBfdXBkYXRlV2FsbE1hdGVyaWFsKHRleHR1cmU6IFRleHR1cmUsIGNvbG9yOiBudW1iZXIgPSBkZWZhdWx0RWRnZUNvbG9yKTogUHJvbWlzZTxNZXNoUGhvbmdNYXRlcmlhbD4ge1xyXG4gICAgICAgIGNvbnN0IGlzU2FtZUNvbG9yID0gY29sb3IgJiYgdGhpcy5fbGFzdC5jb2xvciAmJiBjb2xvciA9PT0gdGhpcy5fbGFzdC5jb2xvcjtcclxuICAgICAgICBjb25zdCBpc1NhbWVUZXh0dXJlID0gc2FtZVRleHR1cmVzKHRleHR1cmUsIHRoaXMuX2xhc3QudGV4dHVyZSk7XHJcbiAgICAgICAgaWYgKGlzU2FtZUNvbG9yICYmIGlzU2FtZVRleHR1cmUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dhbGxNYXRlcmlhbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFpc1NhbWVDb2xvcikge1xyXG4gICAgICAgICAgICB0aGlzLl9sYXN0LmNvbG9yID0gY29sb3I7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghaXNTYW1lVGV4dHVyZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9sYXN0LnRleHR1cmUgPSBPYmplY3QuYXNzaWduKHt9LCB0ZXh0dXJlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBtYXRlcmlhbDtcclxuICAgICAgICBtYXRlcmlhbCA9IG5ldyBUSFJFRS5NZXNoUGhvbmdNYXRlcmlhbCh7XHJcbiAgICAgICAgICAgIGNvbG9yOiBjb2xvcixcclxuICAgICAgICAgICAgc2lkZTogVEhSRUUuRnJvbnRTaWRlXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGlmICh0ZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIG1hdGVyaWFsID0gbmV3IFRIUkVFLk1lc2hTdGFuZGFyZE1hdGVyaWFsKHtcclxuICAgICAgICAgICAgICAgIGNvbG9yOiBjb2xvcixcclxuICAgICAgICAgICAgICAgIHNpZGU6IFRIUkVFLkZyb250U2lkZSxcclxuICAgICAgICAgICAgICAgIHJvdWdobmVzczogIWlzTmlsbCh0ZXh0dXJlLnJvdWdobmVzcykgPyB0ZXh0dXJlLnJvdWdobmVzcyA6IDAuOCxcclxuICAgICAgICAgICAgICAgIG1ldGFsbmVzczogIWlzTmlsbCh0ZXh0dXJlLm1ldGFsbmVzcykgPyB0ZXh0dXJlLm1ldGFsbmVzcyA6IDAsXHJcbiAgICAgICAgICAgICAgICBidW1wU2NhbGU6ICFpc05pbGwodGV4dHVyZS5idW1wU2NhbGUpID8gdGV4dHVyZS5idW1wU2NhbGUgOiAxXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9hZGRNYXRlcmlhbE1hcChtYXRlcmlhbCwgdGV4dHVyZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBtYXRlcmlhbDtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9lcXVhbExhc3RWZWMyKHBsYW5lOiBzdHJpbmcsIHBhcmFtU3VmZml4OiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgICAgICBjb25zdCBwYXJhbU5hbWUgPSBgJHtwbGFuZX0ke3BhcmFtU3VmZml4fWA7XHJcbiAgICAgICAgY29uc3QgZ2V0dGVyID0gdGhpcy5faGFsZkVkZ2VbcGFyYW1OYW1lXSgpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9sYXN0W3BhcmFtTmFtZV0gJiZcclxuICAgICAgICAgICAgdGhpcy5faGFsZkVkZ2VbcGFyYW1OYW1lXSAmJlxyXG4gICAgICAgICAgICB0aGlzLl9sYXN0W3BhcmFtTmFtZV0ueCA9PT0gZ2V0dGVyLnggJiZcclxuICAgICAgICAgICAgdGhpcy5fbGFzdFtwYXJhbU5hbWVdLnkgPT09IGdldHRlci55O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2NvcHlMYXN0KHBsYW5lOiBzdHJpbmcsIHBhcmFtczogc3RyaW5nW10pOiB2b2lkIHtcclxuICAgICAgICBwYXJhbXMuZm9yRWFjaCgocGFyYW06IHN0cmluZykgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwYXJhbU5hbWUgPSBwYXJhbSA9PT0gJ0ludlRyYW5zZm9ybScgP1xyXG4gICAgICAgICAgICAgICAgdGhpcy5faW52VHJhbnNmb3JtUGFyYW0ocGxhbmUpIDpcclxuICAgICAgICAgICAgICAgIGAke3BsYW5lfSR7cGFyYW19YDtcclxuICAgICAgICAgICAgY29uc3QgY3VycmVudCA9ICdmdW5jdGlvbicgPT09IHR5cGVvZiB0aGlzLl9oYWxmRWRnZVtwYXJhbU5hbWVdID9cclxuICAgICAgICAgICAgICAgIHRoaXMuX2hhbGZFZGdlW3BhcmFtTmFtZV0oKSA6IHRoaXMuX2hhbGZFZGdlW3BhcmFtTmFtZV07XHJcbiAgICAgICAgICAgIHRoaXMuX2xhc3RbcGFyYW1OYW1lXSA9IGN1cnJlbnQ7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfdHJhbnNmb3JtUGFyYW0ocGxhbmU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIGAke3BsYW5lfVRyYW5zZm9ybWA7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfaW52VHJhbnNmb3JtUGFyYW0ocGxhbmU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIGBpbnYke3BsYW5lLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpfSR7cGxhbmUuc3Vic3RyKDEpfVRyYW5zZm9ybWA7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfdXBkYXRlTWFpblBsYW5lKHBsYW5lOiBzdHJpbmcsIG1hdGVyaWFsOiBNZXNoQmFzaWNNYXRlcmlhbCB8IE1lc2hQaG9uZ01hdGVyaWFsKTogTWVzaCB7XHJcbiAgICAgICAgbGV0IHVwZGF0ZVBsYW5lOiBNZXNoID0gdGhpcy5fcGxhbmVzW3BsYW5lXTtcclxuICAgICAgICBjb25zdCBnZW86IFNoYXBlR2VvbWV0cnkgPSB0aGlzLl9jcmVhdGVHZW9tZXRyeShcclxuICAgICAgICAgICAgdGhpcy5faGFsZkVkZ2VbYCR7cGxhbmV9U3RhcnRgXSgpLFxyXG4gICAgICAgICAgICB0aGlzLl9oYWxmRWRnZVtgJHtwbGFuZX1FbmRgXSgpLFxyXG4gICAgICAgICAgICB0aGlzLl9oYWxmRWRnZVt0aGlzLl90cmFuc2Zvcm1QYXJhbShwbGFuZSldLFxyXG4gICAgICAgICAgICB0aGlzLl9oYWxmRWRnZVt0aGlzLl9pbnZUcmFuc2Zvcm1QYXJhbShwbGFuZSldLFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgaWYgKCF1cGRhdGVQbGFuZSkge1xyXG4gICAgICAgICAgICB1cGRhdGVQbGFuZSA9IG5ldyBUaHJlZU1lc2goZ2VvLCBtYXRlcmlhbCk7XHJcbiAgICAgICAgICAgIHVwZGF0ZVBsYW5lLm5hbWUgPSAnZWRnZSc7XHJcbiAgICAgICAgICAgIHVwZGF0ZVBsYW5lLnVzZXJEYXRhLndhbGwgPSB0aGlzLl93YWxsO1xyXG4gICAgICAgICAgICB1cGRhdGVQbGFuZS5jYXN0U2hhZG93ID0gdHJ1ZTtcclxuICAgICAgICAgICAgdXBkYXRlUGxhbmUucmVjZWl2ZVNoYWRvdyA9IHRydWU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdXBkYXRlUGxhbmUuZ2VvbWV0cnkgPSBnZW87XHJcbiAgICAgICAgICAgIHVwZGF0ZVBsYW5lLm1hdGVyaWFsID0gbWF0ZXJpYWw7XHJcbiAgICAgICAgICAgIHVwZGF0ZVBsYW5lLm1hdGVyaWFsLm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICB9LyogZWxzZSB7XHJcbiAgICAgIHVwZGF0ZVBsYW5lID0gdGhpcy5tYWtlV2FsbChcclxuICAgICAgICB0aGlzLmhhbGZFZGdlW2Ake3BsYW5lfVN0YXJ0YF0oKSxcclxuICAgICAgICB0aGlzLmhhbGZFZGdlW2Ake3BsYW5lfUVuZGBdKCksXHJcbiAgICAgICAgdGhpcy5oYWxmRWRnZVt0aGlzLnRyYW5zZm9ybVBhcmFtKHBsYW5lKV0sXHJcbiAgICAgICAgdGhpcy5oYWxmRWRnZVt0aGlzLmludlRyYW5zZm9ybVBhcmFtKHBsYW5lKV0sXHJcbiAgICAgICAgbWF0ZXJpYWxcclxuICAgICAgKTtcclxuICAgIH0qL1xyXG4gICAgICAgIHJldHVybiB1cGRhdGVQbGFuZTtcclxuICAgICAgICAvLyBjb25zdCBvbGRQbGFuZSA9IHRoaXMucGxhbmVzW3BsYW5lXTtcclxuICAgICAgICAvLyBjb25zdCBuZXdQbGFuZSA9IHRoaXMubWFrZVdhbGwoXHJcbiAgICAgICAgLy8gICB0aGlzLmhhbGZFZGdlW2Ake3BsYW5lfVN0YXJ0YF0oKSxcclxuICAgICAgICAvLyAgIHRoaXMuaGFsZkVkZ2VbYCR7cGxhbmV9RW5kYF0oKSxcclxuICAgICAgICAvLyAgIHRoaXMuaGFsZkVkZ2VbdGhpcy50cmFuc2Zvcm1QYXJhbShwbGFuZSldLFxyXG4gICAgICAgIC8vICAgdGhpcy5oYWxmRWRnZVt0aGlzLmludlRyYW5zZm9ybVBhcmFtKHBsYW5lKV0sXHJcbiAgICAgICAgLy8gICBtYXRlcmlhbFxyXG4gICAgICAgIC8vICk7XHJcbiAgICAgICAgLy8gaWYgKG9sZFBsYW5lKSB7XHJcbiAgICAgICAgLy8gICAvLyBzY2VuZS5yZW1vdmUob2xkUGxhbmUpO1xyXG4gICAgICAgIC8vICAgVXRpbHMuZGlzcG9zZU9iamVjdChvbGRQbGFuZSk7XHJcbiAgICAgICAgLy8gfVxyXG4gICAgICAgIC8vIC8vIHNjZW5lLmFkZChuZXdQbGFuZSk7XHJcbiAgICAgICAgLy8gcmV0dXJuIG5ld1BsYW5lO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3VwZGF0ZUJvdHRvbVBsYW5lKCk6IE1lc2gge1xyXG4gICAgICAgIGNvbnN0IG9sZFBsYW5lID0gdGhpcy5fcGxhbmVzLmJvdHRvbTtcclxuICAgICAgICBpZiAob2xkUGxhbmUgJiZcclxuICAgICAgICAgICAgdGhpcy5fZXF1YWxMYXN0VmVjMignaW50ZXJpb3InLCAnU3RhcnQnKSAmJlxyXG4gICAgICAgICAgICB0aGlzLl9lcXVhbExhc3RWZWMyKCdpbnRlcmlvcicsICdFbmQnKSAmJlxyXG4gICAgICAgICAgICB0aGlzLl9lcXVhbExhc3RWZWMyKCdleHRlcmlvcicsICdTdGFydCcpICYmXHJcbiAgICAgICAgICAgIHRoaXMuX2VxdWFsTGFzdFZlYzIoJ2V4dGVyaW9yJywgJ0VuZCcpXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBvbGRQbGFuZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgbmV3UGxhbmUgPSB0aGlzLl9idWlsZEZpbGxlcigwLCB0aGlzLl9maWxsZXJNYXRlcmlhbCk7XHJcbiAgICAgICAgaWYgKG9sZFBsYW5lKSB7XHJcbiAgICAgICAgICAgIC8vIERpc3Bvc2UgZnVuY3Rpb24gZG9lcyBub3QgYWN0dWFsbHkgcmVtb3ZlIHRoZSBvYmplY3QgZnJvbSB0aGUgc2NlbmVcclxuICAgICAgICAgICAgVXRpbHMuRGlzcG9zZU9iamVjdChvbGRQbGFuZSk7XHJcbiAgICAgICAgICAgIG9sZFBsYW5lLnZpc2libGUgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gc2NlbmUuYWRkKG5ld1BsYW5lKTtcclxuICAgICAgICByZXR1cm4gbmV3UGxhbmU7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfdXBkYXRlVG9wUGxhbmUoKTogTWVzaCB7XHJcbiAgICAgICAgY29uc3Qgb2xkUGxhbmUgPSB0aGlzLl9wbGFuZXMudG9wO1xyXG4gICAgICAgIGlmIChvbGRQbGFuZSAmJlxyXG4gICAgICAgICAgICB0aGlzLl9sYXN0LmhlaWdodCA9PT0gdGhpcy5fd2FsbC5oZWlnaHQgJiZcclxuICAgICAgICAgICAgdGhpcy5fZXF1YWxMYXN0VmVjMignaW50ZXJpb3InLCAnU3RhcnQnKSAmJlxyXG4gICAgICAgICAgICB0aGlzLl9lcXVhbExhc3RWZWMyKCdpbnRlcmlvcicsICdFbmQnKSAmJlxyXG4gICAgICAgICAgICB0aGlzLl9lcXVhbExhc3RWZWMyKCdleHRlcmlvcicsICdTdGFydCcpICYmXHJcbiAgICAgICAgICAgIHRoaXMuX2VxdWFsTGFzdFZlYzIoJ2V4dGVyaW9yJywgJ0VuZCcpXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBvbGRQbGFuZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKG9sZFBsYW5lKSB7XHJcbiAgICAgICAgICAgIC8vIERpc3Bvc2UgZnVuY3Rpb24gZG9lcyBub3QgYWN0dWFsbHkgcmVtb3ZlIHRoZSBvYmplY3QgZnJvbSB0aGUgc2NlbmVcclxuICAgICAgICAgICAgVXRpbHMuRGlzcG9zZU9iamVjdChvbGRQbGFuZSk7XHJcbiAgICAgICAgICAgIG9sZFBsYW5lLnZpc2libGUgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgbmV3UGxhbmUgPSB0aGlzLl9idWlsZEZpbGxlcih0aGlzLl93YWxsLmhlaWdodCwgdGhpcy5fZmlsbGVyTWF0ZXJpYWwpO1xyXG4gICAgICAgIC8vIHNjZW5lLmFkZChuZXdQbGFuZSk7XHJcbiAgICAgICAgcmV0dXJuIG5ld1BsYW5lO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3VwZGF0ZVNpZGVQbGFuZXMoKTogTWVzaFtdIHtcclxuICAgICAgICBjb25zdCBvbGRQbGFuZXMgPSB0aGlzLl9wbGFuZXMuc2lkZXM7XHJcbiAgICAgICAgaWYgKG9sZFBsYW5lcyAmJlxyXG4gICAgICAgICAgICB0aGlzLl9sYXN0LmhlaWdodCA9PT0gdGhpcy5fd2FsbC5oZWlnaHQgJiZcclxuICAgICAgICAgICAgdGhpcy5fZXF1YWxMYXN0VmVjMignaW50ZXJpb3InLCAnU3RhcnQnKSAmJlxyXG4gICAgICAgICAgICB0aGlzLl9lcXVhbExhc3RWZWMyKCdpbnRlcmlvcicsICdFbmQnKSAmJlxyXG4gICAgICAgICAgICB0aGlzLl9lcXVhbExhc3RWZWMyKCdleHRlcmlvcicsICdTdGFydCcpICYmXHJcbiAgICAgICAgICAgIHRoaXMuX2VxdWFsTGFzdFZlYzIoJ2V4dGVyaW9yJywgJ0VuZCcpXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBvbGRQbGFuZXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IG5ld1BsYW5lcyA9IFtcclxuICAgICAgICAgICAgdGhpcy5fYnVpbGRTaWRlRmlsbGVyKHRoaXMuX2hhbGZFZGdlLmludGVyaW9yU3RhcnQoKSwgdGhpcy5faGFsZkVkZ2UuZXh0ZXJpb3JTdGFydCgpLCB0aGlzLl93YWxsLmhlaWdodCwgdGhpcy5fZmlsbGVyTWF0ZXJpYWwpLFxyXG4gICAgICAgICAgICB0aGlzLl9idWlsZFNpZGVGaWxsZXIodGhpcy5faGFsZkVkZ2UuaW50ZXJpb3JFbmQoKSwgdGhpcy5faGFsZkVkZ2UuZXh0ZXJpb3JFbmQoKSwgdGhpcy5fd2FsbC5oZWlnaHQsIHRoaXMuX2ZpbGxlck1hdGVyaWFsKVxyXG4gICAgICAgIF07XHJcbiAgICAgICAgaWYgKG9sZFBsYW5lcykge1xyXG4gICAgICAgICAgICBvbGRQbGFuZXMuZm9yRWFjaChwID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIERpc3Bvc2UgZnVuY3Rpb24gZG9lcyBub3QgYWN0dWFsbHkgcmVtb3ZlIHRoZSBvYmplY3QgZnJvbSB0aGUgc2NlbmVcclxuICAgICAgICAgICAgICAgIFV0aWxzLkRpc3Bvc2VPYmplY3QocCk7XHJcbiAgICAgICAgICAgICAgICBwLnZpc2libGUgPSBmYWxzZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIG5ld1BsYW5lcy5mb3JFYWNoKHAgPT4gc2NlbmUuYWRkKHApKTtcclxuICAgICAgICByZXR1cm4gbmV3UGxhbmVzO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyB1cGRhdGVQbGFuZXMoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgdGhpcy5fZmlsbGVyTWF0ZXJpYWwgPSB0aGlzLl91cGRhdGVGaWxsZXJNYXRlcmlhbCgpO1xyXG4gICAgICAgIGlmICh0aGlzLl9pc1ZhbGlkKFt0aGlzLl9oYWxmRWRnZS5leHRlcmlvclN0YXJ0KCksIHRoaXMuX2hhbGZFZGdlLmV4dGVyaW9yRW5kKCldKSkge1xyXG4gICAgICAgICAgICB0aGlzLl9wbGFuZXMuZXh0ZXJpb3IgPSB0aGlzLl91cGRhdGVNYWluUGxhbmUoJ2V4dGVyaW9yJywgdGhpcy5fZmlsbGVyTWF0ZXJpYWwpO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5faGFsZkVkZ2UuZ2V0VGV4dHVyZSgpICYmIHRoaXMuX2hhbGZFZGdlLmdldFRleHR1cmUoKS50eXBlICE9PSBUZXh0dXJlVHlwZS5JbWFnZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlVXZzKHRoaXMuX3BsYW5lcy5leHRlcmlvcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IG9sZFdhbGxNYXRlcmlhbCA9IHRoaXMuX3dhbGxNYXRlcmlhbDtcclxuICAgICAgICB0aGlzLl93YWxsTWF0ZXJpYWwgPSBhd2FpdCB0aGlzLl91cGRhdGVXYWxsTWF0ZXJpYWwodGhpcy5faGFsZkVkZ2UuZ2V0VGV4dHVyZSgpLCB0aGlzLl9oYWxmRWRnZS5nZXRDb2xvcigpKTtcclxuICAgICAgICBpZiAodGhpcy5faXNWYWxpZChbdGhpcy5faGFsZkVkZ2UuaW50ZXJpb3JTdGFydCgpLCB0aGlzLl9oYWxmRWRnZS5pbnRlcmlvckVuZCgpXSkpIHtcclxuICAgICAgICAgICAgLy8gdGhpcy5wbGFuZXMuaW50ZXJpb3IgPSAoIW9sZFdhbGxNYXRlcmlhbCB8fCBvbGRXYWxsTWF0ZXJpYWwgPT09IHRoaXMud2FsbE1hdGVyaWFsKVxyXG4gICAgICAgICAgICAvLyAgID8gdGhpcy51cGRhdGVNYWluUGxhbmUoJ2ludGVyaW9yJywgdGhpcy53YWxsTWF0ZXJpYWwpXHJcbiAgICAgICAgICAgIC8vICAgOiB0aGlzLnVwZGF0ZU1haW5QbGFuZU1hdGVyaWFsKCdpbnRlcmlvcicsIHRoaXMud2FsbE1hdGVyaWFsKTtcclxuICAgICAgICAgICAgdGhpcy5fcGxhbmVzLmludGVyaW9yID0gdGhpcy5fdXBkYXRlTWFpblBsYW5lKCdpbnRlcmlvcicsIHRoaXMuX3dhbGxNYXRlcmlhbCk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9oYWxmRWRnZS5nZXRUZXh0dXJlKCkgJiYgdGhpcy5faGFsZkVkZ2UuZ2V0VGV4dHVyZSgpLnR5cGUgIT09IFRleHR1cmVUeXBlLkltYWdlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl91cGRhdGVVdnModGhpcy5fcGxhbmVzLmludGVyaW9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fcGxhbmVzLmJvdHRvbSA9IHRoaXMuX3VwZGF0ZUJvdHRvbVBsYW5lKCk7XHJcbiAgICAgICAgdGhpcy5fcGxhbmVzLnRvcCA9IHRoaXMuX3VwZGF0ZVRvcFBsYW5lKCk7XHJcbiAgICAgICAgdGhpcy5fcGxhbmVzLnNpZGVzID0gdGhpcy5fdXBkYXRlU2lkZVBsYW5lcygpO1xyXG5cclxuICAgICAgICB0aGlzLl9sYXN0LmZpbGxlck1hdGVyaWFsID0gdGhpcy5fZmlsbGVyTWF0ZXJpYWw7XHJcbiAgICAgICAgdGhpcy5fbGFzdC53YWxsTWF0ZXJpYWwgPSB0aGlzLl93YWxsTWF0ZXJpYWw7XHJcbiAgICAgICAgdGhpcy5fbGFzdC5oZWlnaHQgPSB0aGlzLl93YWxsLmhlaWdodDtcclxuICAgICAgICB0aGlzLl9jb3B5TGFzdCgnZXh0ZXJpb3InLCBbJ1N0YXJ0JywgJ0VuZCcsICdUcmFuc2Zvcm0nLCAnSW52VHJhbnNmb3JtJ10pO1xyXG4gICAgICAgIHRoaXMuX2NvcHlMYXN0KCdpbnRlcmlvcicsIFsnU3RhcnQnLCAnRW5kJywgJ1RyYW5zZm9ybScsICdJbnZUcmFuc2Zvcm0nXSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfdXBkYXRlVXZzKG1lc2g6IE1lc2gpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBkaW1lbnNpb25zID0gbmV3IFRIUkVFLlZlY3RvcjIoXHJcbiAgICAgICAgICAgIHRoaXMuX2hhbGZFZGdlLmludGVyaW9yRGlzdGFuY2UoKSxcclxuICAgICAgICAgICAgdGhpcy5fd2FsbC5oZWlnaHQgLSB0aGlzLl93YWxsLnRoaWNrbmVzc1xyXG4gICAgICAgICkubXVsdGlwbHlTY2FsYXIoMTAwKTtcclxuICAgICAgICBjb25zdCByYXRpbzogbnVtYmVyID0gZGltZW5zaW9ucy54IC8gZGltZW5zaW9ucy55O1xyXG4gICAgICAgIGxldCB1dlk6IG51bWJlcjtcclxuICAgICAgICBjb25zdCB0ZW1wVmVjdG9yOiBWZWN0b3IyID0gbmV3IFZlY3RvcjIoKTtcclxuICAgICAgICBjb25zdCB1dkFycmF5OiBCdWZmZXJBdHRyaWJ1dGUgPSA8QnVmZmVyQXR0cmlidXRlPm1lc2guZ2VvbWV0cnkuYXR0cmlidXRlcy51djtcclxuICAgICAgICBpZiAodXZBcnJheSkge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHV2QXJyYXkuY291bnQ7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgdGVtcFZlY3Rvci5mcm9tQnVmZmVyQXR0cmlidXRlKHV2QXJyYXksIGkpO1xyXG4gICAgICAgICAgICAgICAgdXZZID0gdGVtcFZlY3Rvci55O1xyXG4gICAgICAgICAgICAgICAgdXZZIC09IDAuNTtcclxuICAgICAgICAgICAgICAgIHV2WSAvPSByYXRpbztcclxuICAgICAgICAgICAgICAgIHV2WSArPSAwLjU7XHJcbiAgICAgICAgICAgICAgICB1dkFycmF5LnNldFkoaSwgdXZZKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB1dkFycmF5Lm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gc3RhcnQsIGVuZCBoYXZlIHggYW5kIHkgYXR0cmlidXRlcyAoaS5lLiBjb3JuZXJzKVxyXG4gICAgcHJpdmF0ZSBfY3JlYXRlR2VvbWV0cnkoc3RhcnQsIGVuZCwgdHJhbnNmb3JtLCBpbnZUcmFuc2Zvcm0pOiBTaGFwZUdlb21ldHJ5IHtcclxuICAgICAgICBjb25zdCB2MSA9IHRoaXMuX3RvVmVjMyhzdGFydCk7XHJcbiAgICAgICAgY29uc3QgdjIgPSB0aGlzLl90b1ZlYzMoZW5kKTtcclxuICAgICAgICBjb25zdCB2MyA9IHYyLmNsb25lKCk7XHJcbiAgICAgICAgdjMueSA9IHRoaXMuX3dhbGwuaGVpZ2h0O1xyXG4gICAgICAgIGNvbnN0IHY0ID0gdjEuY2xvbmUoKTtcclxuICAgICAgICB2NC55ID0gdGhpcy5fd2FsbC5oZWlnaHQ7XHJcblxyXG4gICAgICAgIGNvbnN0IHBvaW50cyA9IFt2MS5jbG9uZSgpLCB2Mi5jbG9uZSgpLCB2My5jbG9uZSgpLCB2NC5jbG9uZSgpXTtcclxuXHJcbiAgICAgICAgcG9pbnRzLmZvckVhY2goKHApID0+IHtcclxuICAgICAgICAgICAgcC5hcHBseU1hdHJpeDQodHJhbnNmb3JtKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgY29uc3Qgc2hhcGUgPSBuZXcgU2hhcGUoW1xyXG4gICAgICAgICAgICBuZXcgVmVjdG9yMihwb2ludHNbMF0ueCwgcG9pbnRzWzBdLnkpLFxyXG4gICAgICAgICAgICBuZXcgVmVjdG9yMihwb2ludHNbMV0ueCwgcG9pbnRzWzFdLnkpLFxyXG4gICAgICAgICAgICBuZXcgVmVjdG9yMihwb2ludHNbMl0ueCwgcG9pbnRzWzJdLnkpLFxyXG4gICAgICAgICAgICBuZXcgVmVjdG9yMihwb2ludHNbM10ueCwgcG9pbnRzWzNdLnkpXHJcbiAgICAgICAgXSk7XHJcblxyXG4gICAgICAgIC8vIGFkZCBob2xlcyBmb3IgZWFjaCB3YWxsIGl0ZW1cclxuICAgICAgICBjb25zdCBpdGVtSG9sZXMgPSB0aGlzLl93YWxsLml0ZW1zXHJcbiAgICAgICAgICAgIC5maWx0ZXIoKGl0ZW06IFdhbGxJdGVtKSA9PiAhaXNOYU4oaXRlbS5wb3NpdGlvbi54KSlcclxuICAgICAgICAgICAgLm1hcCgoaXRlbTogV2FsbEl0ZW0pID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHBvcyA9IGl0ZW0ucG9zaXRpb24uY2xvbmUoKTtcclxuICAgICAgICAgICAgICAgIHBvcy5hcHBseU1hdHJpeDQodHJhbnNmb3JtKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGhhbGZTaXplID0gaXRlbS5oYWxmU2l6ZTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG1pbiA9IGhhbGZTaXplLmNsb25lKCkubXVsdGlwbHlTY2FsYXIoLTEpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbWF4ID0gaGFsZlNpemUuY2xvbmUoKTtcclxuICAgICAgICAgICAgICAgIG1pbi5hZGQocG9zKTtcclxuICAgICAgICAgICAgICAgIG1heC5hZGQocG9zKTtcclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBob2xlUG9pbnRzID0gW1xyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBWZWN0b3IyKG1pbi54LCBtaW4ueSksXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IFZlY3RvcjIobWF4LngsIG1pbi55KSxcclxuICAgICAgICAgICAgICAgICAgICBuZXcgVmVjdG9yMihtYXgueCwgbWF4LnkpLFxyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBWZWN0b3IyKG1pbi54LCBtYXgueSlcclxuICAgICAgICAgICAgICAgIF07XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGhvbGVQb2ludHM7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIGNvbnN0IHBvbHlnb25zID0gVXRpbHMucG9seWdvbnNVbmlvbihpdGVtSG9sZXMpO1xyXG4gICAgICAgIHBvbHlnb25zLmZvckVhY2goaG9sZVBvbHlnb24gPT4gc2hhcGUuaG9sZXMucHVzaChuZXcgUGF0aChob2xlUG9seWdvbikpKTtcclxuXHJcbiAgICAgICAgY29uc3QgZ2VvbWV0cnkgPSBuZXcgU2hhcGVHZW9tZXRyeShzaGFwZSk7XHJcblxyXG4gICAgICAgIGNvbnN0IHBvc2l0aW9uQXR0cmlidXRlOiBCdWZmZXJBdHRyaWJ1dGUgPSA8QnVmZmVyQXR0cmlidXRlPmdlb21ldHJ5LmdldEF0dHJpYnV0ZSgncG9zaXRpb24nKTtcclxuICAgICAgICBjb25zdCB1dkF0dHJpYnV0ZTogQnVmZmVyQXR0cmlidXRlID0gPEJ1ZmZlckF0dHJpYnV0ZT5nZW9tZXRyeS5nZXRBdHRyaWJ1dGUoJ3V2Jyk7XHJcbiAgICAgICAgVXRpbHMuQXBwbHlCdWZmZXJBdHRyaWJ1dGVNYXRyaXhUcmFuc2Zvcm0ocG9zaXRpb25BdHRyaWJ1dGUsIGludlRyYW5zZm9ybSk7XHJcblxyXG4gICAgICAgIC8vIG1ha2UgVVZzXHJcbiAgICAgICAgY29uc3QgdG90YWxEaXN0YW5jZSA9IFV0aWxzLmRpc3RhbmNlKHYxLngsIHYxLnosIHYyLngsIHYyLnopO1xyXG4gICAgICAgIGNvbnN0IGhlaWdodCA9IHRoaXMuX3dhbGwuaGVpZ2h0O1xyXG5cclxuICAgICAgICBmdW5jdGlvbiB2ZXJ0ZXhUb1V2KHZlcnRleCkge1xyXG4gICAgICAgICAgICBjb25zdCB4ID0gVXRpbHMuZGlzdGFuY2UodjEueCwgdjEueiwgdmVydGV4LngsIHZlcnRleC56KSAvIHRvdGFsRGlzdGFuY2U7XHJcbiAgICAgICAgICAgIGNvbnN0IHkgPSB2ZXJ0ZXgueSAvIGhlaWdodDtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBUSFJFRS5WZWN0b3IyKHgsIHkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgdGVtcFVWQXJyYXk6IFZlY3RvcjJbXSA9IFtdO1xyXG4gICAgICAgIGNvbnN0IHBvc2l0aW9uRGF0YUFzVmVjdG9yM0FycmF5OiBWZWN0b3IzW10gPSBVdGlscy5HZXRWZWN0b3IzQXJyYXlGcm9tQnVmZmVyQXR0cmlidXRlKHBvc2l0aW9uQXR0cmlidXRlLmNsb25lKCkpO1xyXG5cclxuICAgICAgICBwb3NpdGlvbkRhdGFBc1ZlY3RvcjNBcnJheS5mb3JFYWNoKCh2ZXJ0ZXg6IFZlY3RvcjMpID0+IHtcclxuICAgICAgICAgICAgdGVtcFVWQXJyYXkucHVzaCh2ZXJ0ZXhUb1V2KHZlcnRleCkpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0ZW1wVVZBcnJheS5mb3JFYWNoKCh1dlZlY3RvcjogVmVjdG9yMiwgaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgdXZBdHRyaWJ1dGUuc2V0WFkoaW5kZXgsIHV2VmVjdG9yLngsIHV2VmVjdG9yLnkpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB1dkF0dHJpYnV0ZS5uZWVkc1VwZGF0ZSA9IHRydWU7XHJcbiAgICAgICAgZ2VvbWV0cnkuY29tcHV0ZVZlcnRleE5vcm1hbHMoKTtcclxuICAgICAgICByZXR1cm4gZ2VvbWV0cnk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfYnVpbGRTaWRlRmlsbGVyKHAxOiBWZWN0b3IyLCBwMjogVmVjdG9yMiwgaGVpZ2h0OiBudW1iZXIsIG1hdGVyaWFsOiBNYXRlcmlhbCk6IE1lc2gge1xyXG4gICAgICAgIGNvbnN0IHBvaW50cyA9IFtcclxuICAgICAgICAgICAgdGhpcy5fdG9WZWMzKHAxKSxcclxuICAgICAgICAgICAgdGhpcy5fdG9WZWMzKHAyKSxcclxuICAgICAgICAgICAgdGhpcy5fdG9WZWMzKHAyLCBoZWlnaHQpLFxyXG4gICAgICAgICAgICB0aGlzLl90b1ZlYzMocDEsIGhlaWdodClcclxuICAgICAgICBdO1xyXG5cclxuICAgICAgICBjb25zdCBnZW9tZXRyeSA9IG5ldyBCdWZmZXJHZW9tZXRyeSgpLnNldEZyb21Qb2ludHMocG9pbnRzKTtcclxuICAgICAgICBjb25zdCBmaWxsZXIgPSBuZXcgTWVzaChnZW9tZXRyeSwgbWF0ZXJpYWwpO1xyXG4gICAgICAgIGZpbGxlci5jYXN0U2hhZG93ID0gdHJ1ZTtcclxuICAgICAgICBmaWxsZXIucmVjZWl2ZVNoYWRvdyA9IHRydWU7XHJcbiAgICAgICAgZmlsbGVyLm5hbWUgPSAnZWRnZS1zaWRlLWZpbGxlcic7XHJcbiAgICAgICAgcmV0dXJuIGZpbGxlcjtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9idWlsZEZpbGxlcihoZWlnaHQ6IG51bWJlciwgbWF0ZXJpYWw6IE1hdGVyaWFsKTogTWVzaCB7XHJcbiAgICAgICAgY29uc3QgcG9pbnRzID0gW1xyXG4gICAgICAgICAgICB0aGlzLl90b1ZlYzIodGhpcy5faGFsZkVkZ2UuZXh0ZXJpb3JTdGFydCgpKSxcclxuICAgICAgICAgICAgdGhpcy5fdG9WZWMyKHRoaXMuX2hhbGZFZGdlLmV4dGVyaW9yRW5kKCkpLFxyXG4gICAgICAgICAgICB0aGlzLl90b1ZlYzIodGhpcy5faGFsZkVkZ2UuaW50ZXJpb3JFbmQoKSksXHJcbiAgICAgICAgICAgIHRoaXMuX3RvVmVjMih0aGlzLl9oYWxmRWRnZS5pbnRlcmlvclN0YXJ0KCkpXHJcbiAgICAgICAgXTtcclxuXHJcbiAgICAgICAgY29uc3Qgc2hhcGUgPSBuZXcgU2hhcGUocG9pbnRzKTtcclxuICAgICAgICBjb25zdCBnZW9tZXRyeSA9IG5ldyBTaGFwZUdlb21ldHJ5KHNoYXBlKTtcclxuXHJcbiAgICAgICAgY29uc3QgZmlsbGVyID0gbmV3IE1lc2goZ2VvbWV0cnksIG1hdGVyaWFsKTtcclxuICAgICAgICBmaWxsZXIubmFtZSA9ICdlZGdlLWZpbGxlcic7XHJcbiAgICAgICAgZmlsbGVyLmNhc3RTaGFkb3cgPSB0cnVlO1xyXG4gICAgICAgIGZpbGxlci5yZWNlaXZlU2hhZG93ID0gdHJ1ZTtcclxuICAgICAgICBmaWxsZXIucm90YXRpb24uc2V0KE1hdGguUEkgLyAyLCAwLCAwKTtcclxuICAgICAgICBmaWxsZXIucG9zaXRpb24ueSA9IGhlaWdodDtcclxuICAgICAgICByZXR1cm4gZmlsbGVyO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3RvVmVjMihwb3MpOiBWZWN0b3IyIHtcclxuICAgICAgICByZXR1cm4gbmV3IFZlY3RvcjIocG9zLngsIHBvcy55KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF90b1ZlYzMocG9zOiB7IHg6IG51bWJlciwgeTogbnVtYmVyIH0sIGhlaWdodCA9IDApOiBWZWN0b3IzIHtcclxuICAgICAgICByZXR1cm4gbmV3IFZlY3RvcjMocG9zLngsIGhlaWdodCwgcG9zLnkpO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgUm9vbSB7XHJcblxyXG4gICAgcHVibGljIGludGVyaW9yQ29ybmVyczogQ29ybmVyW10gPSBbXTtcclxuXHJcbiAgICBwcml2YXRlIGVkZ2VQb2ludGVyID0gbnVsbDtcclxuICAgIHB1YmxpYyBlZGdlSGVpZ2h0cyA9IFtdO1xyXG5cclxuICAgIHB1YmxpYyBmbG9vclBsYW5lOiBGbG9vclBsYW5lSXRlbSA9IG51bGw7XHJcbiAgICBwdWJsaWMgZmxvb3JUZXh0dXJlOiBUZXh0dXJlO1xyXG4gICAgcHVibGljIGZsb29yQ29sb3I6IG51bWJlciA9IDB4Y2NjY2NjO1xyXG4gICAgcHVibGljIGNlaWxpbmdQbGFuZTogTWVzaCA9IG51bGw7XHJcblxyXG4gICAgLy8gcHJpdmF0ZSBmbG9vckNoYW5nZUNhbGxiYWNrcyA9ICQuQ2FsbGJhY2tzKCk7XHJcblxyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHVibGljIGNvcm5lcnM6IENvcm5lcltdLFxyXG4gICAgICAgIGRlZmF1bHRUZXh0dXJlPzogVGV4dHVyZVxyXG4gICAgKSB7XHJcbiAgICAgICAgaWYgKGRlZmF1bHRUZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZmxvb3JUZXh0dXJlID0gZGVmYXVsdFRleHR1cmU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX3NldEVkZ2VQb2ludGVyKCk7XHJcbiAgICAgICAgdGhpcy5fdXBkYXRlSW50ZXJpb3JDb3JuZXJzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGRpc3Bvc2UoKTogdm9pZCB7XHJcbiAgICAgICAgVXRpbHMuRGlzcG9zZU9iamVjdCh0aGlzLmZsb29yUGxhbmUpO1xyXG4gICAgICAgIFV0aWxzLkRpc3Bvc2VPYmplY3QodGhpcy5jZWlsaW5nUGxhbmUpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRJbnRlcmlvckNvcm5lcnMoKTogVmVjdG9yMltdIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pbnRlcmlvckNvcm5lcnMubWFwKChjOiB7IHg6IG51bWJlciwgeTogbnVtYmVyIH0pID0+IG5ldyBWZWN0b3IyKGMueCwgYy55KSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldFV1aWQoKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zdCBjb3JuZXJVdWlkcyA9IFV0aWxzLm1hcCh0aGlzLmNvcm5lcnMsIGZ1bmN0aW9uIChjKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBjLmlkO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGNvcm5lclV1aWRzLnNvcnQoKTtcclxuICAgICAgICByZXR1cm4gY29ybmVyVXVpZHMuam9pbigpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRUZXh0dXJlKCkge1xyXG4gICAgICAgIC8vIGNvbnN0IHV1aWQgPSB0aGlzLmdldFV1aWQoKTtcclxuICAgICAgICAvLyByZXR1cm4gdGhpcy5mbG9vcnBsYW4uZ2V0Rmxvb3JUZXh0dXJlKHV1aWQpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLmZsb29yVGV4dHVyZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0Q29sb3IoKSB7XHJcbiAgICAgICAgLy8gY29uc3QgdXVpZCA9IHRoaXMuZ2V0VXVpZCgpO1xyXG4gICAgICAgIC8vIHJldHVybiB0aGlzLmZsb29ycGxhbi5nZXRGbG9vckNvbG9yKHV1aWQpIHx8IGRlZmF1bHRGbG9vckNvbG9yO1xyXG4gICAgICAgIHJldHVybiB0aGlzLmZsb29yQ29sb3I7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHVzZVRleHR1cmUoKSB7XHJcbiAgICAgICAgLy8gcmV0dXJuIGRlZmF1bHRGbG9vckNvbG9yID09PSB0aGlzLmdldENvbG9yKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiB0ZXh0dXJlU3RyZXRjaCBhbHdheXMgdHJ1ZSwganVzdCBhbiBhcmd1bWVudCBmb3IgY29uc2lzdGVuY3kgd2l0aCB3YWxsc1xyXG4gICAgICovXHJcbiAgICAvLyBwdWJsaWMgc2V0VGV4dHVyZSh0ZXh0dXJlOiBUZXh0dXJlKSB7XHJcbiAgICAvLyAgIC8vIGNvbnN0IHV1aWQgPSB0aGlzLmdldFV1aWQoKTtcclxuICAgIC8vICAgLy8gdGhpcy5mbG9vcnBsYW4uc2V0Rmxvb3JUZXh0dXJlKHV1aWQsIHRleHR1cmUpO1xyXG4gICAgLy8gICAvLyB0aGlzLmZsb29ycGxhbi5kZWxldGVGbG9vckNvbG9yKHV1aWQpO1xyXG4gICAgLy8gICAvLyB0aGlzLmZsb29yQ2hhbmdlQ2FsbGJhY2tzLmZpcmUoKTtcclxuICAgIC8vIH1cclxuXHJcbiAgICAvLyBwdWJsaWMgc2V0Q29sb3IoY29sb3I6IG51bWJlcikge1xyXG4gICAgLy8gICAvLyBjb25zdCB1dWlkID0gdGhpcy5nZXRVdWlkKCk7XHJcbiAgICAvLyAgIC8vIHRoaXMuZmxvb3JwbGFuLmRlbGV0ZUZsb29yVGV4dHVyZSh1dWlkKTtcclxuICAgIC8vICAgLy8gdGhpcy5mbG9vcnBsYW4uc2V0Rmxvb3JDb2xvcih1dWlkLCBjb2xvcik7XHJcbiAgICAvLyAgIC8vIHRoaXMuZmxvb3JDaGFuZ2VDYWxsYmFja3MuZmlyZSgpO1xyXG4gICAgLy8gfVxyXG5cclxuICAgIHB1YmxpYyB1cGRhdGVXYWxsSGVpZ2h0cygpIHtcclxuICAgICAgICBsZXQgZWRnZSA9IHRoaXMuZWRnZVBvaW50ZXI7XHJcbiAgICAgICAgdGhpcy5lZGdlSGVpZ2h0cy5sZW5ndGggPSAwO1xyXG4gICAgICAgIHdoaWxlICh0cnVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZWRnZUhlaWdodHMucHVzaChlZGdlLndhbGwuaGVpZ2h0KTtcclxuICAgICAgICAgICAgaWYgKGVkZ2UubmV4dCA9PT0gdGhpcy5lZGdlUG9pbnRlcikge1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBlZGdlID0gZWRnZS5uZXh0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc2V0RGVmYXVsdEZsb29yVGV4dHVyZSgpIHtcclxuICAgICAgICAvLyBpZiAoIXRoaXMuX2RlZmF1bHRGbG9vclRleHR1cmUpIHtcclxuICAgICAgICAvLyAgIHJldHVybjtcclxuICAgICAgICAvLyB9XHJcbiAgICAgICAgLy8gY29uc3QgdXVpZCA9IHRoaXMuZ2V0VXVpZCgpO1xyXG4gICAgICAgIC8vIGlmICghdGhpcy5mbG9vcnBsYW4uZ2V0Rmxvb3JUZXh0dXJlKHV1aWQpICYmICF0aGlzLmZsb29ycGxhbi5nZXRGbG9vckNvbG9yKHV1aWQpKSB7XHJcbiAgICAgICAgLy8gICB0aGlzLnNldFRleHR1cmUodGhpcy5fZGVmYXVsdEZsb29yVGV4dHVyZSk7XHJcbiAgICAgICAgLy8gfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3VwZGF0ZUludGVyaW9yQ29ybmVycygpIHtcclxuICAgICAgICBsZXQgZWRnZSA9IHRoaXMuZWRnZVBvaW50ZXI7XHJcbiAgICAgICAgdGhpcy5lZGdlSGVpZ2h0cy5sZW5ndGggPSAwO1xyXG4gICAgICAgIHdoaWxlICh0cnVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaW50ZXJpb3JDb3JuZXJzLnB1c2goZWRnZS5pbnRlcmlvclN0YXJ0KCkpO1xyXG4gICAgICAgICAgICBlZGdlLmdlbmVyYXRlUGxhbmUoKTtcclxuICAgICAgICAgICAgdGhpcy5lZGdlSGVpZ2h0cy5wdXNoKGVkZ2UuaGVpZ2h0KTtcclxuICAgICAgICAgICAgaWYgKGVkZ2UubmV4dCA9PT0gdGhpcy5lZGdlUG9pbnRlcikge1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBlZGdlID0gZWRnZS5uZXh0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3NldEVkZ2VQb2ludGVyKCkge1xyXG5cclxuICAgICAgICBsZXQgcHJldkVkZ2UgPSBudWxsO1xyXG4gICAgICAgIGxldCBmaXJzdEVkZ2UgPSBudWxsO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY29ybmVycy5sZW5ndGg7IGkrKykge1xyXG5cclxuICAgICAgICAgICAgY29uc3QgZmlyc3RDb3JuZXIgPSB0aGlzLmNvcm5lcnNbaV07XHJcbiAgICAgICAgICAgIGNvbnN0IHNlY29uZENvcm5lciA9IHRoaXMuY29ybmVyc1soaSArIDEpICUgdGhpcy5jb3JuZXJzLmxlbmd0aF07XHJcblxyXG4gICAgICAgICAgICAvLyBmaW5kIGlmIHdhbGwgaXMgaGVhZGluZyBpbiB0aGF0IGRpcmVjdGlvblxyXG4gICAgICAgICAgICBjb25zdCB3YWxsVG8gPSBmaXJzdENvcm5lci53YWxsVG8oc2Vjb25kQ29ybmVyKTtcclxuICAgICAgICAgICAgY29uc3Qgd2FsbEZyb20gPSBmaXJzdENvcm5lci53YWxsRnJvbShzZWNvbmRDb3JuZXIpO1xyXG4gICAgICAgICAgICBsZXQgZWRnZTogSGFsZkVkZ2U7XHJcblxyXG4gICAgICAgICAgICBpZiAod2FsbFRvKSB7XHJcbiAgICAgICAgICAgICAgICBlZGdlID0gbmV3IEhhbGZFZGdlKHRoaXMsIHdhbGxUbywgdHJ1ZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAod2FsbEZyb20pIHtcclxuICAgICAgICAgICAgICAgIGVkZ2UgPSBuZXcgSGFsZkVkZ2UodGhpcywgd2FsbEZyb20sIGZhbHNlKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIHNvbWV0aGluZyBob3JyaWJsZSBoYXMgaGFwcGVuZWRcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdjb3JuZXJzIGFyZW50IGNvbm5lY3RlZCBieSBhIHdhbGwsIHVoIG9oJyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICBpZiAoaSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgZmlyc3RFZGdlID0gZWRnZTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGVkZ2UucHJldiA9IHByZXZFZGdlO1xyXG4gICAgICAgICAgICAgICAgcHJldkVkZ2UubmV4dCA9IGVkZ2U7XHJcbiAgICAgICAgICAgICAgICBpZiAoaSArIDEgPT09IHRoaXMuY29ybmVycy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICBmaXJzdEVkZ2UucHJldiA9IGVkZ2U7XHJcbiAgICAgICAgICAgICAgICAgICAgZWRnZS5uZXh0ID0gZmlyc3RFZGdlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHByZXZFZGdlID0gZWRnZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGhvbGQgb24gdG8gYW4gZWRnZSByZWZlcmVuY2VcclxuICAgICAgICB0aGlzLmVkZ2VQb2ludGVyID0gZmlyc3RFZGdlO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgYXJlYSgpOiBudW1iZXIge1xyXG4gICAgICAgIGNvbnN0IHBvbHlnb24gPSB0aGlzLl9wb2x5Z29uRnJvbUNvcm5lcnModGhpcy5pbnRlcmlvckNvcm5lcnMpO1xyXG4gICAgICAgIHJldHVybiBVdGlscy5wb2x5Z29uQXJlYShwb2x5Z29uKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0IGNlbnRlcigpOiB7IHg6IG51bWJlciwgeTogbnVtYmVyIH0ge1xyXG4gICAgICAgIGNvbnN0IHBvbHlnb24gPSB0aGlzLl9wb2x5Z29uRnJvbUNvcm5lcnModGhpcy5jb3JuZXJzKTtcclxuICAgICAgICByZXR1cm4gVXRpbHMucG9seWdvbkNlbnRlcihwb2x5Z29uKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9wb2x5Z29uRnJvbUNvcm5lcnMoY29ybmVyczogQ29ybmVyW10pOiBWZWN0b3IyW10ge1xyXG4gICAgICAgIHJldHVybiBjb3JuZXJzLm1hcChjID0+IG5ldyBWZWN0b3IyKGMueCwgYy55KSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBIFdhbGwgSXRlbSBpcyBhbiBlbnRpdHkgdG8gYmUgcGxhY2VkIHJlbGF0ZWQgdG8gYSB3YWxsLlxyXG4gKi9cclxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFdhbGxJdGVtIGV4dGVuZHMgSXRlbSB7XHJcblxyXG4gICAgLyoqIFRoZSBjdXJyZW50bHkgYXBwbGllZCB3YWxsICovXHJcbiAgICBwdWJsaWMgY3VycmVudFdhbGw6IFdhbGwgPSBudWxsO1xyXG5cclxuICAgIC8qKiBUaGUgY3VycmVudGx5IGFwcGxpZWQgd2FsbCBlZGdlLiAqL1xyXG4gICAgcHVibGljIGN1cnJlbnRXYWxsRWRnZTogSGFsZkVkZ2UgPSBudWxsO1xyXG5cclxuICAgIC8qKiBVc2VkIGZvciBmaW5kaW5nIHJvdGF0aW9ucyAqL1xyXG4gICAgcHJpdmF0ZSBfcmVmVmVjID0gbmV3IFRIUkVFLlZlY3RvcjIoMCwgMS4wKTtcclxuXHJcbiAgICBwcml2YXRlIF9wb3NpdGlvbllUb2xlcmFuY2UgPSAwLjAwNTtcclxuXHJcbiAgICAvKiogKi9cclxuICAgIHByaXZhdGUgX3dhbGxPZmZzZXRTY2FsYXIgPSAwO1xyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHJpdmF0ZSBfc2l6ZVggPSAwO1xyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHJpdmF0ZSBfc2l6ZVkgPSAwO1xyXG5cclxuICAgIHByaXZhdGUgX2ZsaXBwZWQgPSBmYWxzZTtcclxuICAgIHByb3RlY3RlZCB0ZXh0dXJlOiBUZXh0dXJlO1xyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHJvdGVjdGVkIGFkZFRvV2FsbCA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHJvdGVjdGVkIGJvdW5kVG9GbG9vciA9IGZhbHNlO1xyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHJvdGVjdGVkIGZyb250VmlzaWJsZSA9IGZhbHNlO1xyXG4gICAgcHJvdGVjdGVkIGJhY2tWaXNpYmxlID0gZmFsc2U7XHJcbiAgICBwcml2YXRlIF9oYXNGcm9udEVkZ2UgPSBmYWxzZTtcclxuICAgIHByaXZhdGUgX2hhc0JhY2tFZGdlID0gZmFsc2U7XHJcbiAgICBwcml2YXRlIF9vbkZyb250U2lkZTogYm9vbGVhbjtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBtZXRhZGF0YTogTWV0YWRhdGEsXHJcbiAgICAgICAgb2JqZWN0OiBPYmplY3QzRCB8IE1lc2gsXHJcbiAgICAgICAgdGV4dHVyZT86IFRleHR1cmUsXHJcbiAgICAgICAgaGFuZGxlcnM/OiBhbnlcclxuICAgICkge1xyXG4gICAgICAgIHN1cGVyKG1ldGFkYXRhLCBvYmplY3QsIHRleHR1cmUsIGhhbmRsZXJzKTtcclxuXHJcbiAgICAgICAgdGhpcy5hbGxvd1JvdGF0ZSA9IGZhbHNlO1xyXG4gICAgICAgIGlmICh0ZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2V0VGV4dHVyZSh0ZXh0dXJlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwdWJsaWMgcmVtb3ZlZCgpIHtcclxuICAgICAgICBpZiAoIWlzTmlsbCh0aGlzLmN1cnJlbnRXYWxsRWRnZSkgJiYgdGhpcy5hZGRUb1dhbGwpIHtcclxuICAgICAgICAgICAgdGhpcy5jdXJyZW50V2FsbEVkZ2Uud2FsbC5yZW1vdmVJdGVtKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLnJlZHJhd1dhbGwoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJlbW92ZUZyb21XYWxsKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRXYWxsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFdhbGwucmVtb3ZlT25JdGVtKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRXYWxsID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRXYWxsRWRnZSA9IHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPbmx5IGhpZGVzIGl0ZW0gd2hlbiBlbnRpcmUgd2FsbCBpcyBoaWRkZW5cclxuICAgICAqIFRoaXMgcHJldmVudHMgaXRlbXMgYmVpbmcgc2V0IGhpZGRlbiBmb3IgaW5uZXIgd2FsbHNcclxuICAgICAqICovXHJcbiAgICBwdWJsaWMgdXBkYXRlRWRnZVZpc2liaWxpdHkoZWRnZTogRWRnZSkge1xyXG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRXYWxsKSB7XHJcbiAgICAgICAgICAgIGxldCBzaG91bGRTaG93OiBib29sZWFuID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmN1cnJlbnRXYWxsLmJhY2tFZGdlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRXYWxsLmJhY2tFZGdlLmVkZ2VzLmZvckVhY2goKGUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZS52aXNpYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNob3VsZFNob3cgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmN1cnJlbnRXYWxsLmZyb250RWRnZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50V2FsbC5mcm9udEVkZ2UuZWRnZXMuZm9yRWFjaChlID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZS52aXNpYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNob3VsZFNob3cgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMudmlzaWJsZSA9IHNob3VsZFNob3c7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIHVwZGF0ZVNpemUoKSB7XHJcbiAgICAgICAgdGhpcy5fd2FsbE9mZnNldFNjYWxhciA9IHRoaXMuZ2V0RGVwdGgoKSAvIDI7XHJcbiAgICAgICAgdGhpcy5fc2l6ZVggPSB0aGlzLmdldFdpZHRoKCk7XHJcbiAgICAgICAgdGhpcy5fc2l6ZVkgPSB0aGlzLmdldEhlaWdodCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIHJlc2l6ZWQoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuYm91bmRUb0Zsb29yKSB7XHJcbiAgICAgICAgICAgIHRoaXMucG9zaXRpb24ueSA9IHRoaXMuX2JvdW5kVG9GbG9vclkoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMudXBkYXRlU2l6ZSgpO1xyXG4gICAgICAgIHRoaXMucmVkcmF3V2FsbCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIHBsYWNlT25FZGdlKGVkZ2U6IEhhbGZFZGdlKSB7XHJcbiAgICAgICAgaWYgKCFlZGdlKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fb25Gcm9udFNpZGUgPSBlZGdlLndhbGwuZnJvbnRFZGdlID09PSBlZGdlO1xyXG4gICAgICAgIHRoaXMuX2NoYW5nZVdhbGxFZGdlKGVkZ2UpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlU2l6ZSgpO1xyXG5cclxuICAgICAgICAvLyBwb3NpdGlvbiBub3Qgc2V0XHJcbiAgICAgICAgY29uc3QgY2VudGVyID0gZWRnZS5pbnRlcmlvckNlbnRlcigpO1xyXG4gICAgICAgIGNvbnN0IG5ld1BvcyA9IHRoaXMucG9zaXRpb25TZXQgP1xyXG4gICAgICAgICAgICAoZWRnZS53YWxsLmFtb3VudFdhbGxNb3ZlZCA/IHRoaXMucG9zaXRpb24uYWRkKG5ldyBWZWN0b3IzKGVkZ2Uud2FsbC5hbW91bnRXYWxsTW92ZWQueCwgMCwgMCkpIDogdGhpcy5wb3NpdGlvbi5jbG9uZSgpKSA6XHJcbiAgICAgICAgICAgIG5ldyBUSFJFRS5WZWN0b3IzKGNlbnRlci54LCBlZGdlLndhbGwuaGVpZ2h0IC8gMi4wLCBjZW50ZXIueSk7XHJcbiAgICAgICAgdGhpcy5fYm91bmRNb3ZlKG5ld1Bvcyk7XHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbi5jb3B5KG5ld1Bvcyk7XHJcbiAgICAgICAgdGhpcy5yZWRyYXdXYWxsKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJlcG9zaXRpb24oKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgbmV3UG9zOiBWZWN0b3IzID0gdGhpcy5wb3NpdGlvbi5jbG9uZSgpO1xyXG4gICAgICAgIHRoaXMuX2JvdW5kTW92ZShuZXdQb3MpO1xyXG4gICAgICAgIHRoaXMucG9zaXRpb24uY29weShuZXdQb3MpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRGbG9vclkoKTogbnVtYmVyIHtcclxuICAgICAgICBpZiAodGhpcy5oYWxmU2l6ZSAmJiB0aGlzLmN1cnJlbnRXYWxsRWRnZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbW92ZVRvWVBvc2l0aW9uKHRoaXMuaGFsZlNpemUueSArIHRoaXMuZWxldmF0aW9uKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi55O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgaXNWYWxpZFBvc2l0aW9uKHBvc2l0aW9uOiBUSFJFRS5WZWN0b3IzLCByb3RhdGlvbj86IFRIUkVFLkV1bGVyLCBvcHRpb25zPzogYW55KTogQ29sbGlzaW9uSW5mbyB7XHJcbiAgICAgICAgcmV0dXJuIHt2YWxpZDogISF0aGlzLmN1cnJlbnRXYWxsRWRnZX07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwdWJsaWMgbW92ZVRvUG9zaXRpb24odmVjMzogVEhSRUUuVmVjdG9yMywgaW50ZXJzZWN0aW9uPzogVEhSRUUuSW50ZXJzZWN0aW9uKSB7XHJcbiAgICAgICAgaWYgKGludGVyc2VjdGlvbiAmJiB0aGlzLmN1cnJlbnRXYWxsRWRnZSkge1xyXG4gICAgICAgICAgICBpZiAoaW50ZXJzZWN0aW9uLm9iamVjdC51c2VyRGF0YS5lZGdlICYmIGludGVyc2VjdGlvbi5vYmplY3QudXNlckRhdGEuZWRnZS53YWxsICE9PSB0aGlzLmN1cnJlbnRXYWxsRWRnZS53YWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VXYWxsRWRnZShpbnRlcnNlY3Rpb24ub2JqZWN0LnVzZXJEYXRhLmVkZ2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuX2JvdW5kTW92ZSh2ZWMzKTtcclxuICAgICAgICAgICAgdGhpcy5wb3NpdGlvbi5jb3B5KHZlYzMpO1xyXG4gICAgICAgICAgICB0aGlzLnJlZHJhd1dhbGwoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwdWJsaWMgbW92ZVRvMmRQb3NpdGlvbih4OiBudW1iZXIsIHk6IG51bWJlciwgZWRnZTogSGFsZkVkZ2UpIHtcclxuICAgICAgICBjb25zdCB2ZWMzID0gbmV3IFZlY3RvcjMoeCwgdGhpcy5wb3NpdGlvbi55LCB5KTtcclxuICAgICAgICB0aGlzLl9jaGFuZ2VXYWxsRWRnZShlZGdlKTtcclxuICAgICAgICB0aGlzLl9ib3VuZE1vdmUodmVjMyk7XHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbi5jb3B5KHZlYzMpO1xyXG4gICAgICAgIHRoaXMucmVkcmF3V2FsbCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiAqL1xyXG4gICAgcHVibGljIGdldFdhbGxPZmZzZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3dhbGxPZmZzZXRTY2FsYXI7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldFN0YXJ0WCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi54IC0gdGhpcy5nZXRTaXplWCgpIC8gMiAqIE1hdGguY29zKHRoaXMucm90YXRpb24ueSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldFN0YXJ0WSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbi56ICsgdGhpcy5nZXRTaXplWCgpIC8gMiAqIE1hdGguc2luKHRoaXMucm90YXRpb24ueSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldEVuZFgoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zaXRpb24ueCArIHRoaXMuZ2V0U2l6ZVgoKSAvIDIgKiBNYXRoLmNvcyh0aGlzLnJvdGF0aW9uLnkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRFbmRZKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uLnogLSB0aGlzLmdldFNpemVYKCkgLyAyICogTWF0aC5zaW4odGhpcy5yb3RhdGlvbi55KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICBAcmV0dXJucyB4IGF4aXMgc2l6ZSBvZiBpdGVtJ3MgYm91bmRpbmcgYm94XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBnZXRTaXplWCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2l6ZVg7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgQHJldHVybnMgeSBheGlzIHNpemUgb2YgaXRlbSdzIGJvdW5kaW5nIGJveFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0U2l6ZVkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpemVZO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBoZWlnaHRVcGRhdGVkKGFtb3VudD86IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIGlmICghaXNOaWxsKGFtb3VudCkpIHtcclxuICAgICAgICAgICAgdGhpcy5wb3NpdGlvbi55ID0gdGhpcy5fbW92ZVRvWVBvc2l0aW9uKHRoaXMucG9zaXRpb24ueSArIGFtb3VudCk7XHJcbiAgICAgICAgICAgIHRoaXMucmVkcmF3V2FsbCgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHN1cGVyLmhlaWdodFVwZGF0ZWQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHVwZGF0ZUdlb21ldHJ5KHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSB7XHJcbiAgICAgICAgY29uc3QgZ2VvbWV0cnkgPSBHZW9tZXRyeS53YWxsQm94KHdpZHRoLCBoZWlnaHQsIHRoaXMuZ2V0SXRlbVRoaWNrbmVzcygpKTtcclxuICAgICAgICAodGhpcy5vYmplY3QgYXMgTWVzaCkuZ2VvbWV0cnkuZGlzcG9zZSgpO1xyXG4gICAgICAgIGNvbnN0IHJvdGF0aW9uID0gdGhpcy5yb3RhdGlvbi55O1xyXG4gICAgICAgIHRoaXMucm90YXRpb24ueSA9IDA7XHJcbiAgICAgICAgLy8gdGhpcy5pbml0aWFsaXplR2VvbWV0cnkoZ2VvbWV0cnkpO1xyXG4gICAgICAgIHRoaXMucm90YXRpb24ueSA9IHJvdGF0aW9uO1xyXG4gICAgICAgIHRoaXMucmVzaXplZCgpO1xyXG4gICAgICAgIHRoaXMucmVkcmF3V2FsbCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyBzZXRUZXh0dXJlKHRleHR1cmU6IFRleHR1cmUpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICB0aGlzLnRleHR1cmUgPSB0ZXh0dXJlICYmIE9iamVjdC5hc3NpZ24oe30sIHRleHR1cmUpO1xyXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNyZWF0ZU1hdGVyaWFsKHRoaXMuY3VycmVudFdhbGxFZGdlID8gdGhpcy5jdXJyZW50V2FsbEVkZ2Uud2FsbC5zaWRlIDogdW5kZWZpbmVkKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgb25XYWxsTW92ZWQod2FsbDogV2FsbCkge1xyXG4gICAgICAgIGlmICh3YWxsLmZyb250RWRnZSkge1xyXG4gICAgICAgICAgICB0aGlzLnBsYWNlT25FZGdlKHdhbGwuZnJvbnRFZGdlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHdhbGwuYmFja0VkZ2UpIHtcclxuICAgICAgICAgICAgdGhpcy5wbGFjZU9uRWRnZSh3YWxsLmJhY2tFZGdlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHVwZGF0ZU1hdGVyaWFsVmlzaWJpbGl0eShzaWRlOiBudW1iZXIgPSBUSFJFRS5Eb3VibGVTaWRlKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnRleHR1cmUpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5jdXJyZW50V2FsbEVkZ2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBpc1NhbWUgPSB0aGlzLl9pc1dhbGxTYW1lKCk7XHJcbiAgICAgICAgaWYgKCFpc1NhbWUpIHtcclxuICAgICAgICAgICAgdGhpcy5jcmVhdGVNYXRlcmlhbChzaWRlLCBpc1NhbWUpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHRleHR1cmVNYXRlcmlhbEZyb250ID0gKHRoaXMub2JqZWN0IGFzIGFueSkubWF0ZXJpYWxbNF07XHJcbiAgICAgICAgY29uc3QgdGV4dHVyZU1hdGVyaWFsQmFjayA9ICh0aGlzLm9iamVjdCBhcyBhbnkpLm1hdGVyaWFsWzVdO1xyXG4gICAgICAgIHN3aXRjaCAoc2lkZSkge1xyXG4gICAgICAgICAgICBjYXNlIFRIUkVFLkRvdWJsZVNpZGU6XHJcbiAgICAgICAgICAgICAgICB0ZXh0dXJlTWF0ZXJpYWxGcm9udC52aXNpYmxlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHRleHR1cmVNYXRlcmlhbEJhY2sudmlzaWJsZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSBUSFJFRS5Gcm9udFNpZGU6XHJcbiAgICAgICAgICAgICAgICB0ZXh0dXJlTWF0ZXJpYWxGcm9udC52aXNpYmxlID0gdGhpcy5mcm9udFZpc2libGU7XHJcbiAgICAgICAgICAgICAgICB0ZXh0dXJlTWF0ZXJpYWxCYWNrLnZpc2libGUgPSAhdGhpcy5mcm9udFZpc2libGU7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSBUSFJFRS5CYWNrU2lkZTpcclxuICAgICAgICAgICAgICAgIHRleHR1cmVNYXRlcmlhbEZyb250LnZpc2libGUgPSAhdGhpcy5mcm9udFZpc2libGU7XHJcbiAgICAgICAgICAgICAgICB0ZXh0dXJlTWF0ZXJpYWxCYWNrLnZpc2libGUgPSB0aGlzLmZyb250VmlzaWJsZTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgY3JlYXRlVGV4dHVyZU1hdGVyaWFsKG9wdGlvbnM/KTogUHJvbWlzZTxUSFJFRS5NZXNoUGhvbmdNYXRlcmlhbD4ge1xyXG4gICAgICAgIGNvbnN0IHtcclxuICAgICAgICAgICAgc2lkZSA9IFRIUkVFLkRvdWJsZVNpZGUsXHJcbiAgICAgICAgICAgIGZsaXAgPSBmYWxzZVxyXG4gICAgICAgIH0gPSBvcHRpb25zIHx8IHt9O1xyXG4gICAgICAgIGNvbnN0IHRleHR1cmUgPSB0aGlzLmdldFRleHR1cmUoKTtcclxuXHJcbiAgICAgICAgY29uc3QgbWF0ZXJpYWwgPSBuZXcgVEhSRUUuTWVzaFBob25nTWF0ZXJpYWwoe3NpZGV9KTtcclxuICAgICAgICBtYXRlcmlhbC50cmFuc3BhcmVudCA9IHRydWU7XHJcblxyXG4gICAgICAgIGlmICh0ZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuYWRkTWF0ZXJpYWxNYXAobWF0ZXJpYWwsIHRleHR1cmUsIGZsaXApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG1hdGVyaWFsO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRUZXh0dXJlKCk6IFRleHR1cmUge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnRleHR1cmU7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGFzeW5jIGNyZWF0ZU1hdGVyaWFsKHNpZGU6IG51bWJlciA9IFRIUkVFLkRvdWJsZVNpZGUsIGlzU2FtZSA9IHRydWUpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBsZXQgdGV4dHVyZU1hdGVyaWFsRnJvbnQ7XHJcbiAgICAgICAgbGV0IHRleHR1cmVNYXRlcmlhbEJhY2s7XHJcbiAgICAgICAgc3dpdGNoIChzaWRlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgVEhSRUUuRG91YmxlU2lkZTpcclxuICAgICAgICAgICAgICAgIHRoaXMuX2ZsaXBwZWQgPSAhaXNTYW1lO1xyXG4gICAgICAgICAgICAgICAgdGV4dHVyZU1hdGVyaWFsRnJvbnQgPSBhd2FpdCB0aGlzLmNyZWF0ZVRleHR1cmVNYXRlcmlhbCh7c2lkZTogVEhSRUUuRnJvbnRTaWRlLCBmbGlwOiB0aGlzLl9mbGlwcGVkfSk7XHJcbiAgICAgICAgICAgICAgICB0ZXh0dXJlTWF0ZXJpYWxCYWNrID0gYXdhaXQgdGhpcy5jcmVhdGVUZXh0dXJlTWF0ZXJpYWwoe3NpZGU6IFRIUkVFLkZyb250U2lkZSwgZmxpcDogIXRoaXMuX2ZsaXBwZWR9KTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIFRIUkVFLkZyb250U2lkZTpcclxuICAgICAgICAgICAgICAgIHRoaXMuX2ZsaXBwZWQgPSAhaXNTYW1lO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZnJvbnRWaXNpYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dHVyZU1hdGVyaWFsRnJvbnQgPSBhd2FpdCB0aGlzLmNyZWF0ZVRleHR1cmVNYXRlcmlhbCh7c2lkZTogVEhSRUUuRnJvbnRTaWRlLCBmbGlwOiB0aGlzLl9mbGlwcGVkfSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmVNYXRlcmlhbEJhY2sgPSBhd2FpdCB0aGlzLmNyZWF0ZVRleHR1cmVNYXRlcmlhbCh7c2lkZTogVEhSRUUuQmFja1NpZGUsIGZsaXA6ICF0aGlzLl9mbGlwcGVkfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSBUSFJFRS5CYWNrU2lkZToge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZmxpcHBlZCA9ICFpc1NhbWU7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZnJvbnRWaXNpYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dHVyZU1hdGVyaWFsRnJvbnQgPSBhd2FpdCB0aGlzLmNyZWF0ZVRleHR1cmVNYXRlcmlhbCh7c2lkZTogVEhSRUUuRnJvbnRTaWRlLCBmbGlwOiB0aGlzLl9mbGlwcGVkfSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmVNYXRlcmlhbEJhY2sgPSBhd2FpdCB0aGlzLmNyZWF0ZVRleHR1cmVNYXRlcmlhbCh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpZGU6IFRIUkVFLkJhY2tTaWRlLCBmbGlwOiAhdGhpcy5fZmxpcHBlZFxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgKCh0aGlzLm9iamVjdCBhcyBhbnkpLm1hdGVyaWFsIGFzIGFueSkgPSB0aGlzLmdldE1hdGVyaWFscyh0ZXh0dXJlTWF0ZXJpYWxGcm9udCwgdGV4dHVyZU1hdGVyaWFsQmFjayk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIHNldFlQb3NpdGlvbkJhc2VkT25FbGV2YXRpb24oKSB7XHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbi55ID0gdGhpcy5lbGV2YXRpb24gKyB0aGlzLmhhbGZTaXplLnk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGFzeW5jIGFkZE1hdGVyaWFsTWFwKG1hdGVyaWFsOiBUSFJFRS5NZXNoUGhvbmdNYXRlcmlhbCwgdGV4dHVyZTogVGV4dHVyZSwgZmxpcDogYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGNvbnN0IGRpbWVuc2lvbnMgPSB0aGlzLmdldE1hdGVyaWFsTWFwRGltZW5zaW9ucygpO1xyXG4gICAgICAgIHRleHR1cmUuZGltZW5zaW9ucyA9IGRpbWVuc2lvbnMubXVsdGlwbHlTY2FsYXIoMTAwKTtcclxuICAgICAgICBzd2l0Y2ggKHRleHR1cmUudHlwZSkge1xyXG4gICAgICAgICAgICBjYXNlIFRleHR1cmVUeXBlLkltYWdlOlxyXG4gICAgICAgICAgICAgICAgaWYgKGZsaXApIHtcclxuICAgICAgICAgICAgICAgICAgICBtYXRlcmlhbC5tYXAgPSBhd2FpdCBNYXRlcmlhbFV0aWxzLkZyb21GbGlwcGVkSW1hZ2UodGV4dHVyZSwgZGltZW5zaW9ucyk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIG1hdGVyaWFsLm1hcCA9IGF3YWl0IE1hdGVyaWFsVXRpbHMuRnJvbUltYWdlKHRleHR1cmUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgVGV4dHVyZVR5cGUuQ3VzdG9tUGF0dGVybjpcclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsLm1hcCA9IGF3YWl0IE1hdGVyaWFsVXRpbHMuQ3VzdG9tVGlsZU1hcFRleHR1cmUodGV4dHVyZSwgZGltZW5zaW9ucyk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSBUZXh0dXJlVHlwZS5CYXNpYzpcclxuICAgICAgICAgICAgICAgIG1hdGVyaWFsLm1hcCA9IGF3YWl0IE1hdGVyaWFsVXRpbHMuRnJvbVVybCh0ZXh0dXJlLnVybCwgdGV4dHVyZS5zdHJldGNoLCB0ZXh0dXJlLnRpbGVTaXplLCBudWxsLCBudWxsLCB0ZXh0dXJlLmRpbWVuc2lvbnMsIHRleHR1cmUudGlsZVJvdGF0aW9uKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyB0aGlzLnNjZW5lLm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICAvLyB0aGlzLnNjZW5lLnRleHR1cmVMb2FkZWRDYWxsYmFja3MuZmlyZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBnZXRNYXRlcmlhbE1hcERpbWVuc2lvbnMoKTogVEhSRUUuVmVjdG9yMiB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBUSFJFRS5WZWN0b3IyKFxyXG4gICAgICAgICAgICB0aGlzLmdldFdpZHRoKCksXHJcbiAgICAgICAgICAgIHRoaXMuZ2V0SGVpZ2h0KClcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBnZXRNYXRlcmlhbHModGV4dHVyZU1hdGVyaWFsRnJvbnQ6IFRIUkVFLk1hdGVyaWFsLCB0ZXh0dXJlTWF0ZXJpYWxCYWNrOiBUSFJFRS5NYXRlcmlhbCk6IFRIUkVFLk1hdGVyaWFsW10ge1xyXG4gICAgICAgIHJldHVybiBbXHJcbiAgICAgICAgICAgIE1hdGVyaWFsVXRpbHMuZGVmYXVsdFdpbmRvdy5jbG9uZSgpLCAvLyBMZWZ0IHNpZGVcclxuICAgICAgICAgICAgTWF0ZXJpYWxVdGlscy5kZWZhdWx0V2luZG93LmNsb25lKCksIC8vIFJpZ2h0IHNpZGVcclxuICAgICAgICAgICAgTWF0ZXJpYWxVdGlscy5kZWZhdWx0V2luZG93LmNsb25lKCksIC8vIFRvcCBzaWRlXHJcbiAgICAgICAgICAgIE1hdGVyaWFsVXRpbHMuZGVmYXVsdFdpbmRvdy5jbG9uZSgpLCAvLyBCb3R0b20gc2lkZVxyXG4gICAgICAgICAgICB0ZXh0dXJlTWF0ZXJpYWxGcm9udCB8fCBNYXRlcmlhbFV0aWxzLmRlZmF1bHRXaW5kb3cuY2xvbmUoKSwgLy8gRnJvbnQgc2lkZVxyXG4gICAgICAgICAgICB0ZXh0dXJlTWF0ZXJpYWxCYWNrIHx8IE1hdGVyaWFsVXRpbHMuZGVmYXVsdFdpbmRvdy5jbG9uZSgpICAgLy8gQmFjayBzaWRlXHJcbiAgICAgICAgXTtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgZ2V0SXRlbVRoaWNrbmVzcygpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRXYWxsLnRoaWNrbmVzcyAtIDAuMDE7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwcm90ZWN0ZWQgcmVkcmF3V2FsbCgpIHtcclxuICAgICAgICBpZiAodGhpcy5jdXJyZW50V2FsbEVkZ2UgJiYgdGhpcy5jdXJyZW50V2FsbEVkZ2Uud2FsbCkge1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRXYWxsRWRnZS53YWxsLmZpcmVSZWRyYXcoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gdGhpcy51cGRhdGVFZGdlVmlzaWJpbGl0eSh0cnVlLCB0aGlzLl9vbkZyb250U2lkZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqICovXHJcbiAgICBwcml2YXRlIF9jaGFuZ2VXYWxsRWRnZSh3YWxsRWRnZTogSGFsZkVkZ2UpIHtcclxuICAgICAgICBpZiAodGhpcy5jdXJyZW50V2FsbEVkZ2UgPT09IHdhbGxFZGdlKSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5jdXJyZW50V2FsbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50V2FsbCA9IHdhbGxFZGdlLndhbGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWlzTmlsbCh0aGlzLmN1cnJlbnRXYWxsRWRnZSkpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuYWRkVG9XYWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRXYWxsRWRnZS53YWxsLnJlbW92ZUl0ZW0odGhpcyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlZHJhd1dhbGwoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFdhbGxFZGdlLndhbGwucmVtb3ZlT25JdGVtKHRoaXMpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghd2FsbEVkZ2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gZmluZCBhbmdsZSBiZXR3ZWVuIHdhbGwgbm9ybWFsc1xyXG4gICAgICAgIGNvbnN0IG5vcm1hbDIgPSBuZXcgVEhSRUUuVmVjdG9yMigpO1xyXG4gICAgICAgIGNvbnN0IG5vcm1hbDMgPSBVdGlscy5HZXRGYWNlTm9ybWFsRnJvbUJ1ZmZlckdlb21ldHJ5KHdhbGxFZGdlLnBsYW5lLmdlb21ldHJ5LCAwLCAwKTtcclxuICAgICAgICBub3JtYWwyLnggPSBub3JtYWwzLng7XHJcbiAgICAgICAgbm9ybWFsMi55ID0gbm9ybWFsMy56O1xyXG5cclxuICAgICAgICBjb25zdCBhbmdsZSA9IFV0aWxzLmFuZ2xlKFxyXG4gICAgICAgICAgICB0aGlzLl9yZWZWZWMueCwgdGhpcy5fcmVmVmVjLnksXHJcbiAgICAgICAgICAgIG5vcm1hbDIueCwgbm9ybWFsMi55KTtcclxuICAgICAgICB0aGlzLnJvdGF0aW9uLnkgPSAodGhpcy5kZWZhdWx0MTgwID8gTWF0aC5QSSA6IDApICsgYW5nbGU7XHJcbiAgICAgICAgdGhpcy50cmF2ZXJzZShjID0+IGMubWF0cml4V29ybGROZWVkc1VwZGF0ZSA9IHRydWUpO1xyXG5cclxuICAgICAgICAvLyB1cGRhdGUgY3VycmVudFdhbGxcclxuICAgICAgICB0aGlzLmN1cnJlbnRXYWxsID0gd2FsbEVkZ2Uud2FsbDtcclxuICAgICAgICB0aGlzLmN1cnJlbnRXYWxsRWRnZSA9IHdhbGxFZGdlO1xyXG4gICAgICAgIGlmICh0aGlzLmFkZFRvV2FsbCkge1xyXG4gICAgICAgICAgICB3YWxsRWRnZS53YWxsLmFkZEl0ZW0odGhpcyk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLm1ldGFkYXRhLnRleHR1cmUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlTWF0ZXJpYWxWaXNpYmlsaXR5KHdhbGxFZGdlLndhbGwuc2lkZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5yZWRyYXdXYWxsKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgd2FsbEVkZ2Uud2FsbC5hZGRPbkl0ZW0odGhpcyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2JvdW5kVG9GbG9vclkoKSB7XHJcbiAgICAgICAgcmV0dXJuIDAuNSAqIHRoaXMuZ2V0SGVpZ2h0KCkgKiB0aGlzLnNjYWxlLnkgKyAwLjAxO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKiB0YWtlcyB0aGUgbW92ZSB2ZWMzLCBhbmQgbWFrZXMgc3VyZSBvYmplY3Qgc3RheXMgYm91bmRlZCBvbiBwbGFuZSAqL1xyXG4gICAgcHJpdmF0ZSBfYm91bmRNb3ZlKHZlYzMpIHtcclxuICAgICAgICBjb25zdCBlZGdlID0gdGhpcy5jdXJyZW50V2FsbEVkZ2U7XHJcbiAgICAgICAgdmVjMy5hcHBseU1hdHJpeDQoZWRnZS5pbnRlcmlvclRyYW5zZm9ybSk7XHJcbiAgICAgICAgZWRnZS53YWxsLml0ZW1zQ2hhbmdlZCA9IHRydWU7XHJcblxyXG4gICAgICAgIGlmICh2ZWMzLnggPCB0aGlzLl9zaXplWCAvIDIuMCArIHRoaXMuX3Bvc2l0aW9uWVRvbGVyYW5jZSkge1xyXG4gICAgICAgICAgICB2ZWMzLnggPSB0aGlzLl9zaXplWCAvIDIuMCArIHRoaXMuX3Bvc2l0aW9uWVRvbGVyYW5jZTtcclxuICAgICAgICB9IGVsc2UgaWYgKHZlYzMueCA+IChlZGdlLmludGVyaW9yRGlzdGFuY2UoKSAtIHRoaXMuX3NpemVYIC8gMi4wIC0gdGhpcy5fcG9zaXRpb25ZVG9sZXJhbmNlKSkge1xyXG4gICAgICAgICAgICB2ZWMzLnggPSBlZGdlLmludGVyaW9yRGlzdGFuY2UoKSAtIHRoaXMuX3NpemVYIC8gMi4wIC0gdGhpcy5fcG9zaXRpb25ZVG9sZXJhbmNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5ib3VuZFRvRmxvb3IpIHtcclxuICAgICAgICAgICAgdmVjMy55ID0gdGhpcy5fYm91bmRUb0Zsb29yWSgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVsZXZhdGlvbkZpeGVkIHx8ICF0aGlzLmVsZXZhdGlvbkFkanVzdGFibGUpIHtcclxuICAgICAgICAgICAgICAgIC8vIGlmIGVsZXZhdGlvbiBpcyBoaWdoZXIgdGhhbiB0aGUgd2FsbCwgdXNlIG1heFlcclxuICAgICAgICAgICAgICAgIHZlYzMueSA9IE1hdGgubWluKHRoaXMuX2dldE1heFkoZWRnZSksIHRoaXMuaGFsZlNpemUueSArIHRoaXMuZWxldmF0aW9uKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG1heFk6IG51bWJlciA9IHRoaXMuX2dldE1heFkoZWRnZSk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtaW5ZOiBudW1iZXIgPSB0aGlzLl9nZXRNaW5UKCk7XHJcbiAgICAgICAgICAgICAgICBpZiAodmVjMy55IDwgbWluWSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZlYzMueSA9IG1pblk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHZlYzMueSA+IG1heFkpIHtcclxuICAgICAgICAgICAgICAgICAgICB2ZWMzLnkgPSBtYXhZO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5lbGV2YXRpb24gPSB2ZWMzLnkgLSB0aGlzLmhhbGZTaXplLnk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZlYzMueiA9IHRoaXMuZ2V0V2FsbE9mZnNldCgpO1xyXG4gICAgICAgIHZlYzMuYXBwbHlNYXRyaXg0KGVkZ2UuaW52SW50ZXJpb3JUcmFuc2Zvcm0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2lzV2FsbFNhbWUoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgbGV0IGlzU2FtZSA9IGZhbHNlO1xyXG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRXYWxsRWRnZSkge1xyXG4gICAgICAgICAgICBjb25zdCBvbkZyb250U2lkZSA9IHRoaXMuY3VycmVudFdhbGxFZGdlID09PSB0aGlzLmN1cnJlbnRXYWxsRWRnZS53YWxsLmZyb250RWRnZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX29uRnJvbnRTaWRlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX29uRnJvbnRTaWRlID0gb25Gcm9udFNpZGU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaXNTYW1lID0gb25Gcm9udFNpZGUgPT09IHRoaXMuX29uRnJvbnRTaWRlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gaXNTYW1lO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2dldE1heFkoZWRnZTogSGFsZkVkZ2UpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiBlZGdlLmhlaWdodCAtIHRoaXMuX3NpemVZIC8gMi4wIC0gdGhpcy5fcG9zaXRpb25ZVG9sZXJhbmNlO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2dldE1pblQoKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2l6ZVkgLyAyLjAgKyB0aGlzLl9wb3NpdGlvbllUb2xlcmFuY2U7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbW92ZVRvWVBvc2l0aW9uKHBvc2l0aW9uOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIGNvbnN0IG1heFk6IG51bWJlciA9IHRoaXMuX2dldE1heFkodGhpcy5jdXJyZW50V2FsbEVkZ2UpO1xyXG4gICAgICAgIGNvbnN0IG1pblk6IG51bWJlciA9IHRoaXMuX2dldE1pblQoKTtcclxuICAgICAgICBpZiAocG9zaXRpb24gPiBtYXhZKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZWxldmF0aW9uID0gbWF4WSAtIHRoaXMuaGFsZlNpemUueTtcclxuICAgICAgICAgICAgcmV0dXJuIG1heFk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwb3NpdGlvbiA8IG1pblkpIHtcclxuICAgICAgICAgICAgdGhpcy5lbGV2YXRpb24gPSBtaW5ZIC0gdGhpcy5oYWxmU2l6ZS55O1xyXG4gICAgICAgICAgICByZXR1cm4gbWluWTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHBvc2l0aW9uO1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgSW5XYWxsSXRlbSBleHRlbmRzIFdhbGxJdGVtIHtcclxuXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9mcmFtZVdpZHRoOiBudW1iZXIgPSAwLjA3O1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBfZnJhbWVEZXB0aDogbnVtYmVyID0gMC4xO1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBfZGVmYXVsdEZyYW1lQ29sb3I6IG51bWJlciA9IDkwNzAxNDY7IC8vIFJBTC0xMDExXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9kZWZhdWx0RG9vckNvbG9yOiBudW1iZXIgPSAxNjc3NzIxNTsgLy8gUkFMLTkwMTBcclxuXHJcbiAgICBwdWJsaWMgb3BlbmluZyA9IHtcclxuICAgICAgICBzaG93OiBmYWxzZSxcclxuICAgICAgICBkb3VibGU6IGZhbHNlLFxyXG4gICAgICAgIGludmVydERpcmVjdGlvbjogZmFsc2UsXHJcbiAgICAgICAgaW52ZXJ0U2lkZTogdHJ1ZVxyXG4gICAgfTtcclxuXHJcbiAgICBwdWJsaWMgZnJhbWVDb2xvcjogbnVtYmVyID0gdGhpcy5fZGVmYXVsdEZyYW1lQ29sb3I7XHJcbiAgICBwdWJsaWMgZG9vckNvbG9yOiBudW1iZXIgPSB0aGlzLl9kZWZhdWx0RG9vckNvbG9yO1xyXG4gICAgcHVibGljIHdpbmRvd0NvbG9yOiBUSFJFRS5Db2xvciA9IG5ldyBUSFJFRS5Db2xvcigwLjA0MzEsIDAuMDU4OCwgMC4wOTAyKTtcclxuICAgIHB1YmxpYyBpc0dsYXNzOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gICAgcHJvdGVjdGVkIHRvcEZyYW1lOiBUSFJFRS5NZXNoO1xyXG4gICAgcHJvdGVjdGVkIGxlZnRGcmFtZTogVEhSRUUuTWVzaDtcclxuICAgIHByb3RlY3RlZCByaWdodEZyYW1lOiBUSFJFRS5NZXNoO1xyXG4gICAgcHJvdGVjdGVkIGJvdHRvbUZyYW1lOiBUSFJFRS5NZXNoO1xyXG4gICAgcHJvdGVjdGVkIGN1c3RvbU1lc2g6IFRIUkVFLk1lc2g7XHJcbiAgICBwcm90ZWN0ZWQgZnJhbWVNYXRlcmlhbDogVEhSRUUuTWVzaFBob25nTWF0ZXJpYWw7XHJcbiAgICBwcm90ZWN0ZWQgZG9vck1hdGVyaWFsRnJvbnQ6IFRIUkVFLk1lc2hQaG9uZ01hdGVyaWFsO1xyXG5cclxuICAgIHByb3RlY3RlZCB3aW5kb3dNYXRlcmlhbDogVEhSRUUuTWVzaFBob25nTWF0ZXJpYWw7XHJcbiAgICBwcml2YXRlIF9pc1dpbmRvdzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgcHJpdmF0ZSBfZG9vcnBvc3Q6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgICBnZXQgZG9vcnBvc3QoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rvb3Jwb3N0O1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIG1ldGFkYXRhOiBNZXRhZGF0YSxcclxuICAgICAgICBvYmplY3Q6IE9iamVjdDNEIHwgTWVzaCxcclxuICAgICAgICB0ZXh0dXJlPzogVGV4dHVyZVxyXG4gICAgKSB7XHJcbiAgICAgICAgc3VwZXIobWV0YWRhdGEsIG9iamVjdCwgdGV4dHVyZSk7XHJcbiAgICAgICAgdGhpcy5fc2V0RGVmYXVsdCgpO1xyXG4gICAgICAgIHRoaXMuZnJhbWVUaXRsZSA9ICdGcmFtZSc7XHJcbiAgICAgICAgdGhpcy5jdXN0b21NZXNoVGl0bGUgPSB0aGlzLl9pc1dpbmRvdyA/ICdXaW5kb3cnIDogJ0Rvb3InO1xyXG4gICAgICAgIHRoaXMuY2FuQ2hhbmdlQ3VzdG9tTWVzaENvbG9yID0gIXRoaXMuX2lzV2luZG93O1xyXG5cclxuICAgICAgICB0aGlzLnJlY2VpdmVTaGFkb3cgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuYWRkVG9XYWxsID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLl9nbGFzc01hdGVyaWFsQ2hlY2soKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZGlzcG9zZSgpOiB2b2lkIHtcclxuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XHJcbiAgICAgICAgVXRpbHMuRGlzcG9zZU9iamVjdCh0aGlzLnRvcEZyYW1lKTtcclxuICAgICAgICBVdGlscy5EaXNwb3NlT2JqZWN0KHRoaXMubGVmdEZyYW1lKTtcclxuICAgICAgICBVdGlscy5EaXNwb3NlT2JqZWN0KHRoaXMucmlnaHRGcmFtZSk7XHJcbiAgICAgICAgVXRpbHMuRGlzcG9zZU9iamVjdCh0aGlzLmJvdHRvbUZyYW1lKTtcclxuICAgICAgICBVdGlscy5EaXNwb3NlT2JqZWN0KHRoaXMuY3VzdG9tTWVzaCk7XHJcbiAgICAgICAgVXRpbHMuRGlzcG9zZU1hdGVyaWFsKHRoaXMuZnJhbWVNYXRlcmlhbCk7XHJcbiAgICAgICAgVXRpbHMuRGlzcG9zZU1hdGVyaWFsKHRoaXMuZG9vck1hdGVyaWFsRnJvbnQpO1xyXG4gICAgICAgIFV0aWxzLkRpc3Bvc2VNYXRlcmlhbCh0aGlzLndpbmRvd01hdGVyaWFsKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcGxhY2VPbkVkZ2UoZWRnZTogSGFsZkVkZ2UpIHtcclxuICAgICAgICBpZiAodGhpcy5pc0N1c3RvbSkge1xyXG4gICAgICAgICAgICBjb25zdCBjaGVja01hdGVyaWFsOiBUSFJFRS5NZXNoUGhvbmdNYXRlcmlhbCA9IHRoaXMuX2lzV2luZG93ID8gdGhpcy53aW5kb3dNYXRlcmlhbCA6IHRoaXMuZG9vck1hdGVyaWFsRnJvbnQ7XHJcbiAgICAgICAgICAgIGlmICghY2hlY2tNYXRlcmlhbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlTWF0ZXJpYWxzKFRIUkVFLkRvdWJsZVNpZGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlQ3VzdG9tTWVzaCh0aGlzLmdldFdpZHRoKCksIHRoaXMuZ2V0SGVpZ2h0KCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBzdXBlci5wbGFjZU9uRWRnZShlZGdlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogKi9cclxuICAgIHB1YmxpYyBnZXRXYWxsT2Zmc2V0KCkge1xyXG4gICAgICAgIHJldHVybiAtdGhpcy5jdXJyZW50V2FsbEVkZ2Uub2Zmc2V0O1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBkaXN0YW5jZUZyb20yZCh4OiBudW1iZXIsIHk6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIFV0aWxzLnBvaW50RGlzdGFuY2VGcm9tTGluZSh4LCB5LFxyXG4gICAgICAgICAgICB0aGlzLmdldFN0YXJ0WCgpLCB0aGlzLmdldFN0YXJ0WSgpLFxyXG4gICAgICAgICAgICB0aGlzLmdldEVuZFgoKSwgdGhpcy5nZXRFbmRZKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBvbldhbGxVcGRhdGVkKHdhbGw6IFdhbGwpIHtcclxuICAgICAgICBpZiAodGhpcy5tZXRhZGF0YS50ZXh0dXJlKSB7XHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlTWF0ZXJpYWxWaXNpYmlsaXR5KHdhbGwuc2lkZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyB1cGRhdGVGcmFtZUNvbG9yKGNvbG9yOiBudW1iZXIpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmZyYW1lQ29sb3IgPSBjb2xvcjtcclxuICAgICAgICB0aGlzLmZyYW1lTWF0ZXJpYWwuY29sb3Iuc2V0SGV4KGNvbG9yKTtcclxuICAgICAgICB0aGlzLmZyYW1lTWF0ZXJpYWwubmVlZHNVcGRhdGUgPSB0cnVlO1xyXG4gICAgICAgIC8vIHRoaXMuc2NlbmUubmVlZHNVcGRhdGUgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyB1cGRhdGVEb29yQ29sb3IoY29sb3I6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuZG9vckNvbG9yID0gY29sb3I7XHJcbiAgICAgICAgdGhpcy5kb29yTWF0ZXJpYWxGcm9udC5jb2xvci5zZXRIZXgoY29sb3IpO1xyXG4gICAgICAgIHRoaXMuZG9vck1hdGVyaWFsRnJvbnQudHJhbnNwYXJlbnQgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmRvb3JNYXRlcmlhbEZyb250Lm9wYWNpdHkgPSAxO1xyXG4gICAgICAgIHRoaXMuZG9vck1hdGVyaWFsRnJvbnQubWFwID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIHRoaXMuZG9vck1hdGVyaWFsRnJvbnQubmVlZHNVcGRhdGUgPSB0cnVlO1xyXG4gICAgICAgIC8vIHRoaXMuc2NlbmUubmVlZHNVcGRhdGUgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyB1cGRhdGVHbGFzc01hdGVyaWFsKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5pc0dsYXNzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZG9vck1hdGVyaWFsRnJvbnQuY29sb3Iuc2V0SGV4KDB4ZGZmMGYyKTtcclxuICAgICAgICAgICAgdGhpcy5kb29yTWF0ZXJpYWxGcm9udC50cmFuc3BhcmVudCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuZG9vck1hdGVyaWFsRnJvbnQuYWxwaGFUZXN0ID0gMDtcclxuICAgICAgICAgICAgdGhpcy5kb29yTWF0ZXJpYWxGcm9udC5vcGFjaXR5ID0gMC4yO1xyXG4gICAgICAgICAgICB0aGlzLmRvb3JNYXRlcmlhbEZyb250Lm1hcCA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgdGhpcy5kb29yTWF0ZXJpYWxGcm9udC5uZWVkc1VwZGF0ZSA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuZG9vck1hdGVyaWFsRnJvbnQuc2lkZSA9IFRIUkVFLkZyb250U2lkZTtcclxuICAgICAgICAgICAgdGhpcy5pc0dsYXNzID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5jdXN0b21NZXNoLmNhc3RTaGFkb3cgPSBmYWxzZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmRvb3JNYXRlcmlhbEZyb250LnRyYW5zcGFyZW50ID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMuZG9vck1hdGVyaWFsRnJvbnQub3BhY2l0eSA9IDE7XHJcbiAgICAgICAgICAgIHRoaXMuaXNHbGFzcyA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLmN1c3RvbU1lc2guY2FzdFNoYWRvdyA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyB1cGRhdGVHZW9tZXRyeSh3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLmlzQ3VzdG9tKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlQ3VzdG9tTWVzaCh3aWR0aCwgaGVpZ2h0KTtcclxuICAgICAgICAgICAgLy8gdGhpcy5jYWxjdWxhdGVIYWxmU2l6ZSgpO1xyXG4gICAgICAgICAgICB0aGlzLnJlZHJhd1dhbGwoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBzdXBlci51cGRhdGVHZW9tZXRyeSh3aWR0aCwgaGVpZ2h0KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFkanVzdFdhbGxCb3goZ2VvbWV0cnk6IEJveEdlb21ldHJ5KSB7XHJcbiAgICAgICAgZ2VvbWV0cnkuZ2V0QXR0cmlidXRlKCdwb3NpdGlvbicpLm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICBnZW9tZXRyeS5jb21wdXRlQm91bmRpbmdCb3goKTtcclxuICAgICAgICBnZW9tZXRyeS5hcHBseU1hdHJpeDQobmV3IE1hdHJpeDQoKS5tYWtlVHJhbnNsYXRpb24oXHJcbiAgICAgICAgICAgIC0wLjUgKiAoZ2VvbWV0cnkuYm91bmRpbmdCb3gubWF4LnggKyBnZW9tZXRyeS5ib3VuZGluZ0JveC5taW4ueCksXHJcbiAgICAgICAgICAgIC0wLjUgKiAoZ2VvbWV0cnkuYm91bmRpbmdCb3gubWF4LnkgKyBnZW9tZXRyeS5ib3VuZGluZ0JveC5taW4ueSksXHJcbiAgICAgICAgICAgIC0wLjUgKiAoZ2VvbWV0cnkuYm91bmRpbmdCb3gubWF4LnogKyBnZW9tZXRyeS5ib3VuZGluZ0JveC5taW4ueilcclxuICAgICAgICApKTtcclxuICAgICAgICBnZW9tZXRyeS5jb21wdXRlQm91bmRpbmdCb3goKTtcclxuICAgICAgICAodGhpcy5vYmplY3QgYXMgTWVzaCkuZ2VvbWV0cnkgPSBnZW9tZXRyeTtcclxuICAgICAgICB0aGlzLmNhbGN1bGF0ZUhhbGZTaXplKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldFZpc2libGVNZXNoZXMoKTogVEhSRUUuTWVzaFtdIHtcclxuICAgICAgICBpZiAodGhpcy5pc0N1c3RvbSAmJiB0aGlzLnZpc2libGUpIHtcclxuICAgICAgICAgICAgY29uc3QgbWVzaGVzOiBUSFJFRS5NZXNoW10gPSBbXHJcbiAgICAgICAgICAgICAgICB0aGlzLmxlZnRGcmFtZSxcclxuICAgICAgICAgICAgICAgIHRoaXMudG9wRnJhbWUsXHJcbiAgICAgICAgICAgICAgICB0aGlzLnJpZ2h0RnJhbWUsXHJcbiAgICAgICAgICAgICAgICB0aGlzLmN1c3RvbU1lc2hcclxuICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzV2luZG93IC8qfHwgdGhpcy5fZG9vcnBvc3QqLykge1xyXG4gICAgICAgICAgICAgICAgbWVzaGVzLnB1c2godGhpcy5ib3R0b21GcmFtZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIG1lc2hlcztcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0VmlzaWJsZU1lc2hlcygpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgY3JlYXRlVGV4dHVyZU1hdGVyaWFsKG9wdGlvbnM/KTogUHJvbWlzZTxUSFJFRS5NZXNoUGhvbmdNYXRlcmlhbD4ge1xyXG4gICAgICAgIGlmICh0aGlzLmlzQ3VzdG9tKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHtcclxuICAgICAgICAgICAgICAgIHNpZGUgPSBUSFJFRS5Eb3VibGVTaWRlLFxyXG4gICAgICAgICAgICAgICAgZmxpcCA9IGZhbHNlXHJcbiAgICAgICAgICAgIH0gPSBvcHRpb25zIHx8IHt9O1xyXG4gICAgICAgICAgICBjb25zdCBjaGVja01hdGVyaWFsOiBUSFJFRS5NZXNoUGhvbmdNYXRlcmlhbCA9IHRoaXMuX2lzV2luZG93ID8gdGhpcy53aW5kb3dNYXRlcmlhbCA6IHRoaXMuZG9vck1hdGVyaWFsRnJvbnQ7XHJcbiAgICAgICAgICAgIGlmICghY2hlY2tNYXRlcmlhbCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlTWF0ZXJpYWxzKHNpZGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IHRleHR1cmUgPSB0aGlzLmdldFRleHR1cmUoKTtcclxuICAgICAgICAgICAgaWYgKCF0ZXh0dXJlKSB7XHJcbiAgICAgICAgICAgICAgICAvLyByZXNldCB0byBkZWZhdWx0IHRleHR1cmVcclxuICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU1hdGVyaWFscyhzaWRlKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlQ3VzdG9tTWVzaCh0aGlzLmdldFdpZHRoKCksIHRoaXMuZ2V0SGVpZ2h0KCkpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2lzV2luZG93ID8gdGhpcy53aW5kb3dNYXRlcmlhbCA6IHRoaXMuZG9vck1hdGVyaWFsRnJvbnQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWw6IFRIUkVFLk1lc2hQaG9uZ01hdGVyaWFsID0gdGhpcy5faXNXaW5kb3cgPyB0aGlzLndpbmRvd01hdGVyaWFsIDogdGhpcy5kb29yTWF0ZXJpYWxGcm9udDtcclxuICAgICAgICAgICAgY29uc3QgZGVmYXVsdE1hdGVyaWFsOiBUSFJFRS5NZXNoUGhvbmdNYXRlcmlhbCA9IG5ldyBUSFJFRS5NZXNoUGhvbmdNYXRlcmlhbCgpO1xyXG5cclxuICAgICAgICAgICAgbWF0ZXJpYWwudHJhbnNwYXJlbnQgPSBmYWxzZTtcclxuICAgICAgICAgICAgbWF0ZXJpYWwuY29sb3IgPSBkZWZhdWx0TWF0ZXJpYWwuY29sb3IuY2xvbmUoKTtcclxuICAgICAgICAgICAgbWF0ZXJpYWwub3BhY2l0eSA9IGRlZmF1bHRNYXRlcmlhbC5vcGFjaXR5O1xyXG4gICAgICAgICAgICBtYXRlcmlhbC5yZWZyYWN0aW9uUmF0aW8gPSBkZWZhdWx0TWF0ZXJpYWwucmVmcmFjdGlvblJhdGlvO1xyXG4gICAgICAgICAgICBtYXRlcmlhbC5zaGluaW5lc3MgPSBkZWZhdWx0TWF0ZXJpYWwuc2hpbmluZXNzO1xyXG4gICAgICAgICAgICBtYXRlcmlhbC5zcGVjdWxhciA9IGRlZmF1bHRNYXRlcmlhbC5zcGVjdWxhci5jbG9uZSgpO1xyXG5cclxuICAgICAgICAgICAgLy8gQWxsb3dzIGZvciB0cmFuc3BhcmVuY3kgaW4gcG5nJ3NcclxuICAgICAgICAgICAgbWF0ZXJpYWwuYWxwaGFUZXN0ID0gMC41O1xyXG4gICAgICAgICAgICAvLyBNYWtlcyBzdXJlIHRoZSBpbWFnZSBpbiBvbmx5IHByb2plY3RlZCBvbmNlIG9uIHRoZSBtZXNoXHJcbiAgICAgICAgICAgIG1hdGVyaWFsLnNpZGUgPSBUSFJFRS5Gcm9udFNpZGU7XHJcbiAgICAgICAgICAgIC8vIFJlbW92ZXMgd2hpdGUgZWRnZXMgc3Vycm91bmRpbmcgdGhlIGltYWdlXHJcbiAgICAgICAgICAgIG1hdGVyaWFsLnRyYW5zcGFyZW50ID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIC8vIG1hdGVyaWFsLmNvbG9yID0gbmV3IFRIUkVFLkNvbG9yKDEsIDEsIDEpO1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmFkZE1hdGVyaWFsTWFwKG1hdGVyaWFsLCB0ZXh0dXJlLCBmbGlwKTtcclxuICAgICAgICAgICAgbWF0ZXJpYWwubmVlZHNVcGRhdGUgPSB0cnVlO1xyXG4gICAgICAgICAgICByZXR1cm4gbWF0ZXJpYWw7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHN1cGVyLmNyZWF0ZVRleHR1cmVNYXRlcmlhbChvcHRpb25zKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGNyZWF0ZUN1c3RvbU1lc2god2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBoYWxmV2lkdGg6IG51bWJlciA9IHdpZHRoIC8gMjtcclxuICAgICAgICBjb25zdCBoYWxmRnJhbWU6IG51bWJlciA9ICh0aGlzLl9mcmFtZVdpZHRoIC8gMik7XHJcblxyXG4gICAgICAgIHRoaXMubGVmdEZyYW1lID0gdGhpcy5fY3JlYXRlRnJhbWVTaWRlKHRoaXMuX2ZyYW1lV2lkdGgsIHRoaXMuX2dldEhlaWdodEZyYW1lKGhlaWdodCksIHRoaXMuX2ZyYW1lRGVwdGgpO1xyXG4gICAgICAgIHRoaXMubGVmdEZyYW1lLnJvdGF0aW9uLnNldCh0aGlzLl9pc1dpbmRvdyA/IDE4MCAqIChNYXRoLlBJIC8gMTgwKSA6IDAsIDAsIDApO1xyXG4gICAgICAgIHRoaXMubGVmdEZyYW1lLnBvc2l0aW9uLnggPSAtaGFsZldpZHRoICsgaGFsZkZyYW1lO1xyXG4gICAgICAgIHRoaXMubGVmdEZyYW1lLm5hbWUgPSAnbGVmdEZyYW1lJztcclxuICAgICAgICBpZiAoIXRoaXMuX2lzV2luZG93KSB7XHJcbiAgICAgICAgICAgIHRoaXMubGVmdEZyYW1lLnBvc2l0aW9uLnkgPSAtKHRoaXMuX2ZyYW1lV2lkdGggLyAyKSArIDAuMDI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnRvcEZyYW1lID0gdGhpcy5fY3JlYXRlRnJhbWVTaWRlKHRoaXMuX2ZyYW1lV2lkdGgsIHdpZHRoLCB0aGlzLl9mcmFtZURlcHRoKTtcclxuICAgICAgICB0aGlzLnRvcEZyYW1lLnJvdGF0aW9uLnNldCgwLCB0aGlzLl9pc1dpbmRvdyA/IDE4MCAqIChNYXRoLlBJIC8gMTgwKSA6IDAsIC05MCAqIChNYXRoLlBJIC8gMTgwKSk7XHJcbiAgICAgICAgdGhpcy50b3BGcmFtZS5wb3NpdGlvbi55ID0gKGhlaWdodCAvIDIpIC0gKHRoaXMuX2ZyYW1lV2lkdGggLyAyKTtcclxuICAgICAgICB0aGlzLnRvcEZyYW1lLm5hbWUgPSAndG9wRnJhbWUnO1xyXG5cclxuICAgICAgICB0aGlzLnJpZ2h0RnJhbWUgPSB0aGlzLl9jcmVhdGVGcmFtZVNpZGUodGhpcy5fZnJhbWVXaWR0aCwgdGhpcy5fZ2V0SGVpZ2h0RnJhbWUoaGVpZ2h0KSwgdGhpcy5fZnJhbWVEZXB0aCk7XHJcbiAgICAgICAgdGhpcy5yaWdodEZyYW1lLnJvdGF0aW9uLnNldCh0aGlzLl9pc1dpbmRvdyA/IDE4MCAqIChNYXRoLlBJIC8gMTgwKSA6IDAsIDAsIC0xODAgKiAoTWF0aC5QSSAvIDE4MCkpO1xyXG4gICAgICAgIHRoaXMucmlnaHRGcmFtZS5wb3NpdGlvbi54ID0gKHdpZHRoIC8gMikgLSAodGhpcy5fZnJhbWVXaWR0aCAvIDIpO1xyXG4gICAgICAgIHRoaXMucmlnaHRGcmFtZS5uYW1lID0gJ3JpZ2h0RnJhbWUnO1xyXG4gICAgICAgIGlmICghdGhpcy5faXNXaW5kb3cpIHtcclxuICAgICAgICAgICAgdGhpcy5yaWdodEZyYW1lLnBvc2l0aW9uLnkgPSAtKHRoaXMuX2ZyYW1lV2lkdGggLyAyKSArIDAuMDI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5faXNXaW5kb3cgLyp8fCB0aGlzLl9kb29ycG9zdCovKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYm90dG9tRnJhbWUgPSB0aGlzLl9jcmVhdGVGcmFtZVNpZGUodGhpcy5fZnJhbWVXaWR0aCwgd2lkdGgsIHRoaXMuX2ZyYW1lRGVwdGgpO1xyXG4gICAgICAgICAgICB0aGlzLmJvdHRvbUZyYW1lLnJvdGF0aW9uLnNldCgwLCAxODAgKiAoTWF0aC5QSSAvIDE4MCksIDkwICogKE1hdGguUEkgLyAxODApKTtcclxuICAgICAgICAgICAgdGhpcy5ib3R0b21GcmFtZS5wb3NpdGlvbi55ID0gLShoZWlnaHQgLyAyKSArICh0aGlzLl9mcmFtZVdpZHRoIC8gMik7XHJcbiAgICAgICAgICAgIHRoaXMuYm90dG9tRnJhbWUubmFtZSA9ICdib3R0b21GcmFtZSc7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgY3VzdG9tR2VvOiBUSFJFRS5Cb3hHZW9tZXRyeTtcclxuICAgICAgICBpZiAodGhpcy5faXNXaW5kb3cpIHtcclxuICAgICAgICAgICAgY3VzdG9tR2VvID0gbmV3IFRIUkVFLkJveEdlb21ldHJ5KHdpZHRoIC0gKDIgKiB0aGlzLl9mcmFtZVdpZHRoKSArIDAuMDQsIGhlaWdodCAtICgyICogdGhpcy5fZnJhbWVXaWR0aCkgKyAwLjA0LCAwLjAyNCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY3VzdG9tR2VvID0gbmV3IFRIUkVFLkJveEdlb21ldHJ5KHdpZHRoIC0gMC4wMiAqICh0aGlzLl9mcmFtZVdpZHRoIC0gMC4wMiksIGhlaWdodCAtICh0aGlzLl9mcmFtZVdpZHRoIC0gMC4wMiksIDAuMDQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmN1c3RvbU1lc2ggPSBuZXcgVEhSRUUuTWVzaChjdXN0b21HZW8sIHRoaXMuX2lzV2luZG93ID8gdGhpcy53aW5kb3dNYXRlcmlhbCA6IHRoaXMuZG9vck1hdGVyaWFsRnJvbnQpO1xyXG4gICAgICAgIHRoaXMuY3VzdG9tTWVzaC5jYXN0U2hhZG93ID0gdGhpcy5faXNXaW5kb3cgPyBmYWxzZSA6ICF0aGlzLmlzR2xhc3M7XHJcbiAgICAgICAgdGhpcy5jdXN0b21NZXNoLnJlbmRlck9yZGVyID0gLTE7XHJcblxyXG4gICAgICAgIHRoaXMuY3VzdG9tTWVzaC5uYW1lID0gJ2N1c3RvbU1lc2gnO1xyXG4gICAgICAgIGlmICh0aGlzLl9pc1dpbmRvdykge1xyXG4gICAgICAgICAgICB0aGlzLmN1c3RvbU1lc2gubmFtZSArPSAnV2luZG93JztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuaXNHbGFzcykge1xyXG4gICAgICAgICAgICB0aGlzLmN1c3RvbU1lc2gubmFtZSArPSAnR2xhc3MnO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX2lzV2luZG93KSB7XHJcbiAgICAgICAgICAgIHRoaXMuY3VzdG9tTWVzaC5wb3NpdGlvbi56ID0gLTAuMDEyO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuY3VzdG9tTWVzaC5wb3NpdGlvbi55ID0gLSh0aGlzLl9mcmFtZVdpZHRoIC8gMikgKyAwLjAxO1xyXG4gICAgICAgICAgICB0aGlzLmN1c3RvbU1lc2gucG9zaXRpb24ueiA9IDAuMDI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX2dldEFkZGl0aW9uYWxUZXh0dXJlKCkudGhlbigoZnJvbnRBZGRpdGlvbmFsT2JqOiBUSFJFRS5NZXNoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChmcm9udEFkZGl0aW9uYWxPYmopIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGJhY2tBZGRpdGlvbmFsT2JqID0gZnJvbnRBZGRpdGlvbmFsT2JqLmNsb25lKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgYmFja0FkZGl0aW9uYWxPYmoucm90YXRpb24ueCA9IDE4MCAqIChNYXRoLlBJIC8gMTgwKTtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmFkZGl0aW9uYWxUZXh0dXJlLmRhdGEpIHtcclxuICAgICAgICAgICAgICAgICAgICBmcm9udEFkZGl0aW9uYWxPYmoucG9zaXRpb24uc2V0KFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAtKHdpZHRoIC8gMikgKyB0aGlzLmFkZGl0aW9uYWxUZXh0dXJlLmRhdGEueCwgLShoZWlnaHQgLyAyKSArIHRoaXMuYWRkaXRpb25hbFRleHR1cmUuZGF0YS55LCAwLjAyKTtcclxuICAgICAgICAgICAgICAgICAgICBiYWNrQWRkaXRpb25hbE9iai5wb3NpdGlvbi5zZXQoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC0od2lkdGggLyAyKSArIHRoaXMuYWRkaXRpb25hbFRleHR1cmUuZGF0YS54LCAtKGhlaWdodCAvIDIpICsgdGhpcy5hZGRpdGlvbmFsVGV4dHVyZS5kYXRhLnksIC0wLjAyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMuY3VzdG9tTWVzaC5hZGQoZnJvbnRBZGRpdGlvbmFsT2JqKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3VzdG9tTWVzaC5hZGQoYmFja0FkZGl0aW9uYWxPYmopO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRoaXMuY2hpbGRyZW4ubGVuZ3RoID0gMDtcclxuICAgICAgICB0aGlzLmFkZCh0aGlzLmxlZnRGcmFtZSwgdGhpcy5yaWdodEZyYW1lLCB0aGlzLnRvcEZyYW1lLCB0aGlzLmN1c3RvbU1lc2gpO1xyXG4gICAgICAgIGlmICh0aGlzLl9pc1dpbmRvdyAvKnx8IHRoaXMuX2Rvb3Jwb3N0Ki8pIHtcclxuICAgICAgICAgICAgdGhpcy5hZGQodGhpcy5ib3R0b21GcmFtZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY2FsY3VsYXRlSGFsZlNpemUoKTtcclxuICAgICAgICAvLyB0aGlzLnNjZW5lLm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgY2xvbmVJdGVtKCk6IEluV2FsbEl0ZW0ge1xyXG4gICAgICAgIGNvbnN0IGNsb25lOiBJbldhbGxJdGVtID0gdGhpcy5jcmVhdGVDbGFzcygpO1xyXG4gICAgICAgIHRoaXMuY2xvbmVQcm9wZXJ0aWVzKGNsb25lKTtcclxuICAgICAgICBjbG9uZS5uYW1lID0gJ3Rlc3QgY2xvbmUnO1xyXG4gICAgICAgIHJldHVybiBjbG9uZTtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgYXN5bmMgY3JlYXRlTWF0ZXJpYWwoc2lkZSA9IFRIUkVFLkRvdWJsZVNpZGUsIGlzU2FtZSA9IHRydWUpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBpZiAodGhpcy5pc0N1c3RvbSkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNyZWF0ZVRleHR1cmVNYXRlcmlhbCh7c2lkZTogVEhSRUUuRnJvbnRTaWRlLCBmbGlwOiBmYWxzZX0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHN1cGVyLmNyZWF0ZVRleHR1cmVNYXRlcmlhbCh7c2lkZSwgaXNTYW1lfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBjcmVhdGVDbGFzcygpOiBJbldhbGxJdGVtIHtcclxuICAgICAgICAvLyBjcmVhdGUgbmV3IG9iamVjdCBmb3IgcHJvcGVyIGRpbWVuc2lvbnNcclxuICAgICAgICBjb25zdCBtZXNoOiBNZXNoID0gbmV3IE1lc2gobmV3IEJveEdlb21ldHJ5KHRoaXMuaGFsZlNpemUueCAqIDIsIHRoaXMuaGFsZlNpemUueSAqIDIsIHRoaXMuaGFsZlNpemUueiAqIDIpKTtcclxuICAgICAgICByZXR1cm4gbmV3IEluV2FsbEl0ZW0odGhpcy5tZXRhZGF0YSwgbWVzaCk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGNsb25lUHJvcGVydGllcyhjbG9uZTogSW5XYWxsSXRlbSk6IHZvaWQge1xyXG4gICAgICAgIGNsb25lLnVzZXJEYXRhID0gdGhpcy51c2VyRGF0YTtcclxuICAgICAgICBjbG9uZS5kb29yTWF0ZXJpYWxGcm9udCA9IHRoaXMuZG9vck1hdGVyaWFsRnJvbnQgPyA8TWVzaFBob25nTWF0ZXJpYWw+dGhpcy5kb29yTWF0ZXJpYWxGcm9udC5jbG9uZSgpIDogdW5kZWZpbmVkO1xyXG4gICAgICAgIGlmIChjbG9uZS5kb29yTWF0ZXJpYWxGcm9udCkge1xyXG4gICAgICAgICAgICBjbG9uZS5kb29yTWF0ZXJpYWxGcm9udC5lbWlzc2l2ZSA9IG5ldyBUSFJFRS5Db2xvcigweDAwMDAwMCk7XHJcbiAgICAgICAgICAgIGNsb25lLmRvb3JNYXRlcmlhbEZyb250Lm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2xvbmUud2luZG93TWF0ZXJpYWwgPSB0aGlzLndpbmRvd01hdGVyaWFsID8gPE1lc2hQaG9uZ01hdGVyaWFsPnRoaXMud2luZG93TWF0ZXJpYWwuY2xvbmUoKSA6IHVuZGVmaW5lZDtcclxuICAgICAgICBpZiAoY2xvbmUud2luZG93TWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgY2xvbmUud2luZG93TWF0ZXJpYWwuZW1pc3NpdmUgPSBuZXcgVEhSRUUuQ29sb3IoMHgwMDAwMDApO1xyXG4gICAgICAgICAgICBjbG9uZS53aW5kb3dNYXRlcmlhbC5uZWVkc1VwZGF0ZSA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNsb25lLmZyYW1lTWF0ZXJpYWwgPSB0aGlzLmZyYW1lTWF0ZXJpYWwgPyA8TWVzaFBob25nTWF0ZXJpYWw+dGhpcy5mcmFtZU1hdGVyaWFsLmNsb25lKCkgOiB1bmRlZmluZWQ7XHJcbiAgICAgICAgaWYgKGNsb25lLmZyYW1lTWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgY2xvbmUuZnJhbWVNYXRlcmlhbC5lbWlzc2l2ZSA9IG5ldyBUSFJFRS5Db2xvcigweDAwMDAwMCk7XHJcbiAgICAgICAgICAgIGNsb25lLmZyYW1lTWF0ZXJpYWwubmVlZHNVcGRhdGUgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjbG9uZS5mcmFtZUNvbG9yID0gdGhpcy5mcmFtZUNvbG9yO1xyXG4gICAgICAgIGNsb25lLmRvb3JDb2xvciA9IHRoaXMuZG9vckNvbG9yO1xyXG4gICAgICAgICgoY2xvbmUub2JqZWN0IGFzIE1lc2gpLm1hdGVyaWFsIGFzIGFueSkgPSBbY2xvbmUuZnJhbWVNYXRlcmlhbCwgY2xvbmUuX2lzV2luZG93ID8gY2xvbmUud2luZG93TWF0ZXJpYWwgOiBjbG9uZS5kb29yTWF0ZXJpYWxGcm9udF07XHJcbiAgICAgICAgY2xvbmUudGV4dHVyZSA9IHRoaXMudGV4dHVyZTtcclxuICAgICAgICBjbG9uZS5hZGRpdGlvbmFsVGV4dHVyZSA9IHRoaXMuYWRkaXRpb25hbFRleHR1cmU7XHJcbiAgICAgICAgY2xvbmUuaXNHbGFzcyA9IHRoaXMuaXNHbGFzcztcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgZ2V0TWF0ZXJpYWxzKHRleHR1cmVNYXRlcmlhbEZyb250OiBUSFJFRS5NYXRlcmlhbCwgdGV4dHVyZU1hdGVyaWFsQmFjazogVEhSRUUuTWF0ZXJpYWwpOiBUSFJFRS5NYXRlcmlhbFtdIHtcclxuICAgICAgICBpZiAodGhpcy5pc0N1c3RvbSkge1xyXG4gICAgICAgICAgICByZXR1cm4gKHRoaXMub2JqZWN0IGFzIE1lc2gpLm1hdGVyaWFsIGFzIGFueTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0TWF0ZXJpYWxzKHRleHR1cmVNYXRlcmlhbEZyb250LCB0ZXh0dXJlTWF0ZXJpYWxCYWNrKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIGdldE1hdGVyaWFsTWFwRGltZW5zaW9ucygpOiBUSFJFRS5WZWN0b3IyIHtcclxuICAgICAgICBpZiAodGhpcy5pc0N1c3RvbSkge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IFRIUkVFLlZlY3RvcjIoXHJcbiAgICAgICAgICAgICAgICB0aGlzLmdldFdpZHRoKCkgLSAwLjE0LFxyXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRIZWlnaHQoKSAtIDAuMDdcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gc3VwZXIuZ2V0TWF0ZXJpYWxNYXBEaW1lbnNpb25zKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBpbml0aWF0ZUl0ZW1PYmplY3QoZGF0YTogYW55KTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNDdXN0b20gJiYgZGF0YSAmJiBkYXRhLmdlb21ldHJ5KSB7XHJcbiAgICAgICAgICAgIGRhdGEuZ2VvbWV0cnkudmVydGljZXNOZWVkVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgZGF0YS5nZW9tZXRyeS5jb21wdXRlQm91bmRpbmdCb3goKTtcclxuICAgICAgICAgICAgZGF0YS5nZW9tZXRyeS5hcHBseU1hdHJpeDQobmV3IE1hdHJpeDQoKS5tYWtlVHJhbnNsYXRpb24oXHJcbiAgICAgICAgICAgICAgICAtMC41ICogKGRhdGEuZ2VvbWV0cnkuYm91bmRpbmdCb3gubWF4LnggKyBkYXRhLmdlb21ldHJ5LmJvdW5kaW5nQm94Lm1pbi54KSxcclxuICAgICAgICAgICAgICAgIC0wLjUgKiAoZGF0YS5nZW9tZXRyeS5ib3VuZGluZ0JveC5tYXgueSArIGRhdGEuZ2VvbWV0cnkuYm91bmRpbmdCb3gubWluLnkpLFxyXG4gICAgICAgICAgICAgICAgLTAuNSAqIChkYXRhLmdlb21ldHJ5LmJvdW5kaW5nQm94Lm1heC56ICsgZGF0YS5nZW9tZXRyeS5ib3VuZGluZ0JveC5taW4ueilcclxuICAgICAgICAgICAgKSk7XHJcbiAgICAgICAgICAgIGRhdGEuZ2VvbWV0cnkuY29tcHV0ZUJvdW5kaW5nQm94KCk7XHJcbiAgICAgICAgICAgIGNvbnN0IG1heCA9IGRhdGEuZ2VvbWV0cnkuYm91bmRpbmdCb3gubWF4LmNsb25lKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IG1pbiA9IGRhdGEuZ2VvbWV0cnkuYm91bmRpbmdCb3gubWluLmNsb25lKCk7XHJcbiAgICAgICAgICAgIHRoaXMuaGFsZlNpemUgPSBtYXguc3ViKG1pbikuZGl2aWRlU2NhbGFyKDIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9zZXREZWZhdWx0KCk6IHZvaWQge1xyXG4gICAgICAgIC8vIHdvcmthcm91bmQgYmVjYXVzZSBwcm9wZXJ0aWVzIGFyZSBub3QgYXZhaWxhYmxlIHlldCB3aGVuIGNyZWF0aW5nIHdpbmRvdy9kb29yIGZyb20gbG9hZGluZyBmcm9tIGNsb3VkL2xvY2FsXHJcbiAgICAgICAgdGhpcy5mcmFtZUNvbG9yID0gdGhpcy5tZXRhZGF0YS5mcmFtZUNvbG9yID8gdGhpcy5tZXRhZGF0YS5mcmFtZUNvbG9yIDogdGhpcy5fZGVmYXVsdEZyYW1lQ29sb3I7IC8vIFJBTC0xMDExXHJcbiAgICAgICAgdGhpcy5kb29yQ29sb3IgPSB0aGlzLm1ldGFkYXRhLmRvb3JDb2xvciA/IHRoaXMubWV0YWRhdGEuZG9vckNvbG9yIDogdGhpcy5fZGVmYXVsdERvb3JDb2xvcjsgLy8gUkFMLTkwMTBcclxuICAgICAgICB0aGlzLndpbmRvd0NvbG9yID0gdGhpcy5tZXRhZGF0YS53aW5kb3dDb2xvciA/IHRoaXMubWV0YWRhdGEud2luZG93Q29sb3IgOiBuZXcgVEhSRUUuQ29sb3IoMHhkZmYwZjIpO1xyXG4gICAgICAgIHRoaXMuX2lzV2luZG93ID0gdGhpcy5tZXRhZGF0YS5pdGVtVHlwZSA9PT0gSXRlbVR5cGUuSW5XYWxsO1xyXG4gICAgICAgIHRoaXMuX2Rvb3Jwb3N0ID0gdGhpcy5tZXRhZGF0YS5kb29ycG9zdDtcclxuICAgICAgICB0aGlzLmlzR2xhc3MgPSB0aGlzLm1ldGFkYXRhLmlzR2xhc3MgPyB0aGlzLm1ldGFkYXRhLmlzR2xhc3MgOiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9jcmVhdGVNYXRlcmlhbHMoc2lkZTogVEhSRUUuU2lkZSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX3NldERlZmF1bHQoKTtcclxuICAgICAgICB0aGlzLmZyYW1lTWF0ZXJpYWwgPSBuZXcgVEhSRUUuTWVzaFBob25nTWF0ZXJpYWwoe3NpZGU6IHNpZGUsIG5hbWU6ICdmcmFtZU1hdGVyaWFsJ30pO1xyXG4gICAgICAgIHRoaXMuZnJhbWVNYXRlcmlhbC5jb2xvciA9IG5ldyBUSFJFRS5Db2xvcih0aGlzLmZyYW1lQ29sb3IpO1xyXG4gICAgICAgIGlmICh0aGlzLl9pc1dpbmRvdykge1xyXG4gICAgICAgICAgICB0aGlzLndpbmRvd01hdGVyaWFsID0gbmV3IFRIUkVFLk1lc2hQaG9uZ01hdGVyaWFsKHtzaWRlOiBzaWRlLCBjb2xvcjogdGhpcy53aW5kb3dDb2xvciwgbmFtZTogJ3dpbmRvd01hdGVyaWFsJ30pO1xyXG4gICAgICAgICAgICB0aGlzLndpbmRvd01hdGVyaWFsLnRyYW5zcGFyZW50ID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy53aW5kb3dNYXRlcmlhbC5hbHBoYVRlc3QgPSAwO1xyXG4gICAgICAgICAgICB0aGlzLndpbmRvd01hdGVyaWFsLm9wYWNpdHkgPSAwLjI7XHJcbiAgICAgICAgICAgIHRoaXMud2luZG93TWF0ZXJpYWwubWFwID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICB0aGlzLndpbmRvd01hdGVyaWFsLm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy53aW5kb3dNYXRlcmlhbC5zaWRlID0gVEhSRUUuRnJvbnRTaWRlO1xyXG4gICAgICAgICAgICAoKHRoaXMub2JqZWN0IGFzIE1lc2gpLm1hdGVyaWFsIGFzIGFueSkgPSBbdGhpcy5mcmFtZU1hdGVyaWFsLCB0aGlzLndpbmRvd01hdGVyaWFsXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmRvb3JNYXRlcmlhbEZyb250ID0gbmV3IFRIUkVFLk1lc2hQaG9uZ01hdGVyaWFsKHtzaWRlOiBzaWRlLCBuYW1lOiAnZG9vck1hdGVyaWFsRnJvbnQnfSk7XHJcbiAgICAgICAgICAgIHRoaXMuZG9vck1hdGVyaWFsRnJvbnQuY29sb3IgPSBuZXcgVEhSRUUuQ29sb3IodGhpcy5kb29yQ29sb3IpO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fZG9vcnBvc3QpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZG9vck1hdGVyaWFsRnJvbnQudHJhbnNwYXJlbnQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kb29yTWF0ZXJpYWxGcm9udC5vcGFjaXR5ID0gMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAoKHRoaXMub2JqZWN0IGFzIE1lc2gpLm1hdGVyaWFsIGFzIGFueSkgPSBbdGhpcy5mcmFtZU1hdGVyaWFsLCB0aGlzLmRvb3JNYXRlcmlhbEZyb250XTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZ2V0SGVpZ2h0RnJhbWUoaGVpZ2h0OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiBoZWlnaHQgLSAodGhpcy5faXNXaW5kb3cgPyAyICogKHRoaXMuX2ZyYW1lV2lkdGggLSAwLjAyKSA6IHRoaXMuX2ZyYW1lV2lkdGggLSAwLjAyKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9jcmVhdGVGcmFtZVNpZGUod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIGRlcHRoOiBudW1iZXIpOiBUSFJFRS5NZXNoIHtcclxuICAgICAgICBjb25zdCBvdXRlckZyYW1lV2lkdGg6IG51bWJlciA9IHdpZHRoIC0gMC4wMjtcclxuICAgICAgICBjb25zdCBvdXRlckZyYW1lR2VvID0gbmV3IFRIUkVFLkJveEdlb21ldHJ5KG91dGVyRnJhbWVXaWR0aCwgaGVpZ2h0LCBkZXB0aCk7XHJcbiAgICAgICAgY29uc3Qgb3V0ZXJGcmFtZSA9IG5ldyBUSFJFRS5NZXNoKG91dGVyRnJhbWVHZW8sIHRoaXMuZnJhbWVNYXRlcmlhbCk7XHJcbiAgICAgICAgb3V0ZXJGcmFtZS5jYXN0U2hhZG93ID0gdHJ1ZTtcclxuICAgICAgICBvdXRlckZyYW1lLnJlY2VpdmVTaGFkb3cgPSB0cnVlO1xyXG5cclxuICAgICAgICBjb25zdCBpbm5lckZyYW1lR2VvID0gbmV3IFRIUkVFLkJveEdlb21ldHJ5KDAuMDIsIGhlaWdodCwgZGVwdGggLyAyKTtcclxuICAgICAgICBjb25zdCBpbm5lckZyYW1lID0gbmV3IFRIUkVFLk1lc2goaW5uZXJGcmFtZUdlbywgdGhpcy5mcmFtZU1hdGVyaWFsKTtcclxuICAgICAgICBpbm5lckZyYW1lLmNhc3RTaGFkb3cgPSB0cnVlO1xyXG4gICAgICAgIGlubmVyRnJhbWUucmVjZWl2ZVNoYWRvdyA9IHRydWU7XHJcbiAgICAgICAgaW5uZXJGcmFtZS5wb3NpdGlvbi54ID0gKG91dGVyRnJhbWVXaWR0aCAvIDIpICsgMC4wMTtcclxuICAgICAgICBpbm5lckZyYW1lLnBvc2l0aW9uLnogPSAtZGVwdGggLyA0O1xyXG5cclxuICAgICAgICBjb25zdCBmcmFtZVNpZGUgPSBuZXcgVEhSRUUuT2JqZWN0M0QoKTtcclxuICAgICAgICBmcmFtZVNpZGUuYWRkKG91dGVyRnJhbWUsIGlubmVyRnJhbWUpO1xyXG4gICAgICAgIGNvbnN0IGJvdW5kaW5nQm94ID0gbmV3IFRIUkVFLkJveDMoKS5zZXRGcm9tT2JqZWN0KGZyYW1lU2lkZSk7XHJcbiAgICAgICAgY29uc3QgYmJDZW50ZXJQaXZvdCA9IG5ldyBUSFJFRS5WZWN0b3IzKCk7XHJcbiAgICAgICAgYm91bmRpbmdCb3guZ2V0Q2VudGVyKGJiQ2VudGVyUGl2b3QpO1xyXG4gICAgICAgIGNvbnN0IGRlbHRhID0gbmV3IFRIUkVFLlZlY3RvcjMoKS5zdWIoYmJDZW50ZXJQaXZvdCkuc2V0WSgwKTtcclxuICAgICAgICBmcmFtZVNpZGUuY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICBjaGlsZC5wb3NpdGlvbi5hZGQoZGVsdGEpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGNvbnN0IGZyYW1lU2lkZU1lc2ggPSBuZXcgTWVzaCgpO1xyXG4gICAgICAgIGZyYW1lU2lkZU1lc2guYWRkKG91dGVyRnJhbWUsIGlubmVyRnJhbWUpO1xyXG4gICAgICAgIHJldHVybiBmcmFtZVNpZGVNZXNoO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2dldEFkZGl0aW9uYWxUZXh0dXJlKCk6IFByb21pc2U8VEhSRUUuTWVzaD4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZTogRnVuY3Rpb24sIHJlamVjdDogRnVuY3Rpb24pID0+IHtcclxuICAgICAgICAgICAgLy8gaWYgKHRoaXMuYWRkaXRpb25hbFRleHR1cmUpIHtcclxuICAgICAgICAgICAgLy8gICAgIExvYWRlclV0aWxzLkxvYWRPYmpNb2RlbCh0aGlzLmFkZGl0aW9uYWxUZXh0dXJlLnVybCkudGhlbigob2JqOiBUSFJFRS5NZXNoKSA9PiB7XHJcbiAgICAgICAgICAgIC8vICAgICAgICAgY29uc3QgYWRkaXRpb25hbE9iajogVEhSRUUuTWVzaCA9IDxNZXNoPm9iai5jbG9uZSh0cnVlKTtcclxuICAgICAgICAgICAgLy8gICAgICAgICBhZGRpdGlvbmFsT2JqLmNoaWxkcmVuLm1hcChjID0+IGMucG9zaXRpb24uc2V0KDAsIDAsIDApKTtcclxuICAgICAgICAgICAgLy8gICAgICAgICBpZiAodGhpcy5hZGRpdGlvbmFsVGV4dHVyZS5zY2FsZSkge1xyXG4gICAgICAgICAgICAvLyAgICAgICAgICAgICBhZGRpdGlvbmFsT2JqLnNjYWxlLm11bHRpcGx5U2NhbGFyKHRoaXMuYWRkaXRpb25hbFRleHR1cmUuc2NhbGUpO1xyXG4gICAgICAgICAgICAvLyAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gICAgICAgICByZXNvbHZlKGFkZGl0aW9uYWxPYmopO1xyXG4gICAgICAgICAgICAvLyAgICAgfSk7XHJcbiAgICAgICAgICAgIC8vIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXNvbHZlKG51bGwpO1xyXG4gICAgICAgICAgICAvLyB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZ2xhc3NNYXRlcmlhbENoZWNrKCkge1xyXG4gICAgICAgIGxldCBtZXNoZXNGb3VuZCA9IDA7XHJcbiAgICAgICAgdGhpcy50cmF2ZXJzZSgoY2hpbGQpID0+IHtcclxuICAgICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgTWVzaCAmJiBjaGlsZC5tYXRlcmlhbCkge1xyXG4gICAgICAgICAgICAgICAgbWVzaGVzRm91bmQrKztcclxuICAgICAgICAgICAgICAgIGNoaWxkLmNhc3RTaGFkb3cgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxzOiBhbnkgPSAhQXJyYXkuaXNBcnJheShjaGlsZC5tYXRlcmlhbCkgPyBbY2hpbGQubWF0ZXJpYWxdIDogY2hpbGQubWF0ZXJpYWw7XHJcbiAgICAgICAgICAgICAgICBtYXRlcmlhbHMuZm9yRWFjaChtYXRlcmlhbCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGVyaWFsLm5hbWUgJiYgKG1hdGVyaWFsLm5hbWUgPT09ICdGaXhlZF9HbGFzcycgfHwgbWF0ZXJpYWwubmFtZSA9PT0gJ0RlZmF1bHRfR2xhc3MnKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5jYXN0U2hhZG93ID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGVyaWFsLnRyYW5zcGFyZW50ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWF0ZXJpYWwub3BhY2l0eSA9IDAuMjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWF0ZXJpYWwuZm9ybWF0ID0gVEhSRUUuUkdCQUZvcm1hdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWF0ZXJpYWwubmVlZHNVcGRhdGUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIFJlbW92ZSB0byBpZ25vcmUgb2xkIGRvb3IgbW9kZWxzXHJcbiAgICAgICAgaWYgKG1lc2hlc0ZvdW5kID09PSAxKSB7XHJcbiAgICAgICAgICAgIHRoaXMudHJhdmVyc2UoKGNoaWxkKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiBNZXNoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2hpbGQuY2FzdFNoYWRvdyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0ZXJpYWxzOiBhbnkgPSAhQXJyYXkuaXNBcnJheShjaGlsZC5tYXRlcmlhbCkgPyBbY2hpbGQubWF0ZXJpYWxdIDogY2hpbGQubWF0ZXJpYWw7XHJcbiAgICAgICAgICAgICAgICAgICAgbWF0ZXJpYWxzLmZvckVhY2gobSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG0udmlzaWJsZSA9IG0ubmFtZSAmJiAobS5uYW1lID09PSAnRml4ZWRfR2xhc3MnIHx8IG0ubmFtZSA9PT0gJ0RlZmF1bHRfR2xhc3MnKSA/IG0udmlzaWJsZSA9IGZhbHNlIDogbS52aXNpYmxlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgV2FsbEl0ZW1Hcm91cCBleHRlbmRzIEl0ZW1Hcm91cCB7XHJcblxyXG4gICAgcHVibGljIGN1cnJlbnRXYWxsRWRnZTogSGFsZkVkZ2U7XHJcbiAgICBwdWJsaWMgY3VycmVudFdhbGw6IFdhbGw7XHJcbiAgICBwdWJsaWMgZWxldmF0aW9uQWRqdXN0YWJsZTogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gICAgcHJpdmF0ZSBfcG9zaXRpb25ZVG9sZXJhbmNlID0gMC4wMDU7XHJcbiAgICBwcml2YXRlIF9vcmlnaW5hbFJvdGF0aW9uOiBFdWxlcjtcclxuICAgIHByaXZhdGUgX29uRnJvbnRTaWRlOiBib29sZWFuO1xyXG4gICAgcHJpdmF0ZSBfd2FsbE9mZnNldFNjYWxhciA9IDA7XHJcbiAgICBwcml2YXRlIF9zaXplWCA9IDA7XHJcbiAgICBwcml2YXRlIF9zaXplWSA9IDA7XHJcbiAgICBwcml2YXRlIF9yZWZWZWMgPSBuZXcgVEhSRUUuVmVjdG9yMigwLCAxLjApO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICAgICAgdGhpcy5tZXRhZGF0YSA9IHtcclxuICAgICAgICAgICAgaXRlbVR5cGU6IDIyXHJcbiAgICAgICAgfTtcclxuICAgICAgICB0aGlzLnVzZXJEYXRhLml0ZW1UeXBlID0gdGhpcy5tZXRhZGF0YS5pdGVtVHlwZTtcclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgcmVkcmF3V2FsbCgpIHtcclxuICAgICAgICBpZiAodGhpcy5jdXJyZW50V2FsbEVkZ2UgJiYgdGhpcy5jdXJyZW50V2FsbEVkZ2Uud2FsbCkge1xyXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRXYWxsRWRnZS53YWxsLmZpcmVSZWRyYXcoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGlzVmFsaWRQb3NpdGlvbihwb3NpdGlvbjogVmVjdG9yMywgcm90YXRpb24/OiBFdWxlciwgb3B0aW9ucz86IGFueSk6IENvbGxpc2lvbkluZm8ge1xyXG4gICAgICAgIHJldHVybiB7IHZhbGlkOiB0cnVlIH07XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIG1vdmVUb1Bvc2l0aW9uKHZlYzM6IFZlY3RvcjMsIGludGVyc2VjdGlvbj86IEludGVyc2VjdGlvbikge1xyXG4gICAgICAgIGlmIChpbnRlcnNlY3Rpb24pIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmN1cnJlbnRXYWxsRWRnZSAmJiAodGhpcy5pdGVtc1swXSBhcyBXYWxsSXRlbSkuY3VycmVudFdhbGxFZGdlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRXYWxsRWRnZSA9ICh0aGlzLml0ZW1zWzBdIGFzIFdhbGxJdGVtKS5jdXJyZW50V2FsbEVkZ2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudFdhbGxFZGdlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9ib3VuZE1vdmUodmVjMyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBvc2l0aW9uLmNvcHkodmVjMyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlZHJhd1dhbGwoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgY3JlYXRlQm91bmRhcnlCb3goKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5ib3VuZGFyeUJveC5zZXRGcm9tT2JqZWN0KHRoaXMpO1xyXG4gICAgICAgIGNvbnN0IG1heCA9IHRoaXMuYm91bmRhcnlCb3gubWF4LmNsb25lKCk7XHJcbiAgICAgICAgY29uc3QgbWluID0gdGhpcy5ib3VuZGFyeUJveC5taW4uY2xvbmUoKTtcclxuICAgICAgICB0aGlzLmhhbGZTaXplID0gbWF4LnN1YihtaW4pLmRpdmlkZVNjYWxhcigyKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZVNpemUoKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgY2VudGVyUGl2b3QoKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgYm91bmRhcnlCb3hDZW50ZXIgPSB0aGlzLmJvdW5kYXJ5Qm94Q2VudGVyO1xyXG4gICAgICAgIHRoaXMucG9zaXRpb24uY29weShib3VuZGFyeUJveENlbnRlcik7XHJcbiAgICAgICAgdGhpcy5pdGVtcy5mb3JFYWNoKGkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBvcmlnaW5hbFBvc2l0aW9uID0gaS5wb3NpdGlvbi5jbG9uZSgpO1xyXG4gICAgICAgICAgICBjb25zdCBuZXdQb3NpdGlvbiA9IG9yaWdpbmFsUG9zaXRpb24uc3ViKGJvdW5kYXJ5Qm94Q2VudGVyKTtcclxuICAgICAgICAgICAgaS5wb3NpdGlvbi5jb3B5KG5ld1Bvc2l0aW9uKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgdXBkYXRlU2l6ZSgpIHtcclxuICAgICAgICB0aGlzLl93YWxsT2Zmc2V0U2NhbGFyID0gdGhpcy5oYWxmU2l6ZS56O1xyXG4gICAgICAgIHRoaXMuX3NpemVYID0gdGhpcy5oYWxmU2l6ZS54ICogMjtcclxuICAgICAgICB0aGlzLl9zaXplWSA9IHRoaXMuaGFsZlNpemUueSAqIDI7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIG9uV2FsbE1vdmVkKHdhbGw6IFdhbGwpIHtcclxuICAgICAgICBpZiAod2FsbC5mcm9udEVkZ2UpIHtcclxuICAgICAgICAgICAgdGhpcy5wbGFjZU9uRWRnZSh3YWxsLmZyb250RWRnZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh3YWxsLmJhY2tFZGdlKSB7XHJcbiAgICAgICAgICAgIHRoaXMucGxhY2VPbkVkZ2Uod2FsbC5iYWNrRWRnZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBwbGFjZU9uRWRnZShlZGdlOiBIYWxmRWRnZSkge1xyXG4gICAgICAgIHRoaXMuX29yaWdpbmFsUm90YXRpb24gPSB0aGlzLnJvdGF0aW9uLmNsb25lKCk7XHJcblxyXG4gICAgICAgIGlmICghZWRnZSkgeyByZXR1cm47IH1cclxuICAgICAgICB0aGlzLl9vbkZyb250U2lkZSA9IGVkZ2Uud2FsbC5mcm9udEVkZ2UgPT09IGVkZ2U7XHJcbiAgICAgICAgdGhpcy5fY2hhbmdlV2FsbEVkZ2UoZWRnZSk7XHJcblxyXG4gICAgICAgIGNvbnN0IG5ld1BvcyA9IGVkZ2Uud2FsbC5hbW91bnRXYWxsTW92ZWQgPyB0aGlzLnBvc2l0aW9uLmFkZChuZXcgVmVjdG9yMyhlZGdlLndhbGwuYW1vdW50V2FsbE1vdmVkLngsIDAsIDApKSA6IHRoaXMucG9zaXRpb24uY2xvbmUoKTtcclxuICAgICAgICB0aGlzLl9ib3VuZE1vdmUobmV3UG9zKTtcclxuICAgICAgICB0aGlzLnBvc2l0aW9uLmNvcHkobmV3UG9zKTtcclxuICAgICAgICB0aGlzLnJlZHJhd1dhbGwoKTtcclxuICAgICAgICB0aGlzLmFsbG93Um90YXRlID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGhhbmRsZUdyb3VwQ3JlYXRpb24oKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5pdGVtcy5mb3JFYWNoKChpKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5jdXJyZW50V2FsbEVkZ2UpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFdhbGxFZGdlID0gKGkgYXMgV2FsbEl0ZW0pLmN1cnJlbnRXYWxsRWRnZTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFdhbGwgPSB0aGlzLmN1cnJlbnRXYWxsRWRnZS53YWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFdhbGwucmVtb3ZlT25JdGVtKGkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMucGxhY2VPbkVkZ2UodGhpcy5jdXJyZW50V2FsbEVkZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX2NoYW5nZVdhbGxFZGdlKHdhbGxFZGdlOiBIYWxmRWRnZSkge1xyXG4gICAgICAgIC8vIGZpbmQgYW5nbGUgYmV0d2VlbiB3YWxsIG5vcm1hbHNcclxuICAgICAgICBjb25zdCBub3JtYWwyID0gbmV3IFRIUkVFLlZlY3RvcjIoKTtcclxuICAgICAgICBjb25zdCBub3JtYWwzID0gVXRpbHMuR2V0RmFjZU5vcm1hbEZyb21CdWZmZXJHZW9tZXRyeSh3YWxsRWRnZS5wbGFuZS5nZW9tZXRyeSwgMCwgMCk7XHJcbiAgICAgICAgbm9ybWFsMi54ID0gbm9ybWFsMy54O1xyXG4gICAgICAgIG5vcm1hbDIueSA9IG5vcm1hbDMuejtcclxuXHJcbiAgICAgICAgY29uc3Qgd2FsbFJvdGF0aW9uID0gVXRpbHMuYW5nbGUoXHJcbiAgICAgICAgICAgIHRoaXMuX3JlZlZlYy54LCB0aGlzLl9yZWZWZWMueSxcclxuICAgICAgICAgICAgbm9ybWFsMi54LCBub3JtYWwyLnkpO1xyXG5cclxuICAgICAgICAvLyB0cmFuc2ZlciByb3RhdGlvbiBmcm9tIGNoaWxkIHRvIHBhcmVudCBhbmQgcmVzZXQgYm91bmRhcnkgYm94XHJcbiAgICAgICAgaWYgKHRoaXMuaXRlbXNbMF0ucm90YXRpb24ueSAhPT0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLml0ZW1zLmZvckVhY2goKGkpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW1Xb3JsZFBvc2l0aW9uOiBWZWN0b3IzID0gaS5nZXRXb3JsZFBvc2l0aW9uKG5ldyBWZWN0b3IzKCkpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmUoaSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJvdGF0aW9uLnkgPSB3YWxsUm90YXRpb247XHJcbiAgICAgICAgICAgICAgICBpLnBvc2l0aW9uLmNvcHkoaXRlbVdvcmxkUG9zaXRpb24pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hdHRhY2goaSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJvdGF0aW9uLnkgPSAwO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlQm91bmRhcnlCb3goKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMucm90YXRpb24ueSA9IHdhbGxSb3RhdGlvbjtcclxuICAgICAgICB0aGlzLnRyYXZlcnNlKGMgPT4gYy5tYXRyaXhXb3JsZE5lZWRzVXBkYXRlID0gdHJ1ZSk7XHJcblxyXG4gICAgICAgIC8vIHVwZGF0ZSBjdXJyZW50V2FsbFxyXG4gICAgICAgIHRoaXMuY3VycmVudFdhbGwgPSB3YWxsRWRnZS53YWxsO1xyXG4gICAgICAgIHRoaXMuY3VycmVudFdhbGxFZGdlID0gd2FsbEVkZ2U7XHJcbiAgICAgICAgd2FsbEVkZ2Uud2FsbC5hZGRPbkl0ZW0odGhpcyBhcyBhbnkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyB1cGRhdGVFZGdlVmlzaWJpbGl0eShlZGdlOiBFZGdlKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudFdhbGwpIHtcclxuICAgICAgICAgICAgbGV0IHNob3VsZFNob3c6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudFdhbGwuYmFja0VkZ2UpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFdhbGwuYmFja0VkZ2UuZWRnZXMuZm9yRWFjaCgoZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlLnZpc2libGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2hvdWxkU2hvdyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudFdhbGwuZnJvbnRFZGdlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRXYWxsLmZyb250RWRnZS5lZGdlcy5mb3JFYWNoKGUgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlLnZpc2libGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2hvdWxkU2hvdyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy52aXNpYmxlID0gc2hvdWxkU2hvdztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfYm91bmRNb3ZlKHZlYzM6IFZlY3RvcjMpIHtcclxuICAgICAgICBjb25zdCBlZGdlID0gdGhpcy5jdXJyZW50V2FsbEVkZ2U7XHJcbiAgICAgICAgdmVjMy5hcHBseU1hdHJpeDQoZWRnZS5pbnRlcmlvclRyYW5zZm9ybSk7XHJcbiAgICAgICAgZWRnZS53YWxsLml0ZW1zQ2hhbmdlZCA9IHRydWU7XHJcblxyXG4gICAgICAgIGlmICh2ZWMzLnggPCB0aGlzLl9zaXplWCAvIDIuMCArIHRoaXMuX3Bvc2l0aW9uWVRvbGVyYW5jZSkge1xyXG4gICAgICAgICAgICB2ZWMzLnggPSB0aGlzLl9zaXplWCAvIDIuMCArIHRoaXMuX3Bvc2l0aW9uWVRvbGVyYW5jZTtcclxuICAgICAgICB9IGVsc2UgaWYgKHZlYzMueCA+IChlZGdlLmludGVyaW9yRGlzdGFuY2UoKSAtIHRoaXMuX3NpemVYIC8gMi4wIC0gdGhpcy5fcG9zaXRpb25ZVG9sZXJhbmNlKSkge1xyXG4gICAgICAgICAgICB2ZWMzLnggPSBlZGdlLmludGVyaW9yRGlzdGFuY2UoKSAtIHRoaXMuX3NpemVYIC8gMi4wIC0gdGhpcy5fcG9zaXRpb25ZVG9sZXJhbmNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuZWxldmF0aW9uRml4ZWQgfHwgIXRoaXMuZWxldmF0aW9uQWRqdXN0YWJsZSkge1xyXG4gICAgICAgICAgICB2ZWMzLnkgPSB0aGlzLnBvc2l0aW9uLnk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgbWF4WTogbnVtYmVyID0gdGhpcy5fZ2V0TWF4WShlZGdlKTtcclxuICAgICAgICAgICAgY29uc3QgbWluWTogbnVtYmVyID0gdGhpcy5fZ2V0TWluWSgpO1xyXG4gICAgICAgICAgICBpZiAodmVjMy55IDwgbWluWSkge1xyXG4gICAgICAgICAgICAgICAgdmVjMy55ID0gbWluWTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh2ZWMzLnkgPiBtYXhZKSB7XHJcbiAgICAgICAgICAgICAgICB2ZWMzLnkgPSBtYXhZO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuZWxldmF0aW9uID0gdmVjMy55IC0gdGhpcy5oYWxmU2l6ZS55O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmVjMy56ID0gdGhpcy5fd2FsbE9mZnNldFNjYWxhcjtcclxuICAgICAgICB2ZWMzLmFwcGx5TWF0cml4NChlZGdlLmludkludGVyaW9yVHJhbnNmb3JtKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9nZXRNYXhZKGVkZ2U6IEhhbGZFZGdlKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gZWRnZS5oZWlnaHQgLSB0aGlzLmhhbGZTaXplLnkgLSB0aGlzLl9wb3NpdGlvbllUb2xlcmFuY2U7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZ2V0TWluWSgpOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmhhbGZTaXplLnkgKyB0aGlzLl9wb3NpdGlvbllUb2xlcmFuY2U7XHJcbiAgICB9XHJcbn1cclxuIl19